[PATCH] D121512: [Support] zlib::compress: replace compress2 with iterative deflate

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 11 21:46:02 PST 2022


MaskRay created this revision.
MaskRay added a reviewer: ikudrin.
Herald added subscribers: dexonsmith, hiraditya.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

`compressBound` returned size is larger then the input size.
Use the D117853 <https://reviews.llvm.org/D117853> approach to decrease the size of the allocated buffer for most
cases, with the difference that we initialize z_stream with default parameters
and call deflate with `Z_FINISH`.

In addition, drop a call to convertZlibCodeToString since the way we use
deflate (adapted from https://zlib.net/zlib_how.html) can't fail.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121512

Files:
  llvm/lib/Support/Compression.cpp


Index: llvm/lib/Support/Compression.cpp
===================================================================
--- llvm/lib/Support/Compression.cpp
+++ llvm/lib/Support/Compression.cpp
@@ -46,18 +46,29 @@
 
 bool zlib::isAvailable() { return true; }
 
-Error zlib::compress(StringRef InputBuffer,
-                     SmallVectorImpl<char> &CompressedBuffer, int Level) {
-  unsigned long CompressedSize = ::compressBound(InputBuffer.size());
-  CompressedBuffer.resize_for_overwrite(CompressedSize);
-  int Res =
-      ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize,
-                  (const Bytef *)InputBuffer.data(), InputBuffer.size(), Level);
+Error zlib::compress(StringRef In, SmallVectorImpl<char> &Out, int Level) {
+  z_stream s = {};
+  // Default parameters with custom Level.
+  deflateInit2(&s, Level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
+  s.next_in =
+      const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(In.data()));
+  s.avail_in = In.size();
+  Out.resize_for_overwrite(std::max<size_t>(In.size() / 2, 64));
+  size_t Pos = 0;
+  do {
+    if (Pos == Out.size())
+      Out.resize_for_overwrite(Out.size() * 3 / 2);
+    s.next_out = reinterpret_cast<uint8_t *>(Out.data()) + Pos;
+    s.avail_out = Out.size() - Pos;
+    (void)deflate(&s, Z_FINISH);
+    Pos = s.next_out - reinterpret_cast<uint8_t *>(Out.data());
+  } while (s.avail_out == 0);
+  assert(s.avail_in == 0);
+  Out.truncate(Pos);
   // Tell MemorySanitizer that zlib output buffer is fully initialized.
   // This avoids a false report when running LLVM with uninstrumented ZLib.
-  __msan_unpoison(CompressedBuffer.data(), CompressedSize);
-  CompressedBuffer.truncate(CompressedSize);
-  return Res ? createError(convertZlibCodeToString(Res)) : Error::success();
+  __msan_unpoison(Out.data(), Pos);
+  return Error::success();
 }
 
 Error zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D121512.414802.patch
Type: text/x-patch
Size: 1924 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220312/bb58ac8f/attachment.bin>


More information about the llvm-commits mailing list