Index: include/llvm/Support/Compression.h =================================================================== --- include/llvm/Support/Compression.h +++ include/llvm/Support/Compression.h @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_COMPRESSION_H #include "llvm/Support/DataTypes.h" +#include namespace llvm { template class SmallVectorImpl; @@ -32,7 +33,8 @@ bool isAvailable(); -Error compress(StringRef InputBuffer, SmallVectorImpl &CompressedBuffer, +Error compress(StringRef Input, std::unique_ptr &CompressedData, + size_t &CompressedSize, CompressionLevel Level = DefaultCompression); Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, Index: lib/MC/ELFObjectWriter.cpp =================================================================== --- lib/MC/ELFObjectWriter.cpp +++ lib/MC/ELFObjectWriter.cpp @@ -157,8 +157,7 @@ void align(unsigned Alignment); - bool maybeWriteCompression(uint64_t Size, - SmallVectorImpl &CompressedContents, + bool maybeWriteCompression(uint64_t Size, size_t CompressedSize, bool ZLibStyle, unsigned Alignment); public: @@ -791,12 +790,12 @@ // Include the debug info compression header. bool ELFWriter::maybeWriteCompression( - uint64_t Size, SmallVectorImpl &CompressedContents, bool ZLibStyle, + uint64_t Size, size_t CompressedSize, bool ZLibStyle, unsigned Alignment) { if (ZLibStyle) { uint64_t HdrSize = is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr); - if (Size <= HdrSize + CompressedContents.size()) + if (Size <= HdrSize + CompressedSize) return false; // Platform specific header is followed by compressed data. if (is64Bit()) { @@ -817,7 +816,7 @@ // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, // useful for consumers to preallocate a buffer to decompress into. const StringRef Magic = "ZLIB"; - if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) + if (Size <= Magic.size() + sizeof(Size) + CompressedSize) return false; W.OS << Magic; support::endian::write(W.OS, Size, support::big); @@ -851,18 +850,19 @@ raw_svector_ostream VecOS(UncompressedData); Asm.writeSectionData(VecOS, &Section, Layout); - SmallVector CompressedContents; + std::unique_ptr CompressedData; + size_t CompressedSize; if (Error E = zlib::compress( StringRef(UncompressedData.data(), UncompressedData.size()), - CompressedContents)) { + CompressedData, CompressedSize)) { consumeError(std::move(E)); W.OS << UncompressedData; return; } bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z; - if (!maybeWriteCompression(UncompressedData.size(), CompressedContents, - ZlibStyle, Sec.getAlignment())) { + if (!maybeWriteCompression(UncompressedData.size(), CompressedSize, ZlibStyle, + Sec.getAlignment())) { W.OS << UncompressedData; return; } @@ -873,7 +873,7 @@ else // Add "z" prefix to section name. This is zlib-gnu style. MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); - W.OS << CompressedContents; + W.OS << StringRef((char *)CompressedData.get(), CompressedSize); } void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, Index: lib/ProfileData/InstrProf.cpp =================================================================== --- lib/ProfileData/InstrProf.cpp +++ lib/ProfileData/InstrProf.cpp @@ -404,16 +404,19 @@ return WriteStringToResult(0, UncompressedNameStrings); } - SmallString<128> CompressedNameStrings; - Error E = zlib::compress(StringRef(UncompressedNameStrings), - CompressedNameStrings, zlib::BestSizeCompression); + std::unique_ptr CompressedNameStrings; + size_t CompressedSize; + Error E = + zlib::compress(StringRef(UncompressedNameStrings), CompressedNameStrings, + CompressedSize, zlib::BestSizeCompression); if (E) { consumeError(std::move(E)); return make_error(instrprof_error::compress_failed); } - return WriteStringToResult(CompressedNameStrings.size(), - CompressedNameStrings); + return WriteStringToResult( + CompressedSize, + StringRef((char *)CompressedNameStrings.get(), CompressedSize)); } StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar) { Index: lib/Support/Compression.cpp =================================================================== --- lib/Support/Compression.cpp +++ lib/Support/Compression.cpp @@ -57,19 +57,17 @@ bool zlib::isAvailable() { return true; } -Error zlib::compress(StringRef InputBuffer, - SmallVectorImpl &CompressedBuffer, - CompressionLevel Level) { - unsigned long CompressedSize = ::compressBound(InputBuffer.size()); - CompressedBuffer.resize(CompressedSize); +Error zlib::compress(StringRef Input, + std::unique_ptr &CompressedData, + size_t &CompressedSize, CompressionLevel Level) { + CompressedSize = (size_t)::compressBound(Input.size()); + CompressedData.reset(new uint8_t[CompressedSize]); int CLevel = encodeZlibCompressionLevel(Level); - int Res = ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize, - (const Bytef *)InputBuffer.data(), InputBuffer.size(), - CLevel); + int Res = ::compress2(CompressedData.get(), &CompressedSize, + (const Bytef *)Input.data(), Input.size(), CLevel); // 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.resize(CompressedSize); + __msan_unpoison(CompressedData.get(), CompressedSize); return Res ? createError(convertZlibCodeToString(Res)) : Error::success(); } Index: unittests/Support/CompressionTest.cpp =================================================================== --- unittests/Support/CompressionTest.cpp +++ unittests/Support/CompressionTest.cpp @@ -25,22 +25,25 @@ #if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) { - SmallString<32> Compressed; + std::unique_ptr Compressed; + size_t CompressedSize; SmallString<32> Uncompressed; - Error E = zlib::compress(Input, Compressed, Level); + Error E = zlib::compress(Input, Compressed, CompressedSize, Level); EXPECT_FALSE(E); consumeError(std::move(E)); // Check that uncompressed buffer is the same as original. - E = zlib::uncompress(Compressed, Uncompressed, Input.size()); + E = zlib::uncompress(StringRef((char *)Compressed.get(), CompressedSize), + Uncompressed, Input.size()); EXPECT_FALSE(E); consumeError(std::move(E)); EXPECT_EQ(Input, Uncompressed); if (Input.size() > 0) { // Uncompression fails if expected length is too short. - E = zlib::uncompress(Compressed, Uncompressed, Input.size() - 1); + E = zlib::uncompress(StringRef((char *)Compressed.get(), CompressedSize), + Uncompressed, Input.size() - 1); EXPECT_EQ("zlib error: Z_BUF_ERROR", llvm::toString(std::move(E))); } }