summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/Orc/OrcCBindingsStack.h')
-rw-r--r--lib/ExecutionEngine/Orc/OrcCBindingsStack.h382
1 files changed, 243 insertions, 139 deletions
diff --git a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
index 405970e063d8..b9f8a370d2f0 100644
--- a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
+++ b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
@@ -33,6 +34,7 @@
#include <algorithm>
#include <cstdint>
#include <functional>
+#include <map>
#include <memory>
#include <set>
#include <string>
@@ -42,68 +44,61 @@ 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 {
+// FIXME: Kill this off once the Layer concept becomes an interface.
+class GenericLayer {
+public:
+ virtual ~GenericLayer() = default;
- class GenericHandle {
- public:
- virtual ~GenericHandle() = default;
-
- virtual JITSymbol findSymbolIn(const std::string &Name,
- bool ExportedSymbolsOnly) = 0;
- virtual Error removeModule() = 0;
+ virtual JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
+ bool ExportedSymbolsOnly) = 0;
+ virtual Error removeModule(orc::VModuleKey K) = 0;
};
- template <typename LayerT> class GenericHandleImpl : public GenericHandle {
+ template <typename LayerT> class GenericLayerImpl : public GenericLayer {
public:
- GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle)
- : Layer(Layer), Handle(std::move(Handle)) {}
+ GenericLayerImpl(LayerT &Layer) : Layer(Layer) {}
- JITSymbol findSymbolIn(const std::string &Name,
+ JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) override {
- return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
+ return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly);
}
- Error removeModule() override { return Layer.removeModule(Handle); }
+ Error removeModule(orc::VModuleKey K) override {
+ return Layer.removeModule(K);
+ }
private:
LayerT &Layer;
- typename LayerT::ModuleHandleT Handle;
};
template <>
- class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
- : public GenericHandle {
+ class GenericLayerImpl<orc::RTDyldObjectLinkingLayer> : public GenericLayer {
private:
using LayerT = orc::RTDyldObjectLinkingLayer;
public:
+ GenericLayerImpl(LayerT &Layer) : Layer(Layer) {}
- GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
- : Layer(Layer), Handle(std::move(Handle)) {}
-
- JITSymbol findSymbolIn(const std::string &Name,
+ JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) override {
- return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
+ return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly);
}
- Error removeModule() override { return Layer.removeObject(Handle); }
+ Error removeModule(orc::VModuleKey K) override {
+ return Layer.removeObject(K);
+ }
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));
+ template <typename LayerT>
+ std::unique_ptr<GenericLayerImpl<LayerT>> createGenericLayer(LayerT &Layer) {
+ return llvm::make_unique<GenericLayerImpl<LayerT>>(Layer);
}
} // end namespace detail
@@ -126,20 +121,123 @@ private:
using OwningObject = object::OwningBinary<object::ObjectFile>;
-public:
- using ModuleHandleT = unsigned;
+ class CBindingsResolver : public orc::SymbolResolver {
+ public:
+ CBindingsResolver(OrcCBindingsStack &Stack,
+ LLVMOrcSymbolResolverFn ExternalResolver,
+ void *ExternalResolverCtx)
+ : Stack(Stack), ExternalResolver(std::move(ExternalResolver)),
+ ExternalResolverCtx(std::move(ExternalResolverCtx)) {}
+
+ orc::SymbolFlagsMap
+ lookupFlags(const orc::SymbolNameSet &Symbols) override {
+ orc::SymbolFlagsMap SymbolFlags;
+
+ for (auto &S : Symbols) {
+ if (auto Sym = findSymbol(*S))
+ SymbolFlags[S] = Sym.getFlags();
+ else if (auto Err = Sym.takeError()) {
+ Stack.reportError(std::move(Err));
+ return orc::SymbolFlagsMap();
+ }
+ }
+
+ return SymbolFlags;
+ }
+
+ orc::SymbolNameSet
+ lookup(std::shared_ptr<orc::AsynchronousSymbolQuery> Query,
+ orc::SymbolNameSet Symbols) override {
+ orc::SymbolNameSet UnresolvedSymbols;
+
+ for (auto &S : Symbols) {
+ if (auto Sym = findSymbol(*S)) {
+ if (auto Addr = Sym.getAddress()) {
+ Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
+ Query->notifySymbolReady();
+ } else {
+ Stack.ES.legacyFailQuery(*Query, Addr.takeError());
+ return orc::SymbolNameSet();
+ }
+ } else if (auto Err = Sym.takeError()) {
+ Stack.ES.legacyFailQuery(*Query, std::move(Err));
+ return orc::SymbolNameSet();
+ } else
+ UnresolvedSymbols.insert(S);
+ }
+
+ if (Query->isFullyResolved())
+ Query->handleFullyResolved();
+
+ if (Query->isFullyReady())
+ Query->handleFullyReady();
+
+ return UnresolvedSymbols;
+ }
+
+ private:
+ JITSymbol findSymbol(const std::string &Name) {
+ // Search order:
+ // 1. JIT'd symbols.
+ // 2. Runtime overrides.
+ // 3. External resolver (if present).
+
+ if (auto Sym = Stack.CODLayer.findSymbol(Name, true))
+ return Sym;
+ else if (auto Err = Sym.takeError())
+ return Sym.takeError();
+ if (auto Sym = Stack.CXXRuntimeOverrides.searchOverrides(Name))
+ return Sym;
+
+ if (ExternalResolver)
+ return JITSymbol(ExternalResolver(Name.c_str(), ExternalResolverCtx),
+ JITSymbolFlags::Exported);
+
+ return JITSymbol(nullptr);
+ }
+
+ OrcCBindingsStack &Stack;
+ LLVMOrcSymbolResolverFn ExternalResolver;
+ void *ExternalResolverCtx = nullptr;
+ };
+
+public:
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>();
- }),
+ : CCMgr(createLocalCompileCallbackManager(TM.getTargetTriple(), ES, 0)),
+ DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
+ ObjectLayer(ES,
+ [this](orc::VModuleKey K) {
+ auto ResolverI = Resolvers.find(K);
+ assert(ResolverI != Resolvers.end() &&
+ "No resolver for module K");
+ auto Resolver = std::move(ResolverI->second);
+ Resolvers.erase(ResolverI);
+ return ObjLayerT::Resources{
+ std::make_shared<SectionMemoryManager>(), Resolver};
+ },
+ nullptr,
+ [this](orc::VModuleKey K, const object::ObjectFile &Obj,
+ const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) {
+ this->notifyFinalized(K, Obj, LoadedObjInfo);
+ },
+ [this](orc::VModuleKey K, const object::ObjectFile &Obj) {
+ this->notifyFreed(K, Obj);
+ }),
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
- CODLayer(CompileLayer,
+ CODLayer(ES, CompileLayer,
+ [this](orc::VModuleKey K) {
+ auto ResolverI = Resolvers.find(K);
+ assert(ResolverI != Resolvers.end() &&
+ "No resolver for module K");
+ return ResolverI->second;
+ },
+ [this](orc::VModuleKey K,
+ std::shared_ptr<orc::SymbolResolver> Resolver) {
+ assert(!Resolvers.count(K) && "Resolver already present");
+ Resolvers[K] = std::move(Resolver);
+ },
[](Function &F) { return std::set<Function *>({&F}); },
*this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
CXXRuntimeOverrides(
@@ -174,15 +272,15 @@ public:
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();
+ auto WrappedCallback = [=]() -> JITTargetAddress {
+ return Callback(wrap(this), CallbackCtx);
+ };
+
+ if (auto CCAddr = CCMgr->getCompileCallback(std::move(WrappedCallback))) {
+ RetAddr = *CCAddr;
return LLVMOrcErrSuccess;
} else
- return mapError(CCInfoOrErr.takeError());
+ return mapError(CCAddr.takeError());
}
LLVMOrcErrorCode createIndirectStub(StringRef StubName,
@@ -195,42 +293,9 @@ public:
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,
+ addIRModule(orc::VModuleKey &RetKey, LayerT &Layer, std::unique_ptr<Module> M,
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
@@ -247,79 +312,73 @@ public:
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());
+ RetKey = ES.allocateVModule();
+ Resolvers[RetKey] = std::make_shared<CBindingsResolver>(
+ *this, ExternalResolver, ExternalResolverCtx);
+ if (auto Err = Layer.addModule(RetKey, std::move(M)))
+ return mapError(std::move(Err));
+
+ KeyLayers[RetKey] = detail::createGenericLayer(Layer);
// 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);
+ orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames),
+ RetKey);
if (auto Err = CtorRunner.runViaLayer(*this))
return mapError(std::move(Err));
- IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
+ IRStaticDestructorRunners.emplace_back(std::move(DtorNames), RetKey);
- RetHandle = H;
return LLVMOrcErrSuccess;
}
- LLVMOrcErrorCode addIRModuleEager(ModuleHandleT &RetHandle,
- std::shared_ptr<Module> M,
+ LLVMOrcErrorCode addIRModuleEager(orc::VModuleKey &RetKey,
+ std::unique_ptr<Module> M,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
- return addIRModule(RetHandle, CompileLayer, std::move(M),
+ return addIRModule(RetKey, CompileLayer, std::move(M),
llvm::make_unique<SectionMemoryManager>(),
std::move(ExternalResolver), ExternalResolverCtx);
}
- LLVMOrcErrorCode addIRModuleLazy(ModuleHandleT &RetHandle,
- std::shared_ptr<Module> M,
+ LLVMOrcErrorCode addIRModuleLazy(orc::VModuleKey &RetKey,
+ std::unique_ptr<Module> M,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
- return addIRModule(RetHandle, CODLayer, std::move(M),
+ return addIRModule(RetKey, CODLayer, std::move(M),
llvm::make_unique<SectionMemoryManager>(),
std::move(ExternalResolver), ExternalResolverCtx);
}
- LLVMOrcErrorCode removeModule(ModuleHandleT H) {
- if (auto Err = GenericHandles[H]->removeModule())
+ LLVMOrcErrorCode removeModule(orc::VModuleKey K) {
+ // FIXME: Should error release the module key?
+ if (auto Err = KeyLayers[K]->removeModule(K))
return mapError(std::move(Err));
- GenericHandles[H] = nullptr;
- FreeHandleIndexes.push_back(H);
+ ES.releaseVModule(K);
+ KeyLayers.erase(K);
return LLVMOrcErrSuccess;
}
- LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
+ LLVMOrcErrorCode addObject(orc::VModuleKey &RetKey,
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));
+ if (auto Obj = object::ObjectFile::createObjectFile(
+ ObjBuffer->getMemBufferRef())) {
- // Create the resolver.
- auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
+ RetKey = ES.allocateVModule();
+ Resolvers[RetKey] = std::make_shared<CBindingsResolver>(
+ *this, ExternalResolver, ExternalResolverCtx);
- ModuleHandleT H;
- if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
- std::move(Resolver)))
- H = createHandle(ObjectLayer, *HOrErr);
- else
- return mapError(HOrErr.takeError());
+ if (auto Err = ObjectLayer.addObject(RetKey, std::move(ObjBuffer)))
+ return mapError(std::move(Err));
- RetHandle = H;
+ KeyLayers[RetKey] = detail::createGenericLayer(ObjectLayer);
return LLVMOrcErrSuccess;
} else
- return mapError(ObjOrErr.takeError());
+ return mapError(Obj.takeError());
}
JITSymbol findSymbol(const std::string &Name,
@@ -329,9 +388,10 @@ public:
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
}
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
+ assert(KeyLayers.count(K) && "looking up symbol in unknown module");
+ return KeyLayers[K]->findSymbolIn(K, mangle(Name), ExportedSymbolsOnly);
}
LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr,
@@ -354,26 +414,48 @@ public:
return LLVMOrcErrSuccess;
}
+ LLVMOrcErrorCode findSymbolAddressIn(JITTargetAddress &RetAddr,
+ orc::VModuleKey K,
+ const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ RetAddr = 0;
+ if (auto Sym = findSymbolIn(K, 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)));
+ void RegisterJITEventListener(JITEventListener *L) {
+ if (!L)
+ return;
+ EventListeners.push_back(L);
+ }
+
+ void UnregisterJITEventListener(JITEventListener *L) {
+ if (!L)
+ return;
+
+ auto I = find(reverse(EventListeners), L);
+ if (I != EventListeners.rend()) {
+ std::swap(*I, EventListeners.back());
+ EventListeners.pop_back();
}
- return NewHandle;
}
+private:
+
LLVMOrcErrorCode mapError(Error Err) {
LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
@@ -386,22 +468,44 @@ private:
return Result;
}
+ void reportError(Error Err) {
+ // FIXME: Report errors on the execution session.
+ logAllUnhandledErrors(std::move(Err), errs(), "ORC error: ");
+ };
+
+ void notifyFinalized(orc::VModuleKey K,
+ const object::ObjectFile &Obj,
+ const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) {
+ for (auto &Listener : EventListeners)
+ Listener->NotifyObjectEmitted(Obj, LoadedObjInfo);
+ }
+
+ void notifyFreed(orc::VModuleKey K, const object::ObjectFile &Obj) {
+ for (auto &Listener : EventListeners)
+ Listener->NotifyFreeingObject(Obj);
+ }
+
+ orc::ExecutionSession ES;
+ std::unique_ptr<CompileCallbackMgr> CCMgr;
+
+ std::vector<JITEventListener *> EventListeners;
+
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;
+ std::map<orc::VModuleKey, std::unique_ptr<detail::GenericLayer>> KeyLayers;
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
std::string ErrMsg;
+
+ std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
};
} // end namespace llvm