You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
@ -1,409 +0,0 @@
|
||||
//===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- C++ -*---===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||
#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||
|
||||
#include "llvm-c/OrcBindings.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class OrcCBindingsStack;
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
|
||||
LLVMSharedModuleRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
class GenericHandle {
|
||||
public:
|
||||
virtual ~GenericHandle() = default;
|
||||
|
||||
virtual JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) = 0;
|
||||
virtual Error removeModule() = 0;
|
||||
};
|
||||
|
||||
template <typename LayerT> class GenericHandleImpl : public GenericHandle {
|
||||
public:
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
|
||||
JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
Error removeModule() override { return Layer.removeModule(Handle); }
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
typename LayerT::ModuleHandleT Handle;
|
||||
};
|
||||
|
||||
template <>
|
||||
class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
|
||||
: public GenericHandle {
|
||||
private:
|
||||
using LayerT = orc::RTDyldObjectLinkingLayer;
|
||||
public:
|
||||
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
|
||||
JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
Error removeModule() override { return Layer.removeObject(Handle); }
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
typename LayerT::ObjHandleT Handle;
|
||||
};
|
||||
|
||||
|
||||
template <typename LayerT, typename HandleT>
|
||||
std::unique_ptr<GenericHandleImpl<LayerT>>
|
||||
createGenericHandle(LayerT &Layer, HandleT Handle) {
|
||||
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
|
||||
std::move(Handle));
|
||||
}
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
class OrcCBindingsStack {
|
||||
public:
|
||||
|
||||
using CompileCallbackMgr = orc::JITCompileCallbackManager;
|
||||
using ObjLayerT = orc::RTDyldObjectLinkingLayer;
|
||||
using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
|
||||
using CODLayerT =
|
||||
orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
|
||||
|
||||
using CallbackManagerBuilder =
|
||||
std::function<std::unique_ptr<CompileCallbackMgr>()>;
|
||||
|
||||
using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
|
||||
|
||||
private:
|
||||
|
||||
using OwningObject = object::OwningBinary<object::ObjectFile>;
|
||||
|
||||
public:
|
||||
using ModuleHandleT = unsigned;
|
||||
|
||||
OrcCBindingsStack(TargetMachine &TM,
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr,
|
||||
IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
|
||||
: DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
|
||||
CCMgr(std::move(CCMgr)),
|
||||
ObjectLayer(
|
||||
[]() {
|
||||
return std::make_shared<SectionMemoryManager>();
|
||||
}),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
|
||||
CODLayer(CompileLayer,
|
||||
[](Function &F) { return std::set<Function *>({&F}); },
|
||||
*this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
|
||||
CXXRuntimeOverrides(
|
||||
[this](const std::string &S) { return mangle(S); }) {}
|
||||
|
||||
LLVMOrcErrorCode shutdown() {
|
||||
// Run any destructors registered with __cxa_atexit.
|
||||
CXXRuntimeOverrides.runDestructors();
|
||||
// Run any IR destructors.
|
||||
for (auto &DtorRunner : IRStaticDestructorRunners)
|
||||
if (auto Err = DtorRunner.runViaLayer(*this))
|
||||
return mapError(std::move(Err));
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
std::string mangle(StringRef Name) {
|
||||
std::string MangledName;
|
||||
{
|
||||
raw_string_ostream MangledNameStream(MangledName);
|
||||
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
|
||||
}
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
template <typename PtrTy>
|
||||
static PtrTy fromTargetAddress(JITTargetAddress Addr) {
|
||||
return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
|
||||
}
|
||||
|
||||
|
||||
LLVMOrcErrorCode
|
||||
createLazyCompileCallback(JITTargetAddress &RetAddr,
|
||||
LLVMOrcLazyCompileCallbackFn Callback,
|
||||
void *CallbackCtx) {
|
||||
if (auto CCInfoOrErr = CCMgr->getCompileCallback()) {
|
||||
auto &CCInfo = *CCInfoOrErr;
|
||||
CCInfo.setCompileAction([=]() -> JITTargetAddress {
|
||||
return Callback(wrap(this), CallbackCtx);
|
||||
});
|
||||
RetAddr = CCInfo.getAddress();
|
||||
return LLVMOrcErrSuccess;
|
||||
} else
|
||||
return mapError(CCInfoOrErr.takeError());
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode createIndirectStub(StringRef StubName,
|
||||
JITTargetAddress Addr) {
|
||||
return mapError(
|
||||
IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode setIndirectStubPointer(StringRef Name,
|
||||
JITTargetAddress Addr) {
|
||||
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
|
||||
}
|
||||
|
||||
std::shared_ptr<JITSymbolResolver>
|
||||
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return orc::createLambdaResolver(
|
||||
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name)
|
||||
-> JITSymbol {
|
||||
// Search order:
|
||||
// 1. JIT'd symbols.
|
||||
// 2. Runtime overrides.
|
||||
// 3. External resolver (if present).
|
||||
|
||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return Sym.takeError();
|
||||
|
||||
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
|
||||
return Sym;
|
||||
|
||||
if (ExternalResolver)
|
||||
return JITSymbol(
|
||||
ExternalResolver(Name.c_str(), ExternalResolverCtx),
|
||||
JITSymbolFlags::Exported);
|
||||
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) -> JITSymbol {
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename LayerT>
|
||||
LLVMOrcErrorCode
|
||||
addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
|
||||
std::shared_ptr<Module> M,
|
||||
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
|
||||
// Attach a data-layout if one isn't already present.
|
||||
if (M->getDataLayout().isDefault())
|
||||
M->setDataLayout(DL);
|
||||
|
||||
// Record the static constructors and destructors. We have to do this before
|
||||
// we hand over ownership of the module to the JIT.
|
||||
std::vector<std::string> CtorNames, DtorNames;
|
||||
for (auto Ctor : orc::getConstructors(*M))
|
||||
CtorNames.push_back(mangle(Ctor.Func->getName()));
|
||||
for (auto Dtor : orc::getDestructors(*M))
|
||||
DtorNames.push_back(mangle(Dtor.Func->getName()));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
// Add the module to the JIT.
|
||||
ModuleHandleT H;
|
||||
if (auto LHOrErr = Layer.addModule(std::move(M), std::move(Resolver)))
|
||||
H = createHandle(Layer, *LHOrErr);
|
||||
else
|
||||
return mapError(LHOrErr.takeError());
|
||||
|
||||
// Run the static constructors, and save the static destructor runner for
|
||||
// execution when the JIT is torn down.
|
||||
orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
|
||||
if (auto Err = CtorRunner.runViaLayer(*this))
|
||||
return mapError(std::move(Err));
|
||||
|
||||
IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
|
||||
|
||||
RetHandle = H;
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode addIRModuleEager(ModuleHandleT &RetHandle,
|
||||
std::shared_ptr<Module> M,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(RetHandle, CompileLayer, std::move(M),
|
||||
llvm::make_unique<SectionMemoryManager>(),
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode addIRModuleLazy(ModuleHandleT &RetHandle,
|
||||
std::shared_ptr<Module> M,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(RetHandle, CODLayer, std::move(M),
|
||||
llvm::make_unique<SectionMemoryManager>(),
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode removeModule(ModuleHandleT H) {
|
||||
if (auto Err = GenericHandles[H]->removeModule())
|
||||
return mapError(std::move(Err));
|
||||
GenericHandles[H] = nullptr;
|
||||
FreeHandleIndexes.push_back(H);
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
|
||||
std::unique_ptr<MemoryBuffer> ObjBuffer,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
if (auto ObjOrErr =
|
||||
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())) {
|
||||
auto &Obj = *ObjOrErr;
|
||||
auto OwningObj =
|
||||
std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
ModuleHandleT H;
|
||||
if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
|
||||
std::move(Resolver)))
|
||||
H = createHandle(ObjectLayer, *HOrErr);
|
||||
else
|
||||
return mapError(HOrErr.takeError());
|
||||
|
||||
RetHandle = H;
|
||||
|
||||
return LLVMOrcErrSuccess;
|
||||
} else
|
||||
return mapError(ObjOrErr.takeError());
|
||||
}
|
||||
|
||||
JITSymbol findSymbol(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
|
||||
return Sym;
|
||||
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr,
|
||||
const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
RetAddr = 0;
|
||||
if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) {
|
||||
// Successful lookup, non-null symbol:
|
||||
if (auto AddrOrErr = Sym.getAddress()) {
|
||||
RetAddr = *AddrOrErr;
|
||||
return LLVMOrcErrSuccess;
|
||||
} else
|
||||
return mapError(AddrOrErr.takeError());
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
// Lookup failure - report error.
|
||||
return mapError(std::move(Err));
|
||||
}
|
||||
// Otherwise we had a successful lookup but got a null result. We already
|
||||
// set RetAddr to '0' above, so just return success.
|
||||
return LLVMOrcErrSuccess;
|
||||
}
|
||||
|
||||
const std::string &getErrorMessage() const { return ErrMsg; }
|
||||
|
||||
private:
|
||||
template <typename LayerT, typename HandleT>
|
||||
unsigned createHandle(LayerT &Layer, HandleT Handle) {
|
||||
unsigned NewHandle;
|
||||
if (!FreeHandleIndexes.empty()) {
|
||||
NewHandle = FreeHandleIndexes.back();
|
||||
FreeHandleIndexes.pop_back();
|
||||
GenericHandles[NewHandle] =
|
||||
detail::createGenericHandle(Layer, std::move(Handle));
|
||||
return NewHandle;
|
||||
} else {
|
||||
NewHandle = GenericHandles.size();
|
||||
GenericHandles.push_back(
|
||||
detail::createGenericHandle(Layer, std::move(Handle)));
|
||||
}
|
||||
return NewHandle;
|
||||
}
|
||||
|
||||
LLVMOrcErrorCode mapError(Error Err) {
|
||||
LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
|
||||
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
|
||||
// Handler of last resort.
|
||||
Result = LLVMOrcErrGeneric;
|
||||
ErrMsg = "";
|
||||
raw_string_ostream ErrStream(ErrMsg);
|
||||
EIB.log(ErrStream);
|
||||
});
|
||||
return Result;
|
||||
}
|
||||
|
||||
DataLayout DL;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
||||
std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
|
||||
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr;
|
||||
ObjLayerT ObjectLayer;
|
||||
CompileLayerT CompileLayer;
|
||||
CODLayerT CODLayer;
|
||||
|
||||
std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
|
||||
std::vector<unsigned> FreeHandleIndexes;
|
||||
|
||||
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
|
||||
std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
|
||||
std::string ErrMsg;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
Reference in New Issue
Block a user