Skip to content

Commit d5796f8

Browse files
committed
Refactor Bootstrap Logic to Utilize Mach-O Specific Logic
1 parent 1eaae1f commit d5796f8

File tree

3 files changed

+376
-172
lines changed

3 files changed

+376
-172
lines changed

compiler-rt/lib/orc/elfnix_platform.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,13 @@ __orc_rt_elfnix_platform_bootstrap(char *ArgData, size_t ArgSize) {
622622

623623
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
624624
__orc_rt_elfnix_platform_shutdown(char *ArgData, size_t ArgSize) {
625-
ELFNixPlatformRuntimeState::destroy();
626-
return WrapperFunctionResult().release();
625+
return WrapperFunction<SPSError()>::handle(
626+
ArgData, ArgSize,
627+
[]() {
628+
ELFNixPlatformRuntimeState::destroy();
629+
return Error::success();
630+
})
631+
.release();
627632
}
628633

629634
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult

llvm/include/llvm/ExecutionEngine/Orc/ELFNixPlatform.h

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <future>
2323
#include <thread>
24+
#include <unordered_map>
2425
#include <vector>
2526

2627
namespace llvm {
@@ -35,6 +36,34 @@ using ELFNixJITDylibDepInfo = std::vector<ExecutorAddr>;
3536
using ELFNixJITDylibDepInfoMap =
3637
std::vector<std::pair<ExecutorAddr, ELFNixJITDylibDepInfo>>;
3738

39+
struct RuntimeFunction {
40+
RuntimeFunction(SymbolStringPtr Name) : Name(std::move(Name)) {}
41+
SymbolStringPtr Name;
42+
ExecutorAddr Addr;
43+
};
44+
45+
struct FunctionPairKeyHash {
46+
std::size_t
47+
operator()(const std::pair<RuntimeFunction *, RuntimeFunction *> &key) const {
48+
return std::hash<void *>()(key.first->Addr.toPtr<void *>()) ^
49+
std::hash<void *>()(key.second->Addr.toPtr<void *>());
50+
}
51+
};
52+
53+
struct FunctionPairKeyEqual {
54+
std::size_t
55+
operator()(const std::pair<RuntimeFunction *, RuntimeFunction *> &lhs,
56+
const std::pair<RuntimeFunction *, RuntimeFunction *> &rhs) const {
57+
return lhs.first == rhs.first && lhs.second == rhs.second;
58+
}
59+
};
60+
61+
using DeferredRuntimeFnMap = std::unordered_map<
62+
std::pair<RuntimeFunction *, RuntimeFunction *>,
63+
SmallVector<std::pair<shared::WrapperFunctionCall::ArgDataBufferType,
64+
shared::WrapperFunctionCall::ArgDataBufferType>>,
65+
FunctionPairKeyHash, FunctionPairKeyEqual>;
66+
3867
/// Mediates between ELFNix initialization and ExecutionSession state.
3968
class ELFNixPlatform : public Platform {
4069
public:
@@ -110,6 +139,23 @@ class ELFNixPlatform : public Platform {
110139
standardRuntimeUtilityAliases();
111140

112141
private:
142+
// Data needed for bootstrap only.
143+
struct BootstrapInfo {
144+
std::mutex Mutex;
145+
std::condition_variable CV;
146+
size_t ActiveGraphs = 0;
147+
ExecutorAddr ELFNixHeaderAddr;
148+
DeferredRuntimeFnMap DeferredRTFnMap;
149+
150+
void addArgumentsToRTFnMap(
151+
RuntimeFunction *func1, RuntimeFunction *func2,
152+
const shared::WrapperFunctionCall::ArgDataBufferType &arg1,
153+
const shared::WrapperFunctionCall::ArgDataBufferType &arg2) {
154+
auto &argList = DeferredRTFnMap[std::make_pair(func1, func2)];
155+
argList.emplace_back(arg1, arg2);
156+
}
157+
};
158+
113159
// The ELFNixPlatformPlugin scans/modifies LinkGraphs to support ELF
114160
// platform features including initializers, exceptions, TLV, and language
115161
// runtime registration.
@@ -141,15 +187,19 @@ class ELFNixPlatform : public Platform {
141187
using InitSymbolDepMap =
142188
DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
143189

190+
Error bootstrapPipelineStart(jitlink::LinkGraph &G);
191+
Error bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G);
192+
Error bootstrapPipelineEnd(jitlink::LinkGraph &G);
193+
144194
void addInitializerSupportPasses(MaterializationResponsibility &MR,
145195
jitlink::PassConfiguration &Config);
146196

147197
void addDSOHandleSupportPasses(MaterializationResponsibility &MR,
148-
jitlink::PassConfiguration &Config,
149-
bool IsBootstrapping);
198+
jitlink::PassConfiguration &Config);
150199

151200
void addEHAndTLVSupportPasses(MaterializationResponsibility &MR,
152-
jitlink::PassConfiguration &Config);
201+
jitlink::PassConfiguration &Config,
202+
bool IsBootstrapping);
153203

154204
Error preserveInitSections(jitlink::LinkGraph &G,
155205
MaterializationResponsibility &MR);
@@ -188,38 +238,36 @@ class ELFNixPlatform : public Platform {
188238
void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
189239
StringRef SymbolName);
190240

191-
// Records the addresses of runtime symbols used by the platform.
192-
Error bootstrapELFNixRuntime(JITDylib &PlatformJD);
193-
194241
Error registerPerObjectSections(jitlink::LinkGraph &G,
195-
const ELFPerObjectSectionsToRegister &POSR);
242+
const ELFPerObjectSectionsToRegister &POSR,
243+
bool IsBootstrapping);
196244

197245
Expected<uint64_t> createPThreadKey();
198246

199-
struct JDBootstrapState {
200-
JITDylib *JD = nullptr;
201-
std::string JDName;
202-
ExecutorAddr HeaderAddr;
203-
SmallVector<ExecutorAddrRange> Initializers;
204-
};
205-
206-
std::map<JITDylib *, JDBootstrapState> JDBootstrapStates;
207-
208247
ExecutionSession &ES;
248+
JITDylib &PlatformJD;
209249
ObjectLinkingLayer &ObjLinkingLayer;
210250

211251
SymbolStringPtr DSOHandleSymbol;
212-
std::atomic<bool> RuntimeBootstrapped{false};
213-
214-
ExecutorAddr orc_rt_elfnix_platform_bootstrap;
215-
ExecutorAddr orc_rt_elfnix_platform_shutdown;
216-
ExecutorAddr orc_rt_elfnix_register_jitdylib;
217-
ExecutorAddr orc_rt_elfnix_deregister_jitdylib;
218-
ExecutorAddr orc_rt_elfnix_register_init_sections;
219-
ExecutorAddr orc_rt_elfnix_deregister_init_sections;
220-
ExecutorAddr orc_rt_elfnix_register_object_sections;
221-
ExecutorAddr orc_rt_elfnix_deregister_object_sections;
222-
ExecutorAddr orc_rt_elfnix_create_pthread_key;
252+
253+
RuntimeFunction PlatformBootstrap{
254+
ES.intern("__orc_rt_elfnix_platform_bootstrap")};
255+
RuntimeFunction PlatformShutdown{
256+
ES.intern("__orc_rt_elfnix_platform_shutdown")};
257+
RuntimeFunction RegisterJITDylib{
258+
ES.intern("__orc_rt_elfnix_register_jitdylib")};
259+
RuntimeFunction DeregisterJITDylib{
260+
ES.intern("__orc_rt_elfnix_deregister_jitdylib")};
261+
RuntimeFunction RegisterObjectSections{
262+
ES.intern("__orc_rt_elfnix_register_object_sections")};
263+
RuntimeFunction DeregisterObjectSections{
264+
ES.intern("__orc_rt_elfnix_deregister_object_sections")};
265+
RuntimeFunction RegisterInitSections{
266+
ES.intern("__orc_rt_elfnix_register_init_sections")};
267+
RuntimeFunction DeregisterInitSections{
268+
ES.intern("__orc_rt_elfnix_deregister_init_sections")};
269+
RuntimeFunction CreatePThreadKey{
270+
ES.intern("__orc_rt_elfnix_create_pthread_key")};
223271

224272
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
225273

@@ -231,6 +279,8 @@ class ELFNixPlatform : public Platform {
231279
DenseMap<ExecutorAddr, JITDylib *> HandleAddrToJITDylib;
232280
DenseMap<JITDylib *, ExecutorAddr> JITDylibToHandleAddr;
233281
DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
282+
283+
std::atomic<BootstrapInfo *> Bootstrap;
234284
};
235285

236286
namespace shared {

0 commit comments

Comments
 (0)