tberghammer created this revision. tberghammer added reviewers: labath, clayborg. tberghammer added a subscriber: lldb-commits.
Make dwarf parsing multi-threaded 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 (on my machine). http://reviews.llvm.org/D13662 Files: source/Plugins/SymbolFile/DWARF/NameToDIE.cpp source/Plugins/SymbolFile/DWARF/NameToDIE.h source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -65,6 +65,7 @@ #include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDebugMap.h" +#include <future> #include <map> #include <ctype.h> @@ -2038,29 +2039,54 @@ 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::mutex index_mutex; + std::vector<std::future<void>> parsers; + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); - - bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1; - - 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); + parsers.emplace_back(std::async(std::launch::async, [this, cu_idx, debug_info, &index_mutex]() + { + DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1; + + NameToDIE function_basename_index; + NameToDIE function_fullname_index; + NameToDIE function_method_index; + NameToDIE function_selector_index; + NameToDIE objc_class_selectors_index; + NameToDIE global_index; + NameToDIE type_index; + NameToDIE namespace_index; + dwarf_cu->Index(function_basename_index, + function_fullname_index, + function_method_index, + function_selector_index, + objc_class_selectors_index, + global_index, + type_index, + namespace_index); + + // Keep memory down by clearing DIEs if this generate function + // caused them to be parsed + if (clear_dies) + dwarf_cu->ClearDIEs(true); + + std::lock_guard<std::mutex> lock(index_mutex); + m_function_basename_index.Append(function_basename_index); + m_function_fullname_index.Append(function_fullname_index); + m_function_method_index.Append(function_method_index); + m_function_selector_index.Append(function_selector_index); + m_objc_class_selectors_index.Append(objc_class_selectors_index); + m_global_index.Append(global_index); + m_type_index.Append(type_index); + m_namespace_index.Append(namespace_index); + })); } - + + // Wait for all parser to finish + for (auto& p : parsers) + p.wait(); + m_function_basename_index.Finalize(); m_function_fullname_index.Finalize(); m_function_method_index.Finalize(); Index: source/Plugins/SymbolFile/DWARF/NameToDIE.h =================================================================== --- source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -38,6 +38,9 @@ Insert (const lldb_private::ConstString& name, const DIERef& die_ref); void + Append (const NameToDIE& other); + + void Finalize(); size_t Index: source/Plugins/SymbolFile/DWARF/NameToDIE.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -83,3 +83,14 @@ 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)); + } +}
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits