Simplify compression API by decompressing into a SmallVector rather than a MemoryBuffer
authorDavid Blaikie <dblaikie@gmail.com>
Sat, 5 Apr 2014 21:26:44 +0000 (21:26 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Sat, 5 Apr 2014 21:26:44 +0000 (21:26 +0000)
This avoids an extra copy during decompression and avoids the use of
MemoryBuffer which is a weirdly esoteric device that includes unrelated
concepts like "file name" (its rather generic name is a bit misleading).

Similar refactoring of zlib::compress coming up.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205676 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/Compression.h
lib/DebugInfo/DWARFContext.cpp
lib/DebugInfo/DWARFContext.h
lib/Support/Compression.cpp
unittests/Support/CompressionTest.cpp

index 80eff5c6285af0ffccf3b245507a8698f0ab796a..262980928663251183cece7535bf28a2694a44e0 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "llvm/Support/DataTypes.h"
 #include <memory>
+#include "llvm/ADT/SmallVector.h"
 
 namespace llvm {
 
@@ -47,7 +48,7 @@ Status compress(StringRef InputBuffer,
                 CompressionLevel Level = DefaultCompression);
 
 Status uncompress(StringRef InputBuffer,
-                  std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
+                  SmallVectorImpl<char> &UncompressedBuffer,
                   size_t UncompressedSize);
 
 uint32_t crc32(StringRef Buffer);
index 60c5f6ab56d73b4e7893507deb8b64a50d662cc6..a287cf9edb2d915369a5b14e00f021034b04e499 100644 (file)
@@ -637,14 +637,15 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
       if (!zlib::isAvailable() ||
           !consumeCompressedDebugSectionHeader(data, OriginalSize))
         continue;
-      std::unique_ptr<MemoryBuffer> UncompressedSection;
-      if (zlib::uncompress(data, UncompressedSection, OriginalSize) !=
-          zlib::StatusOK)
+      UncompressedSections.resize(UncompressedSections.size() + 1);
+      if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
+          zlib::StatusOK) {
+        UncompressedSections.pop_back();
         continue;
+      }
       // Make data point to uncompressed section contents and save its contents.
       name = name.substr(1);
-      data = UncompressedSection->getBuffer();
-      UncompressedSections.push_back(std::move(UncompressedSection));
+      data = UncompressedSections.back();
     }
 
     StringRef *SectionData =
index ad6841ae9e31c54458ffde66df7b0f441d355401..6d1ae921cec541db3c24e7b4b9123e498172e5d3 100644 (file)
@@ -242,7 +242,7 @@ class DWARFContextInMemory : public DWARFContext {
   StringRef RangeDWOSection;
   StringRef AddrSection;
 
-  SmallVector<std::unique_ptr<MemoryBuffer>, 4> UncompressedSections;
+  SmallVector<SmallString<32>, 4> UncompressedSections;
 
 public:
   DWARFContextInMemory(object::ObjectFile *);
index 5e5336144ab137eade4c65f9d6fe85d35c7cdee6..329a402a07045ca5648154f9da43d693f634383b 100644 (file)
@@ -65,18 +65,13 @@ zlib::Status zlib::compress(StringRef InputBuffer,
 }
 
 zlib::Status zlib::uncompress(StringRef InputBuffer,
-                              std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
+                              SmallVectorImpl<char> &UncompressedBuffer,
                               size_t UncompressedSize) {
-  std::unique_ptr<char[]> TmpBuffer(new char[UncompressedSize]);
-  Status Res = encodeZlibReturnValue(
-      ::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize,
-                   (const Bytef *)InputBuffer.data(), InputBuffer.size()));
-  if (Res == StatusOK) {
-    UncompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
-        StringRef(TmpBuffer.get(), UncompressedSize)));
-    // Tell MSan that memory initialized by zlib is valid.
-    __msan_unpoison(UncompressedBuffer->getBufferStart(), UncompressedSize);
-  }
+  UncompressedBuffer.resize(UncompressedSize);
+  Status Res = encodeZlibReturnValue(::uncompress(
+      (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize,
+      (const Bytef *)InputBuffer.data(), InputBuffer.size()));
+  UncompressedBuffer.resize(UncompressedSize);
   return Res;
 }
 
index db6a8bb1463864907d1cdf734d0b7c8937effcb1..30df0509cce0ef4c48015c9678969a11264a1499 100644 (file)
@@ -25,14 +25,13 @@ namespace {
 
 void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) {
   std::unique_ptr<MemoryBuffer> Compressed;
-  std::unique_ptr<MemoryBuffer> Uncompressed;
+  SmallString<32> Uncompressed;
   EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level));
   // Check that uncompressed buffer is the same as original.
   EXPECT_EQ(zlib::StatusOK, zlib::uncompress(Compressed->getBuffer(),
                                              Uncompressed, Input.size()));
-  EXPECT_EQ(Input.size(), Uncompressed->getBufferSize());
-  EXPECT_EQ(0,
-            memcmp(Input.data(), Uncompressed->getBufferStart(), Input.size()));
+  EXPECT_EQ(Input.size(), Uncompressed.size());
+  EXPECT_EQ(0, memcmp(Input.data(), Uncompressed.data(), Input.size()));
   if (Input.size() > 0) {
     // Uncompression fails if expected length is too short.
     EXPECT_EQ(zlib::StatusBufferTooShort,