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.

llvm-svn: 205676
This commit is contained in:
David Blaikie 2014-04-05 21:26:44 +00:00
parent c12813576c
commit a505f2479e
5 changed files with 18 additions and 22 deletions

View File

@ -16,6 +16,7 @@
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <memory> #include <memory>
#include "llvm/ADT/SmallVector.h"
namespace llvm { namespace llvm {
@ -47,7 +48,7 @@ Status compress(StringRef InputBuffer,
CompressionLevel Level = DefaultCompression); CompressionLevel Level = DefaultCompression);
Status uncompress(StringRef InputBuffer, Status uncompress(StringRef InputBuffer,
std::unique_ptr<MemoryBuffer> &UncompressedBuffer, SmallVectorImpl<char> &UncompressedBuffer,
size_t UncompressedSize); size_t UncompressedSize);
uint32_t crc32(StringRef Buffer); uint32_t crc32(StringRef Buffer);

View File

@ -637,14 +637,15 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
if (!zlib::isAvailable() || if (!zlib::isAvailable() ||
!consumeCompressedDebugSectionHeader(data, OriginalSize)) !consumeCompressedDebugSectionHeader(data, OriginalSize))
continue; continue;
std::unique_ptr<MemoryBuffer> UncompressedSection; UncompressedSections.resize(UncompressedSections.size() + 1);
if (zlib::uncompress(data, UncompressedSection, OriginalSize) != if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
zlib::StatusOK) zlib::StatusOK) {
UncompressedSections.pop_back();
continue; continue;
}
// Make data point to uncompressed section contents and save its contents. // Make data point to uncompressed section contents and save its contents.
name = name.substr(1); name = name.substr(1);
data = UncompressedSection->getBuffer(); data = UncompressedSections.back();
UncompressedSections.push_back(std::move(UncompressedSection));
} }
StringRef *SectionData = StringRef *SectionData =

View File

@ -242,7 +242,7 @@ class DWARFContextInMemory : public DWARFContext {
StringRef RangeDWOSection; StringRef RangeDWOSection;
StringRef AddrSection; StringRef AddrSection;
SmallVector<std::unique_ptr<MemoryBuffer>, 4> UncompressedSections; SmallVector<SmallString<32>, 4> UncompressedSections;
public: public:
DWARFContextInMemory(object::ObjectFile *); DWARFContextInMemory(object::ObjectFile *);

View File

@ -65,18 +65,13 @@ zlib::Status zlib::compress(StringRef InputBuffer,
} }
zlib::Status zlib::uncompress(StringRef InputBuffer, zlib::Status zlib::uncompress(StringRef InputBuffer,
std::unique_ptr<MemoryBuffer> &UncompressedBuffer, SmallVectorImpl<char> &UncompressedBuffer,
size_t UncompressedSize) { size_t UncompressedSize) {
std::unique_ptr<char[]> TmpBuffer(new char[UncompressedSize]); UncompressedBuffer.resize(UncompressedSize);
Status Res = encodeZlibReturnValue( Status Res = encodeZlibReturnValue(::uncompress(
::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize, (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize,
(const Bytef *)InputBuffer.data(), InputBuffer.size())); (const Bytef *)InputBuffer.data(), InputBuffer.size()));
if (Res == StatusOK) { UncompressedBuffer.resize(UncompressedSize);
UncompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
StringRef(TmpBuffer.get(), UncompressedSize)));
// Tell MSan that memory initialized by zlib is valid.
__msan_unpoison(UncompressedBuffer->getBufferStart(), UncompressedSize);
}
return Res; return Res;
} }

View File

@ -25,14 +25,13 @@ namespace {
void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) { void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) {
std::unique_ptr<MemoryBuffer> Compressed; std::unique_ptr<MemoryBuffer> Compressed;
std::unique_ptr<MemoryBuffer> Uncompressed; SmallString<32> Uncompressed;
EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level)); EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level));
// Check that uncompressed buffer is the same as original. // Check that uncompressed buffer is the same as original.
EXPECT_EQ(zlib::StatusOK, zlib::uncompress(Compressed->getBuffer(), EXPECT_EQ(zlib::StatusOK, zlib::uncompress(Compressed->getBuffer(),
Uncompressed, Input.size())); Uncompressed, Input.size()));
EXPECT_EQ(Input.size(), Uncompressed->getBufferSize()); EXPECT_EQ(Input.size(), Uncompressed.size());
EXPECT_EQ(0, EXPECT_EQ(0, memcmp(Input.data(), Uncompressed.data(), Input.size()));
memcmp(Input.data(), Uncompressed->getBufferStart(), Input.size()));
if (Input.size() > 0) { if (Input.size() > 0) {
// Uncompression fails if expected length is too short. // Uncompression fails if expected length is too short.
EXPECT_EQ(zlib::StatusBufferTooShort, EXPECT_EQ(zlib::StatusBufferTooShort,