Skip to content

Commit 5ed0b3a

Browse files
authored
Revert "Reduce llvm-gsymutil memory usage" (#140696)
Reverts #139907 as per discussion in #140545 due to tests becoming flaky
1 parent 3918ef3 commit 5ed0b3a

File tree

5 files changed

+111
-143
lines changed

5 files changed

+111
-143
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ class DWARFContext : public DIContext {
102102
/// Parse a macro[.dwo] or macinfo[.dwo] section.
103103
std::unique_ptr<DWARFDebugMacro>
104104
parseMacroOrMacinfo(MacroSecType SectionType);
105-
106-
virtual Error doWorkThreadSafely(function_ref<Error()> Work) = 0;
107105
};
108106
friend class DWARFContextState;
109107

@@ -492,10 +490,6 @@ class DWARFContext : public DIContext {
492490
/// manually only for DWARF5.
493491
void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }
494492

495-
Error doWorkThreadSafely(function_ref<Error()> Work) {
496-
return State->doWorkThreadSafely(Work);
497-
}
498-
499493
private:
500494
void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
501495
std::vector<DILocal> &Result);

llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,6 @@ class DWARFUnit {
566566

567567
Error tryExtractDIEsIfNeeded(bool CUDieOnly);
568568

569-
/// clearDIEs - Clear parsed DIEs to keep memory usage low.
570-
void clearDIEs(bool KeepCUDie, bool KeepDWODies = false);
571-
572569
private:
573570
/// Size in bytes of the .debug_info data associated with this compile unit.
574571
size_t getDebugInfoSize() const {
@@ -584,6 +581,9 @@ class DWARFUnit {
584581
void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
585582
std::vector<DWARFDebugInfoEntry> &DIEs) const;
586583

584+
/// clearDIEs - Clear parsed DIEs to keep memory usage low.
585+
void clearDIEs(bool KeepCUDie);
586+
587587
/// parseDWO - Parses .dwo file for current compile unit. Returns true if
588588
/// it was actually constructed.
589589
/// The \p AlternativeLocation specifies an alternative location to get

llvm/lib/DebugInfo/DWARF/DWARFContext.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -621,10 +621,6 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
621621
else
622622
return getNormalTypeUnitMap();
623623
}
624-
625-
Error doWorkThreadSafely(function_ref<Error()> Work) override {
626-
return Work();
627-
}
628624
};
629625

630626
class ThreadSafeState : public ThreadUnsafeDWARFContextState {
@@ -740,11 +736,6 @@ class ThreadSafeState : public ThreadUnsafeDWARFContextState {
740736
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
741737
return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
742738
}
743-
744-
Error doWorkThreadSafely(function_ref<Error()> Work) override {
745-
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
746-
return ThreadUnsafeDWARFContextState::doWorkThreadSafely(Work);
747-
}
748739
};
749740
} // namespace
750741

llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp

Lines changed: 102 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -496,111 +496,107 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
496496
}
497497

498498
Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
499-
return Context.doWorkThreadSafely([&]() -> Error {
500-
if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1)
501-
return Error::success(); // Already parsed.
502-
503-
bool HasCUDie = !DieArray.empty();
504-
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
505-
506-
if (DieArray.empty())
507-
return Error::success();
508-
509-
// If CU DIE was just parsed, copy several attribute values from it.
510-
if (HasCUDie)
511-
return Error::success();
512-
513-
DWARFDie UnitDie(this, &DieArray[0]);
514-
if (std::optional<uint64_t> DWOId =
515-
toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
516-
Header.setDWOId(*DWOId);
517-
if (!IsDWO) {
518-
assert(AddrOffsetSectionBase == std::nullopt);
519-
assert(RangeSectionBase == 0);
520-
assert(LocSectionBase == 0);
521-
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
522-
if (!AddrOffsetSectionBase)
523-
AddrOffsetSectionBase =
524-
toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
525-
RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
526-
LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
527-
}
499+
if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1)
500+
return Error::success(); // Already parsed.
528501

529-
// In general, in DWARF v5 and beyond we derive the start of the unit's
530-
// contribution to the string offsets table from the unit DIE's
531-
// DW_AT_str_offsets_base attribute. Split DWARF units do not use this
532-
// attribute, so we assume that there is a contribution to the string
533-
// offsets table starting at offset 0 of the debug_str_offsets.dwo section.
534-
// In both cases we need to determine the format of the contribution,
535-
// which may differ from the unit's format.
536-
DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
537-
IsLittleEndian, 0);
538-
if (IsDWO || getVersion() >= 5) {
539-
auto StringOffsetOrError =
540-
IsDWO ? determineStringOffsetsTableContributionDWO(DA)
541-
: determineStringOffsetsTableContribution(DA);
542-
if (!StringOffsetOrError) {
543-
return createStringError(errc::invalid_argument,
544-
"invalid reference to or invalid content in "
545-
".debug_str_offsets[.dwo]: " +
546-
toString(StringOffsetOrError.takeError()));
547-
}
502+
bool HasCUDie = !DieArray.empty();
503+
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
548504

549-
StringOffsetsTableContribution = *StringOffsetOrError;
550-
}
505+
if (DieArray.empty())
506+
return Error::success();
551507

552-
// DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
553-
// describe address ranges.
554-
if (getVersion() >= 5) {
555-
// In case of DWP, the base offset from the index has to be added.
556-
if (IsDWO) {
557-
uint64_t ContributionBaseOffset = 0;
558-
if (auto *IndexEntry = Header.getIndexEntry())
559-
if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
560-
ContributionBaseOffset = Contrib->getOffset();
561-
setRangesSection(
562-
&Context.getDWARFObj().getRnglistsDWOSection(),
563-
ContributionBaseOffset +
564-
DWARFListTableHeader::getHeaderSize(Header.getFormat()));
565-
} else
566-
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
567-
toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
568-
DWARFListTableHeader::getHeaderSize(
569-
Header.getFormat())));
570-
}
508+
// If CU DIE was just parsed, copy several attribute values from it.
509+
if (HasCUDie)
510+
return Error::success();
511+
512+
DWARFDie UnitDie(this, &DieArray[0]);
513+
if (std::optional<uint64_t> DWOId =
514+
toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
515+
Header.setDWOId(*DWOId);
516+
if (!IsDWO) {
517+
assert(AddrOffsetSectionBase == std::nullopt);
518+
assert(RangeSectionBase == 0);
519+
assert(LocSectionBase == 0);
520+
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
521+
if (!AddrOffsetSectionBase)
522+
AddrOffsetSectionBase =
523+
toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
524+
RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
525+
LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
526+
}
527+
528+
// In general, in DWARF v5 and beyond we derive the start of the unit's
529+
// contribution to the string offsets table from the unit DIE's
530+
// DW_AT_str_offsets_base attribute. Split DWARF units do not use this
531+
// attribute, so we assume that there is a contribution to the string
532+
// offsets table starting at offset 0 of the debug_str_offsets.dwo section.
533+
// In both cases we need to determine the format of the contribution,
534+
// which may differ from the unit's format.
535+
DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
536+
IsLittleEndian, 0);
537+
if (IsDWO || getVersion() >= 5) {
538+
auto StringOffsetOrError =
539+
IsDWO ? determineStringOffsetsTableContributionDWO(DA)
540+
: determineStringOffsetsTableContribution(DA);
541+
if (!StringOffsetOrError)
542+
return createStringError(errc::invalid_argument,
543+
"invalid reference to or invalid content in "
544+
".debug_str_offsets[.dwo]: " +
545+
toString(StringOffsetOrError.takeError()));
546+
547+
StringOffsetsTableContribution = *StringOffsetOrError;
548+
}
571549

550+
// DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
551+
// describe address ranges.
552+
if (getVersion() >= 5) {
553+
// In case of DWP, the base offset from the index has to be added.
572554
if (IsDWO) {
573-
// If we are reading a package file, we need to adjust the location list
574-
// data based on the index entries.
575-
StringRef Data = Header.getVersion() >= 5
576-
? Context.getDWARFObj().getLoclistsDWOSection().Data
577-
: Context.getDWARFObj().getLocDWOSection().Data;
555+
uint64_t ContributionBaseOffset = 0;
578556
if (auto *IndexEntry = Header.getIndexEntry())
579-
if (const auto *C = IndexEntry->getContribution(
580-
Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
581-
Data = Data.substr(C->getOffset(), C->getLength());
582-
583-
DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
584-
LocTable =
585-
std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
586-
LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
587-
} else if (getVersion() >= 5) {
588-
LocTable = std::make_unique<DWARFDebugLoclists>(
589-
DWARFDataExtractor(Context.getDWARFObj(),
590-
Context.getDWARFObj().getLoclistsSection(),
591-
IsLittleEndian, getAddressByteSize()),
592-
getVersion());
593-
} else {
594-
LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
595-
Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
596-
IsLittleEndian, getAddressByteSize()));
597-
}
557+
if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
558+
ContributionBaseOffset = Contrib->getOffset();
559+
setRangesSection(
560+
&Context.getDWARFObj().getRnglistsDWOSection(),
561+
ContributionBaseOffset +
562+
DWARFListTableHeader::getHeaderSize(Header.getFormat()));
563+
} else
564+
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
565+
toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
566+
DWARFListTableHeader::getHeaderSize(
567+
Header.getFormat())));
568+
}
598569

599-
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
600-
// skeleton CU DIE, so that DWARF users not aware of it are not broken.
570+
if (IsDWO) {
571+
// If we are reading a package file, we need to adjust the location list
572+
// data based on the index entries.
573+
StringRef Data = Header.getVersion() >= 5
574+
? Context.getDWARFObj().getLoclistsDWOSection().Data
575+
: Context.getDWARFObj().getLocDWOSection().Data;
576+
if (auto *IndexEntry = Header.getIndexEntry())
577+
if (const auto *C = IndexEntry->getContribution(
578+
Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
579+
Data = Data.substr(C->getOffset(), C->getLength());
580+
581+
DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
582+
LocTable =
583+
std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
584+
LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
585+
} else if (getVersion() >= 5) {
586+
LocTable = std::make_unique<DWARFDebugLoclists>(
587+
DWARFDataExtractor(Context.getDWARFObj(),
588+
Context.getDWARFObj().getLoclistsSection(),
589+
IsLittleEndian, getAddressByteSize()),
590+
getVersion());
591+
} else {
592+
LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
593+
Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
594+
IsLittleEndian, getAddressByteSize()));
595+
}
601596

602-
return Error::success();
603-
});
597+
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
598+
// skeleton CU DIE, so that DWARF users not aware of it are not broken.
599+
return Error::success();
604600
}
605601

606602
bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
@@ -655,21 +651,15 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
655651
return true;
656652
}
657653

658-
void DWARFUnit::clearDIEs(bool KeepCUDie, bool KeepDWODies) {
659-
assert(!Context.doWorkThreadSafely([&] {
660-
if (!KeepDWODies && DWO) {
661-
DWO->clearDIEs(KeepCUDie, KeepDWODies);
662-
}
663-
// Do not use resize() + shrink_to_fit() to free memory occupied by dies.
664-
// shrink_to_fit() is a *non-binding* request to reduce capacity() to
665-
// size(). It depends on the implementation whether the request is
666-
// fulfilled. Create a new vector with a small capacity and assign it to the
667-
// DieArray to have previous contents freed.
668-
DieArray = (KeepCUDie && !DieArray.empty())
669-
? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
670-
: std::vector<DWARFDebugInfoEntry>();
671-
return Error::success();
672-
}));
654+
void DWARFUnit::clearDIEs(bool KeepCUDie) {
655+
// Do not use resize() + shrink_to_fit() to free memory occupied by dies.
656+
// shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
657+
// It depends on the implementation whether the request is fulfilled.
658+
// Create a new vector with a small capacity and assign it to the DieArray to
659+
// have previous contents freed.
660+
DieArray = (KeepCUDie && !DieArray.empty())
661+
? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
662+
: std::vector<DWARFDebugInfoEntry>();
673663
}
674664

675665
Expected<DWARFAddressRangesVector>

llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -656,11 +656,6 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
656656
DWARFDie Die = getDie(*CU);
657657
CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get()));
658658
handleDie(Out, CUI, Die);
659-
// Release the line table, once we're done.
660-
DICtx.clearLineTableForUnit(CU.get());
661-
// Free any DIEs that were allocated by the DWARF parser.
662-
// If/when they're needed by other CU's, they'll be recreated.
663-
CU->clearDIEs(/*KeepCUDie=*/false, /*KeepDWODIEs=*/false);
664659
}
665660
} else {
666661
// LLVM Dwarf parser is not thread-safe and we need to parse all DWARF up
@@ -673,23 +668,24 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
673668
for (const auto &CU : DICtx.compile_units())
674669
CU->getAbbreviations();
675670

671+
// Now parse all DIEs in case we have cross compile unit references in a
672+
// thread pool.
676673
DefaultThreadPool pool(hardware_concurrency(NumThreads));
674+
for (const auto &CU : DICtx.compile_units())
675+
pool.async([&CU]() { CU->getUnitDIE(false /*CUDieOnly*/); });
676+
pool.wait();
677677

678678
// Now convert all DWARF to GSYM in a thread pool.
679679
std::mutex LogMutex;
680680
for (const auto &CU : DICtx.compile_units()) {
681681
DWARFDie Die = getDie(*CU);
682682
if (Die) {
683683
CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get()));
684-
pool.async([this, CUI, &CU, &LogMutex, &Out, Die]() mutable {
684+
pool.async([this, CUI, &LogMutex, &Out, Die]() mutable {
685685
std::string storage;
686686
raw_string_ostream StrStream(storage);
687687
OutputAggregator ThreadOut(Out.GetOS() ? &StrStream : nullptr);
688688
handleDie(ThreadOut, CUI, Die);
689-
DICtx.clearLineTableForUnit(CU.get());
690-
// Free any DIEs that were allocated by the DWARF parser.
691-
// If/when they're needed by other CU's, they'll be recreated.
692-
CU->clearDIEs(/*KeepCUDie=*/false, /*KeepDWODIEs=*/false);
693689
// Print ThreadLogStorage lines into an actual stream under a lock
694690
std::lock_guard<std::mutex> guard(LogMutex);
695691
if (Out.GetOS()) {
@@ -701,9 +697,6 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
701697
}
702698
pool.wait();
703699
}
704-
// Now get rid of all the DIEs that may have been recreated
705-
for (const auto &CU : DICtx.compile_units())
706-
CU->clearDIEs(/*KeepCUDie=*/false, /*KeepDWODIEs=*/false);
707700
size_t FunctionsAddedCount = Gsym.getNumFunctionInfos() - NumBefore;
708701
Out << "Loaded " << FunctionsAddedCount << " functions from DWARF.\n";
709702
return Error::success();

0 commit comments

Comments
 (0)