[Lldb-commits] [lldb] Add download time for each module in statistics (PR #134563)

via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 17 17:06:06 PDT 2025


https://github.com/GeorgeHuyubo updated https://github.com/llvm/llvm-project/pull/134563

>From 28e52ec264f088625410b7202b5de1e7f601f164 Mon Sep 17 00:00:00 2001
From: George Hu <georgehuyubo at gmail.com>
Date: Tue, 8 Apr 2025 18:12:29 -0700
Subject: [PATCH] Add symbol locator time for each module in statistics

Summary:

Test Plan:

Reviewers:

Subscribers:

Tasks:

Tags:

Differential Revision: https://phabricator.intern.facebook.com/D73224269
---
 lldb/include/lldb/Core/Module.h               | 21 +++++++++++++++
 lldb/include/lldb/Core/PluginManager.h        |  7 +++--
 lldb/include/lldb/Target/Statistics.h         |  1 +
 lldb/source/Core/DynamicLoader.cpp            | 26 ++++++++++++++++---
 lldb/source/Core/ModuleList.cpp               | 13 +++++++---
 lldb/source/Core/PluginManager.cpp            | 16 +++++++++---
 .../Platform/MacOSX/PlatformDarwinKernel.cpp  | 12 +++++++--
 .../Process/MacOSX-Kernel/ProcessKDP.cpp      | 26 +++++++++++++++----
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      | 18 ++++++++++---
 .../SymbolVendor/ELF/SymbolVendorELF.cpp      | 25 ++++++++++++++----
 .../MacOSX/SymbolVendorMacOSX.cpp             | 12 +++++++--
 .../PECOFF/SymbolVendorPECOFF.cpp             | 12 +++++++--
 .../SymbolVendor/wasm/SymbolVendorWasm.cpp    | 12 +++++++--
 lldb/source/Target/Statistics.cpp             | 20 ++++++++++++++
 14 files changed, 186 insertions(+), 35 deletions(-)

diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 1ad67d6747850..1c872f922e30a 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -89,6 +89,7 @@ class Module : public std::enable_shared_from_this<Module>,
                public SymbolContextScope {
 public:
   class LookupInfo;
+  class StatisticsMap;
   // Static functions that can track the lifetime of module objects. This is
   // handy because we might have Module objects that are in shared pointers
   // that aren't in the global module list (from ModuleList). If this is the
@@ -885,6 +886,10 @@ class Module : public std::enable_shared_from_this<Module>,
   /// ElapsedTime RAII object.
   StatsDuration &GetSymtabIndexTime() { return m_symtab_index_time; }
 
+  StatisticsMap &GetSymbolLocatorStatistics() {
+    return m_symbol_locator_duration_map;
+  }
+
   void ResetStatistics();
 
   /// \class LookupInfo Module.h "lldb/Core/Module.h"
@@ -956,6 +961,20 @@ class Module : public std::enable_shared_from_this<Module>,
     bool m_match_name_after_lookup = false;
   };
 
+  class StatisticsMap {
+  public:
+    void add(const std::string &key, double value) {
+      if (key.empty())
+        return;
+      auto it = map.find(key);
+      if (it == map.end())
+        map.try_emplace(key, value);
+      else
+        it->second += value;
+    }
+    std::unordered_map<std::string, double> map;
+  };
+
   /// Get a unique hash for this module.
   ///
   /// The hash should be enough to identify the file on disk and the
@@ -1064,6 +1083,8 @@ class Module : public std::enable_shared_from_this<Module>,
   /// time for the symbol tables can be aggregated here.
   StatsDuration m_symtab_index_time;
 
+  StatisticsMap m_symbol_locator_duration_map;
+
   /// A set of hashes of all warnings and errors, to avoid reporting them
   /// multiple times to the same Debugger.
   llvm::DenseMap<llvm::stable_hash, std::unique_ptr<std::once_flag>>
diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
index a6dab045adf27..dfa7bfa6eb9da 100644
--- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h
@@ -377,11 +377,14 @@ class PluginManager {
   static SymbolLocatorCreateInstance
   GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx);
 
-  static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec);
+  static ModuleSpec
+  LocateExecutableObjectFile(const ModuleSpec &module_spec,
+                             std::string *locator_name = nullptr);
 
   static FileSpec
   LocateExecutableSymbolFile(const ModuleSpec &module_spec,
-                             const FileSpecList &default_search_paths);
+                             const FileSpecList &default_search_paths,
+                             std::string *locator_name = nullptr);
 
   static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
                                           Status &error,
diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h
index ee365357fcf31..2b60931f065f7 100644
--- a/lldb/include/lldb/Target/Statistics.h
+++ b/lldb/include/lldb/Target/Statistics.h
@@ -122,6 +122,7 @@ struct ModuleStats {
   double symtab_index_time = 0.0;
   double debug_parse_time = 0.0;
   double debug_index_time = 0.0;
+  llvm::StringMap<double> symbol_locator_time;
   uint64_t debug_info_size = 0;
   bool symtab_loaded_from_cache = false;
   bool symtab_saved_to_cache = false;
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp
index 76c71d2a49a48..9bf5df7f86d25 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -243,15 +243,33 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
     // find an executable and symbol file.
     if (!module_sp) {
       FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-      module_spec.GetSymbolFileSpec() =
-          PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
-      ModuleSpec objfile_module_spec =
-          PluginManager::LocateExecutableObjectFile(module_spec);
+      StatsDuration symbol_duration;
+      std::string symbol_locator_name;
+      StatsDuration object_duration;
+      std::string object_locator_name;
+      ModuleSpec objfile_module_spec;
+      {
+        ElapsedTime elapsed(symbol_duration);
+        module_spec.GetSymbolFileSpec() =
+            PluginManager::LocateExecutableSymbolFile(module_spec, search_paths,
+                                                      &symbol_locator_name);
+      }
+      {
+        ElapsedTime elapsed(object_duration);
+        objfile_module_spec = PluginManager::LocateExecutableObjectFile(
+            module_spec, &object_locator_name);
+      }
       module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
       if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
           FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) {
         module_sp = std::make_shared<Module>(module_spec);
       }
+      if (module_sp) {
+        module_sp->GetSymbolLocatorStatistics().add(
+            object_locator_name, object_duration.get().count());
+        module_sp->GetSymbolLocatorStatistics().add(
+            symbol_locator_name, symbol_duration.get().count());
+      }
     }
 
     // If we haven't found a binary, or we don't have a SymbolFile, see
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 2b8ccab2406c6..00a3db421c73e 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -917,9 +917,14 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
 
   // Fixup the incoming path in case the path points to a valid file, yet the
   // arch or UUID (if one was passed in) don't match.
-  ModuleSpec located_binary_modulespec =
-      PluginManager::LocateExecutableObjectFile(module_spec);
-
+  ModuleSpec located_binary_modulespec;
+  StatsDuration locate_duration;
+  std::string locator_name;
+  {
+    ElapsedTime elapsed(locate_duration);
+    located_binary_modulespec =
+        PluginManager::LocateExecutableObjectFile(module_spec, &locator_name);
+  }
   // Don't look for the file if it appears to be the same one we already
   // checked for above...
   if (located_binary_modulespec.GetFileSpec() != module_file_spec) {
@@ -992,6 +997,8 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
       // By getting the object file we can guarantee that the architecture
       // matches
       if (module_sp && module_sp->GetObjectFile()) {
+        module_sp->GetSymbolLocatorStatistics().add(
+            locator_name, locate_duration.get().count());
         if (module_sp->GetObjectFile()->GetType() ==
             ObjectFile::eTypeStubLibrary) {
           module_sp.reset();
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index e6cb248ef31ce..d10fc00b5014d 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -1217,28 +1217,36 @@ PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
 }
 
 ModuleSpec
-PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
+PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
+                                          std::string *locator_name) {
   auto instances = GetSymbolLocatorInstances().GetSnapshot();
   for (auto &instance : instances) {
     if (instance.locate_executable_object_file) {
       std::optional<ModuleSpec> result =
           instance.locate_executable_object_file(module_spec);
-      if (result)
+      if (result) {
+        if (locator_name)
+          *locator_name = instance.name;
         return *result;
+      }
     }
   }
   return {};
 }
 
 FileSpec PluginManager::LocateExecutableSymbolFile(
-    const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
+    const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
+    std::string *locator_name) {
   auto instances = GetSymbolLocatorInstances().GetSnapshot();
   for (auto &instance : instances) {
     if (instance.locate_executable_symbol_file) {
       std::optional<FileSpec> result = instance.locate_executable_symbol_file(
           module_spec, default_search_paths);
-      if (result)
+      if (result) {
+        if (locator_name)
+          *locator_name = instance.name;
         return *result;
+      }
     }
   }
   return {};
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index 4fbead97e9c1a..11156afea7e90 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -814,8 +814,16 @@ Status PlatformDarwinKernel::GetSharedModuleKernel(
         // append ".dSYM" to the filename for the SymbolFile.
         FileSpecList search_paths =
             process->GetTarget().GetDebugFileSearchPaths();
-        FileSpec dsym_fspec =
-            PluginManager::LocateExecutableSymbolFile(kern_spec, search_paths);
+        StatsDuration locate_duration;
+        std::string locator_name;
+        FileSpec dsym_fspec;
+        {
+          ElapsedTime elapsed(locate_duration);
+          dsym_fspec = PluginManager::LocateExecutableSymbolFile(
+              kern_spec, search_paths, &locator_name);
+        }
+        module_sp->GetSymbolLocatorStatistics().add(
+            locator_name, locate_duration.get().count());
         if (FileSystem::Instance().Exists(dsym_fspec))
           module_sp->SetSymbolFileFileSpec(dsym_fspec);
         if (did_create_ptr)
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 6cc01436aef20..0740b8c22987c 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -276,12 +276,24 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {
               // Lookup UUID locally, before attempting dsymForUUID like action
               FileSpecList search_paths =
                   Target::GetDefaultDebugFileSearchPaths();
-              module_spec.GetSymbolFileSpec() =
-                  PluginManager::LocateExecutableSymbolFile(module_spec,
-                                                            search_paths);
+              StatsDuration symbol_duration;
+              std::string symbol_locator_name;
+              StatsDuration object_duration;
+              std::string object_locator_name;
+              {
+                ElapsedTime elapsed(symbol_duration);
+                module_spec.GetSymbolFileSpec() =
+                    PluginManager::LocateExecutableSymbolFile(
+                        module_spec, search_paths, &symbol_locator_name);
+              }
               if (module_spec.GetSymbolFileSpec()) {
-                ModuleSpec executable_module_spec =
-                    PluginManager::LocateExecutableObjectFile(module_spec);
+                ModuleSpec executable_module_spec;
+                {
+                  ElapsedTime elapsed(object_duration);
+                  executable_module_spec =
+                      PluginManager::LocateExecutableObjectFile(
+                          module_spec, &object_locator_name);
+                }
                 if (FileSystem::Instance().Exists(
                         executable_module_spec.GetFileSpec())) {
                   module_spec.GetFileSpec() =
@@ -297,6 +309,10 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {
 
               if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
                 ModuleSP module_sp(new Module(module_spec));
+                module_sp->GetSymbolLocatorStatistics().add(
+                    object_locator_name, object_duration.get().count());
+                module_sp->GetSymbolLocatorStatistics().add(
+                    symbol_locator_name, symbol_duration.get().count());
                 if (module_sp.get() && module_sp->GetObjectFile()) {
                   // Get the current target executable
                   ModuleSP exe_module_sp(target.GetExecutableModule());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b95159d882bc7..5fd07d1881ea7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4250,13 +4250,18 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
     ModuleSpec module_spec;
     module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
     FileSpec dwp_filespec;
+    StatsDuration duration;
+    std::string locator_name;
     for (const auto &symfile : symfiles.files()) {
       module_spec.GetSymbolFileSpec() =
           FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle());
       LLDB_LOG(log, "Searching for DWP using: \"{0}\"",
                module_spec.GetSymbolFileSpec());
-      dwp_filespec =
-          PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+      {
+        ElapsedTime elapsed(duration);
+        dwp_filespec = PluginManager::LocateExecutableSymbolFile(
+            module_spec, search_paths, &locator_name);
+      }
       if (FileSystem::Instance().Exists(dwp_filespec)) {
         break;
       }
@@ -4267,9 +4272,14 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
       // find the correct DWP file, as the Debuginfod plugin uses *only* this
       // data to correctly match the DWP file with the binary.
       module_spec.GetUUID() = m_objfile_sp->GetUUID();
-      dwp_filespec =
-          PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+      {
+        ElapsedTime elapsed(duration);
+        dwp_filespec = PluginManager::LocateExecutableSymbolFile(
+            module_spec, search_paths, &locator_name);
+      }
     }
+    m_objfile_sp->GetModule()->GetSymbolLocatorStatistics().add(
+        locator_name, duration.get().count());
     if (FileSystem::Instance().Exists(dwp_filespec)) {
       LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
       DataBufferSP dwp_file_data_sp;
diff --git a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index a2c3825cd537f..bd2b94180e63c 100644
--- a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -103,14 +103,26 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
   module_spec.GetSymbolFileSpec() = fspec;
   module_spec.GetUUID() = uuid;
   FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-  FileSpec dsym_fspec =
-      PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+  FileSpec dsym_fspec;
+  StatsDuration symbol_duration;
+  std::string symbol_locator_name;
+  StatsDuration object_duration;
+  std::string object_locator_name;
+  {
+    ElapsedTime elapsed(symbol_duration);
+    dsym_fspec = PluginManager::LocateExecutableSymbolFile(
+        module_spec, search_paths, &symbol_locator_name);
+  }
   if (!dsym_fspec || IsDwpSymbolFile(module_sp, dsym_fspec)) {
     // If we have a stripped binary or if we have a DWP file, SymbolLocator
     // plugins may be able to give us an unstripped binary or an
     // 'only-keep-debug' stripped file.
-    ModuleSpec unstripped_spec =
-        PluginManager::LocateExecutableObjectFile(module_spec);
+    ModuleSpec unstripped_spec;
+    {
+      ElapsedTime elapsed(object_duration);
+      unstripped_spec = PluginManager::LocateExecutableObjectFile(
+          module_spec, &object_locator_name);
+    }
     if (!unstripped_spec)
       return nullptr;
     // The default SymbolLocator plugin returns the original binary if no other
@@ -119,6 +131,10 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
       return nullptr;
     dsym_fspec = unstripped_spec.GetFileSpec();
   }
+  module_sp->GetSymbolLocatorStatistics().add(object_locator_name,
+                                              object_duration.get().count());
+  module_sp->GetSymbolLocatorStatistics().add(symbol_locator_name,
+                                              symbol_duration.get().count());
 
   DataBufferSP dsym_file_data_sp;
   lldb::offset_t dsym_file_data_offset = 0;
@@ -127,7 +143,6 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
       dsym_file_data_sp, dsym_file_data_offset);
   if (!dsym_objfile_sp)
     return nullptr;
-
   // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
   // be able to figure this out consistently as the symbol file may not
   // have stripped the code sections, etc.
diff --git a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
index f46bff8f7d12e..62c0ba09df31a 100644
--- a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -134,8 +134,16 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
       ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
       module_spec.GetUUID() = module_sp->GetUUID();
       FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-      dsym_fspec =
-          PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+      StatsDuration locate_duration;
+      std::string locator_name;
+      FileSpec dsym_fspec;
+      {
+        ElapsedTime elapsed(locate_duration);
+        dsym_fspec = PluginManager::LocateExecutableSymbolFile(
+            module_spec, search_paths, &locator_name);
+      }
+      module_sp->GetSymbolLocatorStatistics().add(
+          locator_name, locate_duration.get().count());
       if (module_spec.GetSourceMappingList().GetSize())
         module_sp->GetSourceMappingList().Append(
             module_spec.GetSourceMappingList(), true);
diff --git a/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp b/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp
index 6393363db51f1..4a37885ecf668 100644
--- a/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp
+++ b/lldb/source/Plugins/SymbolVendor/PECOFF/SymbolVendorPECOFF.cpp
@@ -85,8 +85,16 @@ SymbolVendorPECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
   module_spec.GetSymbolFileSpec() = fspec;
   module_spec.GetUUID() = uuid;
   FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-  FileSpec dsym_fspec =
-      PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+  StatsDuration locate_duration;
+  std::string locator_name;
+  FileSpec dsym_fspec;
+  {
+    ElapsedTime elapsed(locate_duration);
+    dsym_fspec = PluginManager::LocateExecutableSymbolFile(
+        module_spec, search_paths, &locator_name);
+  }
+  module_sp->GetSymbolLocatorStatistics().add(locator_name,
+                                              locate_duration.get().count());
   if (!dsym_fspec)
     return nullptr;
 
diff --git a/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
index f8a9389c0ff93..459b0679148ba 100644
--- a/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
+++ b/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -85,8 +85,16 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
   module_spec.GetSymbolFileSpec() = *symbol_file_spec;
 
   FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-  FileSpec sym_fspec =
-      PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+  StatsDuration locate_duration;
+  std::string locator_name;
+  FileSpec sym_fspec;
+  {
+    ElapsedTime elapsed(locate_duration);
+    sym_fspec = PluginManager::LocateExecutableSymbolFile(
+        module_spec, search_paths, &locator_name);
+  }
+  module_sp->GetSymbolLocatorStatistics().add(locator_name,
+                                              locate_duration.get().count());
   if (!sym_fspec)
     return nullptr;
 
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index b5d2e7bda1edf..d975fd05da98f 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -71,6 +71,14 @@ json::Value ModuleStats::ToJSON() const {
   module.try_emplace("debugInfoHadIncompleteTypes",
                      debug_info_had_incomplete_types);
   module.try_emplace("symbolTableStripped", symtab_stripped);
+
+  if (!symbol_locator_time.empty()) {
+    json::Object obj;
+    for (const auto &entry : symbol_locator_time)
+      obj.try_emplace(entry.first().str(), entry.second);
+    module.try_emplace("symbolLocatorTime", std::move(obj));
+  }
+
   if (!symfile_path.empty())
     module.try_emplace("symbolFilePath", symfile_path);
 
@@ -288,6 +296,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
 
   json::Array json_targets;
   json::Array json_modules;
+  Module::StatisticsMap symbol_locator_total_time;
   double symtab_parse_time = 0.0;
   double symtab_index_time = 0.0;
   double debug_parse_time = 0.0;
@@ -316,6 +325,10 @@ llvm::json::Value DebuggerStats::ReportStatistics(
     ModuleStats module_stat;
     module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count();
     module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();
+    for (auto &entry : module->GetSymbolLocatorStatistics().map) {
+      module_stat.symbol_locator_time.try_emplace(entry.first, entry.second);
+      symbol_locator_total_time.add(entry.first, entry.second);
+    }
     Symtab *symtab = module->GetSymtab(/*can_create=*/false);
     if (symtab) {
       module_stat.symtab_loaded_from_cache = symtab->GetWasLoadedFromCache();
@@ -419,6 +432,13 @@ llvm::json::Value DebuggerStats::ReportStatistics(
     global_stats.try_emplace("targets", std::move(json_targets));
   }
 
+  if (!symbol_locator_total_time.map.empty()) {
+    json::Object obj;
+    for (const auto &entry : symbol_locator_total_time.map)
+      obj.try_emplace(entry.first, entry.second);
+    global_stats.try_emplace("totalSymbolLocatorTime", std::move(obj));
+  }
+
   ConstStringStats const_string_stats;
   json::Object json_memory{
       {"strings", const_string_stats.ToJSON()},



More information about the lldb-commits mailing list