forked from OSchip/llvm-project
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:
parent
c12813576c
commit
a505f2479e
|
@ -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);
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue