diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index b183f16f7d..e994546e36 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -10,6 +10,7 @@ #include "util/v128.hpp" #include "util/simd.hpp" #include "Crypto/unzip.h" + #include #ifdef __linux__ @@ -1170,17 +1171,19 @@ public: //fs::file(name, fs::rewrite).write(obj.getBufferStart(), obj.getBufferSize()); name.append(".gz"); - const std::vector zbuf = zip(reinterpret_cast(obj.getBufferStart()), obj.getBufferSize()); + fs::file module_file(name, fs::rewrite); - if (zbuf.empty()) + if (!module_file) { - jit_log.error("LLVM: Failed to compress module: %s", _module->getName().data()); + jit_log.error("LLVM: Failed to create module file: %s (%s)", name, fs::g_tls_error); return; } - if (!fs::write_file(name, fs::rewrite, zbuf.data(), zbuf.size())) + if (!zip(obj.getBufferStart(), obj.getBufferSize(), module_file)) { - jit_log.error("LLVM: Failed to create module file: %s (%s)", name, fs::g_tls_error); + jit_log.error("LLVM: Failed to compress module: %s", _module->getName().data()); + module_file.close(); + fs::remove_file(name); return; } diff --git a/rpcs3/Crypto/unzip.cpp b/rpcs3/Crypto/unzip.cpp index 04687942c2..ac8682e543 100644 --- a/rpcs3/Crypto/unzip.cpp +++ b/rpcs3/Crypto/unzip.cpp @@ -3,6 +3,8 @@ #include +#include "Emu/savestate_utils.hpp" + std::vector unzip(const void* src, usz size) { if (!src || !size) [[unlikely]] @@ -130,55 +132,6 @@ bool unzip(const void* src, usz size, fs::file& out) return is_valid; } -std::vector zip(const void* src, usz size) -{ - if (!src || !size) - { - return {}; - } - - const uLong zsz = compressBound(::narrow(size)) + 256; - std::vector out(zsz); - - z_stream zs{}; -#ifndef _MSC_VER -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" -#endif - int res = deflateInit2(&zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY); - if (res != Z_OK) - { - return {}; - } -#ifndef _MSC_VER -#pragma GCC diagnostic pop -#endif - zs.avail_in = static_cast(size); - zs.next_in = reinterpret_cast(src); - zs.avail_out = static_cast(out.size()); - zs.next_out = out.data(); - - res = deflate(&zs, Z_FINISH); - - switch (res) - { - case Z_OK: - case Z_STREAM_END: - if (zs.avail_out) - { - out.resize(zsz - zs.avail_out); - } - break; - default: - out.clear(); - break; - } - - deflateEnd(&zs); - - return out; -} - bool zip(const void* src, usz size, fs::file& out) { if (!src || !size || !out) @@ -186,9 +139,28 @@ bool zip(const void* src, usz size, fs::file& out) return false; } - const std::vector zipped = zip(src, size); + utils::serial compressor(false); + compressor.m_file_handler = make_compressed_serialization_file_handler(out); - if (zipped.empty() || out.write(zipped.data(), zipped.size()) != zipped.size()) + std::string_view buffer_view{static_cast(src), size}; + + while (!buffer_view.empty()) + { + if (!compressor.m_file_handler->is_valid()) + { + return false; + } + + const std::string_view slice = buffer_view.substr(0, 0x50'0000); + + compressor(slice); + compressor.breathe(); + buffer_view = buffer_view.substr(slice.size()); + } + + compressor.m_file_handler->finalize(compressor); + + if (!compressor.m_file_handler->is_valid()) { return false; } diff --git a/rpcs3/Crypto/unzip.h b/rpcs3/Crypto/unzip.h index 80025ce65c..d5fa50b4ad 100644 --- a/rpcs3/Crypto/unzip.h +++ b/rpcs3/Crypto/unzip.h @@ -16,14 +16,6 @@ inline bool unzip(const std::vector& src, fs::file& out) return unzip(src.data(), src.size(), out); } -std::vector zip(const void* src, usz size); - -template -inline std::vector zip(const T& src) -{ - return zip(src.data(), src.size()); -} - bool zip(const void* src, usz size, fs::file& out); template diff --git a/rpcs3/Emu/savestate_utils.hpp b/rpcs3/Emu/savestate_utils.hpp index 6a4169e2ff..9e5e3e06ed 100644 --- a/rpcs3/Emu/savestate_utils.hpp +++ b/rpcs3/Emu/savestate_utils.hpp @@ -93,6 +93,11 @@ struct compressed_serialization_file_handler : utils::serialization_file_handler usz get_size(const utils::serial& ar, usz recommended) const override; void skip_until(utils::serial& ar) override; + bool is_valid() const override + { + return !m_errored; + } + void finalize(utils::serial& ar) override; private: diff --git a/rpcs3/util/serialization.hpp b/rpcs3/util/serialization.hpp index 29019d830c..71cbac4ca7 100644 --- a/rpcs3/util/serialization.hpp +++ b/rpcs3/util/serialization.hpp @@ -63,6 +63,11 @@ namespace utils { } + virtual bool is_valid() const + { + return true; + } + virtual void finalize(utils::serial&) = 0; };