Skip to content

Commit 40b77ca

Browse files
committed
DynamicLoaderDarwin load images in parallel
1 parent 2ab9233 commit 40b77ca

8 files changed

+185
-8
lines changed

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
lldb_tablegen(DynamicLoaderDarwinProperties.inc -gen-lldb-property-defs
2+
SOURCE DynamicLoaderDarwinProperties.td
3+
TARGET LLDBPluginDynamicLoaderDarwinPropertiesGen)
4+
5+
lldb_tablegen(DynamicLoaderDarwinPropertiesEnum.inc -gen-lldb-property-enum-defs
6+
SOURCE DynamicLoaderDarwinProperties.td
7+
TARGET LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)
8+
19
add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
210
DynamicLoaderMacOSXDYLD.cpp
311
DynamicLoaderMacOS.cpp
412
DynamicLoaderDarwin.cpp
13+
DynamicLoaderDarwinProperties.cpp
514

615
LINK_LIBS
716
lldbBreakpoint
@@ -16,3 +25,7 @@ add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
1625
Support
1726
TargetParser
1827
)
28+
29+
add_dependencies(lldbPluginDynamicLoaderMacOSXDYLD
30+
LLDBPluginDynamicLoaderDarwinPropertiesGen
31+
LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "DynamicLoaderDarwin.h"
1010

11+
#include "DynamicLoaderDarwinProperties.h"
1112
#include "lldb/Breakpoint/StoppointCallbackContext.h"
1213
#include "lldb/Core/Debugger.h"
1314
#include "lldb/Core/Module.h"
@@ -31,6 +32,7 @@
3132
#include "lldb/Utility/LLDBLog.h"
3233
#include "lldb/Utility/Log.h"
3334
#include "lldb/Utility/State.h"
35+
#include "llvm/Support/ThreadPool.h"
3436

3537
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
3638
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -77,6 +79,17 @@ void DynamicLoaderDarwin::DidLaunch() {
7779
SetNotificationBreakpoint();
7880
}
7981

82+
void DynamicLoaderDarwin::CreateSettings(lldb_private::Debugger &debugger) {
83+
if (!PluginManager::GetSettingForDynamicLoaderPlugin(
84+
debugger, DynamicLoaderDarwinProperties::GetSettingName())) {
85+
const bool is_global_setting = true;
86+
PluginManager::CreateSettingForDynamicLoaderPlugin(
87+
debugger,
88+
DynamicLoaderDarwinProperties::GetGlobal().GetValueProperties(),
89+
"Properties for the DynamicLoaderDarwin plug-in.", is_global_setting);
90+
}
91+
}
92+
8093
// Clear out the state of this class.
8194
void DynamicLoaderDarwin::Clear(bool clear_process) {
8295
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -88,7 +101,7 @@ void DynamicLoaderDarwin::Clear(bool clear_process) {
88101
}
89102

90103
ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
91-
ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
104+
const ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
92105
if (did_create_ptr)
93106
*did_create_ptr = false;
94107

@@ -642,6 +655,41 @@ ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
642655

643656
void DynamicLoaderDarwin::ClearDYLDModule() { m_dyld_module_wp.reset(); }
644657

658+
template <typename InputIterator, typename ResultType>
659+
static std::vector<ResultType> parallel_map(
660+
llvm::ThreadPoolInterface &threadPool, InputIterator first,
661+
InputIterator last,
662+
llvm::function_ref<ResultType(
663+
const typename std::iterator_traits<InputIterator>::value_type &)>
664+
transform) {
665+
const auto size = std::distance(first, last);
666+
std::vector<ResultType> results(size);
667+
if (size > 0) {
668+
llvm::ThreadPoolTaskGroup taskGroup(threadPool);
669+
auto it = first;
670+
for (ssize_t i = 0; i < size; ++i, ++it) {
671+
taskGroup.async([&, i, it]() { results[i] = transform(*it); });
672+
}
673+
taskGroup.wait();
674+
}
675+
return results;
676+
}
677+
678+
template <typename InputIterator, typename ResultType>
679+
static std::vector<ResultType>
680+
map(InputIterator first, InputIterator last,
681+
llvm::function_ref<ResultType(
682+
const typename std::iterator_traits<InputIterator>::value_type &)>
683+
transform) {
684+
const auto size = std::distance(first, last);
685+
std::vector<ResultType> results(size);
686+
auto it = first;
687+
for (ssize_t i = 0; i < size; ++i, ++it) {
688+
results[i] = transform(*it);
689+
}
690+
return results;
691+
}
692+
645693
bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
646694
ImageInfo::collection &image_infos) {
647695
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -651,17 +699,28 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
651699
Target &target = m_process->GetTarget();
652700
ModuleList &target_images = target.GetImages();
653701

654-
for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
702+
auto ImageLoad = [this, log](const ImageInfo &image_info) {
655703
if (log) {
656704
LLDB_LOGF(log, "Adding new image at address=0x%16.16" PRIx64 ".",
657-
image_infos[idx].address);
658-
image_infos[idx].PutToLog(log);
705+
image_info.address);
706+
image_info.PutToLog(log);
659707
}
708+
return FindTargetModuleForImageInfo(image_info, true, nullptr);
709+
};
710+
bool is_parallel_load =
711+
DynamicLoaderDarwinProperties::GetGlobal().GetEnableParallelImageLoad();
712+
auto images =
713+
is_parallel_load
714+
? parallel_map<ImageInfo::collection::const_iterator, ModuleSP>(
715+
Debugger::GetThreadPool(), image_infos.begin(),
716+
image_infos.end(), ImageLoad)
717+
: map<ImageInfo::collection::const_iterator, ModuleSP>(
718+
image_infos.begin(), image_infos.end(), ImageLoad);
660719

720+
for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
661721
m_dyld_image_infos.push_back(image_infos[idx]);
662722

663-
ModuleSP image_module_sp(
664-
FindTargetModuleForImageInfo(image_infos[idx], true, nullptr));
723+
ModuleSP image_module_sp = images[idx];
665724

666725
if (image_module_sp) {
667726
ObjectFile *objfile = image_module_sp->GetObjectFile();

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
5858

5959
std::optional<lldb_private::Address> GetStartAddress() override;
6060

61+
static void CreateSettings(lldb_private::Debugger &debugger);
62+
6163
protected:
6264
void PrivateInitialize(lldb_private::Process *process);
6365

@@ -174,7 +176,7 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
174176

175177
bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
176178

177-
lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
179+
lldb::ModuleSP FindTargetModuleForImageInfo(const ImageInfo &image_info,
178180
bool can_create,
179181
bool *did_create_ptr);
180182

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===-- DynamicLoaderDarwinProperties.cpp ---------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "DynamicLoaderDarwinProperties.h"
10+
11+
using namespace lldb_private;
12+
13+
#define LLDB_PROPERTIES_dynamicloaderdarwin_experimental
14+
#include "DynamicLoaderDarwinProperties.inc"
15+
16+
enum {
17+
#define LLDB_PROPERTIES_dynamicloaderdarwin_experimental
18+
#include "DynamicLoaderDarwinPropertiesEnum.inc"
19+
};
20+
21+
llvm::StringRef DynamicLoaderDarwinProperties::GetSettingName() {
22+
static constexpr llvm::StringLiteral g_setting_name("darwin");
23+
return g_setting_name;
24+
}
25+
26+
DynamicLoaderDarwinProperties::ExperimentalProperties::ExperimentalProperties()
27+
: Properties(std::make_shared<OptionValueProperties>(
28+
GetExperimentalSettingsName())) {
29+
m_collection_sp->Initialize(g_dynamicloaderdarwin_experimental_properties);
30+
}
31+
32+
DynamicLoaderDarwinProperties::DynamicLoaderDarwinProperties()
33+
: Properties(std::make_shared<OptionValueProperties>(GetSettingName())),
34+
m_experimental_properties(std::make_unique<ExperimentalProperties>()) {
35+
m_collection_sp->AppendProperty(
36+
Properties::GetExperimentalSettingsName(),
37+
"Experimental settings - setting these won't produce errors if the "
38+
"setting is not present.",
39+
true, m_experimental_properties->GetValueProperties());
40+
}
41+
42+
bool DynamicLoaderDarwinProperties::GetEnableParallelImageLoad() const {
43+
return m_experimental_properties->GetPropertyAtIndexAs<bool>(
44+
ePropertyEnableParallelImageLoad,
45+
g_dynamicloaderdarwin_experimental_properties
46+
[ePropertyEnableParallelImageLoad]
47+
.default_uint_value != 0);
48+
}
49+
50+
DynamicLoaderDarwinProperties &DynamicLoaderDarwinProperties::GetGlobal() {
51+
static DynamicLoaderDarwinProperties g_settings;
52+
return g_settings;
53+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===-- DynamicLoaderDarwinProperties.h -------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWINPROPERTIES_H
10+
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWINPROPERTIES_H
11+
12+
#include "lldb/Core/UserSettingsController.h"
13+
14+
namespace lldb_private {
15+
16+
class DynamicLoaderDarwinProperties : public Properties {
17+
public:
18+
class ExperimentalProperties : public Properties {
19+
public:
20+
ExperimentalProperties();
21+
};
22+
static llvm::StringRef GetSettingName();
23+
static DynamicLoaderDarwinProperties &GetGlobal();
24+
DynamicLoaderDarwinProperties();
25+
~DynamicLoaderDarwinProperties() override = default;
26+
bool GetEnableParallelImageLoad() const;
27+
28+
private:
29+
std::unique_ptr<ExperimentalProperties> m_experimental_properties;
30+
};
31+
32+
} // namespace lldb_private
33+
34+
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWINPROPERTIES_H
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include "../../../../include/lldb/Core/PropertiesBase.td"
2+
3+
let Definition = "dynamicloaderdarwin_experimental" in {
4+
def EnableParallelImageLoad: Property<"enable-parallel-image-load", "Boolean">,
5+
Global,
6+
DefaultTrue,
7+
Desc<"Load images in parallel.">;
8+
}

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,8 @@ bool DynamicLoaderMacOSXDYLD::IsFullyInitialized() {
11471147

11481148
void DynamicLoaderMacOSXDYLD::Initialize() {
11491149
PluginManager::RegisterPlugin(GetPluginNameStatic(),
1150-
GetPluginDescriptionStatic(), CreateInstance);
1150+
GetPluginDescriptionStatic(), CreateInstance,
1151+
DebuggerInitialize);
11511152
DynamicLoaderMacOS::Initialize();
11521153
}
11531154

@@ -1156,6 +1157,11 @@ void DynamicLoaderMacOSXDYLD::Terminate() {
11561157
PluginManager::UnregisterPlugin(CreateInstance);
11571158
}
11581159

1160+
void DynamicLoaderMacOSXDYLD::DebuggerInitialize(
1161+
lldb_private::Debugger &debugger) {
1162+
CreateSettings(debugger);
1163+
}
1164+
11591165
llvm::StringRef DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
11601166
return "Dynamic loader plug-in that watches for shared library loads/unloads "
11611167
"in MacOSX user processes.";

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
5050
static lldb_private::DynamicLoader *
5151
CreateInstance(lldb_private::Process *process, bool force);
5252

53+
static void DebuggerInitialize(lldb_private::Debugger &debugger);
54+
5355
/// Called after attaching a process.
5456
///
5557
/// Allow DynamicLoader plug-ins to execute some code after

0 commit comments

Comments
 (0)