diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp')
| -rw-r--r-- | lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp index 58efc2256ae1..57da7003da2b 100644 --- a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/DebugInfo/CodeView/RecordName.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" @@ -20,6 +21,7 @@ #include "llvm/DebugInfo/PDB/Native/Hash.h" #include "llvm/Support/BinaryItemStream.h" #include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/xxhash.h" #include <algorithm> #include <vector> @@ -29,8 +31,27 @@ using namespace llvm::pdb; using namespace llvm::codeview; struct llvm::pdb::GSIHashStreamBuilder { + struct UdtDenseMapInfo { + static inline CVSymbol getEmptyKey() { + static CVSymbol Empty; + return Empty; + } + static inline CVSymbol getTombstoneKey() { + static CVSymbol Tombstone(static_cast<SymbolKind>(-1), + ArrayRef<uint8_t>()); + return Tombstone; + } + static unsigned getHashValue(const CVSymbol &Val) { + return xxHash64(Val.RecordData); + } + static bool isEqual(const CVSymbol &LHS, const CVSymbol &RHS) { + return LHS.RecordData == RHS.RecordData; + } + }; + std::vector<CVSymbol> Records; uint32_t StreamIndex; + llvm::DenseSet<CVSymbol, UdtDenseMapInfo> UdtHashes; std::vector<PSHashRecord> HashRecords; std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap; std::vector<support::ulittle32_t> HashBuckets; @@ -42,10 +63,18 @@ struct llvm::pdb::GSIHashStreamBuilder { template <typename T> void addSymbol(const T &Symbol, MSFBuilder &Msf) { T Copy(Symbol); - Records.push_back(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(), - CodeViewContainer::Pdb)); + addSymbol(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(), + CodeViewContainer::Pdb)); + } + void addSymbol(const CVSymbol &Symbol) { + if (Symbol.kind() == S_UDT) { + auto Iter = UdtHashes.insert(Symbol); + if (!Iter.second) + return; + } + + Records.push_back(Symbol); } - void addSymbol(const CVSymbol &Symbol) { Records.push_back(Symbol); } }; uint32_t GSIHashStreamBuilder::calculateSerializedLength() const { @@ -144,11 +173,10 @@ void GSIHashStreamBuilder::finalizeBuckets(uint32_t RecordZeroOffset) { // can properly early-out when it detects the record won't be found. The // algorithm used here corredsponds to the function // caseInsensitiveComparePchPchCchCch in the reference implementation. - llvm::sort(Bucket.begin(), Bucket.end(), - [](const std::pair<StringRef, PSHashRecord> &Left, - const std::pair<StringRef, PSHashRecord> &Right) { - return gsiRecordLess(Left.first, Right.first); - }); + llvm::sort(Bucket, [](const std::pair<StringRef, PSHashRecord> &Left, + const std::pair<StringRef, PSHashRecord> &Right) { + return gsiRecordLess(Left.first, Right.first); + }); for (const auto &Entry : Bucket) HashRecords.push_back(Entry.second); @@ -273,10 +301,6 @@ void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) { GSH->addSymbol(Sym, Msf); } -void GSIStreamBuilder::addGlobalSymbol(const UDTSym &Sym) { - GSH->addSymbol(Sym, Msf); -} - void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Sym) { GSH->addSymbol(Sym); } @@ -310,13 +334,14 @@ Error GSIStreamBuilder::commitPublicsHashStream( PublicsStreamHeader Header; // FIXME: Fill these in. They are for incremental linking. + Header.SymHash = PSH->calculateSerializedLength(); + Header.AddrMap = PSH->Records.size() * 4; Header.NumThunks = 0; Header.SizeOfThunk = 0; Header.ISectThunkTable = 0; + memset(Header.Padding, 0, sizeof(Header.Padding)); Header.OffThunkTable = 0; Header.NumSections = 0; - Header.SymHash = PSH->calculateSerializedLength(); - Header.AddrMap = PSH->Records.size() * 4; if (auto EC = Writer.writeObject(Header)) return EC; |
