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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits