Skip to content

Commit 16b79c1

Browse files
authored
Revert "Reduce llvm-gsymutil memory usage (#139907)"
This reverts commit ebb1535.
1 parent d013556 commit 16b79c1

File tree

5 files changed

+113
-141
lines changed

5 files changed

+113
-141
lines changed

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ class DWARFContext : public DIContext {
103103
std::unique_ptr<DWARFDebugMacro>
104104
parseMacroOrMacinfo(MacroSecType SectionType);
105105

106-
virtual Error doWorkThreadSafely(function_ref<Error()> Work) = 0;
107106
};
108107
friend class DWARFContextState;
109108

@@ -492,10 +491,6 @@ class DWARFContext : public DIContext {
492491
/// manually only for DWARF5.
493492
void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }
494493

495-
Error doWorkThreadSafely(function_ref<Error()> Work) {
496-
return State->doWorkThreadSafely(Work);
497-
}
498-
499494
private:
500495
void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
501496
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: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -622,9 +622,7 @@ class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
622622
return getNormalTypeUnitMap();
623623
}
624624

625-
Error doWorkThreadSafely(function_ref<Error()> Work) override {
626-
return Work();
627-
}
625+
628626
};
629627

630628
class ThreadSafeState : public ThreadUnsafeDWARFContextState {
@@ -740,11 +738,6 @@ class ThreadSafeState : public ThreadUnsafeDWARFContextState {
740738
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
741739
return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
742740
}
743-
744-
Error doWorkThreadSafely(function_ref<Error()> Work) override {
745-
std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
746-
return ThreadUnsafeDWARFContextState::doWorkThreadSafely(Work);
747-
}
748741
};
749742
} // namespace
750743

llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp

Lines changed: 103 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -496,111 +496,108 @@ 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()) ||
500+
DieArray.size() > 1)
501+
return Error::success(); // Already parsed.
528502

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-
}
503+
bool HasCUDie = !DieArray.empty();
504+
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
548505

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

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-
}
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+
}
528+
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+
548+
StringOffsetsTableContribution = *StringOffsetOrError;
549+
}
571550

551+
// DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
552+
// describe address ranges.
553+
if (getVersion() >= 5) {
554+
// In case of DWP, the base offset from the index has to be added.
572555
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;
556+
uint64_t ContributionBaseOffset = 0;
578557
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-
}
558+
if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
559+
ContributionBaseOffset = Contrib->getOffset();
560+
setRangesSection(
561+
&Context.getDWARFObj().getRnglistsDWOSection(),
562+
ContributionBaseOffset +
563+
DWARFListTableHeader::getHeaderSize(Header.getFormat()));
564+
} else
565+
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
566+
toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
567+
DWARFListTableHeader::getHeaderSize(
568+
Header.getFormat())));
569+
}
598570

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.
571+
if (IsDWO) {
572+
// If we are reading a package file, we need to adjust the location list
573+
// data based on the index entries.
574+
StringRef Data = Header.getVersion() >= 5
575+
? Context.getDWARFObj().getLoclistsDWOSection().Data
576+
: Context.getDWARFObj().getLocDWOSection().Data;
577+
if (auto *IndexEntry = Header.getIndexEntry())
578+
if (const auto *C = IndexEntry->getContribution(
579+
Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
580+
Data = Data.substr(C->getOffset(), C->getLength());
581+
582+
DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
583+
LocTable =
584+
std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
585+
LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
586+
} else if (getVersion() >= 5) {
587+
LocTable = std::make_unique<DWARFDebugLoclists>(
588+
DWARFDataExtractor(Context.getDWARFObj(),
589+
Context.getDWARFObj().getLoclistsSection(),
590+
IsLittleEndian, getAddressByteSize()),
591+
getVersion());
592+
} else {
593+
LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
594+
Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
595+
IsLittleEndian, getAddressByteSize()));
596+
}
601597

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

606603
bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
@@ -655,21 +652,15 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
655652
return true;
656653
}
657654

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-
}));
655+
void DWARFUnit::clearDIEs(bool KeepCUDie) {
656+
// Do not use resize() + shrink_to_fit() to free memory occupied by dies.
657+
// shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
658+
// It depends on the implementation whether the request is fulfilled.
659+
// Create a new vector with a small capacity and assign it to the DieArray to
660+
// have previous contents freed.
661+
DieArray = (KeepCUDie && !DieArray.empty())
662+
? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
663+
: std::vector<DWARFDebugInfoEntry>();
673664
}
674665

675666
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)