[llvm] Implement streaming compression for compressed ELF sections. (PR #87211)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 23:16:13 PDT 2024
================
@@ -201,6 +261,51 @@ void zstd::compress(ArrayRef<uint8_t> Input,
CompressedBuffer.truncate(CompressedSize);
}
+void zstd::compressToStream(ArrayRef<uint8_t> Input, raw_ostream &OS, int Level,
+ bool EnableLdm) {
+ // Allocate a buffer to hold the output.
+ size_t OutBufferSize = ZSTD_CStreamOutSize();
+ auto OutBuffer = std::make_unique<char[]>(OutBufferSize);
+
+ ZSTD_CStream *CStream = ZSTD_createCStream();
+ if (!CStream)
+ report_bad_alloc_error("Failed to create ZSTD_CCtx");
+
+ // Ensure that the ZSTD_CStream is cleaned up on all exit paths.
+ auto FreeCStreamOnExit =
+ make_scope_exit([=]() { ZSTD_freeCStream(CStream); });
+
+ if (ZSTD_isError(ZSTD_CCtx_setParameter(
+ CStream, ZSTD_c_enableLongDistanceMatching, EnableLdm ? 1 : 0))) {
+ report_bad_alloc_error("Failed to set ZSTD_c_enableLongDistanceMatching");
+ }
+
+ if (ZSTD_isError(
+ ZSTD_CCtx_setParameter(CStream, ZSTD_c_compressionLevel, Level))) {
+ report_bad_alloc_error("Failed to set ZSTD_c_compressionLevel");
+ }
+
+ ZSTD_inBuffer ZInput = {Input.data(), Input.size(), 0};
+
+ // Repeatedly compress into the output buffer and flush it into the
+ // output stream. Repeat until we have drained the entire compression
+ // state.
+ size_t ZRet;
+ do {
+ ZSTD_outBuffer ZOutput = {OutBuffer.get(), OutBufferSize, 0};
+ ZRet = ZSTD_compressStream2(CStream, &ZOutput, &ZInput, ZSTD_e_end);
----------------
MaskRay wrote:
With suitable input and output buffers, ZSTD_compressStream2 will never fail. So `assert !isError` should be fine.
https://github.com/llvm/llvm-project/pull/87211
More information about the llvm-commits
mailing list