phlav created this revision. phlav added reviewers: lldb-commits, clayborg. phlav added a subscriber: phlav.
"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. http://reviews.llvm.org/D20738 Files: SymbolFileDWARF.cpp
Index: SymbolFileDWARF.cpp =================================================================== --- SymbolFileDWARF.cpp +++ SymbolFileDWARF.cpp @@ -2162,15 +2162,19 @@ 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); std::vector<NameToDIE> function_selector_index(num_compile_units); std::vector<NameToDIE> objc_class_selectors_index(num_compile_units); 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 @@ &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 @@ [&]() { 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':",
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits