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

Reply via email to