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.

llvm-svn: 303591
This commit is contained in:
David Blaikie 2017-05-23 00:30:42 +00:00
parent 2db1369c1f
commit f9803fb4bb
4 changed files with 47 additions and 38 deletions

View File

@ -71,6 +71,12 @@ class DWARFContext : public DIContext {
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
struct DWOFile {
object::OwningBinary<object::ObjectFile> File;
std::unique_ptr<DWARFContext> Context;
};
StringMap<std::weak_ptr<DWOFile>> 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<DWARFContext> getDWOContext(StringRef AbsolutePath);
private:
/// Return the compile unit that includes an offset (relative to .debug_info).
DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);

View File

@ -143,17 +143,7 @@ class DWARFUnit {
typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
die_iterator_range;
class DWOHolder {
object::OwningBinary<object::ObjectFile> DWOFile;
std::unique_ptr<DWARFContext> DWOContext;
DWARFUnit *DWOU = nullptr;
public:
DWOHolder(StringRef DWOPath, uint64_t DWOId);
DWARFUnit *getUnit() const { return DWOU; }
};
std::unique_ptr<DWOHolder> DWO;
std::shared_ptr<DWARFUnit> DWO;
const DWARFUnitIndex::Entry *IndexEntry;

View File

@ -897,6 +897,28 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
return InliningInfo;
}
std::shared_ptr<DWARFContext>
DWARFContext::getDWOContext(StringRef AbsolutePath) {
auto &Entry = DWOFiles[AbsolutePath];
if (auto S = Entry.lock()) {
DWARFContext *Ctxt = S->Context.get();
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
}
auto S = std::make_shared<DWOFile>();
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<DWARFContextInMemory>(*S->File.getBinary());
Entry = S;
auto *Ctxt = S->Context.get();
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
}
static Error createError(const Twine &Reason, llvm::Error E) {
return make_error<StringError>(Reason + toString(std::move(E)),
inconvertibleErrorCode());

View File

@ -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<DWARFContext>(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<DWOHolder>(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<DWARFUnit>(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())