[Lldb-commits] [lldb] r271209 - [LLDB] Make sure that indexing is done before clearing DIE info
Cameron Desrochers via lldb-commits
lldb-commits at lists.llvm.org
Mon May 30 08:32:53 PDT 2016
Author: cameron314
Date: Mon May 30 10:32:51 2016
New Revision: 271209
URL: http://llvm.org/viewvc/llvm-project?rev=271209&view=rev
Log:
[LLDB] Make sure that indexing is done before clearing DIE info
"ClearDIEs()" was being called too soon, before everyone was done using the DIEs.
This fix delays the calls to ::ClearDIEs() until all compile units have been indexed.
1 - Call "::ExtractDIEsIfNeeded()" on all compile units on separate threads. See if each CU has the DIEs parsed and remember this.
2 - Index all compile units on separate threads.
3 - Clear any DIEs in any compile units that didn't have their DIEs parsed after all compile units have been indexed.
Patch by phlav
Differential Revision: http://reviews.llvm.org/D20738
Modified:
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=271209&r1=271208&r2=271209&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon May 30 10:32:51 2016
@@ -2162,6 +2162,9 @@ SymbolFileDWARF::Index ()
if (debug_info)
{
const uint32_t num_compile_units = GetNumCompileUnits();
+ if (num_compile_units == 0)
+ return;
+
std::vector<NameToDIE> function_basename_index(num_compile_units);
std::vector<NameToDIE> function_fullname_index(num_compile_units);
std::vector<NameToDIE> function_method_index(num_compile_units);
@@ -2170,7 +2173,8 @@ SymbolFileDWARF::Index ()
std::vector<NameToDIE> global_index(num_compile_units);
std::vector<NameToDIE> type_index(num_compile_units);
std::vector<NameToDIE> namespace_index(num_compile_units);
-
+
+ std::vector<bool> clear_cu_dies(num_compile_units, false);
auto parser_fn = [this,
debug_info,
&function_basename_index,
@@ -2183,25 +2187,62 @@ SymbolFileDWARF::Index ()
&namespace_index](uint32_t cu_idx)
{
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
-
- dwarf_cu->Index(function_basename_index[cu_idx],
- function_fullname_index[cu_idx],
- function_method_index[cu_idx],
- function_selector_index[cu_idx],
- objc_class_selectors_index[cu_idx],
- global_index[cu_idx],
- type_index[cu_idx],
- namespace_index[cu_idx]);
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- dwarf_cu->ClearDIEs(true);
-
+ if (dwarf_cu)
+ {
+ dwarf_cu->Index(function_basename_index[cu_idx],
+ function_fullname_index[cu_idx],
+ function_method_index[cu_idx],
+ function_selector_index[cu_idx],
+ objc_class_selectors_index[cu_idx],
+ global_index[cu_idx],
+ type_index[cu_idx],
+ namespace_index[cu_idx]);
+ }
return cu_idx;
};
+ auto extract_fn = [this,
+ debug_info,
+ num_compile_units](uint32_t cu_idx)
+ {
+ DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu)
+ {
+ // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
+ // DIEs for a compile unit have already been parsed.
+ return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
+ }
+ return std::make_pair(cu_idx, false);
+ };
+
+ // Create a task runner that extracts dies for each DWARF compile unit in a separate thread
+ TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner_extract.AddTask(extract_fn, cu_idx);
+
+ //----------------------------------------------------------------------
+ // First figure out which compile units didn't have their DIEs already
+ // parsed and remember this. If no DIEs were parsed prior to this index
+ // function call, we are going to want to clear the CU dies after we
+ // are done indexing to make sure we don't pull in all DWARF dies, but
+ // we need to wait until all compile units have been indexed in case
+ // a DIE in one compile unit refers to another and the indexes accesses
+ // those DIEs.
+ //----------------------------------------------------------------------
+ while (true)
+ {
+ auto f = task_runner_extract.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ unsigned cu_idx;
+ bool clear;
+ std::tie(cu_idx, clear) = f.get();
+ clear_cu_dies[cu_idx] = clear;
+ }
+
+ // Now create a task runner that can index each DWARF compile unit in a separate
+ // thread so we can index quickly.
+
TaskRunner<uint32_t> task_runner;
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
task_runner.AddTask(parser_fn, cu_idx);
@@ -2233,6 +2274,16 @@ SymbolFileDWARF::Index ()
[&]() { m_type_index.Finalize(); },
[&]() { m_namespace_index.Finalize(); });
+ //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any compile units if indexing
+ // caused us to load the compile unit's DIEs.
+ //----------------------------------------------------------------------
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ {
+ if (clear_cu_dies[cu_idx])
+ debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
+ }
+
#if defined (ENABLE_DEBUG_PRINTF)
StreamFile s(stdout, false);
s.Printf ("DWARF index for '%s':",
More information about the lldb-commits
mailing list