Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -93,6 +93,8 @@ void *m_user_data = nullptr; DWARFDebugInfoEntry::collection m_die_array; // The compile unit debug information entry item + // Prevent m_extractdies_mutex lock overhead for most cases. + std::atomic_size_t m_die_array_size_atomic { 0 }; std::unique_ptr m_func_aranges_ap; // A table similar to // the .debug_aranges // table, but this one @@ -116,6 +118,8 @@ // in the main object file dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; + std::mutex m_extractdies_mutex; + void ParseProducerInfo(); private: Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -83,6 +83,8 @@ void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) { if (m_die_array.size() > 1) { + std::lock_guard guard(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() @@ -94,8 +96,11 @@ // Save at least the compile unit DIE DWARFDebugInfoEntry::collection tmp_array; m_die_array.swap(tmp_array); - if (keep_compile_unit_die) + m_die_array_size_atomic = 0; + if (keep_compile_unit_die) { m_die_array.push_back(tmp_array.front()); + ++m_die_array_size_atomic; + } } if (m_dwo_symbol_file) @@ -109,9 +114,19 @@ // done. //---------------------------------------------------------------------- size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) { - const size_t initial_die_array_size = 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, this]() -> bool { + initial_die_array_size = m_die_array_size_atomic; + return (cu_die_only && initial_die_array_size > 0) + || initial_die_array_size > 1; + }; + if (already_parsed()) + return 0; + std::lock_guard guard(m_extractdies_mutex); + if (already_parsed()) + return 0; + std::shared_ptr m_die_array_finished_set(nullptr, + [&](void*){ m_die_array_size_atomic = m_die_array.size(); }); static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(