From b206103abcf358453ac4ed8d4373f44f4c88e5c0 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Sat, 5 Apr 2014 21:26:44 +0000 Subject: [PATCH] Simplify compression API by decompressing into a SmallVector rather than a MemoryBuffer 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 | 3 ++- lib/DebugInfo/DWARFContext.cpp | 11 ++++++----- lib/DebugInfo/DWARFContext.h | 2 +- lib/Support/Compression.cpp | 17 ++++++----------- unittests/Support/CompressionTest.cpp | 7 +++---- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h index 80eff5c6285..26298092866 100644 --- a/include/llvm/Support/Compression.h +++ b/include/llvm/Support/Compression.h @@ -16,6 +16,7 @@ #include "llvm/Support/DataTypes.h" #include +#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 &UncompressedBuffer, + SmallVectorImpl &UncompressedBuffer, size_t UncompressedSize); uint32_t crc32(StringRef Buffer); diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 60c5f6ab56d..a287cf9edb2 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -637,14 +637,15 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) if (!zlib::isAvailable() || !consumeCompressedDebugSectionHeader(data, OriginalSize)) continue; - std::unique_ptr 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 = diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h index ad6841ae9e3..6d1ae921cec 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -242,7 +242,7 @@ class DWARFContextInMemory : public DWARFContext { StringRef RangeDWOSection; StringRef AddrSection; - SmallVector, 4> UncompressedSections; + SmallVector, 4> UncompressedSections; public: DWARFContextInMemory(object::ObjectFile *); diff --git a/lib/Support/Compression.cpp b/lib/Support/Compression.cpp index 5e5336144ab..329a402a070 100644 --- a/lib/Support/Compression.cpp +++ b/lib/Support/Compression.cpp @@ -65,18 +65,13 @@ zlib::Status zlib::compress(StringRef InputBuffer, } zlib::Status zlib::uncompress(StringRef InputBuffer, - std::unique_ptr &UncompressedBuffer, + SmallVectorImpl &UncompressedBuffer, size_t UncompressedSize) { - std::unique_ptr 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; } diff --git a/unittests/Support/CompressionTest.cpp b/unittests/Support/CompressionTest.cpp index db6a8bb1463..30df0509cce 100644 --- a/unittests/Support/CompressionTest.cpp +++ b/unittests/Support/CompressionTest.cpp @@ -25,14 +25,13 @@ namespace { void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) { std::unique_ptr Compressed; - std::unique_ptr 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,