diff options
author | Tamas Berghammer <tberghammer@google.com> | 2015-10-23 10:34:49 +0000 |
---|---|---|
committer | Tamas Berghammer <tberghammer@google.com> | 2015-10-23 10:34:49 +0000 |
commit | 2ff8870b6f49bc2cbfc79e4a65d0fe9dc4a51a7f (patch) | |
tree | dafa093bd4cfc3269f062346522614c8d64804e1 /lldb/source/Plugins/SymbolFile | |
parent | d779da91de1f5706e1413bcd9c2e9cb64365e580 (diff) | |
download | bcm5719-llvm-2ff8870b6f49bc2cbfc79e4a65d0fe9dc4a51a7f.tar.gz bcm5719-llvm-2ff8870b6f49bc2cbfc79e4a65d0fe9dc4a51a7f.zip |
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
llvm-svn: 251106
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp | 11 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 86 |
3 files changed, 78 insertions, 22 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 8085cabed33..775bb6718b8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -83,3 +83,14 @@ NameToDIE::ForEach (std::function <bool(const char *name, const DIERef& die_ref) 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)); + } +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index fde52bdbf19..7fc66138f51 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -38,6 +38,9 @@ public: Insert (const lldb_private::ConstString& name, const DIERef& die_ref); void + Append (const NameToDIE& other); + + void Finalize(); size_t diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index e893980ce9e..6ff1c986558 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -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); + 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]); } - - 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(); + + 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); |