Files
clang-p2996/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp
Lang Hames 213666f804 [ORC] Move CWrapperFunctionResult out of the detail:: namespace.
This type has been moved up into the llvm::orc::shared namespace.

This type was originally put in the detail:: namespace on the assumption that
few (if any) LLVM source files would need to use it. In practice it has been
needed in many places, and will continue to be needed until/unless
OrcTargetProcess is fully merged into the ORC runtime.
2021-10-30 16:12:45 -07:00

198 lines
6.7 KiB
C++

//===---- ExecutorProcessControl.cpp -- Executor process control APIs -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Process.h"
#define DEBUG_TYPE "orc"
namespace llvm {
namespace orc {
ExecutorProcessControl::MemoryAccess::~MemoryAccess() {}
ExecutorProcessControl::~ExecutorProcessControl() {}
SelfExecutorProcessControl::SelfExecutorProcessControl(
std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
Triple TargetTriple, unsigned PageSize,
std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)
: ExecutorProcessControl(std::move(SSP), std::move(D)) {
OwnedMemMgr = std::move(MemMgr);
if (!OwnedMemMgr)
OwnedMemMgr = std::make_unique<jitlink::InProcessMemoryManager>(
sys::Process::getPageSizeEstimate());
this->TargetTriple = std::move(TargetTriple);
this->PageSize = PageSize;
this->MemMgr = OwnedMemMgr.get();
this->MemAccess = this;
this->JDI = {ExecutorAddr::fromPtr(jitDispatchViaWrapperFunctionManager),
ExecutorAddr::fromPtr(this)};
if (this->TargetTriple.isOSBinFormatMachO())
GlobalManglingPrefix = '_';
}
Expected<std::unique_ptr<SelfExecutorProcessControl>>
SelfExecutorProcessControl::Create(
std::shared_ptr<SymbolStringPool> SSP,
std::unique_ptr<TaskDispatcher> D,
std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
if (!SSP)
SSP = std::make_shared<SymbolStringPool>();
if (!D) {
#if LLVM_ENABLE_THREADS
D = std::make_unique<DynamicThreadPoolTaskDispatcher>();
#else
D = std::make_unique<InPlaceTaskDispatcher>();
#endif
}
auto PageSize = sys::Process::getPageSize();
if (!PageSize)
return PageSize.takeError();
Triple TT(sys::getProcessTriple());
return std::make_unique<SelfExecutorProcessControl>(
std::move(SSP), std::move(D), std::move(TT), *PageSize,
std::move(MemMgr));
}
Expected<tpctypes::DylibHandle>
SelfExecutorProcessControl::loadDylib(const char *DylibPath) {
std::string ErrMsg;
auto Dylib = std::make_unique<sys::DynamicLibrary>(
sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg));
if (!Dylib->isValid())
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
DynamicLibraries.push_back(std::move(Dylib));
return pointerToJITTargetAddress(DynamicLibraries.back().get());
}
Expected<std::vector<tpctypes::LookupResult>>
SelfExecutorProcessControl::lookupSymbols(ArrayRef<LookupRequest> Request) {
std::vector<tpctypes::LookupResult> R;
for (auto &Elem : Request) {
auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
assert(llvm::any_of(DynamicLibraries,
[=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
return DL.get() == Dylib;
}) &&
"Invalid handle");
R.push_back(std::vector<JITTargetAddress>());
for (auto &KV : Elem.Symbols) {
auto &Sym = KV.first;
std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
(*Sym).size() - !!GlobalManglingPrefix);
void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str());
if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
// FIXME: Collect all failing symbols before erroring out.
SymbolNameVector MissingSymbols;
MissingSymbols.push_back(Sym);
return make_error<SymbolsNotFound>(SSP, std::move(MissingSymbols));
}
R.back().push_back(pointerToJITTargetAddress(Addr));
}
}
return R;
}
Expected<int32_t>
SelfExecutorProcessControl::runAsMain(ExecutorAddr MainFnAddr,
ArrayRef<std::string> Args) {
using MainTy = int (*)(int, char *[]);
return orc::runAsMain(MainFnAddr.toPtr<MainTy>(), Args);
}
void SelfExecutorProcessControl::callWrapperAsync(ExecutorAddr WrapperFnAddr,
IncomingWFRHandler SendResult,
ArrayRef<char> ArgBuffer) {
using WrapperFnTy =
shared::CWrapperFunctionResult (*)(const char *Data, size_t Size);
auto *WrapperFn = WrapperFnAddr.toPtr<WrapperFnTy>();
SendResult(WrapperFn(ArgBuffer.data(), ArgBuffer.size()));
}
Error SelfExecutorProcessControl::disconnect() {
D->shutdown();
return Error::success();
}
void SelfExecutorProcessControl::writeUInt8sAsync(
ArrayRef<tpctypes::UInt8Write> Ws, WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*W.Addr.toPtr<uint8_t *>() = W.Value;
OnWriteComplete(Error::success());
}
void SelfExecutorProcessControl::writeUInt16sAsync(
ArrayRef<tpctypes::UInt16Write> Ws, WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*W.Addr.toPtr<uint16_t *>() = W.Value;
OnWriteComplete(Error::success());
}
void SelfExecutorProcessControl::writeUInt32sAsync(
ArrayRef<tpctypes::UInt32Write> Ws, WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*W.Addr.toPtr<uint32_t *>() = W.Value;
OnWriteComplete(Error::success());
}
void SelfExecutorProcessControl::writeUInt64sAsync(
ArrayRef<tpctypes::UInt64Write> Ws, WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*W.Addr.toPtr<uint64_t *>() = W.Value;
OnWriteComplete(Error::success());
}
void SelfExecutorProcessControl::writeBuffersAsync(
ArrayRef<tpctypes::BufferWrite> Ws, WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
memcpy(W.Addr.toPtr<char *>(), W.Buffer.data(), W.Buffer.size());
OnWriteComplete(Error::success());
}
shared::CWrapperFunctionResult
SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
void *Ctx, const void *FnTag, const char *Data, size_t Size) {
LLVM_DEBUG({
dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size
<< " byte payload.\n";
});
std::promise<shared::WrapperFunctionResult> ResultP;
auto ResultF = ResultP.get_future();
static_cast<SelfExecutorProcessControl *>(Ctx)
->getExecutionSession()
.runJITDispatchHandler(
[ResultP = std::move(ResultP)](
shared::WrapperFunctionResult Result) mutable {
ResultP.set_value(std::move(Result));
},
pointerToJITTargetAddress(FnTag), {Data, Size});
return ResultF.get().release();
}
} // end namespace orc
} // end namespace llvm