1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

LLVM: compress PPU cache

Compress PPU modules to .gz (backward compatible with uncompressed cache)
This commit is contained in:
Nekotekina 2019-12-27 22:50:14 +03:00
parent e54438d3a7
commit 70e26eeb45
2 changed files with 84 additions and 3 deletions

View File

@ -7,6 +7,7 @@
#include "sysinfo.h" #include "sysinfo.h"
#include "VirtualMemory.h" #include "VirtualMemory.h"
#include <immintrin.h> #include <immintrin.h>
#include <zlib.h>
#ifdef __linux__ #ifdef __linux__
#include <sys/mman.h> #include <sys/mman.h>
@ -912,12 +913,92 @@ public:
{ {
std::string name = m_path; std::string name = m_path;
name.append(module->getName()); 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()); LOG_NOTICE(GENERAL, "LLVM: Created module: %s", module->getName().data());
} }
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path) 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}) if (fs::file cached{path, fs::read})
{ {
auto buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(cached.size()); auto buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(cached.size());

View File

@ -1617,7 +1617,7 @@ extern void ppu_initialize(const ppu_module& info)
} }
// Check object file // 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) if (!jit)
{ {
@ -1657,7 +1657,7 @@ extern void ppu_initialize(const ppu_module& info)
g_progr_pdone++; 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; return;
} }