Skip to content

Commit d6183d6

Browse files
committed
DynamicLoaderDarwin load images in parallel
1 parent 3c3df1b commit d6183d6

File tree

6 files changed

+132
-6
lines changed

6 files changed

+132
-6
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
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
@@ -16,3 +24,7 @@ add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD PLUGIN
1624
Support
1725
TargetParser
1826
)
27+
28+
add_dependencies(lldbPluginDynamicLoaderMacOSXDYLD
29+
LLDBPluginDynamicLoaderDarwinPropertiesGen
30+
LLDBPluginDynamicLoaderDarwinPropertiesEnumGen)

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

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
3636
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
37+
#include "llvm/Support/ThreadPool.h"
3738

3839
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
3940
#ifdef ENABLE_DEBUG_PRINTF
@@ -48,6 +49,36 @@
4849
using namespace lldb;
4950
using namespace lldb_private;
5051

52+
#define LLDB_PROPERTIES_dynamicloaderdarwin
53+
#include "DynamicLoaderDarwinProperties.inc"
54+
55+
enum {
56+
#define LLDB_PROPERTIES_dynamicloaderdarwin
57+
#include "DynamicLoaderDarwinPropertiesEnum.inc"
58+
};
59+
60+
ConstString &DynamicLoaderDarwinProperties::GetSettingName() {
61+
static ConstString g_setting_name("darwin");
62+
return g_setting_name;
63+
}
64+
65+
DynamicLoaderDarwinProperties::DynamicLoaderDarwinProperties() : Properties() {
66+
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
67+
m_collection_sp->Initialize(g_dynamicloaderdarwin_properties);
68+
}
69+
70+
bool DynamicLoaderDarwinProperties::GetEnableParallelImageLoad() const {
71+
return GetPropertyAtIndexAs<bool>(
72+
ePropertyEnableParallelImageLoad,
73+
g_dynamicloaderdarwin_properties[ePropertyEnableParallelImageLoad]
74+
.default_uint_value != 0);
75+
}
76+
77+
DynamicLoaderDarwinProperties &DynamicLoaderDarwinProperties::GetGlobal() {
78+
static DynamicLoaderDarwinProperties g_settings;
79+
return g_settings;
80+
}
81+
5182
// Constructor
5283
DynamicLoaderDarwin::DynamicLoaderDarwin(Process *process)
5384
: DynamicLoader(process), m_dyld_module_wp(), m_libpthread_module_wp(),
@@ -77,6 +108,17 @@ void DynamicLoaderDarwin::DidLaunch() {
77108
SetNotificationBreakpoint();
78109
}
79110

111+
void DynamicLoaderDarwin::CreateSettings(lldb_private::Debugger &debugger) {
112+
if (!PluginManager::GetSettingForDynamicLoaderPlugin(
113+
debugger, DynamicLoaderDarwinProperties::GetSettingName())) {
114+
const bool is_global_setting = true;
115+
PluginManager::CreateSettingForDynamicLoaderPlugin(
116+
debugger,
117+
DynamicLoaderDarwinProperties::GetGlobal().GetValueProperties(),
118+
"Properties for the DynamicLoaderDarwin plug-in.", is_global_setting);
119+
}
120+
}
121+
80122
// Clear out the state of this class.
81123
void DynamicLoaderDarwin::Clear(bool clear_process) {
82124
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -640,6 +682,41 @@ ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
640682

641683
void DynamicLoaderDarwin::ClearDYLDModule() { m_dyld_module_wp.reset(); }
642684

685+
template <typename InputIterator, typename ResultType>
686+
std::vector<ResultType>
687+
parallel_map(llvm::ThreadPoolInterface &threadPool, InputIterator first,
688+
InputIterator last,
689+
llvm::function_ref<ResultType(
690+
typename std::iterator_traits<InputIterator>::value_type &)>
691+
transform) {
692+
const auto size = std::distance(first, last);
693+
std::vector<ResultType> results(size);
694+
if (size > 0) {
695+
llvm::ThreadPoolTaskGroup taskGroup(threadPool);
696+
auto it = first;
697+
for (ssize_t i = 0; i < size; ++i, ++it) {
698+
taskGroup.async([&, i, it]() { results[i] = transform(*it); });
699+
}
700+
taskGroup.wait();
701+
}
702+
return results;
703+
}
704+
705+
template <typename InputIterator, typename ResultType>
706+
std::vector<ResultType>
707+
map(InputIterator first, InputIterator last,
708+
llvm::function_ref<
709+
ResultType(typename std::iterator_traits<InputIterator>::value_type &)>
710+
transform) {
711+
const auto size = std::distance(first, last);
712+
std::vector<ResultType> results(size);
713+
auto it = first;
714+
for (ssize_t i = 0; i < size; ++i, ++it) {
715+
results[i] = transform(*it);
716+
}
717+
return results;
718+
}
719+
643720
bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
644721
ImageInfo::collection &image_infos) {
645722
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -649,17 +726,27 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
649726
Target &target = m_process->GetTarget();
650727
ModuleList &target_images = target.GetImages();
651728

652-
for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
729+
auto ImageLoad = [this, log](ImageInfo &image_info) {
653730
if (log) {
654731
LLDB_LOGF(log, "Adding new image at address=0x%16.16" PRIx64 ".",
655-
image_infos[idx].address);
656-
image_infos[idx].PutToLog(log);
732+
image_info.address);
733+
image_info.PutToLog(log);
657734
}
735+
return FindTargetModuleForImageInfo(image_info, true, nullptr);
736+
};
737+
bool is_parallel_load =
738+
DynamicLoaderDarwinProperties::GetGlobal().GetEnableParallelImageLoad();
739+
auto images = is_parallel_load
740+
? parallel_map<ImageInfo::collection::iterator, ModuleSP>(
741+
Debugger::GetThreadPool(), image_infos.begin(),
742+
image_infos.end(), ImageLoad)
743+
: map<ImageInfo::collection::iterator, ModuleSP>(
744+
image_infos.begin(), image_infos.end(), ImageLoad);
658745

746+
for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
659747
m_dyld_image_infos.push_back(image_infos[idx]);
660748

661-
ModuleSP image_module_sp(
662-
FindTargetModuleForImageInfo(image_infos[idx], true, nullptr));
749+
ModuleSP image_module_sp = images[idx];
663750

664751
if (image_module_sp) {
665752
ObjectFile *objfile = image_module_sp->GetObjectFile();

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424

2525
namespace lldb_private {
2626

27+
class DynamicLoaderDarwinProperties : public Properties {
28+
public:
29+
static ConstString &GetSettingName();
30+
static DynamicLoaderDarwinProperties &GetGlobal();
31+
DynamicLoaderDarwinProperties();
32+
~DynamicLoaderDarwinProperties() override = default;
33+
bool GetEnableParallelImageLoad() const;
34+
};
35+
2736
class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
2837
public:
2938
DynamicLoaderDarwin(lldb_private::Process *process);
@@ -58,6 +67,8 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
5867

5968
std::optional<lldb_private::Address> GetStartAddress() override;
6069

70+
static void CreateSettings(lldb_private::Debugger &debugger);
71+
6172
protected:
6273
void PrivateInitialize(lldb_private::Process *process);
6374

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" in {
4+
def EnableParallelImageLoad: Property<"enable-parallel-image-load", "Boolean">,
5+
Global,
6+
DefaultFalse,
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
@@ -1144,7 +1144,8 @@ bool DynamicLoaderMacOSXDYLD::IsFullyInitialized() {
11441144

11451145
void DynamicLoaderMacOSXDYLD::Initialize() {
11461146
PluginManager::RegisterPlugin(GetPluginNameStatic(),
1147-
GetPluginDescriptionStatic(), CreateInstance);
1147+
GetPluginDescriptionStatic(), CreateInstance,
1148+
DebuggerInitialize);
11481149
DynamicLoaderMacOS::Initialize();
11491150
}
11501151

@@ -1153,6 +1154,11 @@ void DynamicLoaderMacOSXDYLD::Terminate() {
11531154
PluginManager::UnregisterPlugin(CreateInstance);
11541155
}
11551156

1157+
void DynamicLoaderMacOSXDYLD::DebuggerInitialize(
1158+
lldb_private::Debugger &debugger) {
1159+
CreateSettings(debugger);
1160+
}
1161+
11561162
llvm::StringRef DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
11571163
return "Dynamic loader plug-in that watches for shared library loads/unloads "
11581164
"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)