From 1f200adfa7c1a87ca8af43c4eb5f471379899d26 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 6 Jul 2018 02:33:58 +0000 Subject: [PDB] Sort globals symbols by name in GSI hash buckets. It seems like the debugger first computes a symbol's bucket, and then does a binary search of entries in the bucket using the symbol's name in order to find it. If the bucket entries are not in sorted order, this obviously won't work. After this patch a couple of simple test cases show that we generate an exactly identical GSI hash stream, which is very nice. llvm-svn: 336405 --- llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'llvm/lib/DebugInfo') diff --git a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp index 63d63c1e054..eaea24a05f2 100644 --- a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp @@ -83,7 +83,8 @@ Error GSIHashStreamBuilder::commit(BinaryStreamWriter &Writer) { } void GSIHashStreamBuilder::finalizeBuckets(uint32_t RecordZeroOffset) { - std::array, IPHR_HASH + 1> TmpBuckets; + std::array>, IPHR_HASH + 1> + TmpBuckets; uint32_t SymOffset = RecordZeroOffset; for (const CVSymbol &Sym : Records) { PSHashRecord HR; @@ -94,8 +95,7 @@ void GSIHashStreamBuilder::finalizeBuckets(uint32_t RecordZeroOffset) { // Hash the name to figure out which bucket this goes into. StringRef Name = getSymbolName(Sym); size_t BucketIdx = hashStringV1(Name) % IPHR_HASH; - TmpBuckets[BucketIdx].push_back(HR); // FIXME: Does order matter? - + TmpBuckets[BucketIdx].push_back(std::make_pair(Name, HR)); SymOffset += Sym.length(); } @@ -117,8 +117,22 @@ void GSIHashStreamBuilder::finalizeBuckets(uint32_t RecordZeroOffset) { ulittle32_t ChainStartOff = ulittle32_t(HashRecords.size() * SizeOfHROffsetCalc); HashBuckets.push_back(ChainStartOff); - for (const auto &HR : Bucket) - HashRecords.push_back(HR); + + // Sort each bucket by memcmp of the symbol's name. + std::sort(Bucket.begin(), Bucket.end(), + [](const std::pair &Left, + const std::pair &Right) { + size_t LS = Left.first.size(); + size_t RS = Right.first.size(); + if (LS < RS) + return true; + if (LS > RS) + return false; + return Left.first < Right.first; + }); + + for (const auto &Entry : Bucket) + HashRecords.push_back(Entry.second); } } -- cgit v1.2.3