Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -90,6 +90,7 @@ bool IsDWOUnit() { return m_is_dwo; } uint64_t GetDWOId(); + uint64_t GetDWOIdIfAlreadyParsed() const { return m_dwo_id; } void ExtractUnitDIEIfNeeded(); void ExtractUnitDIENoDwoIfNeeded(); Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -22,7 +22,8 @@ ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf, llvm::DenseSet units_to_avoid = {}) : DWARFIndex(module), m_dwarf(&dwarf), - m_units_to_avoid(std::move(units_to_avoid)) {} + m_units_to_avoid(std::move(units_to_avoid)), + m_has_indexed_type_units(false) {} void Preload() override { Index(); } @@ -67,6 +68,7 @@ NameToDIE namespaces; }; void Index(); + void IndexImpl(bool full_index, uint64_t unit_dwo_id); void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set); static void IndexUnitImpl(DWARFUnit &unit, @@ -78,6 +80,8 @@ SymbolFileDWARF *m_dwarf; /// Which dwarf units should we skip while building the index. llvm::DenseSet m_units_to_avoid; + llvm::DenseSet m_ids_already_indexed; + bool m_has_indexed_type_units; IndexSet m_set; }; Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -24,11 +24,17 @@ using namespace lldb; void ManualDWARFIndex::Index() { + IndexImpl(true, 0); +} + +void ManualDWARFIndex::IndexImpl(bool full_index, uint64_t unit_dwo_id) { if (!m_dwarf) return; SymbolFileDWARF &main_dwarf = *m_dwarf; - m_dwarf = nullptr; + + if (full_index) + m_dwarf = nullptr; LLDB_SCOPED_TIMERF("%p", static_cast(&main_dwarf)); @@ -45,16 +51,25 @@ // IndexUnit. for (size_t U = 0; U < main_info.GetNumUnits(); ++U) { DWARFUnit *unit = main_info.GetUnitAtIndex(U); - if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0) - units_to_index.push_back(unit); + if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0 && m_ids_already_indexed.count(unit->GetDWOId()) == 0) { + if (full_index || unit->GetDWOId() == unit_dwo_id) + units_to_index.push_back(unit); + } } - if (dwp_info && dwp_info->ContainsTypeUnits()) { + if (!full_index && !units_to_index.empty()) + m_ids_already_indexed.insert(unit_dwo_id); // Don't index this again + if (!m_has_indexed_type_units && dwp_info && dwp_info->ContainsTypeUnits()) { + m_has_indexed_type_units = true; for (size_t U = 0; U < dwp_info->GetNumUnits(); ++U) { if (auto *tu = llvm::dyn_cast(dwp_info->GetUnitAtIndex(U))) units_to_index.push_back(tu); } } + // We no longer need this; clear to save memory + if (full_index) + m_ids_already_indexed.clear(); + if (units_to_index.empty()) return; @@ -359,7 +374,7 @@ void ManualDWARFIndex::GetGlobalVariables( const DWARFUnit &unit, llvm::function_ref callback) { - Index(); + IndexImpl(false, unit.GetDWOIdIfAlreadyParsed()); m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback)); } Index: lldb/test/Shell/SymbolFile/DWARF/dwp-debug-types.s =================================================================== --- lldb/test/Shell/SymbolFile/DWARF/dwp-debug-types.s +++ lldb/test/Shell/SymbolFile/DWARF/dwp-debug-types.s @@ -16,15 +16,15 @@ # Make sure each entity is present in the index only once. # SYMBOLS: Globals and statics: -# SYMBOLS-DAG: INFO/00000023 "A" -# SYMBOLS-DAG: INFO/0000005a "A" +# SYMBOLS-DAG: INFO/0000002b "A" +# SYMBOLS-DAG: INFO/0000006a "A" # SYMBOLS-EMPTY: # SYMBOLS: Types: # SYMBOLS-DAG: TYPE/00000018 "ENUM0" -# SYMBOLS-DAG: TYPE/0000004d "ENUM1" # SYMBOLS-DAG: TYPE/0000002d "int" # SYMBOLS-DAG: TYPE/00000062 "int" +# SYMBOLS-DAG: TYPE/0000004d "ENUM1" # SYMBOLS-EMPTY: .ifdef MAIN @@ -77,6 +77,8 @@ .byte 8 # DW_FORM_string .byte 3 # DW_AT_name .byte 8 # DW_FORM_string + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 .byte 0 # EOM(1) .byte 0 # EOM(2) .byte \I*10+2 # Abbreviation Code @@ -148,6 +150,7 @@ .byte \I*10+1 # Abbrev DW_TAG_compile_unit .asciz "Hand-written DWARF" # DW_AT_producer .byte '0'+\I, '.', 'c', 0 # DW_AT_name + .quad \I # DW_AT_GNU_dwo_id .byte \I*10+2 # Abbrev DW_TAG_variable .asciz "A" # DW_AT_name .long .Lenum_ref\I-.Lcu_begin\I# DW_AT_type Index: lldb/test/Shell/SymbolFile/DWARF/dwp.s =================================================================== --- lldb/test/Shell/SymbolFile/DWARF/dwp.s +++ lldb/test/Shell/SymbolFile/DWARF/dwp.s @@ -133,6 +133,8 @@ .byte 8 # DW_FORM_string .byte 3 # DW_AT_name .byte 8 # DW_FORM_string + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 .byte 0 # EOM(1) .byte 0 # EOM(2) .byte \I*10+2 # Abbreviation Code @@ -201,6 +203,7 @@ .byte \I*10+1 # Abbrev DW_TAG_compile_unit .asciz "Hand-written DWARF" # DW_AT_producer .byte '0'+\I, '.', 'c', 0 # DW_AT_name + .quad \I # DW_AT_GNU_dwo_id .byte \I*10+2 # Abbrev DW_TAG_variable .asciz "A" # DW_AT_name .long .Ltypedef\I-.Lcu_begin\I# DW_AT_type