summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile
diff options
context:
space:
mode:
authorTamas Berghammer <tberghammer@google.com>2015-10-23 10:34:49 +0000
committerTamas Berghammer <tberghammer@google.com>2015-10-23 10:34:49 +0000
commit2ff8870b6f49bc2cbfc79e4a65d0fe9dc4a51a7f (patch)
treedafa093bd4cfc3269f062346522614c8d64804e1 /lldb/source/Plugins/SymbolFile
parentd779da91de1f5706e1413bcd9c2e9cb64365e580 (diff)
downloadbcm5719-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.cpp11
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp86
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);
OpenPOWER on IntegriCloud