[compiler-rt] f363f9d - [ORC][Runtime] Add `dlupdate` for elf (#110406)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 02:26:04 PST 2024
Author: SahilPatidar
Date: 2024-11-06T21:26:00+11:00
New Revision: f363f9d61eaff7090a19d226ea8786b2987d4fcc
URL: https://github.com/llvm/llvm-project/commit/f363f9d61eaff7090a19d226ea8786b2987d4fcc
DIFF: https://github.com/llvm/llvm-project/commit/f363f9d61eaff7090a19d226ea8786b2987d4fcc.diff
LOG: [ORC][Runtime] Add `dlupdate` for elf (#110406)
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.
Added:
Modified:
compiler-rt/lib/orc/dlfcn_wrapper.cpp
compiler-rt/lib/orc/elfnix_platform.cpp
compiler-rt/lib/orc/elfnix_platform.h
llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
index dec8d1e5bbc31e..3d7da18e3045b9 100644
--- a/compiler-rt/lib/orc/dlfcn_wrapper.cpp
+++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
@@ -42,7 +42,7 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
.release();
}
-#ifdef __APPLE__
+#ifndef _WIN32
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
__orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<int32_t(SPSExecutorAddr)>::handle(
diff --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp
index 24cc6e1ef11778..6473139e931d82 100644
--- a/compiler-rt/lib/orc/elfnix_platform.cpp
+++ b/compiler-rt/lib/orc/elfnix_platform.cpp
@@ -105,6 +105,7 @@ class ELFNixPlatformRuntimeState {
const char *dlerror();
void *dlopen(std::string_view Name, int Mode);
+ int dlupdate(void *DSOHandle);
int dlclose(void *DSOHandle);
void *dlsym(void *DSOHandle, std::string_view Symbol);
@@ -136,6 +137,10 @@ class ELFNixPlatformRuntimeState {
Error dlopenInitialize(std::unique_lock<std::recursive_mutex> &JDStatesLock,
PerJITDylibState &JDS,
ELFNixJITDylibDepInfoMap &DepInfo);
+ Error dlupdateImpl(void *DSOHandle);
+ Error dlupdateFull(std::unique_lock<std::recursive_mutex> &JDStatesLock,
+ PerJITDylibState &JDS);
+
Error dlcloseImpl(void *DSOHandle);
Error dlcloseInitialize(std::unique_lock<std::recursive_mutex> &JDStatesLock,
PerJITDylibState &JDS);
@@ -309,6 +314,15 @@ void *ELFNixPlatformRuntimeState::dlopen(std::string_view Path, int Mode) {
}
}
+int ELFNixPlatformRuntimeState::dlupdate(void *DSOHandle) {
+ if (auto Err = dlupdateImpl(DSOHandle)) {
+ // FIXME: Make dlerror thread safe.
+ DLFcnError = toString(std::move(Err));
+ return -1;
+ }
+ return 0;
+}
+
int ELFNixPlatformRuntimeState::dlclose(void *DSOHandle) {
if (auto Err = dlcloseImpl(DSOHandle)) {
DLFcnError = toString(std::move(Err));
@@ -523,6 +537,50 @@ Error ELFNixPlatformRuntimeState::dlopenInitialize(
return Error::success();
}
+Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle) {
+ std::unique_lock<std::recursive_mutex> Lock(JDStatesMutex);
+
+ // Try to find JITDylib state by name.
+ auto *JDS = getJITDylibStateByHeaderAddr(DSOHandle);
+
+ if (!JDS) {
+ std::ostringstream ErrStream;
+ ErrStream << "No registered JITDylib for " << DSOHandle;
+ return make_error<StringError>(ErrStream.str());
+ }
+
+ if (!JDS->referenced())
+ return make_error<StringError>("dlupdate failed, JITDylib must be open.");
+
+ if (auto Err = dlupdateFull(Lock, *JDS))
+ return Err;
+
+ return Error::success();
+}
+
+Error ELFNixPlatformRuntimeState::dlupdateFull(
+ std::unique_lock<std::recursive_mutex> &JDStatesLock,
+ PerJITDylibState &JDS) {
+ // Call back to the JIT to push the initializers.
+ Expected<ELFNixJITDylibDepInfoMap> DepInfo((ELFNixJITDylibDepInfoMap()));
+ // Unlock so that we can accept the initializer update.
+ JDStatesLock.unlock();
+ if (auto Err = WrapperFunction<SPSExpected<SPSELFNixJITDylibDepInfoMap>(
+ SPSExecutorAddr)>::
+ call(JITDispatch(&__orc_rt_elfnix_push_initializers_tag), DepInfo,
+ ExecutorAddr::fromPtr(JDS.Header)))
+ return Err;
+ JDStatesLock.lock();
+
+ if (!DepInfo)
+ return DepInfo.takeError();
+
+ if (auto Err = runInits(JDStatesLock, JDS))
+ return Err;
+
+ return Error::success();
+}
+
Error ELFNixPlatformRuntimeState::dlcloseImpl(void *DSOHandle) {
std::unique_lock<std::recursive_mutex> Lock(JDStatesMutex);
@@ -765,6 +823,10 @@ void *__orc_rt_elfnix_jit_dlopen(const char *path, int mode) {
return ELFNixPlatformRuntimeState::get().dlopen(path, mode);
}
+int __orc_rt_elfnix_jit_dlupdate(void *dso_handle) {
+ return ELFNixPlatformRuntimeState::get().dlupdate(dso_handle);
+}
+
int __orc_rt_elfnix_jit_dlclose(void *dso_handle) {
return ELFNixPlatformRuntimeState::get().dlclose(dso_handle);
}
diff --git a/compiler-rt/lib/orc/elfnix_platform.h b/compiler-rt/lib/orc/elfnix_platform.h
index 5ecbdf0cb9c86f..0d61cbb948019c 100644
--- a/compiler-rt/lib/orc/elfnix_platform.h
+++ b/compiler-rt/lib/orc/elfnix_platform.h
@@ -25,6 +25,7 @@ ORC_RT_INTERFACE void __orc_rt_elfnix_cxa_finalize(void *dso_handle);
// dlfcn functions.
ORC_RT_INTERFACE const char *__orc_rt_elfnix_jit_dlerror();
ORC_RT_INTERFACE void *__orc_rt_elfnix_jit_dlopen(const char *path, int mode);
+ORC_RT_INTERFACE int __orc_rt_elfnix_jit_dlupdate(void *dso_handle);
ORC_RT_INTERFACE int __orc_rt_elfnix_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE void *__orc_rt_elfnix_jit_dlsym(void *dso_handle,
const char *symbol);
diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
index c8c341668ddd0e..6cea9845a3403b 100644
--- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
@@ -372,6 +372,7 @@ ELFNixPlatform::standardRuntimeUtilityAliases() {
{"__orc_rt_run_program", "__orc_rt_elfnix_run_program"},
{"__orc_rt_jit_dlerror", "__orc_rt_elfnix_jit_dlerror"},
{"__orc_rt_jit_dlopen", "__orc_rt_elfnix_jit_dlopen"},
+ {"__orc_rt_jit_dlupdate", "__orc_rt_elfnix_jit_dlupdate"},
{"__orc_rt_jit_dlclose", "__orc_rt_elfnix_jit_dlclose"},
{"__orc_rt_jit_dlsym", "__orc_rt_elfnix_jit_dlsym"},
{"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}};
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index db39fec12e5fcb..b31f4629565493 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -625,7 +625,8 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
[](const JITDylibSearchOrder &SO) { return SO; });
StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper";
bool dlupdate = false;
- if (ES.getTargetTriple().isOSBinFormatMachO()) {
+ const Triple &TT = ES.getTargetTriple();
+ if (TT.isOSBinFormatMachO() || TT.isOSBinFormatELF()) {
if (InitializedDylib.contains(&JD)) {
WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
dlupdate = true;
@@ -639,12 +640,10 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
int32_t result;
auto E = ES.callSPSWrapper<SPSDLUpdateSig>(WrapperAddr->getAddress(),
result, DSOHandles[&JD]);
- if (E)
- return E;
- else if (result)
+ if (result)
return make_error<StringError>("dlupdate failed",
inconvertibleErrorCode());
- return Error::success();
+ return E;
}
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
DSOHandles[&JD], JD.getName(),
More information about the llvm-commits
mailing list