Skip to content

Commit 2cdc496

Browse files
author
Kevin Frei
committed
Added locking
1 parent 6073460 commit 2cdc496

File tree

3 files changed

+44
-20
lines changed

3 files changed

+44
-20
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
2323
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
2424
#include "llvm/Support/DataExtractor.h"
25+
#include "llvm/Support/RWMutex.h"
2526
#include <cassert>
2627
#include <cstddef>
2728
#include <cstdint>
@@ -257,6 +258,9 @@ class DWARFUnit {
257258

258259
std::shared_ptr<DWARFUnit> DWO;
259260

261+
mutable llvm::sys::RWMutex m_cu_die_array_mutex;
262+
mutable llvm::sys::RWMutex m_all_die_array_mutex;
263+
260264
protected:
261265
friend dwarf_linker::parallel::CompileUnit;
262266

@@ -566,7 +570,8 @@ class DWARFUnit {
566570

567571
Error tryExtractDIEsIfNeeded(bool CUDieOnly);
568572

569-
void freeDIEs();
573+
/// clearDIEs - Clear parsed DIEs to keep memory usage low.
574+
void clearDIEs(bool KeepCUDie);
570575

571576
private:
572577
/// Size in bytes of the .debug_info data associated with this compile unit.
@@ -583,9 +588,6 @@ class DWARFUnit {
583588
void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
584589
std::vector<DWARFDebugInfoEntry> &DIEs) const;
585590

586-
/// clearDIEs - Clear parsed DIEs to keep memory usage low.
587-
void clearDIEs(bool KeepCUDie);
588-
589591
/// parseDWO - Parses .dwo file for current compile unit. Returns true if
590592
/// it was actually constructed.
591593
/// The \p AlternativeLocation specifies an alternative location to get

llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -495,26 +495,43 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
495495
Context.getRecoverableErrorHandler()(std::move(e));
496496
}
497497

498-
void DWARFUnit::freeDIEs() {
499-
if (DieArray.capacity())
500-
std::vector<DWARFDebugInfoEntry>().swap(DieArray);
501-
}
502-
503498
Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
504-
if ((CUDieOnly && !DieArray.empty()) ||
505-
DieArray.size() > 1)
506-
return Error::success(); // Already parsed.
507-
508-
bool HasCUDie = !DieArray.empty();
509-
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
499+
// read-lock:
500+
{
501+
llvm::sys::ScopedReader Lock(m_cu_die_array_mutex);
502+
if ((CUDieOnly && !DieArray.empty()) ||
503+
DieArray.size() > 1)
504+
return Error::success(); // Already parsed.
505+
}
506+
bool HasCUDie = false;
507+
// write-lock:
508+
{
509+
llvm::sys::ScopedWriter Lock(m_cu_die_array_mutex);
510+
if ((CUDieOnly && !DieArray.empty()) ||
511+
DieArray.size() > 1)
512+
return Error::success(); // Already parsed.
513+
HasCUDie = !DieArray.empty();
514+
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
515+
}
510516

517+
// read-lock:
518+
{
519+
llvm::sys::ScopedReader Lock(m_all_die_array_mutex);
511520
if (DieArray.empty())
512521
return Error::success();
513522

514523
// If CU DIE was just parsed, copy several attribute values from it.
515524
if (HasCUDie)
516525
return Error::success();
526+
}
527+
// write-lock:
528+
llvm::sys::ScopedWriter Lock(m_all_die_array_mutex);
529+
if (DieArray.empty())
530+
return Error::success();
517531

532+
// If CU DIE was just parsed, copy several attribute values from it.
533+
if (HasCUDie)
534+
return Error::success();
518535
DWARFDie UnitDie(this, &DieArray[0]);
519536
if (std::optional<uint64_t> DWOId =
520537
toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
@@ -663,6 +680,8 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
663680
// It depends on the implementation whether the request is fulfilled.
664681
// Create a new vector with a small capacity and assign it to the DieArray to
665682
// have previous contents freed.
683+
llvm::sys::ScopedWriter CULock(m_cu_die_array_mutex);
684+
llvm::sys::ScopedWriter AllLock(m_all_die_array_mutex);
666685
DieArray = (KeepCUDie && !DieArray.empty())
667686
? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
668687
: std::vector<DWARFDebugInfoEntry>();

llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -619,24 +619,27 @@ Error DwarfTransformer::convert(uint32_t NumThreads, OutputAggregator &Out) {
619619
raw_string_ostream StrStream(storage);
620620
OutputAggregator ThreadOut(Out.GetOS() ? &StrStream : nullptr);
621621
handleDie(ThreadOut, CUI, Die);
622+
// Release the line table once we're done.
623+
DICtx.clearLineTableForUnit(CU.get());
624+
// Free any DIEs that were allocated by the DWARF parser.
625+
// If/when they're needed by other CU's, they'll be recreated.
626+
CU->clearDIEs(false);
622627
// Print ThreadLogStorage lines into an actual stream under a lock
623628
std::lock_guard<std::mutex> guard(LogMutex);
624629
if (Out.GetOS()) {
625630
StrStream.flush();
626631
Out << storage;
627632
}
628-
// Release the line table and DIEs once we're done.
629-
DICtx.clearLineTableForUnit(CU.get());
630-
CU->freeDIEs();
631-
632633
Out.Merge(ThreadOut);
634+
633635
});
634636
}
635637
}
636638
pool.wait();
637639
}
640+
// Now get rid of all the DIEs that may have been recreated
638641
for (const auto &CU : DICtx.compile_units())
639-
CU->freeDIEs();
642+
CU->clearDIEs(false);
640643
size_t FunctionsAddedCount = Gsym.getNumFunctionInfos() - NumBefore;
641644
Out << "Loaded " << FunctionsAddedCount << " functions from DWARF.\n";
642645
return Error::success();

0 commit comments

Comments
 (0)