Skip to content

Commit

Permalink
LLVM: compress PPU cache
Browse files Browse the repository at this point in the history
Compress PPU modules to .gz (backward compatible with uncompressed cache)
  • Loading branch information
Nekotekina committed Dec 27, 2019
1 parent e54438d commit 70e26ee
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 3 deletions.
83 changes: 82 additions & 1 deletion Utilities/JIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "sysinfo.h"
#include "VirtualMemory.h"
#include <immintrin.h>
#include <zlib.h>

#ifdef __linux__
#include <sys/mman.h>
Expand Down Expand Up @@ -912,12 +913,92 @@ class ObjectCache final : public llvm::ObjectCache
{
std::string name = m_path;
name.append(module->getName());
fs::file(name, fs::rewrite).write(obj.getBufferStart(), obj.getBufferSize());
//fs::file(name, fs::rewrite).write(obj.getBufferStart(), obj.getBufferSize());
name.append(".gz");

z_stream zs{};
uLong zsz = compressBound(obj.getBufferSize()) + 256;
auto zbuf = std::make_unique<uchar[]>(zsz);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
deflateInit2(&zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY);
#pragma GCC diagnostic pop
zs.avail_in = static_cast<uInt>(obj.getBufferSize());
zs.next_in = reinterpret_cast<uchar*>(const_cast<char*>(obj.getBufferStart()));
zs.avail_out = static_cast<uInt>(zsz);
zs.next_out = zbuf.get();

switch (deflate(&zs, Z_FINISH))
{
case Z_OK:
case Z_STREAM_END:
{
deflateEnd(&zs);
break;
}
default:
{
LOG_ERROR(GENERAL, "LLVM: Failed to compress module: %s", module->getName().data());
deflateEnd(&zs);
return;
}
}

fs::file(name, fs::rewrite).write(zbuf.get(), zsz - zs.avail_out);
LOG_NOTICE(GENERAL, "LLVM: Created module: %s", module->getName().data());
}

static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
{
if (fs::file cached{path + ".gz", fs::read})
{
std::vector<uchar> gz = cached.to_vector<uchar>();
std::vector<uchar> out;
z_stream zs{};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
inflateInit2(&zs, 16 + 15);
#pragma GCC diagnostic pop
zs.avail_in = static_cast<uInt>(gz.size());
zs.next_in = gz.data();
out.resize(gz.size() * 6);
zs.avail_out = static_cast<uInt>(out.size());
zs.next_out = out.data();

while (zs.avail_in)
{
switch (inflate(&zs, Z_FINISH))
{
case Z_OK: break;
case Z_STREAM_END: break;
case Z_BUF_ERROR:
{
if (zs.avail_in)
break;
[[fallthrough]];
}
default:
inflateEnd(&zs);
return nullptr;
}

if (zs.avail_in)
{
auto cur_size = zs.next_out - out.data();
out.resize(out.size() + 65536);
zs.avail_out = static_cast<uInt>(out.size() - cur_size);
zs.next_out = out.data() + cur_size;
}
}

out.resize(zs.next_out - out.data());
inflateEnd(&zs);

auto buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(out.size());
std::memcpy(buf->getBufferStart(), out.data(), out.size());
return buf;
}

if (fs::file cached{path, fs::read})
{
auto buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(cached.size());
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ extern void ppu_initialize(const ppu_module& info)
}

// Check object file
if (fs::is_file(cache_path + obj_name))
if (fs::is_file(cache_path + obj_name + ".gz") || fs::is_file(cache_path + obj_name))
{
if (!jit)
{
Expand Down Expand Up @@ -1657,7 +1657,7 @@ extern void ppu_initialize(const ppu_module& info)
g_progr_pdone++;
}

if (Emu.IsStopped() || !jit || !fs::is_file(cache_path + obj_name))
if (Emu.IsStopped() || !jit || !fs::is_file(cache_path + obj_name + ".gz"))
{
return;
}
Expand Down

0 comments on commit 70e26ee

Please sign in to comment.