[llvm] Reduce llvm-gsymutil memory usage (PR #139907)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 15 06:01:01 PDT 2025
https://github.com/peremyach updated https://github.com/llvm/llvm-project/pull/139907
>From d92d7da4c9274a8f4ce69323a47f04d3dd6dd9a1 Mon Sep 17 00:00:00 2001
From: Arslan Khabutdinov <akhabutdinov at fb.com>
Date: Wed, 14 May 2025 02:56:12 -0700
Subject: [PATCH] Reduce llvm-gsymutil memory usage
---
.../llvm/DebugInfo/DWARF/DWARFContext.h | 16 +-
llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 22 +-
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 177 +++++------
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 278 ++++++++++--------
llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp | 35 ++-
5 files changed, 271 insertions(+), 257 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 6df3f5066e327..4cb1033aab8e4 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -66,6 +66,7 @@ class DWARFContext : public DIContext {
};
DWARFContext &D;
+
public:
DWARFContextState(DWARFContext &DC) : D(DC) {}
virtual ~DWARFContextState() = default;
@@ -79,8 +80,8 @@ class DWARFContext : public DIContext {
virtual const DWARFDebugLoc *getDebugLoc() = 0;
virtual const DWARFDebugAranges *getDebugAranges() = 0;
virtual Expected<const DWARFDebugLine::LineTable *>
- getLineTableForUnit(DWARFUnit *U,
- function_ref<void(Error)> RecoverableErrHandler) = 0;
+ getLineTableForUnit(DWARFUnit *U,
+ function_ref<void(Error)> RecoverableErrHandler) = 0;
virtual void clearLineTableForUnit(DWARFUnit *U) = 0;
virtual Expected<const DWARFDebugFrame *> getDebugFrame() = 0;
virtual Expected<const DWARFDebugFrame *> getEHFrame() = 0;
@@ -94,7 +95,7 @@ class DWARFContext : public DIContext {
virtual const AppleAcceleratorTable &getAppleNamespaces() = 0;
virtual const AppleAcceleratorTable &getAppleObjC() = 0;
virtual std::shared_ptr<DWARFContext>
- getDWOContext(StringRef AbsolutePath) = 0;
+ getDWOContext(StringRef AbsolutePath) = 0;
virtual const DenseMap<uint64_t, DWARFTypeUnit *> &
getTypeUnitMap(bool IsDWO) = 0;
virtual bool isThreadSafe() const = 0;
@@ -103,6 +104,7 @@ class DWARFContext : public DIContext {
std::unique_ptr<DWARFDebugMacro>
parseMacroOrMacinfo(MacroSecType SectionType);
+ virtual void doWorkThreadSafely(function_ref<void()> Work) = 0;
};
friend class DWARFContextState;
@@ -205,9 +207,7 @@ class DWARFContext : public DIContext {
DWOUnits.begin() + DWOUnits.getNumInfoUnits());
}
- const DWARFUnitVector &getDWOUnitsVector() {
- return State->getDWOUnits();
- }
+ const DWARFUnitVector &getDWOUnitsVector() { return State->getDWOUnits(); }
/// Return true of this DWARF context is a DWP file.
bool isDWP() const;
@@ -491,6 +491,10 @@ class DWARFContext : public DIContext {
/// manually only for DWARF5.
void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }
+ void doWorkThreadSafely(function_ref<void()> Work) {
+ State->doWorkThreadSafely(Work);
+ }
+
private:
void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
std::vector<DILocal> &Result);
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 80c27aea89312..75a800bdf017a 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -27,6 +27,7 @@
#include <cstdint>
#include <map>
#include <memory>
+#include <mutex>
#include <set>
#include <utility>
#include <vector>
@@ -125,7 +126,8 @@ bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U);
/// Describe a collection of units. Intended to hold all units either from
/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
-class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
+class DWARFUnitVector final
+ : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
std::function<std::unique_ptr<DWARFUnit>(uint64_t, DWARFSectionKind,
const DWARFSection *,
const DWARFUnitIndex::Entry *)>
@@ -137,8 +139,8 @@ class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1>
using iterator = typename UnitVector::iterator;
using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
- using compile_unit_range =
- decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit));
+ using compile_unit_range = decltype(make_filter_range(
+ std::declval<iterator_range>(), isCompileUnit));
DWARFUnit *getUnitForOffset(uint64_t Offset) const;
DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
@@ -257,6 +259,8 @@ class DWARFUnit {
std::shared_ptr<DWARFUnit> DWO;
+ mutable std::recursive_mutex FreeDIEsMutex;
+
protected:
friend dwarf_linker::parallel::CompileUnit;
@@ -316,7 +320,7 @@ class DWARFUnit {
bool isLittleEndian() const { return IsLittleEndian; }
bool isDWOUnit() const { return IsDWO; }
- DWARFContext& getContext() const { return Context; }
+ DWARFContext &getContext() const { return Context; }
const DWARFSection &getInfoSection() const { return InfoSection; }
uint64_t getOffset() const { return Header.getOffset(); }
const dwarf::FormParams &getFormParams() const {
@@ -377,9 +381,7 @@ class DWARFUnit {
RangeSectionBase = Base;
}
- uint64_t getLocSectionBase() const {
- return LocSectionBase;
- }
+ uint64_t getLocSectionBase() const { return LocSectionBase; }
std::optional<object::SectionedAddress>
getAddrOffsetSectionItem(uint32_t Index) const;
@@ -566,6 +568,9 @@ class DWARFUnit {
Error tryExtractDIEsIfNeeded(bool CUDieOnly);
+ /// clearDIEs - Clear parsed DIEs to keep memory usage low.
+ void clearDIEs(bool KeepCUDie, bool KeepDWODies = false);
+
private:
/// Size in bytes of the .debug_info data associated with this compile unit.
size_t getDebugInfoSize() const {
@@ -581,9 +586,6 @@ class DWARFUnit {
void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
std::vector<DWARFDebugInfoEntry> &DIEs) const;
- /// clearDIEs - Clear parsed DIEs to keep memory usage low.
- void clearDIEs(bool KeepCUDie);
-
/// parseDWO - Parses .dwo file for current compile unit. Returns true if
/// it was actually constructed.
/// The \p AlternativeLocation specifies an alternative location to get
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index e76e518ef8595..907f8e3eba8b6 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -68,7 +68,6 @@ using DWARFLineTable = DWARFDebugLine::LineTable;
using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
-
void fixupIndexV4(DWARFContext &C, DWARFUnitIndex &Index) {
using EntryType = DWARFUnitIndex::Entry::SectionContribution;
using EntryMap = DenseMap<uint32_t, EntryType>;
@@ -201,7 +200,6 @@ static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
return *Cache;
}
-
std::unique_ptr<DWARFDebugMacro>
DWARFContext::DWARFContextState::parseMacroOrMacinfo(MacroSecType SectionType) {
auto Macro = std::make_unique<DWARFDebugMacro>();
@@ -281,9 +279,8 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
std::string DWPName;
public:
- ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP) :
- DWARFContext::DWARFContextState(DC),
- DWPName(std::move(DWP)) {}
+ ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP)
+ : DWARFContext::DWARFContextState(DC), DWPName(std::move(DWP)) {}
DWARFUnitVector &getNormalUnits() override {
if (NormalUnits.empty()) {
@@ -327,8 +324,8 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
if (CUIndex)
return *CUIndex;
- DataExtractor Data(D.getDWARFObj().getCUIndexSection(),
- D.isLittleEndian(), 0);
+ DataExtractor Data(D.getDWARFObj().getCUIndexSection(), D.isLittleEndian(),
+ 0);
CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
if (CUIndex->parse(Data))
fixupIndex(D, *CUIndex);
@@ -338,8 +335,8 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
if (TUIndex)
return *TUIndex;
- DataExtractor Data(D.getDWARFObj().getTUIndexSection(),
- D.isLittleEndian(), 0);
+ DataExtractor Data(D.getDWARFObj().getTUIndexSection(), D.isLittleEndian(),
+ 0);
TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
bool isParseSuccessful = TUIndex->parse(Data);
// If we are parsing TU-index and for .debug_types section we don't need
@@ -363,8 +360,8 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
if (Abbrev)
return Abbrev.get();
- DataExtractor Data(D.getDWARFObj().getAbbrevSection(),
- D.isLittleEndian(), 0);
+ DataExtractor Data(D.getDWARFObj().getAbbrevSection(), D.isLittleEndian(),
+ 0);
Abbrev = std::make_unique<DWARFDebugAbbrev>(Data);
return Abbrev.get();
}
@@ -393,8 +390,9 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
return Aranges.get();
}
- Expected<const DWARFDebugLine::LineTable *>
- getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
+ Expected<const DWARFDebugLine::LineTable *> getLineTableForUnit(
+ DWARFUnit *U,
+ function_ref<void(Error)> RecoverableErrorHandler) override {
if (!Line)
Line = std::make_unique<DWARFDebugLine>();
@@ -420,7 +418,6 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
U->isLittleEndian(), U->getAddressByteSize());
return Line->getOrParseLineTable(Data, stmtOffset, U->getContext(), U,
RecoverableErrorHandler);
-
}
void clearLineTableForUnit(DWARFUnit *U) override {
@@ -445,20 +442,19 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
const DWARFObject &DObj = D.getDWARFObj();
const DWARFSection &DS = DObj.getFrameSection();
- // There's a "bug" in the DWARFv3 standard with respect to the target address
- // size within debug frame sections. While DWARF is supposed to be independent
- // of its container, FDEs have fields with size being "target address size",
- // which isn't specified in DWARF in general. It's only specified for CUs, but
- // .eh_frame can appear without a .debug_info section. Follow the example of
- // other tools (libdwarf) and extract this from the container (ObjectFile
- // provides this information). This problem is fixed in DWARFv4
- // See this dwarf-discuss discussion for more details:
+ // There's a "bug" in the DWARFv3 standard with respect to the target
+ // address size within debug frame sections. While DWARF is supposed to be
+ // independent of its container, FDEs have fields with size being "target
+ // address size", which isn't specified in DWARF in general. It's only
+ // specified for CUs, but .eh_frame can appear without a .debug_info
+ // section. Follow the example of other tools (libdwarf) and extract this
+ // from the container (ObjectFile provides this information). This problem
+ // is fixed in DWARFv4 See this dwarf-discuss discussion for more details:
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
DObj.getAddressSize());
- auto DF =
- std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/false,
- DS.Address);
+ auto DF = std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/false,
+ DS.Address);
if (Error E = DF->parse(Data))
return std::move(E);
@@ -474,9 +470,8 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
const DWARFSection &DS = DObj.getEHFrameSection();
DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
DObj.getAddressSize());
- auto DF =
- std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/true,
- DS.Address);
+ auto DF = std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/true,
+ DS.Address);
if (Error E = DF->parse(Data))
return std::move(E);
EHFrame.swap(DF);
@@ -512,20 +507,17 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
const DWARFObject &DObj = D.getDWARFObj();
return getAccelTable(AppleNames, DObj, DObj.getAppleNamesSection(),
DObj.getStrSection(), D.isLittleEndian());
-
}
const AppleAcceleratorTable &getAppleTypes() override {
const DWARFObject &DObj = D.getDWARFObj();
return getAccelTable(AppleTypes, DObj, DObj.getAppleTypesSection(),
DObj.getStrSection(), D.isLittleEndian());
-
}
const AppleAcceleratorTable &getAppleNamespaces() override {
const DWARFObject &DObj = D.getDWARFObj();
return getAccelTable(AppleNamespaces, DObj,
- DObj.getAppleNamespacesSection(),
- DObj.getStrSection(), D.isLittleEndian());
-
+ DObj.getAppleNamespacesSection(), DObj.getStrSection(),
+ D.isLittleEndian());
}
const AppleAcceleratorTable &getAppleObjC() override {
const DWARFObject &DObj = D.getDWARFObj();
@@ -533,8 +525,7 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
DObj.getStrSection(), D.isLittleEndian());
}
- std::shared_ptr<DWARFContext>
- getDWOContext(StringRef AbsolutePath) override {
+ std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath) override {
if (auto S = DWP.lock()) {
DWARFContext *Ctxt = S->Context.get();
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
@@ -595,7 +586,7 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {
if (!NormalTypeUnits) {
NormalTypeUnits.emplace();
- for (const auto &U :D.normal_units()) {
+ for (const auto &U : D.normal_units()) {
if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
(*NormalTypeUnits)[TU->getTypeHash()] = TU;
}
@@ -606,7 +597,7 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {
if (!DWOTypeUnits) {
DWOTypeUnits.emplace();
- for (const auto &U :D.dwo_units()) {
+ for (const auto &U : D.dwo_units()) {
if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
(*DWOTypeUnits)[TU->getTypeHash()] = TU;
}
@@ -622,15 +613,15 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
return getNormalTypeUnitMap();
}
-
+ void doWorkThreadSafely(function_ref<void()> Work) override { Work(); }
};
class ThreadSafeState : public ThreadUnsafeDWARFContextState {
std::recursive_mutex Mutex;
public:
- ThreadSafeState(DWARFContext &DC, std::string &DWP) :
- ThreadUnsafeDWARFContextState(DC, DWP) {}
+ ThreadSafeState(DWARFContext &DC, std::string &DWP)
+ : ThreadUnsafeDWARFContextState(DC, DWP) {}
DWARFUnitVector &getNormalUnits() override {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
@@ -672,10 +663,12 @@ class ThreadSafeState : public ThreadUnsafeDWARFContextState {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
return ThreadUnsafeDWARFContextState::getDebugAranges();
}
- Expected<const DWARFDebugLine::LineTable *>
- getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
+ Expected<const DWARFDebugLine::LineTable *> getLineTableForUnit(
+ DWARFUnit *U,
+ function_ref<void(Error)> RecoverableErrorHandler) override {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
- return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);
+ return ThreadUnsafeDWARFContextState::getLineTableForUnit(
+ U, RecoverableErrorHandler);
}
void clearLineTableForUnit(DWARFUnit *U) override {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
@@ -725,8 +718,7 @@ class ThreadSafeState : public ThreadUnsafeDWARFContextState {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
return ThreadUnsafeDWARFContextState::getAppleObjC();
}
- std::shared_ptr<DWARFContext>
- getDWOContext(StringRef AbsolutePath) override {
+ std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath) override {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);
}
@@ -738,6 +730,11 @@ class ThreadSafeState : public ThreadUnsafeDWARFContextState {
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
}
+
+ void doWorkThreadSafely(function_ref<void()> Work) override {
+ std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
+ ThreadUnsafeDWARFContextState::doWorkThreadSafely(Work);
+ }
};
} // namespace
@@ -746,14 +743,13 @@ DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
std::function<void(Error)> RecoverableErrorHandler,
std::function<void(Error)> WarningHandler,
bool ThreadSafe)
- : DIContext(CK_DWARF),
- RecoverableErrorHandler(RecoverableErrorHandler),
+ : DIContext(CK_DWARF), RecoverableErrorHandler(RecoverableErrorHandler),
WarningHandler(WarningHandler), DObj(std::move(DObj)) {
- if (ThreadSafe)
- State = std::make_unique<ThreadSafeState>(*this, DWPName);
- else
- State = std::make_unique<ThreadUnsafeDWARFContextState>(*this, DWPName);
- }
+ if (ThreadSafe)
+ State = std::make_unique<ThreadSafeState>(*this, DWPName);
+ else
+ State = std::make_unique<ThreadUnsafeDWARFContextState>(*this, DWPName);
+}
DWARFContext::~DWARFContext() = default;
@@ -770,7 +766,7 @@ static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
return;
}
OS << "UUID: ";
- memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
+ memcpy(&UUID, LC.Ptr + sizeof(LC.C), sizeof(UUID));
OS.write_uuid(UUID);
Triple T = MachO->getArchTriple();
OS << " (" << T.getArchName() << ')';
@@ -944,7 +940,6 @@ static void dumpRnglistsSection(
}
}
-
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
DWARFDataExtractor Data, const DWARFObject &Obj,
std::optional<uint64_t> DumpOffset) {
@@ -1234,8 +1229,8 @@ void DWARFContext::dump(
if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
DObj->getAddrSection().Data)) {
- DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
- isLittleEndian(), 0);
+ DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(), isLittleEndian(),
+ 0);
dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
}
@@ -1347,8 +1342,7 @@ DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint64_t Hash, bool IsDWO) {
DWARFUnitVector &DWOUnits = State->getDWOUnits();
if (const auto &TUI = getTUIndex()) {
if (const auto *R = TUI.getFromHash(Hash))
- return dyn_cast_or_null<DWARFTypeUnit>(
- DWOUnits.getUnitForIndexEntry(*R));
+ return dyn_cast_or_null<DWARFTypeUnit>(DWOUnits.getUnitForIndexEntry(*R));
return nullptr;
}
return State->getTypeUnitMap(IsDWO).lookup(Hash);
@@ -1410,17 +1404,11 @@ bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
return Success;
}
-const DWARFUnitIndex &DWARFContext::getCUIndex() {
- return State->getCUIndex();
-}
+const DWARFUnitIndex &DWARFContext::getCUIndex() { return State->getCUIndex(); }
-const DWARFUnitIndex &DWARFContext::getTUIndex() {
- return State->getTUIndex();
-}
+const DWARFUnitIndex &DWARFContext::getTUIndex() { return State->getTUIndex(); }
-DWARFGdbIndex &DWARFContext::getGdbIndex() {
- return State->getGdbIndex();
-}
+DWARFGdbIndex &DWARFContext::getGdbIndex() { return State->getGdbIndex(); }
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
return State->getDebugAbbrev();
@@ -1462,7 +1450,6 @@ const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
return State->getDebugMacinfoDWO();
}
-
const DWARFDebugNames &DWARFContext::getDebugNames() {
return State->getDebugNames();
}
@@ -2147,7 +2134,7 @@ class DWARFObjInMemory final : public DWARFObject {
consumeError(NameOrErr.takeError());
++SectionAmountMap[Name];
- SectionNames.push_back({ Name, true });
+ SectionNames.push_back({Name, true});
// Skip BSS and Virtual sections, they aren't interesting.
if (Section.isBSS() || Section.isVirtual())
@@ -2382,17 +2369,19 @@ class DWARFObjInMemory final : public DWARFObject {
StringRef getAbbrevSection() const override { return AbbrevSection; }
const DWARFSection &getLocSection() const override { return LocSection; }
- const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
- StringRef getArangesSection() const override { return ArangesSection; }
- const DWARFSection &getFrameSection() const override {
- return FrameSection;
+ const DWARFSection &getLoclistsSection() const override {
+ return LoclistsSection;
}
+ StringRef getArangesSection() const override { return ArangesSection; }
+ const DWARFSection &getFrameSection() const override { return FrameSection; }
const DWARFSection &getEHFrameSection() const override {
return EHFrameSection;
}
const DWARFSection &getLineSection() const override { return LineSection; }
StringRef getStrSection() const override { return StrSection; }
- const DWARFSection &getRangesSection() const override { return RangesSection; }
+ const DWARFSection &getRangesSection() const override {
+ return RangesSection;
+ }
const DWARFSection &getRnglistsSection() const override {
return RnglistsSection;
}
@@ -2400,8 +2389,12 @@ class DWARFObjInMemory final : public DWARFObject {
StringRef getMacroDWOSection() const override { return MacroDWOSection; }
StringRef getMacinfoSection() const override { return MacinfoSection; }
StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
- const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
- const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
+ const DWARFSection &getPubnamesSection() const override {
+ return PubnamesSection;
+ }
+ const DWARFSection &getPubtypesSection() const override {
+ return PubtypesSection;
+ }
const DWARFSection &getGnuPubnamesSection() const override {
return GnuPubnamesSection;
}
@@ -2420,9 +2413,7 @@ class DWARFObjInMemory final : public DWARFObject {
const DWARFSection &getAppleObjCSection() const override {
return AppleObjCSection;
}
- const DWARFSection &getNamesSection() const override {
- return NamesSection;
- }
+ const DWARFSection &getNamesSection() const override { return NamesSection; }
StringRef getFileName() const override { return FileName; }
uint8_t getAddressSize() const override { return AddressSize; }
@@ -2439,28 +2430,22 @@ class DWARFObjInMemory final : public DWARFObject {
};
} // namespace
-std::unique_ptr<DWARFContext>
-DWARFContext::create(const object::ObjectFile &Obj,
- ProcessDebugRelocations RelocAction,
- const LoadedObjectInfo *L, std::string DWPName,
- std::function<void(Error)> RecoverableErrorHandler,
- std::function<void(Error)> WarningHandler,
- bool ThreadSafe) {
+std::unique_ptr<DWARFContext> DWARFContext::create(
+ const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction,
+ const LoadedObjectInfo *L, std::string DWPName,
+ std::function<void(Error)> RecoverableErrorHandler,
+ std::function<void(Error)> WarningHandler, bool ThreadSafe) {
auto DObj = std::make_unique<DWARFObjInMemory>(
Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
- return std::make_unique<DWARFContext>(std::move(DObj),
- std::move(DWPName),
- RecoverableErrorHandler,
- WarningHandler,
+ return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
+ RecoverableErrorHandler, WarningHandler,
ThreadSafe);
}
-std::unique_ptr<DWARFContext>
-DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
- uint8_t AddrSize, bool isLittleEndian,
- std::function<void(Error)> RecoverableErrorHandler,
- std::function<void(Error)> WarningHandler,
- bool ThreadSafe) {
+std::unique_ptr<DWARFContext> DWARFContext::create(
+ const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize,
+ bool isLittleEndian, std::function<void(Error)> RecoverableErrorHandler,
+ std::function<void(Error)> WarningHandler, bool ThreadSafe) {
auto DObj =
std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
return std::make_unique<DWARFContext>(
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index bdd04b00f557b..60d2298d0da14 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -33,6 +33,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <iostream>
#include <utility>
#include <vector>
@@ -44,10 +45,9 @@ void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
DWARFSectionKind SectionKind) {
const DWARFObject &D = C.getDWARFObj();
addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
- &D.getLocSection(), D.getStrSection(),
- D.getStrOffsetsSection(), &D.getAddrSection(),
- D.getLineSection(), D.isLittleEndian(), false, false,
- SectionKind);
+ &D.getLocSection(), D.getStrSection(), D.getStrOffsetsSection(),
+ &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(),
+ false, false, SectionKind);
}
void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
@@ -55,11 +55,11 @@ void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
DWARFSectionKind SectionKind,
bool Lazy) {
const DWARFObject &D = C.getDWARFObj();
- addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
- &D.getLocDWOSection(), D.getStrDWOSection(),
- D.getStrOffsetsDWOSection(), &D.getAddrSection(),
- D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
- SectionKind);
+ addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(),
+ &D.getRangesDWOSection(), &D.getLocDWOSection(),
+ D.getStrDWOSection(), D.getStrOffsetsDWOSection(),
+ &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
+ true, Lazy, SectionKind);
}
void DWARFUnitVector::addUnitsImpl(
@@ -107,12 +107,12 @@ void DWARFUnitVector::addUnitsImpl(
std::unique_ptr<DWARFUnit> U;
if (Header.isTypeUnit())
U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
- RS, LocSection, SS, SOS, AOS, LS,
- LE, IsDWO, *this);
+ RS, LocSection, SS, SOS, AOS, LS,
+ LE, IsDWO, *this);
else
- U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
- DA, RS, LocSection, SS, SOS,
- AOS, LS, LE, IsDWO, *this);
+ U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header, DA,
+ RS, LocSection, SS, SOS, AOS, LS,
+ LE, IsDWO, *this);
return U;
};
}
@@ -496,108 +496,114 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
}
Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
- if ((CUDieOnly && !DieArray.empty()) ||
- DieArray.size() > 1)
- return Error::success(); // Already parsed.
-
- bool HasCUDie = !DieArray.empty();
- extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
-
- if (DieArray.empty())
- return Error::success();
-
- // If CU DIE was just parsed, copy several attribute values from it.
- if (HasCUDie)
- return Error::success();
-
- DWARFDie UnitDie(this, &DieArray[0]);
- if (std::optional<uint64_t> DWOId =
- toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
- Header.setDWOId(*DWOId);
- if (!IsDWO) {
- assert(AddrOffsetSectionBase == std::nullopt);
- assert(RangeSectionBase == 0);
- assert(LocSectionBase == 0);
- AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
- if (!AddrOffsetSectionBase)
- AddrOffsetSectionBase =
- toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
- RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
- LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
- }
+ Error e = Error::success();
+ Context.doWorkThreadSafely([&] {
+ if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1) {
+ return; // Already parsed.
+ }
+ bool HasCUDie = !DieArray.empty();
+ extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
- // In general, in DWARF v5 and beyond we derive the start of the unit's
- // contribution to the string offsets table from the unit DIE's
- // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
- // attribute, so we assume that there is a contribution to the string
- // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
- // In both cases we need to determine the format of the contribution,
- // which may differ from the unit's format.
- DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
- IsLittleEndian, 0);
- if (IsDWO || getVersion() >= 5) {
- auto StringOffsetOrError =
- IsDWO ? determineStringOffsetsTableContributionDWO(DA)
- : determineStringOffsetsTableContribution(DA);
- if (!StringOffsetOrError)
- return createStringError(errc::invalid_argument,
- "invalid reference to or invalid content in "
- ".debug_str_offsets[.dwo]: " +
- toString(StringOffsetOrError.takeError()));
+ if (DieArray.empty()) {
+ return;
+ }
- StringOffsetsTableContribution = *StringOffsetOrError;
- }
+ // If CU DIE was just parsed, copy several attribute values from it.
+ if (HasCUDie) {
+ return;
+ }
+
+ DWARFDie UnitDie(this, &DieArray[0]);
+ if (std::optional<uint64_t> DWOId =
+ toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
+ Header.setDWOId(*DWOId);
+ if (!IsDWO) {
+ assert(AddrOffsetSectionBase == std::nullopt);
+ assert(RangeSectionBase == 0);
+ assert(LocSectionBase == 0);
+ AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
+ if (!AddrOffsetSectionBase)
+ AddrOffsetSectionBase =
+ toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
+ RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+ LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
+ }
+
+ // In general, in DWARF v5 and beyond we derive the start of the unit's
+ // contribution to the string offsets table from the unit DIE's
+ // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
+ // attribute, so we assume that there is a contribution to the string
+ // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
+ // In both cases we need to determine the format of the contribution,
+ // which may differ from the unit's format.
+ DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+ IsLittleEndian, 0);
+ if (IsDWO || getVersion() >= 5) {
+ auto StringOffsetOrError =
+ IsDWO ? determineStringOffsetsTableContributionDWO(DA)
+ : determineStringOffsetsTableContribution(DA);
+ if (!StringOffsetOrError) {
+ e = createStringError(errc::invalid_argument,
+ "invalid reference to or invalid content in "
+ ".debug_str_offsets[.dwo]: " +
+ toString(StringOffsetOrError.takeError()));
+ return;
+ }
+
+ StringOffsetsTableContribution = *StringOffsetOrError;
+ }
+
+ // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
+ // describe address ranges.
+ if (getVersion() >= 5) {
+ // In case of DWP, the base offset from the index has to be added.
+ if (IsDWO) {
+ uint64_t ContributionBaseOffset = 0;
+ if (auto *IndexEntry = Header.getIndexEntry())
+ if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
+ ContributionBaseOffset = Contrib->getOffset();
+ setRangesSection(
+ &Context.getDWARFObj().getRnglistsDWOSection(),
+ ContributionBaseOffset +
+ DWARFListTableHeader::getHeaderSize(Header.getFormat()));
+ } else
+ setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
+ toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
+ DWARFListTableHeader::getHeaderSize(
+ Header.getFormat())));
+ }
- // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
- // describe address ranges.
- if (getVersion() >= 5) {
- // In case of DWP, the base offset from the index has to be added.
if (IsDWO) {
- uint64_t ContributionBaseOffset = 0;
+ // If we are reading a package file, we need to adjust the location list
+ // data based on the index entries.
+ StringRef Data = Header.getVersion() >= 5
+ ? Context.getDWARFObj().getLoclistsDWOSection().Data
+ : Context.getDWARFObj().getLocDWOSection().Data;
if (auto *IndexEntry = Header.getIndexEntry())
- if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
- ContributionBaseOffset = Contrib->getOffset();
- setRangesSection(
- &Context.getDWARFObj().getRnglistsDWOSection(),
- ContributionBaseOffset +
- DWARFListTableHeader::getHeaderSize(Header.getFormat()));
- } else
- setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
- toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
- DWARFListTableHeader::getHeaderSize(
- Header.getFormat())));
- }
-
- if (IsDWO) {
- // If we are reading a package file, we need to adjust the location list
- // data based on the index entries.
- StringRef Data = Header.getVersion() >= 5
- ? Context.getDWARFObj().getLoclistsDWOSection().Data
- : Context.getDWARFObj().getLocDWOSection().Data;
- if (auto *IndexEntry = Header.getIndexEntry())
- if (const auto *C = IndexEntry->getContribution(
- Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
- Data = Data.substr(C->getOffset(), C->getLength());
-
- DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
- LocTable =
- std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
- LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
- } else if (getVersion() >= 5) {
- LocTable = std::make_unique<DWARFDebugLoclists>(
- DWARFDataExtractor(Context.getDWARFObj(),
- Context.getDWARFObj().getLoclistsSection(),
- IsLittleEndian, getAddressByteSize()),
- getVersion());
- } else {
- LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
- Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
- IsLittleEndian, getAddressByteSize()));
- }
+ if (const auto *C = IndexEntry->getContribution(
+ Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
+ Data = Data.substr(C->getOffset(), C->getLength());
+
+ DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
+ LocTable =
+ std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
+ LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
+ } else if (getVersion() >= 5) {
+ LocTable = std::make_unique<DWARFDebugLoclists>(
+ DWARFDataExtractor(Context.getDWARFObj(),
+ Context.getDWARFObj().getLoclistsSection(),
+ IsLittleEndian, getAddressByteSize()),
+ getVersion());
+ } else {
+ LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
+ Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
+ IsLittleEndian, getAddressByteSize()));
+ }
- // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
- // skeleton CU DIE, so that DWARF users not aware of it are not broken.
- return Error::success();
+ // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
+ // skeleton CU DIE, so that DWARF users not aware of it are not broken.
+ });
+ return e;
}
bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
@@ -652,15 +658,20 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
return true;
}
-void DWARFUnit::clearDIEs(bool KeepCUDie) {
- // Do not use resize() + shrink_to_fit() to free memory occupied by dies.
- // shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
- // It depends on the implementation whether the request is fulfilled.
- // Create a new vector with a small capacity and assign it to the DieArray to
- // have previous contents freed.
- DieArray = (KeepCUDie && !DieArray.empty())
- ? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
- : std::vector<DWARFDebugInfoEntry>();
+void DWARFUnit::clearDIEs(bool KeepCUDie, bool KeepDWODies) {
+ Context.doWorkThreadSafely([&] {
+ if (!KeepDWODies && DWO) {
+ DWO->clearDIEs(KeepCUDie, KeepDWODies);
+ }
+ // Do not use resize() + shrink_to_fit() to free memory occupied by dies.
+ // shrink_to_fit() is a *non-binding* request to reduce capacity() to
+ // size(). It depends on the implementation whether the request is
+ // fulfilled. Create a new vector with a small capacity and assign it to the
+ // DieArray to have previous contents freed.
+ DieArray = (KeepCUDie && !DieArray.empty())
+ ? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
+ : std::vector<DWARFDebugInfoEntry>();
+ });
}
Expected<DWARFAddressRangesVector>
@@ -868,9 +879,8 @@ DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
return R->second.second;
}
-void
-DWARFUnit::getInlinedChainForAddress(uint64_t Address,
- SmallVectorImpl<DWARFDie> &InlinedChain) {
+void DWARFUnit::getInlinedChainForAddress(
+ uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) {
assert(InlinedChain.empty());
// Try to look for subprogram DIEs in the DWO file.
parseDWO();
@@ -886,7 +896,7 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address,
}
if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
InlinedChain.push_back(SubroutineDIE);
- SubroutineDIE = SubroutineDIE.getParent();
+ SubroutineDIE = SubroutineDIE.getParent();
}
}
@@ -1087,7 +1097,8 @@ StrOffsetsContributionDescriptor::validateContributionSize(
if (ValidationSize >= Size)
if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
return *this;
- return createStringError(errc::invalid_argument, "length exceeds section size");
+ return createStringError(errc::invalid_argument,
+ "length exceeds section size");
}
// Look for a DWARF64-formatted contribution to the string offsets table
@@ -1095,10 +1106,13 @@ StrOffsetsContributionDescriptor::validateContributionSize(
static Expected<StrOffsetsContributionDescriptor>
parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
if (!DA.isValidOffsetForDataOfSize(Offset, 16))
- return createStringError(errc::invalid_argument, "section offset exceeds section size");
+ return createStringError(errc::invalid_argument,
+ "section offset exceeds section size");
if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
- return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit");
+ return createStringError(
+ errc::invalid_argument,
+ "32 bit contribution referenced from a 64 bit unit");
uint64_t Size = DA.getU64(&Offset);
uint8_t Version = DA.getU16(&Offset);
@@ -1113,7 +1127,8 @@ parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
static Expected<StrOffsetsContributionDescriptor>
parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
if (!DA.isValidOffsetForDataOfSize(Offset, 8))
- return createStringError(errc::invalid_argument, "section offset exceeds section size");
+ return createStringError(errc::invalid_argument,
+ "section offset exceeds section size");
uint32_t ContributionSize = DA.getU32(&Offset);
if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
@@ -1135,7 +1150,8 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
switch (Format) {
case dwarf::DwarfFormat::DWARF64: {
if (Offset < 16)
- return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix");
+ return createStringError(errc::invalid_argument,
+ "insufficient space for 64 bit header prefix");
auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, Offset - 16);
if (!DescOrError)
return DescOrError.takeError();
@@ -1144,7 +1160,8 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
}
case dwarf::DwarfFormat::DWARF32: {
if (Offset < 8)
- return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix");
+ return createStringError(errc::invalid_argument,
+ "insufficient space for 32 bit header prefix");
auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, Offset - 8);
if (!DescOrError)
return DescOrError.takeError();
@@ -1182,7 +1199,8 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA) {
return std::nullopt;
Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
// Look for a valid contribution at the given offset.
- auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset);
+ auto DescOrError =
+ parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset);
if (!DescOrError)
return DescOrError.takeError();
return *DescOrError;
diff --git a/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp b/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
index 7a0256f10ea60..cba59955131b4 100644
--- a/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
+++ b/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
@@ -82,7 +82,6 @@ struct llvm::gsym::CUInfo {
}
};
-
static DWARFDie GetParentDeclContextDIE(DWARFDie &Die) {
if (DWARFDie SpecDie =
Die.getAttributeValueAsReferencedDie(dwarf::DW_AT_specification)) {
@@ -170,7 +169,7 @@ getQualifiedNameIndex(DWARFDie &Die, uint64_t Language, GsymCreator &Gsym) {
// templates
if (ParentName.front() == '<' && ParentName.back() == '>')
Name = "{" + ParentName.substr(1, ParentName.size() - 2).str() + "}" +
- "::" + Name;
+ "::" + Name;
else
Name = ParentName.str() + "::" + Name;
}
@@ -432,7 +431,7 @@ static void convertFunctionLineTable(OutputAggregator &Out, CUInfo &CUI,
// Skip multiple line entries for the same file and line.
auto LastLE = FI.OptLineTable->last();
if (LastLE && LastLE->File == FileIdx && LastLE->Line == Row.Line)
- continue;
+ continue;
// Only push a row if it isn't an end sequence. End sequence markers are
// included for the last address in a function or the last contiguous
// address in a sequence.
@@ -656,6 +655,11 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
DWARFDie Die = getDie(*CU);
CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get()));
handleDie(Out, CUI, Die);
+ // Release the line table, once we're done.
+ DICtx.clearLineTableForUnit(CU.get());
+ // Free any DIEs that were allocated by the DWARF parser.
+ // If/when they're needed by other CU's, they'll be recreated.
+ CU->clearDIEs(/*KeepCUDie=*/false);
}
} else {
// LLVM Dwarf parser is not thread-safe and we need to parse all DWARF up
@@ -668,12 +672,7 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
for (const auto &CU : DICtx.compile_units())
CU->getAbbreviations();
- // Now parse all DIEs in case we have cross compile unit references in a
- // thread pool.
DefaultThreadPool pool(hardware_concurrency(NumThreads));
- for (const auto &CU : DICtx.compile_units())
- pool.async([&CU]() { CU->getUnitDIE(false /*CUDieOnly*/); });
- pool.wait();
// Now convert all DWARF to GSYM in a thread pool.
std::mutex LogMutex;
@@ -681,11 +680,16 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
DWARFDie Die = getDie(*CU);
if (Die) {
CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get()));
- pool.async([this, CUI, &LogMutex, &Out, Die]() mutable {
+ pool.async([this, CUI, &CU, &LogMutex, &Out, Die]() mutable {
std::string storage;
raw_string_ostream StrStream(storage);
OutputAggregator ThreadOut(Out.GetOS() ? &StrStream : nullptr);
handleDie(ThreadOut, CUI, Die);
+ // Release the line table once we're done.
+ DICtx.clearLineTableForUnit(CU.get());
+ // Free any DIEs that were allocated by the DWARF parser.
+ // If/when they're needed by other CU's, they'll be recreated.
+ CU->clearDIEs(/*KeepCUDie=*/false);
// Print ThreadLogStorage lines into an actual stream under a lock
std::lock_guard<std::mutex> guard(LogMutex);
if (Out.GetOS()) {
@@ -697,6 +701,9 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
}
pool.wait();
}
+ // Now get rid of all the DIEs that may have been recreated
+ for (const auto &CU : DICtx.compile_units())
+ CU->clearDIEs(/*KeepCUDie=*/false);
size_t FunctionsAddedCount = Gsym.getNumFunctionInfos() - NumBefore;
Out << "Loaded " << FunctionsAddedCount << " functions from DWARF.\n";
return Error::success();
@@ -718,8 +725,8 @@ llvm::Error DwarfTransformer::verify(StringRef GsymPath,
for (uint32_t I = 0; I < NumAddrs; ++I) {
auto FuncAddr = Gsym->getAddress(I);
if (!FuncAddr)
- return createStringError(std::errc::invalid_argument,
- "failed to extract address[%i]", I);
+ return createStringError(std::errc::invalid_argument,
+ "failed to extract address[%i]", I);
auto FI = Gsym->getFunctionInfo(*FuncAddr);
if (!FI)
@@ -734,8 +741,7 @@ llvm::Error DwarfTransformer::verify(StringRef GsymPath,
if (!LR)
return LR.takeError();
- auto DwarfInlineInfos =
- DICtx.getInliningInfoForAddress(SectAddr, DLIS);
+ auto DwarfInlineInfos = DICtx.getInliningInfoForAddress(SectAddr, DLIS);
uint32_t NumDwarfInlineInfos = DwarfInlineInfos.getNumberOfFrames();
if (NumDwarfInlineInfos == 0) {
DwarfInlineInfos.addFrame(
@@ -773,8 +779,7 @@ llvm::Error DwarfTransformer::verify(StringRef GsymPath,
continue;
}
- for (size_t Idx = 0, count = LR->Locations.size(); Idx < count;
- ++Idx) {
+ for (size_t Idx = 0, count = LR->Locations.size(); Idx < count; ++Idx) {
const auto &gii = LR->Locations[Idx];
if (Idx < NumDwarfInlineInfos) {
const auto &dii = DwarfInlineInfos.getFrame(Idx);
More information about the llvm-commits
mailing list