[Lldb-commits] [lldb] DynamicLoaderDarwin load images in parallel (PR #110439)

Dmitrii Galimzianov via lldb-commits lldb-commits at lists.llvm.org
Sun Sep 29 14:15:20 PDT 2024


https://github.com/DmT021 created https://github.com/llvm/llvm-project/pull/110439

When `plugin.dynamic-loader.darwin.enable-parallel-image-load` is enabled `DynamicLoaderDarwin::AddModulesUsingImageInfos` will load images in parallel using the thread pool.

>From d6183d6b0e1c755d6adf3f52463742e50a234f16 Mon Sep 17 00:00:00 2001
From: Dmitrii Galimzianov <dmt021 at gmail.com>
Date: Sun, 29 Sep 2024 22:24:19 +0200
Subject: [PATCH] DynamicLoaderDarwin load images in parallel

---
 .../DynamicLoader/MacOSX-DYLD/CMakeLists.txt  | 12 +++
 .../MacOSX-DYLD/DynamicLoaderDarwin.cpp       | 97 ++++++++++++++++++-
 .../MacOSX-DYLD/DynamicLoaderDarwin.h         | 11 +++
 .../DynamicLoaderDarwinProperties.td          |  8 ++
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp   |  8 +-
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h     |  2 +
 6 files changed, 132 insertions(+), 6 deletions(-)
 create mode 100644 lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwinProperties.td

diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
index 7308374c8bfba6..b53699b31252ab 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
@@ -1,3 +1,11 @@
+lldb_tablegen(DynamicLoaderDarwinProperties.inc -gen-lldb-property-defs
+  SOURCE DynamicLoaderDarwinProperties.td
+  TARGET LLDBPluginDynamicLoaderDarwinPropertiesGen)
+
+lldb_tablegen(DynamicLoaderDarwinPropertiesEnum.inc -gen-lldb-property-enum-defs
+  SOURCE DynamicLoaderDarwinProperties.td
+  TARGET LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)
+
 add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
   DynamicLoaderMacOSXDYLD.cpp
   DynamicLoaderMacOS.cpp
@@ -16,3 +24,7 @@ add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
     Support
     TargetParser
   )
+
+add_dependencies(lldbPluginDynamicLoaderMacOSXDYLD
+  LLDBPluginDynamicLoaderDarwinPropertiesGen
+  LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 3863b6b3520db4..b085ccb4fcaa42 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -34,6 +34,7 @@
 
 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "llvm/Support/ThreadPool.h"
 
 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
 #ifdef ENABLE_DEBUG_PRINTF
@@ -48,6 +49,36 @@
 using namespace lldb;
 using namespace lldb_private;
 
+#define LLDB_PROPERTIES_dynamicloaderdarwin
+#include "DynamicLoaderDarwinProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_dynamicloaderdarwin
+#include "DynamicLoaderDarwinPropertiesEnum.inc"
+};
+
+ConstString &DynamicLoaderDarwinProperties::GetSettingName() {
+  static ConstString g_setting_name("darwin");
+  return g_setting_name;
+}
+
+DynamicLoaderDarwinProperties::DynamicLoaderDarwinProperties() : Properties() {
+  m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
+  m_collection_sp->Initialize(g_dynamicloaderdarwin_properties);
+}
+
+bool DynamicLoaderDarwinProperties::GetEnableParallelImageLoad() const {
+  return GetPropertyAtIndexAs<bool>(
+      ePropertyEnableParallelImageLoad,
+      g_dynamicloaderdarwin_properties[ePropertyEnableParallelImageLoad]
+              .default_uint_value != 0);
+}
+
+DynamicLoaderDarwinProperties &DynamicLoaderDarwinProperties::GetGlobal() {
+  static DynamicLoaderDarwinProperties g_settings;
+  return g_settings;
+}
+
 // Constructor
 DynamicLoaderDarwin::DynamicLoaderDarwin(Process *process)
     : DynamicLoader(process), m_dyld_module_wp(), m_libpthread_module_wp(),
@@ -77,6 +108,17 @@ void DynamicLoaderDarwin::DidLaunch() {
   SetNotificationBreakpoint();
 }
 
+void DynamicLoaderDarwin::CreateSettings(lldb_private::Debugger &debugger) {
+  if (!PluginManager::GetSettingForDynamicLoaderPlugin(
+          debugger, DynamicLoaderDarwinProperties::GetSettingName())) {
+    const bool is_global_setting = true;
+    PluginManager::CreateSettingForDynamicLoaderPlugin(
+        debugger,
+        DynamicLoaderDarwinProperties::GetGlobal().GetValueProperties(),
+        "Properties for the DynamicLoaderDarwin plug-in.", is_global_setting);
+  }
+}
+
 // Clear out the state of this class.
 void DynamicLoaderDarwin::Clear(bool clear_process) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -640,6 +682,41 @@ ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
 
 void DynamicLoaderDarwin::ClearDYLDModule() { m_dyld_module_wp.reset(); }
 
+template <typename InputIterator, typename ResultType>
+std::vector<ResultType>
+parallel_map(llvm::ThreadPoolInterface &threadPool, InputIterator first,
+             InputIterator last,
+             llvm::function_ref<ResultType(
+                 typename std::iterator_traits<InputIterator>::value_type &)>
+                 transform) {
+  const auto size = std::distance(first, last);
+  std::vector<ResultType> results(size);
+  if (size > 0) {
+    llvm::ThreadPoolTaskGroup taskGroup(threadPool);
+    auto it = first;
+    for (ssize_t i = 0; i < size; ++i, ++it) {
+      taskGroup.async([&, i, it]() { results[i] = transform(*it); });
+    }
+    taskGroup.wait();
+  }
+  return results;
+}
+
+template <typename InputIterator, typename ResultType>
+std::vector<ResultType>
+map(InputIterator first, InputIterator last,
+    llvm::function_ref<
+        ResultType(typename std::iterator_traits<InputIterator>::value_type &)>
+        transform) {
+  const auto size = std::distance(first, last);
+  std::vector<ResultType> results(size);
+  auto it = first;
+  for (ssize_t i = 0; i < size; ++i, ++it) {
+    results[i] = transform(*it);
+  }
+  return results;
+}
+
 bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
     ImageInfo::collection &image_infos) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -649,17 +726,27 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
   Target &target = m_process->GetTarget();
   ModuleList &target_images = target.GetImages();
 
-  for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
+  auto ImageLoad = [this, log](ImageInfo &image_info) {
     if (log) {
       LLDB_LOGF(log, "Adding new image at address=0x%16.16" PRIx64 ".",
-                image_infos[idx].address);
-      image_infos[idx].PutToLog(log);
+                image_info.address);
+      image_info.PutToLog(log);
     }
+    return FindTargetModuleForImageInfo(image_info, true, nullptr);
+  };
+  bool is_parallel_load =
+      DynamicLoaderDarwinProperties::GetGlobal().GetEnableParallelImageLoad();
+  auto images = is_parallel_load
+                    ? parallel_map<ImageInfo::collection::iterator, ModuleSP>(
+                          Debugger::GetThreadPool(), image_infos.begin(),
+                          image_infos.end(), ImageLoad)
+                    : map<ImageInfo::collection::iterator, ModuleSP>(
+                          image_infos.begin(), image_infos.end(), ImageLoad);
 
+  for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
     m_dyld_image_infos.push_back(image_infos[idx]);
 
-    ModuleSP image_module_sp(
-        FindTargetModuleForImageInfo(image_infos[idx], true, nullptr));
+    ModuleSP image_module_sp = images[idx];
 
     if (image_module_sp) {
       ObjectFile *objfile = image_module_sp->GetObjectFile();
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
index 3613c4c29b1785..d297b10feb2ec5 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -24,6 +24,15 @@
 
 namespace lldb_private {
 
+class DynamicLoaderDarwinProperties : public Properties {
+public:
+  static ConstString &GetSettingName();
+  static DynamicLoaderDarwinProperties &GetGlobal();
+  DynamicLoaderDarwinProperties();
+  ~DynamicLoaderDarwinProperties() override = default;
+  bool GetEnableParallelImageLoad() const;
+};
+
 class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
 public:
   DynamicLoaderDarwin(lldb_private::Process *process);
@@ -58,6 +67,8 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
 
   std::optional<lldb_private::Address> GetStartAddress() override;
 
+  static void CreateSettings(lldb_private::Debugger &debugger);
+
 protected:
   void PrivateInitialize(lldb_private::Process *process);
 
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwinProperties.td b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwinProperties.td
new file mode 100644
index 00000000000000..bfeaf21fcec1a4
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwinProperties.td
@@ -0,0 +1,8 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "dynamicloaderdarwin" in {
+  def EnableParallelImageLoad: Property<"enable-parallel-image-load", "Boolean">,
+    Global,
+    DefaultFalse,
+    Desc<"Load images in parallel.">;
+}
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 9ceadb21d28413..d650d522f9261c 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -1144,7 +1144,8 @@ bool DynamicLoaderMacOSXDYLD::IsFullyInitialized() {
 
 void DynamicLoaderMacOSXDYLD::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
-                                GetPluginDescriptionStatic(), CreateInstance);
+                                GetPluginDescriptionStatic(), CreateInstance,
+                                DebuggerInitialize);
   DynamicLoaderMacOS::Initialize();
 }
 
@@ -1153,6 +1154,11 @@ void DynamicLoaderMacOSXDYLD::Terminate() {
   PluginManager::UnregisterPlugin(CreateInstance);
 }
 
+void DynamicLoaderMacOSXDYLD::DebuggerInitialize(
+    lldb_private::Debugger &debugger) {
+  CreateSettings(debugger);
+}
+
 llvm::StringRef DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
   return "Dynamic loader plug-in that watches for shared library loads/unloads "
          "in MacOSX user processes.";
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index ae7451722a8d75..924e2fc107743c 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -50,6 +50,8 @@ class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
   static lldb_private::DynamicLoader *
   CreateInstance(lldb_private::Process *process, bool force);
 
+  static void DebuggerInitialize(lldb_private::Debugger &debugger);
+
   /// Called after attaching a process.
   ///
   /// Allow DynamicLoader plug-ins to execute some code after



More information about the lldb-commits mailing list