@@ -32,116 +32,118 @@ using namespace lldb_private::plugin::dwarf;
3232using namespace llvm ::dwarf;
3333
3434void ManualDWARFIndex::Index () {
35- std::call_once (m_indexed_flag, [this ]() {
36- ElapsedTime elapsed (m_index_time);
37- LLDB_SCOPED_TIMERF (" %p" , static_cast <void *>(m_dwarf));
38- if (LoadFromCache ()) {
39- m_dwarf->SetDebugInfoIndexWasLoadedFromCache ();
40- return ;
41- }
35+ std::call_once (m_indexed_flag, [this ]() { IndexImpl (); });
36+ }
4237
43- DWARFDebugInfo &main_info = m_dwarf->DebugInfo ();
44- SymbolFileDWARFDwo *dwp_dwarf = m_dwarf->GetDwpSymbolFile ().get ();
45- DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo () : nullptr ;
46-
47- std::vector<DWARFUnit *> units_to_index;
48- units_to_index.reserve (main_info.GetNumUnits () +
49- (dwp_info ? dwp_info->GetNumUnits () : 0 ));
50-
51- // Process all units in the main file, as well as any type units in the dwp
52- // file. Type units in dwo files are handled when we reach the dwo file in
53- // IndexUnit.
54- for (size_t U = 0 ; U < main_info.GetNumUnits (); ++U) {
55- DWARFUnit *unit = main_info.GetUnitAtIndex (U);
56- if (unit && m_units_to_avoid.count (unit->GetOffset ()) == 0 )
57- units_to_index.push_back (unit);
58- }
59- if (dwp_info && dwp_info->ContainsTypeUnits ()) {
60- for (size_t U = 0 ; U < dwp_info->GetNumUnits (); ++U) {
61- if (auto *tu =
62- llvm::dyn_cast<DWARFTypeUnit>(dwp_info->GetUnitAtIndex (U))) {
63- if (!m_type_sigs_to_avoid.contains (tu->GetTypeHash ()))
64- units_to_index.push_back (tu);
65- }
38+ void ManualDWARFIndex::IndexImpl () {
39+ ElapsedTime elapsed (m_index_time);
40+ LLDB_SCOPED_TIMERF (" %p" , static_cast <void *>(m_dwarf));
41+ if (LoadFromCache ()) {
42+ m_dwarf->SetDebugInfoIndexWasLoadedFromCache ();
43+ return ;
44+ }
45+
46+ DWARFDebugInfo &main_info = m_dwarf->DebugInfo ();
47+ SymbolFileDWARFDwo *dwp_dwarf = m_dwarf->GetDwpSymbolFile ().get ();
48+ DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo () : nullptr ;
49+
50+ std::vector<DWARFUnit *> units_to_index;
51+ units_to_index.reserve (main_info.GetNumUnits () +
52+ (dwp_info ? dwp_info->GetNumUnits () : 0 ));
53+
54+ // Process all units in the main file, as well as any type units in the dwp
55+ // file. Type units in dwo files are handled when we reach the dwo file in
56+ // IndexUnit.
57+ for (size_t U = 0 ; U < main_info.GetNumUnits (); ++U) {
58+ DWARFUnit *unit = main_info.GetUnitAtIndex (U);
59+ if (unit && m_units_to_avoid.count (unit->GetOffset ()) == 0 )
60+ units_to_index.push_back (unit);
61+ }
62+ if (dwp_info && dwp_info->ContainsTypeUnits ()) {
63+ for (size_t U = 0 ; U < dwp_info->GetNumUnits (); ++U) {
64+ if (auto *tu =
65+ llvm::dyn_cast<DWARFTypeUnit>(dwp_info->GetUnitAtIndex (U))) {
66+ if (!m_type_sigs_to_avoid.contains (tu->GetTypeHash ()))
67+ units_to_index.push_back (tu);
6668 }
6769 }
70+ }
6871
69- if (units_to_index.empty ())
70- return ;
71-
72- StreamString module_desc;
73- m_module.GetDescription (module_desc.AsRawOstream (),
74- lldb::eDescriptionLevelBrief);
75-
76- // Include 2 passes per unit to index for extracting DIEs from the unit and
77- // indexing the unit, and then extra entries for finalizing each index in
78- // the set.
79- const auto indices = IndexSet<NameToDIE>::Indices ();
80- const uint64_t total_progress = units_to_index.size () * 2 + indices.size ();
81- Progress progress (" Manually indexing DWARF" , module_desc.GetData (),
82- total_progress, /* debugger=*/ nullptr ,
83- Progress::kDefaultHighFrequencyReportTime );
84-
85- // Share one thread pool across operations to avoid the overhead of
86- // recreating the threads.
87- llvm::ThreadPoolTaskGroup task_group (Debugger::GetThreadPool ());
88- const size_t num_threads = Debugger::GetThreadPool ().getMaxConcurrency ();
89-
90- // Run a function for each compile unit in parallel using as many threads as
91- // are available. This is significantly faster than submiting a new task for
92- // each unit.
93- auto for_each_unit = [&](auto &&fn) {
94- std::atomic<size_t > next_cu_idx = 0 ;
95- auto wrapper = [&fn, &next_cu_idx, &units_to_index,
96- &progress](size_t worker_id) {
97- size_t cu_idx;
98- while ((cu_idx = next_cu_idx.fetch_add (1 , std::memory_order_relaxed)) <
99- units_to_index.size ()) {
100- fn (worker_id, cu_idx, units_to_index[cu_idx]);
101- progress.Increment ();
102- }
103- };
104-
105- for (size_t i = 0 ; i < num_threads; ++i)
106- task_group.async (wrapper, i);
72+ if (units_to_index.empty ())
73+ return ;
10774
108- task_group.wait ();
75+ StreamString module_desc;
76+ m_module.GetDescription (module_desc.AsRawOstream (),
77+ lldb::eDescriptionLevelBrief);
78+
79+ // Include 2 passes per unit to index for extracting DIEs from the unit and
80+ // indexing the unit, and then extra entries for finalizing each index in
81+ // the set.
82+ const auto indices = IndexSet<NameToDIE>::Indices ();
83+ const uint64_t total_progress = units_to_index.size () * 2 + indices.size ();
84+ Progress progress (" Manually indexing DWARF" , module_desc.GetData (),
85+ total_progress, /* debugger=*/ nullptr ,
86+ Progress::kDefaultHighFrequencyReportTime );
87+
88+ // Share one thread pool across operations to avoid the overhead of
89+ // recreating the threads.
90+ llvm::ThreadPoolTaskGroup task_group (Debugger::GetThreadPool ());
91+ const size_t num_threads = Debugger::GetThreadPool ().getMaxConcurrency ();
92+
93+ // Run a function for each compile unit in parallel using as many threads as
94+ // are available. This is significantly faster than submiting a new task for
95+ // each unit.
96+ auto for_each_unit = [&](auto &&fn) {
97+ std::atomic<size_t > next_cu_idx = 0 ;
98+ auto wrapper = [&fn, &next_cu_idx, &units_to_index,
99+ &progress](size_t worker_id) {
100+ size_t cu_idx;
101+ while ((cu_idx = next_cu_idx.fetch_add (1 , std::memory_order_relaxed)) <
102+ units_to_index.size ()) {
103+ fn (worker_id, cu_idx, units_to_index[cu_idx]);
104+ progress.Increment ();
105+ }
109106 };
110107
111- // Extract dies for all DWARFs unit in parallel. Figure out which units
112- // didn't have their DIEs already parsed and remember this. If no DIEs were
113- // parsed prior to this index function call, we are going to want to clear
114- // the CU dies after we are done indexing to make sure we don't pull in all
115- // DWARF dies, but we need to wait until all units have been indexed in case
116- // a DIE in one unit refers to another and the indexes accesses those DIEs.
117- std::vector<std::optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies (
118- units_to_index.size ());
119- for_each_unit ([&clear_cu_dies](size_t , size_t idx, DWARFUnit *unit) {
120- clear_cu_dies[idx] = unit->ExtractDIEsScoped ();
121- });
108+ for (size_t i = 0 ; i < num_threads; ++i)
109+ task_group.async (wrapper, i);
122110
123- // Now index all DWARF unit in parallel.
124- std::vector<IndexSet<NameToDIE>> sets (num_threads);
125- for_each_unit (
126- [this , dwp_dwarf, &sets](size_t worker_id, size_t , DWARFUnit *unit) {
127- IndexUnit (*unit, dwp_dwarf, sets[worker_id]);
128- });
129-
130- // Merge partial indexes into a single index. Process each index in a set in
131- // parallel.
132- for (NameToDIE IndexSet<NameToDIE>::*index : indices) {
133- task_group.async ([this , &sets, index, &progress]() {
134- NameToDIE &result = m_set.*index;
135- for (auto &set : sets)
136- result.Append (set.*index);
137- result.Finalize ();
138- progress.Increment ();
139- });
140- }
141111 task_group.wait ();
142-
143- SaveToCache ();
112+ };
113+
114+ // Extract dies for all DWARFs unit in parallel. Figure out which units
115+ // didn't have their DIEs already parsed and remember this. If no DIEs were
116+ // parsed prior to this index function call, we are going to want to clear
117+ // the CU dies after we are done indexing to make sure we don't pull in all
118+ // DWARF dies, but we need to wait until all units have been indexed in case
119+ // a DIE in one unit refers to another and the indexes accesses those DIEs.
120+ std::vector<std::optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies (
121+ units_to_index.size ());
122+ for_each_unit ([&clear_cu_dies](size_t , size_t idx, DWARFUnit *unit) {
123+ clear_cu_dies[idx] = unit->ExtractDIEsScoped ();
144124 });
125+
126+ // Now index all DWARF unit in parallel.
127+ std::vector<IndexSet<NameToDIE>> sets (num_threads);
128+ for_each_unit (
129+ [this , dwp_dwarf, &sets](size_t worker_id, size_t , DWARFUnit *unit) {
130+ IndexUnit (*unit, dwp_dwarf, sets[worker_id]);
131+ });
132+
133+ // Merge partial indexes into a single index. Process each index in a set in
134+ // parallel.
135+ for (NameToDIE IndexSet<NameToDIE>::*index : indices) {
136+ task_group.async ([this , &sets, index, &progress]() {
137+ NameToDIE &result = m_set.*index;
138+ for (auto &set : sets)
139+ result.Append (set.*index);
140+ result.Finalize ();
141+ progress.Increment ();
142+ });
143+ }
144+ task_group.wait ();
145+
146+ SaveToCache ();
145147}
146148
147149void ManualDWARFIndex::IndexUnit (DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
0 commit comments