Browse Source

[core] inline pointers to avoid uneeded allocs (lto fails to heap ellide)

Signed-off-by: lizzie <lizzie@eden-emu.dev>
pull/3284/head
lizzie 4 weeks ago
committed by crueter
parent
commit
09fd1672c8
  1. 177
      src/core/core.cpp
  2. 13
      src/core/core.h
  3. 6
      src/core/hle/service/am/applet.h

177
src/core/core.cpp

@ -112,11 +112,10 @@ struct System::Impl {
u64 program_id; u64 program_id;
void Initialize(System& system) { void Initialize(System& system) {
device_memory = std::make_unique<Core::DeviceMemory>();
device_memory.emplace();
is_multicore = Settings::values.use_multi_core.GetValue(); is_multicore = Settings::values.use_multi_core.GetValue();
extended_memory_layout =
Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
extended_memory_layout = Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
core_timing.SetMulticore(is_multicore); core_timing.SetMulticore(is_multicore);
core_timing.Initialize([&system]() { system.RegisterHostThread(); }); core_timing.Initialize([&system]() { system.RegisterHostThread(); });
@ -132,7 +131,7 @@ struct System::Impl {
// Create default implementations of applets if one is not provided. // Create default implementations of applets if one is not provided.
frontend_applets.SetDefaultAppletsIfMissing(); frontend_applets.SetDefaultAppletsIfMissing();
is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
auto const is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
kernel.SetMulticore(is_multicore); kernel.SetMulticore(is_multicore);
cpu_manager.SetMulticore(is_multicore); cpu_manager.SetMulticore(is_multicore);
@ -254,7 +253,7 @@ struct System::Impl {
} }
void InitializeDebugger(System& system, u16 port) { void InitializeDebugger(System& system, u16 port) {
debugger = std::make_unique<Debugger>(system, port);
debugger.emplace(system, port);
} }
void InitializeKernel(System& system) { void InitializeKernel(System& system) {
@ -268,24 +267,22 @@ struct System::Impl {
} }
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
host1x_core.emplace(system);
gpu_core = VideoCore::CreateGPU(emu_window, system); gpu_core = VideoCore::CreateGPU(emu_window, system);
if (!gpu_core) {
if (!gpu_core)
return SystemResultStatus::ErrorVideoCore; return SystemResultStatus::ErrorVideoCore;
}
audio_core = std::make_unique<AudioCore::AudioCore>(system);
audio_core.emplace(system);
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
services =
std::make_unique<Service::Services>(service_manager, system, stop_event.get_token());
services.emplace(service_manager, system, stop_event.get_token());
is_powered_on = true; is_powered_on = true;
exit_locked = false; exit_locked = false;
exit_requested = false; exit_requested = false;
if (Settings::values.enable_renderdoc_hotkey) { if (Settings::values.enable_renderdoc_hotkey) {
renderdoc_api = std::make_unique<Tools::RenderdocAPI>();
renderdoc_api.emplace();
} }
LOG_DEBUG(Core, "Initialized OK"); LOG_DEBUG(Core, "Initialized OK");
@ -303,16 +300,11 @@ struct System::Impl {
// Create the application process // Create the application process
Loader::ResultStatus load_result{}; Loader::ResultStatus load_result{};
std::vector<u8> control; std::vector<u8> control;
auto process =
Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file,
params.program_id, params.program_index);
auto process = Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file, params.program_id, params.program_index);
if (load_result != Loader::ResultStatus::Success) { if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
ShutdownMainProcess(); ShutdownMainProcess();
return static_cast<SystemResultStatus>(
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
return SystemResultStatus(u32(SystemResultStatus::ErrorLoader) + u32(load_result));
} }
if (!app_loader) { if (!app_loader) {
@ -337,8 +329,7 @@ struct System::Impl {
// Set up the rest of the system. // Set up the rest of the system.
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) { if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", int(init_result));
ShutdownMainProcess(); ShutdownMainProcess();
return init_result; return init_result;
} }
@ -361,24 +352,19 @@ struct System::Impl {
} }
} }
perf_stats = std::make_unique<PerfStats>(params.program_id);
perf_stats.emplace(params.program_id);
// Reset counters and set time origin to current frame // Reset counters and set time origin to current frame
GetAndResetPerfStats(); GetAndResetPerfStats();
perf_stats->BeginSystemFrame(); perf_stats->BeginSystemFrame();
std::string title_version;
const FileSys::PatchManager pm(params.program_id, system.GetFileSystemController(),
system.GetContentProvider());
const auto metadata = pm.GetControlMetadata();
if (metadata.first != nullptr) {
title_version = metadata.first->GetVersionString();
}
const FileSys::PatchManager pm(params.program_id, system.GetFileSystemController(), system.GetContentProvider());
auto const metadata = pm.GetControlMetadata();
std::string title_version = metadata.first != nullptr ? metadata.first->GetVersionString() : "";
if (app_loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) { if (app_loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) {
LOG_ERROR(Core, "Failed to find program id for ROM"); LOG_ERROR(Core, "Failed to find program id for ROM");
} }
GameSettings::LoadOverrides(program_id, gpu_core->Renderer()); GameSettings::LoadOverrides(program_id, gpu_core->Renderer());
if (auto room_member = Network::GetRoomMember().lock()) { if (auto room_member = Network::GetRoomMember().lock()) {
Network::GameInfo game_info; Network::GameInfo game_info;
@ -387,9 +373,7 @@ struct System::Impl {
game_info.version = title_version; game_info.version = title_version;
room_member->SendGameInfo(game_info); room_member->SendGameInfo(game_info);
} }
status = SystemResultStatus::Success;
return status;
return SystemResultStatus::Success;
} }
void ShutdownMainProcess() { void ShutdownMainProcess() {
@ -448,112 +432,79 @@ struct System::Impl {
} }
Loader::ResultStatus GetGameName(std::string& out) const { Loader::ResultStatus GetGameName(std::string& out) const {
if (app_loader == nullptr)
return Loader::ResultStatus::ErrorNotInitialized;
return app_loader->ReadTitle(out);
}
void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
status = new_status;
if (details) {
status_details = details;
}
return app_loader ? app_loader->ReadTitle(out) : Loader::ResultStatus::ErrorNotInitialized;
} }
PerfStatsResults GetAndResetPerfStats() { PerfStatsResults GetAndResetPerfStats() {
return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs()); return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
} }
mutable std::mutex suspend_guard;
std::atomic_bool is_paused{};
std::atomic<bool> is_shutting_down{};
Timing::CoreTiming core_timing; Timing::CoreTiming core_timing;
Kernel::KernelCore kernel; Kernel::KernelCore kernel;
/// RealVfsFilesystem instance /// RealVfsFilesystem instance
FileSys::VirtualFilesystem virtual_filesystem; FileSys::VirtualFilesystem virtual_filesystem;
/// ContentProviderUnion instance
std::unique_ptr<FileSys::ContentProviderUnion> content_provider;
Service::FileSystem::FileSystemController fs_controller; Service::FileSystem::FileSystemController fs_controller;
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
std::unique_ptr<Tegra::GPU> gpu_core;
std::unique_ptr<Tegra::Host1x::Host1x> host1x_core;
std::unique_ptr<Core::DeviceMemory> device_memory;
std::unique_ptr<AudioCore::AudioCore> audio_core;
Core::HID::HIDCore hid_core; Core::HID::HIDCore hid_core;
CpuManager cpu_manager; CpuManager cpu_manager;
std::atomic_bool is_powered_on{};
bool exit_locked = false;
bool exit_requested = false;
bool nvdec_active{};
Reporter reporter; Reporter reporter;
std::unique_ptr<Memory::CheatEngine> cheat_engine;
std::unique_ptr<Tools::Freezer> memory_freezer;
std::array<u8, 0x20> build_id{};
std::unique_ptr<Tools::RenderdocAPI> renderdoc_api;
/// Applets /// Applets
Service::AM::AppletManager applet_manager; Service::AM::AppletManager applet_manager;
Service::AM::Frontend::FrontendAppletHolder frontend_applets; Service::AM::Frontend::FrontendAppletHolder frontend_applets;
/// APM (Performance) services /// APM (Performance) services
Service::APM::Controller apm_controller{core_timing}; Service::APM::Controller apm_controller{core_timing};
/// Service State /// Service State
Service::Glue::ARPManager arp_manager; Service::Glue::ARPManager arp_manager;
Service::Account::ProfileManager profile_manager; Service::Account::ProfileManager profile_manager;
/// Service manager
std::shared_ptr<Service::SM::ServiceManager> service_manager;
/// Services
std::unique_ptr<Service::Services> services;
/// Network instance /// Network instance
Network::NetworkInstance network_instance; Network::NetworkInstance network_instance;
/// Debugger
std::unique_ptr<Core::Debugger> debugger;
SystemResultStatus status = SystemResultStatus::Success;
std::string status_details = "";
std::unique_ptr<Core::PerfStats> perf_stats;
Core::SpeedLimiter speed_limiter; Core::SpeedLimiter speed_limiter;
bool is_multicore{};
bool is_async_gpu{};
bool extended_memory_layout{};
ExecuteProgramCallback execute_program_callback; ExecuteProgramCallback execute_program_callback;
ExitCallback exit_callback; ExitCallback exit_callback;
std::stop_source stop_event;
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
std::optional<Service::Services> services;
std::optional<Core::Debugger> debugger;
std::optional<Service::KernelHelpers::ServiceContext> general_channel_context;
std::optional<Service::Event> general_channel_event;
std::optional<Core::PerfStats> perf_stats;
std::optional<Tegra::Host1x::Host1x> host1x_core;
std::optional<Core::DeviceMemory> device_memory;
std::optional<AudioCore::AudioCore> audio_core;
std::optional<Memory::CheatEngine> cheat_engine;
std::optional<Tools::Freezer> memory_freezer;
std::optional<Tools::RenderdocAPI> renderdoc_api;
std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> gpu_dirty_memory_managers;
std::vector<std::vector<u8>> user_channel;
std::vector<std::vector<u8>> general_channel;
std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES>
gpu_dirty_memory_managers;
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
std::array<u8, 0x20> build_id{};
std::deque<std::vector<u8>> user_channel;
/// Service manager
std::shared_ptr<Service::SM::ServiceManager> service_manager;
/// ContentProviderUnion instance
std::unique_ptr<FileSys::ContentProviderUnion> content_provider;
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
std::unique_ptr<Tegra::GPU> gpu_core;
std::stop_source stop_event;
mutable std::mutex suspend_guard;
std::mutex general_channel_mutex; std::mutex general_channel_mutex;
std::deque<std::vector<u8>> general_channel;
std::unique_ptr<Service::KernelHelpers::ServiceContext> general_channel_context; // lazy
std::unique_ptr<Service::Event> general_channel_event; // lazy
bool general_channel_initialized{false};
std::atomic_bool is_paused{};
std::atomic_bool is_shutting_down{};
std::atomic_bool is_powered_on{};
bool is_multicore : 1 = false;
bool extended_memory_layout : 1 = false;
bool exit_locked : 1 = false;
bool exit_requested : 1 = false;
bool nvdec_active : 1 = false;
void EnsureGeneralChannelInitialized(System& system) { void EnsureGeneralChannelInitialized(System& system) {
if (general_channel_initialized) {
return;
if (!general_channel_event) {
general_channel_context.emplace(system, "GeneralChannel");
general_channel_event.emplace(*general_channel_context);
} }
general_channel_context = std::make_unique<Service::KernelHelpers::ServiceContext>(system, "GeneralChannel");
general_channel_event = std::make_unique<Service::Event>(*general_channel_context);
general_channel_initialized = true;
} }
}; };
@ -776,14 +727,6 @@ Loader::ResultStatus System::GetGameName(std::string& out) const {
return impl->GetGameName(out); return impl->GetGameName(out);
} }
void System::SetStatus(SystemResultStatus new_status, const char* details) {
impl->SetStatus(new_status, details);
}
const std::string& System::GetStatusDetails() const {
return impl->status_details;
}
Loader::AppLoader& System::GetAppLoader() { Loader::AppLoader& System::GetAppLoader() {
return *impl->app_loader; return *impl->app_loader;
} }
@ -803,7 +746,7 @@ FileSys::VirtualFilesystem System::GetFilesystem() const {
void System::RegisterCheatList(const std::vector<Memory::CheatEntry>& list, void System::RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
const std::array<u8, 32>& build_id, u64 main_region_begin, const std::array<u8, 32>& build_id, u64 main_region_begin,
u64 main_region_size) { u64 main_region_size) {
impl->cheat_engine = std::make_unique<Memory::CheatEngine>(*this, list, build_id);
impl->cheat_engine.emplace(*this, list, build_id);
impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size); impl->cheat_engine->SetMainMemoryParameters(main_region_begin, main_region_size);
} }
@ -964,11 +907,13 @@ void System::ExecuteProgram(std::size_t program_index) {
} }
} }
std::deque<std::vector<u8>>& System::GetUserChannel() {
/// @brief Gets a reference to the user channel stack.
/// It is used to transfer data between programs.
std::vector<std::vector<u8>>& System::GetUserChannel() {
return impl->user_channel; return impl->user_channel;
} }
std::deque<std::vector<u8>>& System::GetGeneralChannel() {
std::vector<std::vector<u8>>& System::GetGeneralChannel() {
return impl->general_channel; return impl->general_channel;
} }
@ -984,7 +929,7 @@ void System::PushGeneralChannelData(std::vector<u8>&& data) {
bool System::TryPopGeneralChannel(std::vector<u8>& out_data) { bool System::TryPopGeneralChannel(std::vector<u8>& out_data) {
std::scoped_lock lk{impl->general_channel_mutex}; std::scoped_lock lk{impl->general_channel_mutex};
if (!impl->general_channel_initialized || impl->general_channel.empty()) {
if (!impl->general_channel_event || impl->general_channel.empty()) {
return false; return false;
} }
out_data = std::move(impl->general_channel.back()); out_data = std::move(impl->general_channel.back());

13
src/core/core.h

@ -325,10 +325,6 @@ public:
/// Gets the name of the current game /// Gets the name of the current game
[[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const; [[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
void SetStatus(SystemResultStatus new_status, const char* details);
[[nodiscard]] const std::string& GetStatusDetails() const;
[[nodiscard]] Loader::AppLoader& GetAppLoader(); [[nodiscard]] Loader::AppLoader& GetAppLoader();
[[nodiscard]] const Loader::AppLoader& GetAppLoader() const; [[nodiscard]] const Loader::AppLoader& GetAppLoader() const;
@ -424,13 +420,8 @@ public:
*/ */
void ExecuteProgram(std::size_t program_index); void ExecuteProgram(std::size_t program_index);
/**
* Gets a reference to the user channel stack.
* It is used to transfer data between programs.
*/
[[nodiscard]] std::deque<std::vector<u8>>& GetUserChannel();
[[nodiscard]] std::deque<std::vector<u8>>& GetGeneralChannel();
[[nodiscard]] std::vector<std::vector<u8>>& GetUserChannel();
[[nodiscard]] std::vector<std::vector<u8>>& GetGeneralChannel();
void PushGeneralChannelData(std::vector<u8>&& data); void PushGeneralChannelData(std::vector<u8>&& data);
bool TryPopGeneralChannel(std::vector<u8>& out_data); bool TryPopGeneralChannel(std::vector<u8>& out_data);
[[nodiscard]] Service::Event& GetGeneralChannelEvent(); [[nodiscard]] Service::Event& GetGeneralChannelEvent();

6
src/core/hle/service/am/applet.h

@ -95,9 +95,9 @@ struct Applet {
bool request_exit_to_library_applet_at_execute_next_program_enabled{}; bool request_exit_to_library_applet_at_execute_next_program_enabled{};
// Channels // Channels
std::deque<std::vector<u8>> user_channel_launch_parameter{};
std::deque<std::vector<u8>> preselected_user_launch_parameter{};
std::deque<std::vector<u8>> friend_invitation_storage_channel{};
std::vector<std::vector<u8>> user_channel_launch_parameter{};
std::vector<std::vector<u8>> preselected_user_launch_parameter{};
std::vector<std::vector<u8>> friend_invitation_storage_channel{};
// Context Stack // Context Stack
std::stack<SharedPointer<IStorage>> context_stack{}; std::stack<SharedPointer<IStorage>> context_stack{};

Loading…
Cancel
Save