Skip to content

Commit bb36630

Browse files
authored
[ORC][Runtime] Add dlupdate for coff (#115448)
With the help of @lhames, This pull request introduces the dlupdate function in the ORC runtime. dlupdate enables incremental execution of new initializers introduced in the REPL environment. Unlike traditional dlopen, which manages initializers, code mapping, and library reference counts, dlupdate focuses exclusively on running new initializers.
1 parent 5260920 commit bb36630

File tree

5 files changed

+79
-10
lines changed

5 files changed

+79
-10
lines changed

compiler-rt/lib/orc/coff_platform.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class COFFPlatformRuntimeState {
110110

111111
const char *dlerror();
112112
void *dlopen(std::string_view Name, int Mode);
113+
int dlupdate(void *DSOHandle);
113114
int dlclose(void *Header);
114115
void *dlsym(void *Header, std::string_view Symbol);
115116

@@ -141,6 +142,10 @@ class COFFPlatformRuntimeState {
141142
Error dlopenFull(JITDylibState &JDS);
142143
Error dlopenInitialize(JITDylibState &JDS, COFFJITDylibDepInfoMap &DepInfo);
143144

145+
Error dlupdateImpl(void *DSOHandle);
146+
Error dlupdateFull(JITDylibState &JDS);
147+
Error dlupdateInitialize(JITDylibState &JDS);
148+
144149
Error dlcloseImpl(void *DSOHandle);
145150
Error dlcloseDeinitialize(JITDylibState &JDS);
146151

@@ -265,6 +270,20 @@ void *COFFPlatformRuntimeState::dlopen(std::string_view Path, int Mode) {
265270
}
266271
}
267272

273+
int COFFPlatformRuntimeState::dlupdate(void *DSOHandle) {
274+
ORC_RT_DEBUG({
275+
std::string S;
276+
printdbg("COFFPlatform::dlupdate(%p) (%s)\n", DSOHandle, S.c_str());
277+
});
278+
std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex);
279+
if (auto Err = dlupdateImpl(DSOHandle)) {
280+
// FIXME: Make dlerror thread safe.
281+
DLFcnError = toString(std::move(Err));
282+
return -1;
283+
}
284+
return 0;
285+
}
286+
268287
int COFFPlatformRuntimeState::dlclose(void *DSOHandle) {
269288
ORC_RT_DEBUG({
270289
auto *JDS = getJITDylibStateByHeader(DSOHandle);
@@ -390,6 +409,55 @@ Error COFFPlatformRuntimeState::dlopenInitialize(
390409
return Error::success();
391410
}
392411

412+
Error COFFPlatformRuntimeState::dlupdateImpl(void *DSOHandle) {
413+
// Try to find JITDylib state by header.
414+
auto *JDS = getJITDylibStateByHeader(DSOHandle);
415+
416+
if (!JDS) {
417+
std::ostringstream ErrStream;
418+
ErrStream << "No registered JITDylib for " << DSOHandle;
419+
return make_error<StringError>(ErrStream.str());
420+
}
421+
422+
if (!JDS->referenced())
423+
return make_error<StringError>("dlupdate failed, JITDylib must be open.");
424+
425+
if (auto Err = dlupdateFull(*JDS))
426+
return Err;
427+
428+
return Error::success();
429+
}
430+
431+
Error COFFPlatformRuntimeState::dlupdateFull(JITDylibState &JDS) {
432+
// Call back to the JIT to push the initializers.
433+
Expected<COFFJITDylibDepInfoMap> DepInfoMap((COFFJITDylibDepInfoMap()));
434+
if (auto Err = WrapperFunction<SPSExpected<SPSCOFFJITDylibDepInfoMap>(
435+
SPSExecutorAddr)>::
436+
call(JITDispatch(&__orc_rt_coff_push_initializers_tag), DepInfoMap,
437+
ExecutorAddr::fromPtr(JDS.Header)))
438+
return Err;
439+
if (!DepInfoMap)
440+
return DepInfoMap.takeError();
441+
442+
if (auto Err = dlupdateInitialize(JDS))
443+
return Err;
444+
445+
return Error::success();
446+
}
447+
448+
Error COFFPlatformRuntimeState::dlupdateInitialize(JITDylibState &JDS) {
449+
ORC_RT_DEBUG({
450+
printdbg("COFFPlatformRuntimeState::dlupdateInitialize(\"%s\")\n",
451+
JDS.Name.c_str());
452+
});
453+
454+
// Run static initializers.
455+
JDS.CInitSection.RunAllNewAndFlush();
456+
JDS.CXXInitSection.RunAllNewAndFlush();
457+
458+
return Error::success();
459+
}
460+
393461
Error COFFPlatformRuntimeState::dlcloseImpl(void *DSOHandle) {
394462
// Try to find JITDylib state by header.
395463
auto *JDS = getJITDylibStateByHeader(DSOHandle);
@@ -667,6 +735,10 @@ void *__orc_rt_coff_jit_dlopen(const char *path, int mode) {
667735
return COFFPlatformRuntimeState::get().dlopen(path, mode);
668736
}
669737

738+
int __orc_rt_coff_jit_dlupdate(void *dso_handle) {
739+
return COFFPlatformRuntimeState::get().dlupdate(dso_handle);
740+
}
741+
670742
int __orc_rt_coff_jit_dlclose(void *header) {
671743
return COFFPlatformRuntimeState::get().dlclose(header);
672744
}

compiler-rt/lib/orc/coff_platform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// dlfcn functions.
2020
ORC_RT_INTERFACE const char *__orc_rt_coff_jit_dlerror();
2121
ORC_RT_INTERFACE void *__orc_rt_coff_jit_dlopen(const char *path, int mode);
22+
ORC_RT_INTERFACE int __orc_rt_coff_jit_dlupdate(void *dso_handle);
2223
ORC_RT_INTERFACE int __orc_rt_coff_jit_dlclose(void *header);
2324
ORC_RT_INTERFACE void *__orc_rt_coff_jit_dlsym(void *header,
2425
const char *symbol);

compiler-rt/lib/orc/dlfcn_wrapper.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
4242
.release();
4343
}
4444

45-
#ifndef _WIN32
4645
ORC_RT_INTERFACE orc_rt_WrapperFunctionResult
4746
__orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
4847
return WrapperFunction<int32_t(SPSExecutorAddr)>::handle(
@@ -52,7 +51,6 @@ __orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
5251
})
5352
.release();
5453
}
55-
#endif
5654

5755
ORC_RT_INTERFACE orc_rt_WrapperFunctionResult
5856
__orc_rt_jit_dlclose_wrapper(const char *ArgData, size_t ArgSize) {

llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ COFFPlatform::standardRuntimeUtilityAliases() {
361361
{"__orc_rt_run_program", "__orc_rt_coff_run_program"},
362362
{"__orc_rt_jit_dlerror", "__orc_rt_coff_jit_dlerror"},
363363
{"__orc_rt_jit_dlopen", "__orc_rt_coff_jit_dlopen"},
364+
{"__orc_rt_jit_dlupdate", "__orc_rt_coff_jit_dlupdate"},
364365
{"__orc_rt_jit_dlclose", "__orc_rt_coff_jit_dlclose"},
365366
{"__orc_rt_jit_dlsym", "__orc_rt_coff_jit_dlsym"},
366367
{"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}};

llvm/lib/ExecutionEngine/Orc/LLJIT.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -617,14 +617,11 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
617617
[](const JITDylibSearchOrder &SO) { return SO; });
618618
StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper";
619619
bool dlupdate = false;
620-
const Triple &TT = ES.getTargetTriple();
621-
if (TT.isOSBinFormatMachO() || TT.isOSBinFormatELF()) {
622-
if (InitializedDylib.contains(&JD)) {
623-
WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
624-
dlupdate = true;
625-
} else
626-
InitializedDylib.insert(&JD);
627-
}
620+
if (InitializedDylib.contains(&JD)) {
621+
WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
622+
dlupdate = true;
623+
} else
624+
InitializedDylib.insert(&JD);
628625

629626
if (auto WrapperAddr =
630627
ES.lookup(MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {

0 commit comments

Comments
 (0)