Skip to content

Commit f84916d

Browse files
author
Tamas Berghammer
committedOct 20, 2015
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). Differential revision: http://reviews.llvm.org/D13662 llvm-svn: 250821
1 parent ccb3676 commit f84916d

File tree

3 files changed

+71
-23
lines changed

3 files changed

+71
-23
lines changed
 

Diff for: ‎lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,14 @@ NameToDIE::ForEach (std::function <bool(const char *name, const DIERef& die_ref)
8383
break;
8484
}
8585
}
86+
87+
void
88+
NameToDIE::Append (const NameToDIE& other)
89+
{
90+
const uint32_t size = other.m_map.GetSize();
91+
for (uint32_t i = 0; i < size; ++i)
92+
{
93+
m_map.Append(other.m_map.GetCStringAtIndexUnchecked (i),
94+
other.m_map.GetValueAtIndexUnchecked (i));
95+
}
96+
}

Diff for: ‎lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class NameToDIE
3737
void
3838
Insert (const lldb_private::ConstString& name, const DIERef& die_ref);
3939

40+
void
41+
Append (const NameToDIE& other);
42+
4043
void
4144
Finalize();
4245

Diff for: ‎lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

+57-23
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050

5151
#include "lldb/Target/Language.h"
5252

53+
#include "lldb/Utility/TaskPool.h"
54+
5355
#include "DWARFASTParser.h"
5456
#include "DWARFCompileUnit.h"
5557
#include "DWARFDebugAbbrev.h"
@@ -2035,40 +2037,72 @@ SymbolFileDWARF::Index ()
20352037
"SymbolFileDWARF::Index (%s)",
20362038
GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
20372039

2040+
2041+
20382042
DWARFDebugInfo* debug_info = DebugInfo();
20392043
if (debug_info)
20402044
{
2041-
uint32_t cu_idx = 0;
20422045
const uint32_t num_compile_units = GetNumCompileUnits();
2043-
for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2046+
std::vector<NameToDIE> function_basename_index(num_compile_units);
2047+
std::vector<NameToDIE> function_fullname_index(num_compile_units);
2048+
std::vector<NameToDIE> function_method_index(num_compile_units);
2049+
std::vector<NameToDIE> function_selector_index(num_compile_units);
2050+
std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
2051+
std::vector<NameToDIE> global_index(num_compile_units);
2052+
std::vector<NameToDIE> type_index(num_compile_units);
2053+
std::vector<NameToDIE> namespace_index(num_compile_units);
2054+
2055+
auto parser_fn = [this,
2056+
debug_info,
2057+
&function_basename_index,
2058+
&function_fullname_index,
2059+
&function_method_index,
2060+
&function_selector_index,
2061+
&objc_class_selectors_index,
2062+
&global_index,
2063+
&type_index,
2064+
&namespace_index](uint32_t cu_idx)
20442065
{
20452066
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
2067+
bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
20462068

2047-
bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
2069+
dwarf_cu->Index(function_basename_index[cu_idx],
2070+
function_fullname_index[cu_idx],
2071+
function_method_index[cu_idx],
2072+
function_selector_index[cu_idx],
2073+
objc_class_selectors_index[cu_idx],
2074+
global_index[cu_idx],
2075+
type_index[cu_idx],
2076+
namespace_index[cu_idx]);
20482077

2049-
dwarf_cu->Index (m_function_basename_index,
2050-
m_function_fullname_index,
2051-
m_function_method_index,
2052-
m_function_selector_index,
2053-
m_objc_class_selectors_index,
2054-
m_global_index,
2055-
m_type_index,
2056-
m_namespace_index);
2057-
20582078
// Keep memory down by clearing DIEs if this generate function
20592079
// caused them to be parsed
20602080
if (clear_dies)
2061-
dwarf_cu->ClearDIEs (true);
2062-
}
2063-
2064-
m_function_basename_index.Finalize();
2065-
m_function_fullname_index.Finalize();
2066-
m_function_method_index.Finalize();
2067-
m_function_selector_index.Finalize();
2068-
m_objc_class_selectors_index.Finalize();
2069-
m_global_index.Finalize();
2070-
m_type_index.Finalize();
2071-
m_namespace_index.Finalize();
2081+
dwarf_cu->ClearDIEs(true);
2082+
};
2083+
2084+
std::vector<std::future<void>> results;
2085+
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2086+
results.emplace_back(TaskPool::AddTask(parser_fn, cu_idx));
2087+
for (auto& f : results)
2088+
f.wait();
2089+
2090+
auto merge_fn = [](NameToDIE& target, const std::vector<NameToDIE>& sources)
2091+
{
2092+
for (const auto& src : sources)
2093+
target.Append(src);
2094+
target.Finalize();
2095+
};
2096+
2097+
TaskPool::RunTasks(
2098+
[&]() { merge_fn(m_function_basename_index, function_basename_index); },
2099+
[&]() { merge_fn(m_function_fullname_index, function_fullname_index); },
2100+
[&]() { merge_fn(m_function_method_index, function_method_index); },
2101+
[&]() { merge_fn(m_function_selector_index, function_selector_index); },
2102+
[&]() { merge_fn(m_objc_class_selectors_index, objc_class_selectors_index); },
2103+
[&]() { merge_fn(m_global_index, global_index); },
2104+
[&]() { merge_fn(m_type_index, type_index); },
2105+
[&]() { merge_fn(m_namespace_index, namespace_index); });
20722106

20732107
#if defined (ENABLE_DEBUG_PRINTF)
20742108
StreamFile s(stdout, false);

0 commit comments

Comments
 (0)
Please sign in to comment.