Author: tberghammer Date: Fri Oct 23 05:34:49 2015 New Revision: 251106 URL: http://llvm.org/viewvc/llvm-project?rev=251106&view=rev Log: Re-commit "Make dwarf parsing multi-threaded"
Re-commit the change after fixing a lot of race condition in LLDB exposed by this change Loading the debug info from a large application is the slowest task LLDB do. This CL makes most of the dwarf parsing code multi-threaded. As a result the speed of "attach; backtrace; exit;" when the inferior is an LLDB with full debug info increased by a factor of 2. Differential revision: http://reviews.llvm.org/D13662 Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp?rev=251106&r1=251105&r2=251106&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp Fri Oct 23 05:34:49 2015 @@ -83,3 +83,14 @@ NameToDIE::ForEach (std::function <bool( break; } } + +void +NameToDIE::Append (const NameToDIE& other) +{ + const uint32_t size = other.m_map.GetSize(); + for (uint32_t i = 0; i < size; ++i) + { + m_map.Append(other.m_map.GetCStringAtIndexUnchecked (i), + other.m_map.GetValueAtIndexUnchecked (i)); + } +} Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h?rev=251106&r1=251105&r2=251106&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h Fri Oct 23 05:34:49 2015 @@ -38,6 +38,9 @@ public: Insert (const lldb_private::ConstString& name, const DIERef& die_ref); void + Append (const NameToDIE& other); + + void Finalize(); size_t 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=251106&r1=251105&r2=251106&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Oct 23 05:34:49 2015 @@ -50,6 +50,8 @@ #include "lldb/Target/Language.h" +#include "lldb/Utility/TaskPool.h" + #include "DWARFASTParser.h" #include "DWARFCompileUnit.h" #include "DWARFDebugAbbrev.h" @@ -2015,37 +2017,77 @@ SymbolFileDWARF::Index () DWARFDebugInfo* debug_info = DebugInfo(); if (debug_info) { - uint32_t cu_idx = 0; const uint32_t num_compile_units = GetNumCompileUnits(); - for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) + 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); + + auto parser_fn = [this, + debug_info, + &function_basename_index, + &function_fullname_index, + &function_method_index, + &function_selector_index, + &objc_class_selectors_index, + &global_index, + &type_index, + &namespace_index](uint32_t cu_idx) { DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1; - 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]); - dwarf_cu->Index (m_function_basename_index, - m_function_fullname_index, - m_function_method_index, - m_function_selector_index, - m_objc_class_selectors_index, - m_global_index, - m_type_index, - m_namespace_index); - // Keep memory down by clearing DIEs if this generate function // caused them to be parsed if (clear_dies) - dwarf_cu->ClearDIEs (true); - } - - m_function_basename_index.Finalize(); - m_function_fullname_index.Finalize(); - m_function_method_index.Finalize(); - m_function_selector_index.Finalize(); - m_objc_class_selectors_index.Finalize(); - m_global_index.Finalize(); - m_type_index.Finalize(); - m_namespace_index.Finalize(); + dwarf_cu->ClearDIEs(true); + + return cu_idx; + }; + + 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); + + while (true) + { + std::future<uint32_t> f = task_runner.WaitForNextCompletedTask(); + if (!f.valid()) + break; + uint32_t cu_idx = f.get(); + + m_function_basename_index.Append(function_basename_index[cu_idx]); + m_function_fullname_index.Append(function_fullname_index[cu_idx]); + m_function_method_index.Append(function_method_index[cu_idx]); + m_function_selector_index.Append(function_selector_index[cu_idx]); + m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]); + m_global_index.Append(global_index[cu_idx]); + m_type_index.Append(type_index[cu_idx]); + m_namespace_index.Append(namespace_index[cu_idx]); + } + + TaskPool::RunTasks( + [&]() { m_function_basename_index.Finalize(); }, + [&]() { m_function_fullname_index.Finalize(); }, + [&]() { m_function_method_index.Finalize(); }, + [&]() { m_function_selector_index.Finalize(); }, + [&]() { m_objc_class_selectors_index.Finalize(); }, + [&]() { m_global_index.Finalize(); }, + [&]() { m_type_index.Finalize(); }, + [&]() { m_namespace_index.Finalize(); }); #if defined (ENABLE_DEBUG_PRINTF) StreamFile s(stdout, false); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits