21
21
22
22
#include < future>
23
23
#include < thread>
24
+ #include < unordered_map>
24
25
#include < vector>
25
26
26
27
namespace llvm {
@@ -35,6 +36,34 @@ using ELFNixJITDylibDepInfo = std::vector<ExecutorAddr>;
35
36
using ELFNixJITDylibDepInfoMap =
36
37
std::vector<std::pair<ExecutorAddr, ELFNixJITDylibDepInfo>>;
37
38
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
+
38
67
// / Mediates between ELFNix initialization and ExecutionSession state.
39
68
class ELFNixPlatform : public Platform {
40
69
public:
@@ -110,6 +139,23 @@ class ELFNixPlatform : public Platform {
110
139
standardRuntimeUtilityAliases ();
111
140
112
141
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
+
113
159
// The ELFNixPlatformPlugin scans/modifies LinkGraphs to support ELF
114
160
// platform features including initializers, exceptions, TLV, and language
115
161
// runtime registration.
@@ -141,15 +187,19 @@ class ELFNixPlatform : public Platform {
141
187
using InitSymbolDepMap =
142
188
DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
143
189
190
+ Error bootstrapPipelineStart (jitlink::LinkGraph &G);
191
+ Error bootstrapPipelineRecordRuntimeFunctions (jitlink::LinkGraph &G);
192
+ Error bootstrapPipelineEnd (jitlink::LinkGraph &G);
193
+
144
194
void addInitializerSupportPasses (MaterializationResponsibility &MR,
145
195
jitlink::PassConfiguration &Config);
146
196
147
197
void addDSOHandleSupportPasses (MaterializationResponsibility &MR,
148
- jitlink::PassConfiguration &Config,
149
- bool IsBootstrapping);
198
+ jitlink::PassConfiguration &Config);
150
199
151
200
void addEHAndTLVSupportPasses (MaterializationResponsibility &MR,
152
- jitlink::PassConfiguration &Config);
201
+ jitlink::PassConfiguration &Config,
202
+ bool IsBootstrapping);
153
203
154
204
Error preserveInitSections (jitlink::LinkGraph &G,
155
205
MaterializationResponsibility &MR);
@@ -188,38 +238,36 @@ class ELFNixPlatform : public Platform {
188
238
void rt_lookupSymbol (SendSymbolAddressFn SendResult, ExecutorAddr Handle,
189
239
StringRef SymbolName);
190
240
191
- // Records the addresses of runtime symbols used by the platform.
192
- Error bootstrapELFNixRuntime (JITDylib &PlatformJD);
193
-
194
241
Error registerPerObjectSections (jitlink::LinkGraph &G,
195
- const ELFPerObjectSectionsToRegister &POSR);
242
+ const ELFPerObjectSectionsToRegister &POSR,
243
+ bool IsBootstrapping);
196
244
197
245
Expected<uint64_t > createPThreadKey ();
198
246
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
-
208
247
ExecutionSession &ES;
248
+ JITDylib &PlatformJD;
209
249
ObjectLinkingLayer &ObjLinkingLayer;
210
250
211
251
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" )};
223
271
224
272
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
225
273
@@ -231,6 +279,8 @@ class ELFNixPlatform : public Platform {
231
279
DenseMap<ExecutorAddr, JITDylib *> HandleAddrToJITDylib;
232
280
DenseMap<JITDylib *, ExecutorAddr> JITDylibToHandleAddr;
233
281
DenseMap<JITDylib *, uint64_t > JITDylibToPThreadKey;
282
+
283
+ std::atomic<BootstrapInfo *> Bootstrap;
234
284
};
235
285
236
286
namespace shared {
0 commit comments