jankratochvil updated this revision to Diff 149037.
jankratochvil edited the summary of this revision.
https://reviews.llvm.org/D40470
Files:
source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFUnit.h
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -13,6 +13,7 @@
#include "DWARFDIE.h"
#include "DWARFDebugInfoEntry.h"
#include "lldb/lldb-enumerations.h"
+#include "llvm/Support/RWMutex.h"
class DWARFUnit;
class DWARFCompileUnit;
@@ -172,10 +173,17 @@
void *m_user_data = nullptr;
// The compile unit debug information entry item
DWARFDebugInfoEntry::collection m_die_array;
+ mutable llvm::sys::RWMutex m_die_array_mutex;
+ // It gets increased by ExtractDIEsIfNeeded() and decreased by ClearDIEs().
+ // BuildAddressRangeTable and SymbolFileDWARF::Index can populate m_die_array
+ // only temporarily while other functions calling only
+ // ExtractDIEsIfNeeded() will keep m_die_array populated forever.
+ uint32_t m_die_array_usecount = 0;
// GetUnitDIEPtrOnly() needs to return pointer to the first DIE.
// But the first element of m_die_array after ExtractUnitDIEIfNeeded()
// would possibly move in memory after later ExtractDIEsIfNeeded().
DWARFDebugInfoEntry m_first_die;
+ llvm::sys::RWMutex m_first_die_mutex;
// A table similar to the .debug_aranges table, but this one points to the
// exact DW_TAG_subprogram DIEs
std::unique_ptr<DWARFDebugAranges> m_func_aranges_ap;
@@ -206,14 +214,17 @@
// if needed.
const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() {
ExtractUnitDIEIfNeeded();
+ // m_first_die_mutex is not required as m_first_die is never cleared.
if (!m_first_die)
return NULL;
return &m_first_die;
}
// Get all DWARF debug informration entries. Parse all DIEs if needed.
const DWARFDebugInfoEntry *DIEPtr() {
ExtractDIEsIfNeeded();
+ // m_die_array_mutex is not required as ExtractDIEsIfNeeded() has not
+ // been matched by ClearDIEs().
if (m_die_array.empty())
return NULL;
return &m_die_array[0];
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -39,6 +39,12 @@
// Parses first DIE of a compile unit.
//----------------------------------------------------------------------
void DWARFUnit::ExtractUnitDIEIfNeeded() {
+ {
+ llvm::sys::ScopedReader lock(m_first_die_mutex);
+ if (m_first_die)
+ return; // Already parsed
+ }
+ llvm::sys::ScopedWriter lock(m_first_die_mutex);
if (m_first_die)
return; // Already parsed
@@ -69,8 +75,19 @@
// Parses a compile unit and indexes its DIEs if it hasn't already been done.
//----------------------------------------------------------------------
bool DWARFUnit::ExtractDIEsIfNeeded() {
+ {
+ llvm::sys::ScopedReader lock(m_die_array_mutex);
+ if (!m_die_array.empty())
+ return 0; // Already parsed
+ }
+ llvm::sys::ScopedWriter lock(m_die_array_mutex);
if (!m_die_array.empty())
return 0; // Already parsed
+ // Protect against use count overflow.
+ if (m_die_array_usecount
+ < std::numeric_limits<decltype(m_die_array_usecount)>::max())
+ ++m_die_array_usecount;
+ llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex);
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(
@@ -227,6 +244,7 @@
}
}
+// m_die_array_mutex must be already held as read/write.
void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
@@ -280,11 +298,14 @@
DWARFDIECollection &dies,
uint32_t depth) const {
size_t old_size = dies.Size();
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
- for (pos = m_die_array.begin(); pos != end; ++pos) {
- if (pos->Tag() == tag)
- dies.Append(DWARFDIE(this, &(*pos)));
+ {
+ llvm::sys::ScopedReader lock(m_die_array_mutex);
+ DWARFDebugInfoEntry::const_iterator pos;
+ DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+ for (pos = m_die_array.begin(); pos != end; ++pos) {
+ if (pos->Tag() == tag)
+ dies.Append(DWARFDIE(this, &(*pos)));
+ }
}
// Return the number of DIEs added to the collection
@@ -325,9 +346,18 @@
m_base_obj_offset = base_obj_offset;
}
+// It may be called only after: ExtractDIEsIfNeeded() == true
void DWARFUnit::ClearDIEs() {
- m_die_array.clear();
- m_die_array.shrink_to_fit();
+ {
+ llvm::sys::ScopedWriter lock(m_die_array_mutex);
+ lldbassert(!m_die_array.empty());
+ lldbassert(m_die_array_usecount > 0);
+ if (--m_die_array_usecount > 0)
+ return;
+
+ m_die_array.clear();
+ m_die_array.shrink_to_fit();
+ }
if (m_dwo_symbol_file)
m_dwo_symbol_file->GetCompileUnit()->ClearDIEs();
@@ -472,6 +502,8 @@
if (ContainsDIEOffset(die_offset)) {
ExtractDIEsIfNeeded();
+ // m_die_array_mutex is not required as ExtractDIEsIfNeeded() has
+ // not been matched by ClearDIEs().
DWARFDebugInfoEntry::const_iterator end = m_die_array.cend();
DWARFDebugInfoEntry::const_iterator pos =
lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset);
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits