Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Feb 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions rpcs3/Emu/Cell/PPUModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>();

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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>();

Expand Down
7 changes: 5 additions & 2 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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)
{
Expand All @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion rpcs3/Emu/Cell/lv2/sys_overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion rpcs3/Emu/Cell/lv2/sys_prx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
32 changes: 26 additions & 6 deletions rpcs3/Loader/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down Expand Up @@ -329,6 +324,31 @@ class elf_object
}
}

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
{
Expand Down