From 9e47896c082e94e586f1ac434af32be14c9ae235 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 23 May 2017 00:30:42 +0000 Subject: [PATCH] libDebugInfo: Avoid independently parsing the same .dwo file for two separate CUs residing there NFC, just an optimization. Will be building on this for DWP support shortly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303591 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DWARF/DWARFContext.h | 8 ++++ include/llvm/DebugInfo/DWARF/DWARFUnit.h | 12 +----- lib/DebugInfo/DWARF/DWARFContext.cpp | 22 +++++++++++ lib/DebugInfo/DWARF/DWARFUnit.cpp | 43 ++++++++------------- 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index d3a63edf10f..25ddcf38a65 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -71,6 +71,12 @@ class DWARFContext : public DIContext { std::unique_ptr AbbrevDWO; std::unique_ptr LocDWO; + struct DWOFile { + object::OwningBinary File; + std::unique_ptr Context; + }; + StringMap> DWOFiles; + /// Read compile units from the debug_info section (if necessary) /// and store them in CUs. void parseCompileUnits(); @@ -248,6 +254,8 @@ public: return version == 2 || version == 3 || version == 4 || version == 5; } + std::shared_ptr getDWOContext(StringRef AbsolutePath); + private: /// Return the compile unit that includes an offset (relative to .debug_info). DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index ae7fd24ce5b..d0f7bd0d623 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -143,17 +143,7 @@ class DWARFUnit { typedef iterator_range::iterator> die_iterator_range; - class DWOHolder { - object::OwningBinary DWOFile; - std::unique_ptr DWOContext; - DWARFUnit *DWOU = nullptr; - - public: - DWOHolder(StringRef DWOPath, uint64_t DWOId); - - DWARFUnit *getUnit() const { return DWOU; } - }; - std::unique_ptr DWO; + std::shared_ptr DWO; const DWARFUnitIndex::Entry *IndexEntry; diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 8e7c6c43d1a..41a4620372e 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -897,6 +897,28 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; } +std::shared_ptr +DWARFContext::getDWOContext(StringRef AbsolutePath) { + auto &Entry = DWOFiles[AbsolutePath]; + if (auto S = Entry.lock()) { + DWARFContext *Ctxt = S->Context.get(); + return std::shared_ptr(std::move(S), Ctxt); + } + + auto S = std::make_shared(); + auto Obj = object::ObjectFile::createObjectFile(AbsolutePath); + if (!Obj) { + // TODO: Actually report errors helpfully. + consumeError(Obj.takeError()); + return nullptr; + } + S->File = std::move(Obj.get()); + S->Context = llvm::make_unique(*S->File.getBinary()); + Entry = S; + auto *Ctxt = S->Context.get(); + return std::shared_ptr(std::move(S), Ctxt); +} + static Error createError(const Twine &Reason, llvm::Error E) { return make_error(Reason + toString(std::move(E)), inconvertibleErrorCode()); diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index c268afc222c..b9280b77962 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -249,23 +249,6 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { return DieArray.size(); } -DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath, uint64_t DWOId) { - auto Obj = object::ObjectFile::createObjectFile(DWOPath); - if (!Obj) { - // TODO: Actually report errors helpfully. - consumeError(Obj.takeError()); - return; - } - DWOFile = std::move(Obj.get()); - DWOContext.reset( - cast(new DWARFContextInMemory(*DWOFile.getBinary()))); - for (const auto &DWOCU : DWOContext->dwo_compile_units()) - if (DWOCU->getDWOId() == DWOId) { - DWOU = DWOCU.get(); - return; - } -} - bool DWARFUnit::parseDWO() { if (isDWO) return false; @@ -287,16 +270,21 @@ bool DWARFUnit::parseDWO() { auto DWOId = getDWOId(); if (!DWOId) return false; - DWO = llvm::make_unique(AbsolutePath, *DWOId); - DWARFUnit *DWOCU = DWO->getUnit(); - if (!DWOCU) { - DWO.reset(); + auto DWOContext = Context.getDWOContext(AbsolutePath); + if (!DWOContext) + return false; + + for (const auto &DWOCU : DWOContext->dwo_compile_units()) + if (DWOCU->getDWOId() == DWOId) { + DWO = std::shared_ptr(std::move(DWOContext), DWOCU.get()); + break; + } + if (!DWO) return false; - } // Share .debug_addr and .debug_ranges section with compile unit in .dwo - DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); + DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); auto DWORangesBase = UnitDie.getRangesBaseAttribute(); - DWOCU->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0); + DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0); return true; } @@ -339,8 +327,9 @@ void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) { // Collect address ranges from DIEs in .dwo if necessary. bool DWOCreated = parseDWO(); - if (DWO.get()) - DWO->getUnit()->collectAddressRanges(CURanges); + assert(!DWOCreated); + if (DWO) + DWO->collectAddressRanges(CURanges); if (DWOCreated) DWO.reset(); @@ -400,7 +389,7 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address, // First, find the subroutine that contains the given address (the leaf // of inlined chain). DWARFDie SubroutineDIE = - (DWO ? DWO->getUnit() : this)->getSubroutineForAddress(Address); + (DWO ? DWO.get() : this)->getSubroutineForAddress(Address); while (SubroutineDIE) { if (SubroutineDIE.isSubroutineDIE()) -- 2.50.1