jankratochvil created this revision.
Herald added subscribers: JDevlieghere, aprantl.
Multiple DW_TAG_compile_unit being indexed in a multithreaded way can request
reading of the same DW_TAG_partial_unit.
Unfortunately one cannot detect DWZ file ahead of time to disable such locking
overhead as DWARFCompileUnit::Extract does not read the first DIE which is the
only place one could find early enough if the DWARF file is using any
DW_TAG_partial_unit.
All DWZ patches are also applied in: git clone -b dwz
git://git.jankratochvil.net/lldb
https://reviews.llvm.org/D40470
Files:
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -70,6 +70,9 @@
dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
dw_offset_t m_file_offset;
+ std::mutex m_extractdies_mutex;
+ bool m_die_array_finished;
+
private:
static uint8_t g_default_addr_size;
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -91,6 +91,8 @@
void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
if (m_data->m_die_array.size() > 1) {
+ std::lock_guard<std::mutex> guard(m_data->m_extractdies_mutex);
+
// std::vectors never get any smaller when resized to a smaller size,
// or when clear() or erase() are called, the size will report that it
// is smaller, but the memory allocated remains intact (call capacity()
@@ -118,9 +120,21 @@
// done.
//----------------------------------------------------------------------
size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
- const size_t initial_die_array_size = m_data->m_die_array.size();
- if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size >
1)
- return 0; // Already parsed
+ size_t initial_die_array_size;
+ auto already_parsed = [cu_die_only, &initial_die_array_size]() -> bool {
+ return (cu_die_only && initial_die_array_size > 0)
+ || initial_die_array_size > 1;
+ };
+ if (already_parsed() && m_data->m_die_array_finished)
+ return 0;
+ std::lock_guard<std::mutex> guard(m_data->m_extractdies_mutex);
+ if (already_parsed()) {
+ lldbassert(m_data->m_die_array_finished);
+ return 0;
+ }
+ m_data->m_die_array_finished = false;
+ std::shared_ptr<void> m_die_array_finished_set(nullptr,
+ [&](void*){ m_data->m_die_array_finished = true; });
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -70,6 +70,9 @@
dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
dw_offset_t m_file_offset;
+ std::mutex m_extractdies_mutex;
+ bool m_die_array_finished;
+
private:
static uint8_t g_default_addr_size;
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -91,6 +91,8 @@
void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
if (m_data->m_die_array.size() > 1) {
+ std::lock_guard<std::mutex> guard(m_data->m_extractdies_mutex);
+
// std::vectors never get any smaller when resized to a smaller size,
// or when clear() or erase() are called, the size will report that it
// is smaller, but the memory allocated remains intact (call capacity()
@@ -118,9 +120,21 @@
// done.
//----------------------------------------------------------------------
size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
- const size_t initial_die_array_size = m_data->m_die_array.size();
- if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1)
- return 0; // Already parsed
+ size_t initial_die_array_size;
+ auto already_parsed = [cu_die_only, &initial_die_array_size]() -> bool {
+ return (cu_die_only && initial_die_array_size > 0)
+ || initial_die_array_size > 1;
+ };
+ if (already_parsed() && m_data->m_die_array_finished)
+ return 0;
+ std::lock_guard<std::mutex> guard(m_data->m_extractdies_mutex);
+ if (already_parsed()) {
+ lldbassert(m_data->m_die_array_finished);
+ return 0;
+ }
+ m_data->m_die_array_finished = false;
+ std::shared_ptr<void> m_die_array_finished_set(nullptr,
+ [&](void*){ m_data->m_die_array_finished = true; });
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits