PPU LLVM: Fix memory leak on precompilation

This commit is contained in:
Eladash 2024-03-30 17:20:08 +03:00 committed by Elad Ashkenazi
parent d62e90f5b4
commit f0abb4473e
3 changed files with 26 additions and 13 deletions

View file

@ -172,7 +172,7 @@ bool serialize<ppu_thread::cr_bits>(utils::serial& ar, typename ppu_thread::cr_b
} }
extern void ppu_initialize(); extern void ppu_initialize();
extern void ppu_finalize(const ppu_module& info); extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false);
extern bool ppu_initialize(const ppu_module& info, bool check_only = false, u64 file_size = 0); extern bool ppu_initialize(const ppu_module& info, bool check_only = false, u64 file_size = 0);
static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name, const ppu_module& whole_module); static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name, const ppu_module& whole_module);
extern bool ppu_load_exec(const ppu_exec_object&, bool virtual_load, const std::string&, utils::serial* = nullptr); extern bool ppu_load_exec(const ppu_exec_object&, bool virtual_load, const std::string&, utils::serial* = nullptr);
@ -3706,21 +3706,31 @@ extern fs::file make_file_view(fs::file&& _file, u64 offset, u64 max_size = umax
return file; return file;
} }
extern void ppu_finalize(const ppu_module& info) extern void ppu_finalize(const ppu_module& info, bool force_mem_release)
{ {
if (info.name.empty()) if (!force_mem_release && info.name.empty())
{ {
// Don't remove main module from memory // Don't remove main module from memory
return; return;
} }
const std::string dev_flash = vfs::get("/dev_flash/sys/"); if (!force_mem_release && Emu.GetCat() == "1P")
{
return;
}
if (info.path.starts_with(dev_flash) || Emu.GetCat() == "1P") const bool may_be_elf = fmt::to_lower(info.path.substr(std::max<usz>(info.path.size(), 3) - 3)) != "prx";
if (!may_be_elf)
{
const std::string dev_flash = vfs::get("/dev_flash/sys/external");
if (!force_mem_release && info.path.starts_with(dev_flash))
{ {
// Don't remove dev_flash prx from memory // Don't remove dev_flash prx from memory
return; return;
} }
}
// Get cache path for this executable // Get cache path for this executable
std::string cache_path = fs::get_cache_dir() + "cache/"; std::string cache_path = fs::get_cache_dir() + "cache/";
@ -3960,7 +3970,10 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
::semaphore<2> ovl_sema; ::semaphore<2> ovl_sema;
named_thread_group workers("SPRX Worker ", std::min<u32>(utils::get_thread_count(), ::size32(file_queue)), [&] const u32 software_thread_limit = std::min<u32>(g_cfg.core.llvm_threads ? g_cfg.core.llvm_threads : u32{umax}, ::size32(file_queue));
const u32 cpu_thread_limit = utils::get_thread_count() > 8u ? std::max<u32>(utils::get_thread_count(), 2) - 1 : utils::get_thread_count(); // One LLVM thread less
named_thread_group workers("SPRX Worker ", std::min<u32>(software_thread_limit, cpu_thread_limit), [&]
{ {
#ifdef __APPLE__ #ifdef __APPLE__
pthread_jit_write_protect_np(false); pthread_jit_write_protect_np(false);
@ -4015,7 +4028,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
{ {
obj.clear(), src.close(); // Clear decrypted file and elf object memory obj.clear(), src.close(); // Clear decrypted file and elf object memory
ppu_initialize(*prx, false, file_size); ppu_initialize(*prx, false, file_size);
ppu_finalize(*prx); ppu_finalize(*prx, true);
continue; continue;
} }
@ -4063,7 +4076,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
obj.clear(), src.close(); // Clear decrypted file and elf object memory obj.clear(), src.close(); // Clear decrypted file and elf object memory
ppu_initialize(*ovlm, false, file_size); ppu_initialize(*ovlm, false, file_size);
ppu_finalize(*ovlm); ppu_finalize(*ovlm, true);
break; break;
} }
@ -4164,7 +4177,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
Emu.ConfigurePPUCache(!Emu.IsPathInsideDir(_main.path, g_cfg_vfs.get_dev_flash())); Emu.ConfigurePPUCache(!Emu.IsPathInsideDir(_main.path, g_cfg_vfs.get_dev_flash()));
ppu_initialize(_main, false, file_size); ppu_initialize(_main, false, file_size);
spu_cache::initialize(false); spu_cache::initialize(false);
ppu_finalize(_main); ppu_finalize(_main, true);
_main = {}; _main = {};
g_fxo->get<spu_cache>() = std::move(current_cache); g_fxo->get<spu_cache>() = std::move(current_cache);
break; break;

View file

@ -16,7 +16,7 @@
extern std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar = nullptr); extern std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar = nullptr);
extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0);
extern void ppu_finalize(const ppu_module&); extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false);
LOG_CHANNEL(sys_overlay); LOG_CHANNEL(sys_overlay);

View file

@ -20,7 +20,7 @@
extern std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64, utils::serial* = nullptr); extern std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64, utils::serial* = nullptr);
extern void ppu_unload_prx(const lv2_prx& prx); extern void ppu_unload_prx(const lv2_prx& prx);
extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0);
extern void ppu_finalize(const ppu_module&); extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false);
extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<bool>& loaded_flags); extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<bool>& loaded_flags);
LOG_CHANNEL(sys_prx); LOG_CHANNEL(sys_prx);