diff options
author | Zachary Turner <zturner@google.com> | 2016-05-27 01:54:44 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-05-27 01:54:44 +0000 |
commit | 8dbe3629a09a754464f1420ce3059676c986090a (patch) | |
tree | a332a7c4b100869604af7066e58aa664ac623289 /llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp | |
parent | bd8e9542163f4218b6ad52df8c143c06263ff4a2 (diff) | |
download | llvm-8dbe3629a09a754464f1420ce3059676c986090a.zip llvm-8dbe3629a09a754464f1420ce3059676c986090a.tar.gz llvm-8dbe3629a09a754464f1420ce3059676c986090a.tar.bz2 |
[codeview,pdb] Try really hard to conserve memory when reading.
PDBs can be extremely large. We're already mapping the entire
PDB into the process's address space, but to make matters worse
the blocks of the PDB are not arranged contiguously. So, when
we have something like an array or a string embedded into the
stream, we have to make a copy. Since it's convenient to use
traditional data structures to iterate and manipulate these
records, we need the memory to be contiguous.
As a result of this, we were using roughly twice as much memory
as the file size of the PDB, because every stream was copied
out and re-stitched together contiguously.
This patch addresses this by improving the MappedBlockStream
to allocate from a BumpPtrAllocator only when a read requires
a discontiguous read. Furthermore, it introduces some data
structures backed by a stream which can iterate over both
fixed and variable length records of a PDB. Since everything
is backed by a stream and not a buffer, we can read almost
everything from the PDB with zero copies.
Differential Revision: http://reviews.llvm.org/D20654
Reviewed By: ruiu
llvm-svn: 270951
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp | 77 |
1 files changed, 31 insertions, 46 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp index 362c402c..9ccb7ed 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" + +#include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/Support/Endian.h" @@ -16,6 +18,7 @@ using namespace llvm::pdb; using namespace llvm::support; namespace { + struct SCBytes { ulittle16_t Section; char Padding1[2]; @@ -60,17 +63,29 @@ struct ModInfo::FileLayout { // for now since it is unused. ulittle32_t SrcFileNameNI; // Name Index for src file name ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB - char VarInfo[1]; // Module name followed by Obj File Name - - StringRef getModuleName() const { return StringRef(VarInfo); } + // Null terminated Module name + // Null terminated Obj File Name +}; - StringRef getObjectFileName() const { - return StringRef(getModuleName().end() + 1); +ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) { + codeview::StreamReader Reader(Stream); + if (auto EC = Reader.readObject(Layout)) { + consumeError(std::move(EC)); + return; } -}; + if (auto EC = Reader.readZeroString(ModuleName)) { + consumeError(std::move(EC)); + return; + } + if (auto EC = Reader.readZeroString(ObjFileName)) { + consumeError(std::move(EC)); + return; + } +} -ModInfo::ModInfo(const uint8_t *Bytes) - : Layout(reinterpret_cast<const FileLayout *>(Bytes)) {} +ModInfo::ModInfo(const ModInfo &Info) + : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName), + Layout(Info.Layout) {} ModInfo::~ModInfo() {} @@ -100,44 +115,14 @@ uint32_t ModInfo::getPdbFilePathNameIndex() const { return Layout->PdbFilePathNI; } -llvm::StringRef ModInfo::getModuleName() const { - return Layout->getModuleName(); -} - -llvm::StringRef ModInfo::getObjFileName() const { - return Layout->getObjectFileName(); -} - -ModInfoIterator::ModInfoIterator(const uint8_t *Stream) : Bytes(Stream) {} - -ModInfoIterator::ModInfoIterator(const ModInfoIterator &Other) - : Bytes(Other.Bytes) {} - -ModInfo ModInfoIterator::operator*() { return ModInfo(Bytes); } - -ModInfoIterator &ModInfoIterator::operator++() { - StringRef Obj = ModInfo(Bytes).getObjFileName(); - Bytes = Obj.bytes_end() + 1; - Bytes = reinterpret_cast<const uint8_t *>(llvm::alignAddr(Bytes, 4)); - - return *this; -} +StringRef ModInfo::getModuleName() const { return ModuleName; } -ModInfoIterator ModInfoIterator::operator++(int) { - ModInfoIterator Copy(*this); - ++(*this); - return Copy; -} - -bool ModInfoIterator::operator==(const ModInfoIterator &Other) { - return Bytes == Other.Bytes; -} - -bool ModInfoIterator::operator!=(const ModInfoIterator &Other) { - return !(*this == Other); -} +StringRef ModInfo::getObjFileName() const { return ObjFileName; } -ModInfoIterator &ModInfoIterator::operator=(const ModInfoIterator &Other) { - Bytes = Other.Bytes; - return *this; +uint32_t ModInfo::getRecordLength() const { + uint32_t M = ModuleName.str().size() + 1; + uint32_t O = ObjFileName.str().size() + 1; + uint32_t Size = sizeof(FileLayout) + M + O; + Size = llvm::alignTo(Size, 4); + return Size; } |