[llvm] [PDB] Refactor cache strategy for function symbol lookups (PR #188927)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 09:52:55 PDT 2026
================
@@ -355,29 +366,67 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
consumeError(ExpectedModS.takeError());
return nullptr;
}
- CVSymbolArray Syms = ExpectedModS->getSymbolArray();
- // Search for the symbol in this module.
+ // Return empty intervals in AddressToSymbolId from Start to Stop.
+ auto getInsertRanges = [this](uint64_t Start, uint64_t Stop) {
+ SmallVector<std::pair<uint64_t, uint64_t>> Ranges;
+ auto Iter = AddressToSymbolId.find(Start);
+ while (Iter.valid() && IMapTy::KeyTraits::nonEmpty(Start, Stop)) {
+ if (IMapTy::KeyTraits::startLess(Start, Iter.start()))
+ Ranges.push_back({Start, std::min(Iter.start(), Stop)});
+
+ // Same result as Start = std::min(Stop, Iter.stop()).
+ Start = Iter.stop();
+ ++Iter;
+ }
+ if (IMapTy::KeyTraits::nonEmpty(Start, Stop))
+ Ranges.push_back({Start, Stop});
+
+ return Ranges;
+ };
+
+ // Decode symbols in this module.
+ CVSymbolArray Syms = ExpectedModS->getSymbolArray();
for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
continue;
+
auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
- if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
- Offset < PS.CodeOffset + PS.CodeSize) {
- // Check if the symbol is already cached.
- auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
- if (Found != AddressToSymbolId.end())
- return getSymbolById(Found->second);
-
- // Otherwise, create a new symbol.
+ uint64_t SymStart = Session.getVAFromSectOffset(PS.Segment, PS.CodeOffset);
+ uint64_t SymStop = SymStart + PS.CodeSize;
+ if (LLVM_UNLIKELY(!IMapTy::KeyTraits::nonEmpty(SymStart, SymStop))) {
+ I = Syms.at(PS.End);
+ continue;
+ }
+#ifndef NDEBUG
+ const auto &AddrToModuleIndex = Session.getAddrToModuleIndex();
+ auto ModIter = AddrToModuleIndex.find(SymStart);
+ using ModKeyTraits =
+ std::remove_reference_t<decltype(AddrToModuleIndex)>::KeyTraits;
+ assert(ModIter.valid() &&
+ !ModKeyTraits::startLess(SymStart, ModIter.start()) &&
+ !ModKeyTraits::stopLess(ModIter.stop(), SymStop - 1) &&
+ "Symbol spans modules");
----------------
Nerixyz wrote:
This could check that `moduleIndexForVA(SymStart) == moduleIndexForVA(SymStop - 1)`. Then you can avoid having `getAddrToModuleIndex`.
https://github.com/llvm/llvm-project/pull/188927
More information about the llvm-commits
mailing list