PPU LLVM: Reduce PRX/OVL compilation memory usage a little

This commit is contained in:
Eladash 2021-02-12 13:40:55 +02:00 committed by Ivan
parent 0a23a5ef50
commit 423cc1685c
6 changed files with 53 additions and 11 deletions

View File

@ -809,6 +809,11 @@ void try_spawn_ppu_if_exclusive_program(const ppu_module& m)
std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::string& path)
{
if (elf != elf_error::ok)
{
return nullptr;
}
// Create new PRX object
const auto prx = idm::make_ptr<lv2_obj, lv2_prx>();
@ -1161,6 +1166,11 @@ void ppu_unload_prx(const lv2_prx& prx)
bool ppu_load_exec(const ppu_exec_object& elf)
{
if (elf != elf_error::ok)
{
return false;
}
// Check if it is a standalone executable first
for (const auto& prog : elf.progs)
{
@ -1740,6 +1750,11 @@ bool ppu_load_exec(const ppu_exec_object& elf)
std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_exec_object& elf, const std::string& path)
{
if (elf != elf_error::ok)
{
return {nullptr, CELL_ENOENT};
}
// Access linkage information object
const auto link = g_fxo->get<ppu_linkage_info>();

View File

@ -2423,13 +2423,14 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<lv2_
elf_error prx_err{}, ovl_err{};
if (const ppu_prx_object obj = src; (prx_err = obj, obj == elf_error::ok))
if (ppu_prx_object obj = src; (prx_err = obj, obj == elf_error::ok))
{
std::unique_lock lock(sprx_mtx);
if (auto prx = ppu_load_prx(obj, path))
{
lock.unlock();
obj.clear(), src.close(); // Clear decrypted file and elf object memory
ppu_initialize(*prx);
idm::remove<lv2_obj, lv2_prx>(idm::last_id());
lock.lock();
@ -2443,7 +2444,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<lv2_
prx_err = elf_error::header_type;
}
if (const ppu_exec_object obj = src; (ovl_err = obj, obj == elf_error::ok))
if (ppu_exec_object obj = src; (ovl_err = obj, obj == elf_error::ok))
{
while (ovl_err == elf_error::ok)
{
@ -2459,6 +2460,8 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<lv2_
break;
}
obj.clear(), src.close(); // Clear decrypted file and elf object memory
ppu_initialize(*ovlm);
for (auto& seg : ovlm->segs)

View File

@ -35,7 +35,7 @@ static error_code overlay_load_module(vm::ptr<u32> ovlmid, const std::string& vp
u128 klic = g_fxo->get<loaded_npdrm_keys>()->devKlic.load();
const ppu_exec_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic));
ppu_exec_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic));
if (obj != elf_error::ok)
{
@ -44,6 +44,8 @@ static error_code overlay_load_module(vm::ptr<u32> ovlmid, const std::string& vp
const auto [ovlm, error] = ppu_load_overlay(obj, vfs::get(vpath));
obj.clear();
if (error)
{
return error;

View File

@ -266,7 +266,7 @@ static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptr<s
u128 klic = g_fxo->get<loaded_npdrm_keys>()->devKlic.load();
const ppu_prx_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic));
ppu_prx_object obj = decrypt_self(std::move(src), reinterpret_cast<u8*>(&klic));
if (obj != elf_error::ok)
{
@ -275,6 +275,8 @@ static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptr<s
const auto prx = ppu_load_prx(obj, path);
obj.clear();
if (!prx)
{
return CELL_PRX_ERROR_ILLEGAL_LIBRARY;

View File

@ -1597,7 +1597,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
// Overlay (OVL) executable (only load it)
else if (vm::map(0x3000'0000, 0x1000'0000, 0x200); !ppu_load_overlay(ppu_exec, m_path).first)
{
ppu_exec = fs::file{};
ppu_exec.set_error(elf_error::header_type);
}
if (ppu_exec != elf_error::ok)

View File

@ -170,12 +170,7 @@ enum class elf_error
template<template<typename T> class en_t, typename sz_t, elf_machine Machine, elf_os OS, elf_type Type>
class elf_object
{
elf_error m_error{};
elf_error set_error(elf_error e)
{
return m_error = e;
}
elf_error m_error = elf_error::stream; // Set initial error to "file not found" error
public:
using ehdr_t = elf_ehdr<en_t, sz_t>;
@ -329,6 +324,31 @@ public:
}
}
elf_object& clear()
{
// Do not use clear() in order to dealloc memory
progs = {};
shdrs = {};
header.e_magic = 0;
m_error = elf_error::stream;
return *this;
}
elf_object& set_error(elf_error error)
{
// Setting an error causes the state to clear if there was no error before
// Trying to set elf_error::ok is ignored
if (error != elf_error::ok)
{
if (m_error == elf_error::ok)
clear();
m_error = error;
}
return *this;
}
// Return error code
operator elf_error() const
{