diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index d38b71989f..5f27bdd8e1 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -110,6 +110,7 @@ const ppu_decoder g_ppu_interpreter_fast; const ppu_decoder g_ppu_itype; extern void ppu_initialize(); +extern void ppu_finalize(const ppu_module& info); extern void ppu_initialize(const ppu_module& info); static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name); extern void ppu_execute_syscall(ppu_thread& ppu, u64 code); @@ -1921,6 +1922,83 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value) return ppu_store_reservation(ppu, addr, reg_value); } +#ifdef LLVM_AVAILABLE +namespace +{ + // Compiled PPU module info + struct jit_module + { + std::vector vars; + std::vector funcs; + std::shared_ptr pjit; + }; + + struct jit_module_manager + { + shared_mutex mutex; + std::unordered_map map; + + jit_module& get(const std::string& name) + { + std::lock_guard lock(mutex); + return map.emplace(name, jit_module{}).first->second; + } + + void remove(const std::string& name) noexcept + { + std::lock_guard lock(mutex); + + const auto found = map.find(name); + + if (found == map.end()) [[unlikely]] + { + ppu_log.error("Failed to remove module %s", name); + return; + } + + map.erase(found); + } + }; +} +#endif + +extern void ppu_finalize(const ppu_module& info) +{ + // Get cache path for this executable + std::string cache_path; + + if (info.name.empty()) + { + // Don't remove main module from memory + return; + } + else + { + // Get PPU cache location + cache_path = fs::get_cache_dir() + "cache/"; + + const std::string dev_flash = vfs::get("/dev_flash/"); + + if (info.path.starts_with(dev_flash) || Emu.GetCat() == "1P") + { + // Don't remove dev_flash prx from memory + return; + } + else if (!Emu.GetTitleID().empty()) + { + cache_path += Emu.GetTitleID(); + cache_path += '/'; + } + + // Add PPU hash and filename + fmt::append(cache_path, "ppu-%s-%s/", fmt::base57(info.sha1), info.path.substr(info.path.find_last_of('/') + 1)); + } + +#ifdef LLVM_AVAILABLE + g_fxo->get()->remove(cache_path + info.name); +#endif +} + extern void ppu_initialize() { const auto _main = g_fxo->get(); @@ -2056,14 +2134,6 @@ extern void ppu_initialize(const ppu_module& info) // Initialize progress dialog g_progr = "Compiling PPU modules..."; - // Compiled PPU module info - struct jit_module - { - std::vector vars; - std::vector funcs; - std::shared_ptr pjit; - }; - struct jit_core_allocator { const s32 thread_count = g_cfg.core.llvm_threads ? std::min(g_cfg.core.llvm_threads, limit()) : limit(); @@ -2077,18 +2147,6 @@ extern void ppu_initialize(const ppu_module& info) } }; - struct jit_module_manager - { - shared_mutex mutex; - std::unordered_map map; - - jit_module& get(const std::string& name) - { - std::lock_guard lock(mutex); - return map.emplace(name, jit_module{}).first->second; - } - }; - // Permanently loaded compiled PPU modules (name -> data) jit_module& jit_mod = g_fxo->get()->get(cache_path + info.name); diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp index da0a1f5921..cf7e6e3535 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp @@ -15,6 +15,7 @@ extern std::shared_ptr ppu_load_overlay(const ppu_exec_object&, const std::string& path); extern void ppu_initialize(const ppu_module&); +extern void ppu_finalize(const ppu_module&); LOG_CHANNEL(sys_overlay); @@ -118,5 +119,7 @@ error_code sys_overlay_unload_module(u32 ovlmid) vm::dealloc(seg.addr); } + ppu_finalize(*_main); + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 7031a1a89c..97954a6d0e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -18,6 +18,7 @@ extern std::shared_ptr ppu_load_prx(const ppu_prx_object&, const std::string&); extern void ppu_unload_prx(const lv2_prx& prx); extern void ppu_initialize(const ppu_module&); +extern void ppu_finalize(const ppu_module&); LOG_CHANNEL(sys_prx); @@ -590,6 +591,8 @@ error_code _sys_prx_unload_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptrexit ? prx->exit() : CELL_OK; return CELL_OK; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index fc2fff776d..301054af4b 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -69,6 +69,7 @@ atomic_t g_watchdog_hold_ctr{0}; extern void ppu_load_exec(const ppu_exec_object&); extern void spu_load_exec(const spu_exec_object&); extern void ppu_initialize(const ppu_module&); +extern void ppu_finalize(const ppu_module&); extern void ppu_unload_prx(const lv2_prx&); extern std::shared_ptr ppu_load_prx(const ppu_prx_object&, const std::string&); @@ -1227,6 +1228,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool idm::remove(idm::last_id()); lock.lock(); ppu_unload_prx(*prx); + lock.unlock(); + ppu_finalize(*prx); g_progr_fdone++; continue; }