IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
public:
- using ModuleHandle = decltype(CompileLayer)::ModuleHandleT;
KaleidoscopeJIT()
: ES(SSP),
TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandle addModule(std::unique_ptr<Module> M) {
+ VModuleKey addModule(std::unique_ptr<Module> M) {
// Add the module to the JIT with a new VModuleKey.
- return cantFail(CompileLayer.addModule(ES.allocateVModule(), std::move(M)));
+ auto K = ES.allocateVModule();
+ cantFail(CompileLayer.addModule(K, std::move(M)));
+ return K;
}
JITSymbol findSymbol(const std::string Name) {
return cantFail(findSymbol(Name).getAddress());
}
- void removeModule(ModuleHandle H) {
- cantFail(CompileLayer.removeModule(H));
+ void removeModule(VModuleKey K) {
+ cantFail(CompileLayer.removeModule(K));
}
};
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
public:
- using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT()
: ES(SSP),
TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandle addModule(std::unique_ptr<Module> M) {
+ VModuleKey addModule(std::unique_ptr<Module> M) {
// Add the module to the JIT with a new VModuleKey.
- return cantFail(
- OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
+ auto K = ES.allocateVModule();
+ cantFail(OptimizeLayer.addModule(K, std::move(M)));
+ return K;
}
JITSymbol findSymbol(const std::string Name) {
return OptimizeLayer.findSymbol(MangledNameStream.str(), true);
}
- void removeModule(ModuleHandle H) {
- cantFail(OptimizeLayer.removeModule(H));
+ void removeModule(VModuleKey K) {
+ cantFail(OptimizeLayer.removeModule(K));
}
private:
CompileOnDemandLayer<decltype(OptimizeLayer)> CODLayer;
public:
- using ModuleHandle = decltype(CODLayer)::ModuleHandleT;
KaleidoscopeJIT()
: ES(SSP), TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandle addModule(std::unique_ptr<Module> M) {
+ VModuleKey addModule(std::unique_ptr<Module> M) {
// Create a new VModuleKey.
VModuleKey K = ES.allocateVModule();
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); });
// Add the module to the JIT with the new key.
- return cantFail(CODLayer.addModule(K, std::move(M)));
+ cantFail(CODLayer.addModule(K, std::move(M)));
+ return K;
}
JITSymbol findSymbol(const std::string Name) {
return CODLayer.findSymbol(MangledNameStream.str(), true);
}
- void removeModule(ModuleHandle H) {
- cantFail(CODLayer.removeModule(H));
+ void removeModule(VModuleKey K) {
+ cantFail(CODLayer.removeModule(K));
}
private:
std::unique_ptr<IndirectStubsManager> IndirectStubsMgr;
public:
- using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT()
: ES(SSP),
TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandle addModule(std::unique_ptr<Module> M) {
+ VModuleKey addModule(std::unique_ptr<Module> M) {
// Add the module to the JIT with a new VModuleKey.
- return cantFail(
- OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
+ auto K = ES.allocateVModule();
+ cantFail(OptimizeLayer.addModule(K, std::move(M)));
+ return K;
}
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
return OptimizeLayer.findSymbol(mangle(Name), true);
}
- void removeModule(ModuleHandle H) {
- cantFail(OptimizeLayer.removeModule(H));
+ void removeModule(VModuleKey K) {
+ cantFail(OptimizeLayer.removeModule(K));
}
private:
MyRemote &Remote;
public:
- using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT(MyRemote &Remote)
: ES(SSP),
TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandle addModule(std::unique_ptr<Module> M) {
+ VModuleKey addModule(std::unique_ptr<Module> M) {
// Add the module with a new VModuleKey.
- return cantFail(
- OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
+ auto K = ES.allocateVModule();
+ cantFail(OptimizeLayer.addModule(K, std::move(M)));
+ return K;
}
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
return OptimizeLayer.findSymbol(mangle(Name), true);
}
- void removeModule(ModuleHandle H) {
- cantFail(OptimizeLayer.removeModule(H));
+ void removeModule(VModuleKey K) {
+ cantFail(OptimizeLayer.removeModule(K));
}
private:
public:
using ObjLayerT = RTDyldObjectLinkingLayer;
using CompileLayerT = IRCompileLayer<ObjLayerT, SimpleCompiler>;
- using ModuleHandleT = CompileLayerT::ModuleHandleT;
KaleidoscopeJIT()
: ES(SSP),
TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandleT addModule(std::unique_ptr<Module> M) {
- auto H =
- cantFail(CompileLayer.addModule(ES.allocateVModule(), std::move(M)));
- ModuleHandles.push_back(H);
- return H;
+ VModuleKey addModule(std::unique_ptr<Module> M) {
+ auto K = ES.allocateVModule();
+ cantFail(CompileLayer.addModule(K, std::move(M)));
+ ModuleKeys.push_back(K);
+ return K;
}
- void removeModule(ModuleHandleT H) {
- ModuleHandles.erase(find(ModuleHandles, H));
- cantFail(CompileLayer.removeModule(H));
+ void removeModule(VModuleKey K) {
+ ModuleKeys.erase(find(ModuleKeys, K));
+ cantFail(CompileLayer.removeModule(K));
}
JITSymbol findSymbol(const std::string Name) {
// Search modules in reverse order: from last added to first added.
// This is the opposite of the usual search order for dlsym, but makes more
// sense in a REPL where we want to bind to the newest available definition.
- for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend()))
+ for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend()))
if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))
return Sym;
const DataLayout DL;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
- std::vector<ModuleHandleT> ModuleHandles;
+ std::vector<VModuleKey> ModuleKeys;
};
} // end namespace orc
typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
-typedef uint32_t LLVMOrcModuleHandle;
+typedef uint64_t LLVMOrcModuleHandle;
typedef uint64_t LLVMOrcTargetAddress;
typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name, void *LookupCtx);
typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
return LambdaMaterializer<MaterializerFtor>(std::move(M));
}
- using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT;
-
// Provide type-erasure for the Modules and MemoryManagers.
template <typename ResourceT>
class ResourceOwner {
using SourceModulesList = std::vector<SourceModuleEntry>;
using SourceModuleHandle = typename SourceModulesList::size_type;
+ LogicalDylib() = default;
+
+ LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
+ std::unique_ptr<IndirectStubsMgrT> StubsMgr)
+ : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
+ StubsMgr(std::move(StubsMgr)) {}
+
SourceModuleHandle
addSourceModule(std::shared_ptr<Module> M) {
SourceModuleHandle H = SourceModules.size();
bool ExportedSymbolsOnly) {
if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
return Sym;
- for (auto BLH : BaseLayerHandles)
- if (auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
+ for (auto BLK : BaseLayerVModuleKeys)
+ if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
}
Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
- for (auto &BLH : BaseLayerHandles)
- if (auto Err = BaseLayer.removeModule(BLH))
+ for (auto &BLK : BaseLayerVModuleKeys)
+ if (auto Err = BaseLayer.removeModule(BLK))
return Err;
return Error::success();
}
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
StaticGlobalRenamer StaticRenamer;
SourceModulesList SourceModules;
- std::vector<BaseLayerModuleHandleT> BaseLayerHandles;
+ std::vector<VModuleKey> BaseLayerVModuleKeys;
};
- using LogicalDylibList = std::list<LogicalDylib>;
-
public:
- /// @brief Handle to loaded module.
- using ModuleHandleT = typename LogicalDylibList::iterator;
-
/// @brief Module partitioning functor.
using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
~CompileOnDemandLayer() {
// FIXME: Report error on log.
while (!LogicalDylibs.empty())
- consumeError(removeModule(LogicalDylibs.begin()));
+ consumeError(removeModule(LogicalDylibs.begin()->first));
}
/// @brief Add a module to the compile-on-demand layer.
- Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
+ Error addModule(VModuleKey K, std::shared_ptr<Module> M) {
- LogicalDylibs.push_back(LogicalDylib());
- auto &LD = LogicalDylibs.back();
- LD.K = std::move(K);
- LD.StubsMgr = CreateIndirectStubsManager();
- LD.BackingResolver = GetSymbolResolver(LD.K);
+ assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
+ auto I = LogicalDylibs.insert(
+ LogicalDylibs.end(),
+ std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
+ CreateIndirectStubsManager())));
- if (auto Err = addLogicalModule(LD, std::move(M)))
- return std::move(Err);
-
- return std::prev(LogicalDylibs.end());
+ return addLogicalModule(I->second, std::move(M));
}
/// @brief Add extra modules to an existing logical module.
- Error addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
- return addLogicalModule(*H, std::move(M));
+ Error addExtraModule(VModuleKey K, std::shared_ptr<Module> M) {
+ return addLogicalModule(LogicalDylibs[K], std::move(M));
}
- /// @brief Remove the module represented by the given handle.
+ /// @brief Remove the module represented by the given key.
///
/// This will remove all modules in the layers below that were derived from
- /// the module represented by H.
- Error removeModule(ModuleHandleT H) {
- auto Err = H->removeModulesFromBaseLayer(BaseLayer);
- LogicalDylibs.erase(H);
+ /// the module represented by K.
+ Error removeModule(VModuleKey K) {
+ auto I = LogicalDylibs.find(K);
+ assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
+ auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
+ LogicalDylibs.erase(I);
return Err;
}
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it exists.
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- for (auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
- LDI != LDE; ++LDI) {
- if (auto Sym = LDI->StubsMgr->findStub(Name, ExportedSymbolsOnly))
+ for (auto &KV : LogicalDylibs) {
+ if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
return Sym;
- if (auto Sym = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
+ if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
/// @brief Get the address of a symbol provided by this layer, or some layer
/// below this one.
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
+ assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
+ return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
}
/// @brief Update the stub for the given function to point at FnBodyAddr.
SetSymbolResolver(LD.K, std::move(GVsResolver));
- if (auto GVsHOrErr = BaseLayer.addModule(LD.K, std::move(GVsM)))
- LD.BaseLayerHandles.push_back(*GVsHOrErr);
- else
- return GVsHOrErr.takeError();
+ if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
+ return Err;
+
+ LD.BaseLayerVModuleKeys.push_back(LD.K);
return Error::success();
}
JITTargetAddress CalledAddr = 0;
auto Part = Partition(F);
- if (auto PartHOrErr = emitPartition(LD, LMId, Part)) {
- auto &PartH = *PartHOrErr;
+ if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
+ auto &PartKey = *PartKeyOrErr;
for (auto *SubF : Part) {
std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
- if (auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false)) {
+ if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
llvm_unreachable("Function not emitted for partition");
}
- LD.BaseLayerHandles.push_back(PartH);
+ LD.BaseLayerVModuleKeys.push_back(PartKey);
} else
- return PartHOrErr.takeError();
+ return PartKeyOrErr.takeError();
return CalledAddr;
}
template <typename PartitionT>
- Expected<BaseLayerModuleHandleT>
+ Expected<VModuleKey>
emitPartition(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
const PartitionT &Part) {
});
SetSymbolResolver(K, std::move(Resolver));
- return BaseLayer.addModule(std::move(K), std::move(M));
+ if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
+ return std::move(Err);
+
+ return K;
}
ExecutionSession &ES;
CompileCallbackMgrT &CompileCallbackMgr;
IndirectStubsManagerBuilderT CreateIndirectStubsManager;
- LogicalDylibList LogicalDylibs;
+ std::map<VModuleKey, LogicalDylib> LogicalDylibs;
bool CloneStubsIntoPartitions;
};
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
-#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include <algorithm>
#include <cstdint>
#include <string>
-#include <vector>
#include <utility>
+#include <vector>
namespace llvm {
public:
/// @brief Construct a CtorDtorRunner for the given range using the given
/// name mangling function.
- CtorDtorRunner(std::vector<std::string> CtorDtorNames,
- typename JITLayerT::ModuleHandleT H)
- : CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
+ CtorDtorRunner(std::vector<std::string> CtorDtorNames, VModuleKey K)
+ : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
/// @brief Run the recorded constructors/destructors through the given JIT
/// layer.
for (const auto &CtorDtorName : CtorDtorNames) {
dbgs() << "Searching for ctor/dtor: " << CtorDtorName << "...";
- if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
+ if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) {
dbgs() << " found symbol...";
if (auto AddrOrErr = CtorDtorSym.getAddress()) {
dbgs() << " at addr " << format("0x%016x", *AddrOrErr) << "\n";
private:
std::vector<std::string> CtorDtorNames;
- typename JITLayerT::ModuleHandleT H;
+ orc::VModuleKey K;
};
/// @brief Support class for static dtor execution. For hosted (in-process) JITs
class IRCompileLayer {
public:
- /// @brief Handle to a compiled module.
- using ModuleHandleT = typename BaseLayerT::ObjHandleT;
-
/// @brief Construct an IRCompileLayer with the given BaseLayer, which must
/// implement the ObjectLayer concept.
IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
/// @brief Compile the module, and add the resulting object to the base layer
/// along with the given memory manager and symbol resolver.
- ///
- /// @return A handle for the added module.
- Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
+ Error addModule(VModuleKey K, std::shared_ptr<Module> M) {
using CompileResult = decltype(Compile(*M));
auto Obj = std::make_shared<CompileResult>(Compile(*M));
return BaseLayer.addObject(std::move(K), std::move(Obj));
}
- /// @brief Remove the module associated with the handle H.
- Error removeModule(ModuleHandleT H) {
- return BaseLayer.removeObject(H);
- }
+ /// @brief Remove the module associated with the VModuleKey K.
+ Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
/// @brief Get the address of the given symbol in compiled module represented
/// by the handle H. This call is forwarded to the base layer's
/// implementation.
- /// @param H The handle for the module to search in.
+ /// @param K The VModuleKey for the module to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given module.
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
+ return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
}
/// @brief Immediately emit and finalize the module represented by the given
/// handle.
/// @param H Handle for module to emit/finalize.
- Error emitAndFinalize(ModuleHandleT H) {
- return BaseLayer.emitAndFinalize(H);
- }
+ Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
private:
BaseLayerT &BaseLayer;
class IRTransformLayer {
public:
- /// @brief Handle to a set of added modules.
- using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
-
/// @brief Construct an IRTransformLayer with the given BaseLayer
IRTransformLayer(BaseLayerT &BaseLayer,
TransformFtor Transform = TransformFtor())
/// the layer below, along with the memory manager and symbol resolver.
///
/// @return A handle for the added modules.
- Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
+ Error addModule(VModuleKey K, std::shared_ptr<Module> M) {
return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
}
- /// @brief Remove the module associated with the handle H.
- Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
+ /// @brief Remove the module associated with the VModuleKey K.
+ Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
}
/// @brief Get the address of the given symbol in the context of the module
- /// represented by the handle H. This call is forwarded to the base
+ /// represented by the VModuleKey K. This call is forwarded to the base
/// layer's implementation.
/// @param H The handle for the module to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given module.
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
+ return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
}
/// @brief Immediately emit and finalize the module represented by the given
- /// handle.
+ /// VModuleKey.
/// @param H Handle for module to emit/finalize.
- Error emitAndFinalize(ModuleHandleT H) {
- return BaseLayer.emitAndFinalize(H);
- }
+ Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
/// @brief Access the transform functor directly.
TransformFtor& getTransform() { return Transform; }
/// is deferred until the first time the client requests the address (via
/// JITSymbol::getAddress) for a symbol contained in this layer.
template <typename BaseLayerT> class LazyEmittingLayer {
-public:
-
- using BaseLayerHandleT = typename BaseLayerT::ModuleHandleT;
-
private:
class EmissionDeferredModule {
public:
return 0;
else if (this->EmitState == NotEmitted) {
this->EmitState = Emitting;
- if (auto HandleOrErr = this->emitToBaseLayer(B))
- Handle = std::move(*HandleOrErr);
- else
- return HandleOrErr.takeError();
+ if (auto Err = this->emitToBaseLayer(B))
+ return std::move(Err);
this->EmitState = Emitted;
}
- if (auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly))
+ if (auto Sym = B.findSymbolIn(K, PName, ExportedSymbolsOnly))
return Sym.getAddress();
else if (auto Err = Sym.takeError())
return std::move(Err);
// RuntimeDyld that did the lookup), so just return a nullptr here.
return nullptr;
case Emitted:
- return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
+ return B.findSymbolIn(K, Name, ExportedSymbolsOnly);
}
llvm_unreachable("Invalid emit-state.");
}
Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
- return EmitState != NotEmitted ? BaseLayer.removeModule(Handle)
+ return EmitState != NotEmitted ? BaseLayer.removeModule(K)
: Error::success();
}
"Cannot emitAndFinalize while already emitting");
if (EmitState == NotEmitted) {
EmitState = Emitting;
- Handle = emitToBaseLayer(BaseLayer);
+ emitToBaseLayer(BaseLayer);
EmitState = Emitted;
}
- BaseLayer.emitAndFinalize(Handle);
+ BaseLayer.emitAndFinalize(K);
}
private:
return buildMangledSymbols(Name, ExportedSymbolsOnly);
}
- Expected<BaseLayerHandleT> emitToBaseLayer(BaseLayerT &BaseLayer) {
+ Error emitToBaseLayer(BaseLayerT &BaseLayer) {
// We don't need the mangled names set any more: Once we've emitted this
// to the base layer we'll just look for symbols there.
MangledSymbols.reset();
}
enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
- BaseLayerHandleT Handle;
VModuleKey K;
std::shared_ptr<Module> M;
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
};
- using ModuleListT = std::list<std::unique_ptr<EmissionDeferredModule>>;
-
BaseLayerT &BaseLayer;
- ModuleListT ModuleList;
+ std::map<VModuleKey, std::unique_ptr<EmissionDeferredModule>> ModuleMap;
public:
- /// @brief Handle to a loaded module.
- using ModuleHandleT = typename ModuleListT::iterator;
-
/// @brief Construct a lazy emitting layer.
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
/// @brief Add the given module to the lazy emitting layer.
- Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
- return ModuleList.insert(
- ModuleList.end(),
- llvm::make_unique<EmissionDeferredModule>(std::move(K), std::move(M)));
+ Error addModule(VModuleKey K, std::shared_ptr<Module> M) {
+ assert(!ModuleMap.count(K) && "VModuleKey K already in use");
+ ModuleMap[K] =
+ llvm::make_unique<EmissionDeferredModule>(std::move(K), std::move(M));
+ return Error::success();
}
/// @brief Remove the module represented by the given handle.
///
/// This method will free the memory associated with the given module, both
/// in this layer, and the base layer.
- Error removeModule(ModuleHandleT H) {
- Error Err = (*H)->removeModuleFromBaseLayer(BaseLayer);
- ModuleList.erase(H);
- return Err;
+ Error removeModule(VModuleKey K) {
+ auto I = ModuleMap.find(K);
+ assert(I != ModuleMap.end() && "VModuleKey K not valid here");
+ auto EDM = std::move(I.second);
+ ModuleMap.erase(I);
+ return EDM->removeModuleFromBaseLayer(BaseLayer);
}
/// @brief Search for the given named symbol.
// If not found then search the deferred modules. If any of these contain a
// definition of 'Name' then they will return a JITSymbol that will emit
// the corresponding module when the symbol address is requested.
- for (auto &DeferredMod : ModuleList)
- if (auto Symbol = DeferredMod->find(Name, ExportedSymbolsOnly, BaseLayer))
+ for (auto &KV : ModuleMap)
+ if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer))
return Symbol;
// If no definition found anywhere return a null symbol.
}
/// @brief Get the address of the given symbol in the context of the of
- /// compiled modules represented by the handle H.
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ /// compiled modules represented by the key K.
+ JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
+ assert(ModuleMap.count(K) && "VModuleKey K not valid here");
+ return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
}
/// @brief Immediately emit and finalize the module represented by the given
- /// handle.
- /// @param H Handle for module to emit/finalize.
- Error emitAndFinalize(ModuleHandleT H) {
- return (*H)->emitAndFinalize(BaseLayer);
+ /// key.
+ Error emitAndFinalize(VModuleKey K) {
+ assert(ModuleMap.count(K) && "VModuleKey K not valid here");
+ return ModuleMap[K]->emitAndFinalize(BaseLayer);
}
};
template <typename BaseLayerT, typename TransformFtor>
class ObjectTransformLayer {
public:
- /// @brief Handle to a set of added objects.
- using ObjHandleT = typename BaseLayerT::ObjHandleT;
-
/// @brief Construct an ObjectTransformLayer with the given BaseLayer
ObjectTransformLayer(BaseLayerT &BaseLayer,
TransformFtor Transform = TransformFtor())
/// memory manager and symbol resolver.
///
/// @return A handle for the added objects.
- template <typename ObjectPtr>
- Expected<ObjHandleT> addObject(VModuleKey K, ObjectPtr Obj) {
+ template <typename ObjectPtr> Error addObject(VModuleKey K, ObjectPtr Obj) {
return BaseLayer.addObject(std::move(K), Transform(std::move(Obj)));
}
- /// @brief Remove the object set associated with the handle H.
- Error removeObject(ObjHandleT H) { return BaseLayer.removeObject(H); }
+ /// @brief Remove the object set associated with the VModuleKey K.
+ Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
}
/// @brief Get the address of the given symbol in the context of the set of
- /// objects represented by the handle H. This call is forwarded to the
- /// base layer's implementation.
+ /// objects represented by the VModuleKey K. This call is forwarded to
+ /// the base layer's implementation.
/// @param H The handle for the object set to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given object set.
- JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
+ return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
}
/// @brief Immediately emit and finalize the object set represented by the
- /// given handle.
- /// @param H Handle for object set to emit/finalize.
- Error emitAndFinalize(ObjHandleT H) {
- return BaseLayer.emitAndFinalize(H);
- }
+ /// given VModuleKey K.
+ Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
- /// @brief Map section addresses for the objects associated with the handle H.
- void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
+ /// @brief Map section addresses for the objects associated with the
+ /// VModuleKey K.
+ void mapSectionAddress(VModuleKey K, const void *LocalAddress,
JITTargetAddress TargetAddr) {
- BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr);
+ BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr);
}
/// @brief Access the transform functor directly.
StringMap<JITEvaluatedSymbol> SymbolTable;
bool Finalized = false;
};
-
- using LinkedObjectListT = std::list<std::unique_ptr<LinkedObject>>;
-
-public:
- /// @brief Handle to a loaded object.
- using ObjHandleT = LinkedObjectListT::iterator;
};
/// @brief Bare bones object linking layer.
using RTDyldObjectLinkingLayerBase::ObjectPtr;
/// @brief Functor for receiving object-loaded notifications.
- using NotifyLoadedFtor =
- std::function<void(ObjHandleT, const ObjectPtr &Obj,
- const RuntimeDyld::LoadedObjectInfo &)>;
+ using NotifyLoadedFtor = std::function<void(
+ VModuleKey, const ObjectPtr &Obj, const RuntimeDyld::LoadedObjectInfo &)>;
/// @brief Functor for receiving finalization notifications.
- using NotifyFinalizedFtor = std::function<void(ObjHandleT)>;
+ using NotifyFinalizedFtor = std::function<void(VModuleKey)>;
private:
template <typename MemoryManagerPtrT, typename FinalizerFtor>
MemMgr->deregisterEHFrames();
}
- void setHandle(ObjHandleT H) {
- PFC->Handle = H;
- }
-
Error finalize() override {
assert(PFC && "mapSectionAddress called on finalized LinkedObject");
PFC->RTDyld = &RTDyld;
this->Finalized = true;
- auto Err = PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
+ auto Err = PFC->Finalizer(RTDyld, std::move(PFC->Obj),
[&]() { this->updateSymbolTable(RTDyld); });
// Release resources.
std::shared_ptr<SymbolResolver> Resolver;
FinalizerFtor Finalizer;
bool ProcessAllSections;
- ObjHandleT Handle;
RuntimeDyld *RTDyld;
};
}
/// @brief Add an object to the JIT.
- ///
- /// @return A handle that can be used to refer to the loaded object (for
- /// symbol searching, finalization, freeing memory, etc.).
- Expected<ObjHandleT> addObject(VModuleKey K, ObjectPtr Obj) {
- auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
- const ObjectPtr &ObjToLoad,
- std::function<void()> LOSHandleLoad) -> Error {
+ Error addObject(VModuleKey K, ObjectPtr Obj) {
+ auto Finalizer = [&, K](RuntimeDyld &RTDyld, const ObjectPtr &ObjToLoad,
+ std::function<void()> LOSHandleLoad) -> Error {
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
RTDyld.loadObject(*ObjToLoad->getBinary());
LOSHandleLoad();
if (this->NotifyLoaded)
- this->NotifyLoaded(H, ObjToLoad, *Info);
+ this->NotifyLoaded(K, ObjToLoad, *Info);
RTDyld.finalizeWithMemoryManagerLocking();
inconvertibleErrorCode());
if (this->NotifyFinalized)
- this->NotifyFinalized(H);
+ this->NotifyFinalized(K);
return Error::success();
};
- auto LO =
+ assert(!LinkedObjects.count(K) && "VModuleKey already in use");
+
+ LinkedObjects[K] =
createLinkedObject(ES, std::move(Obj), GetMemMgr(K), GetResolver(K),
std::move(Finalizer), ProcessAllSections);
- // LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
- // below.
- auto *LOPtr = LO.get();
-
- ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO));
- LOPtr->setHandle(Handle);
- return Handle;
+ return Error::success();
}
- /// @brief Remove the object associated with handle H.
+ /// @brief Remove the object associated with VModuleKey K.
///
/// All memory allocated for the object will be freed, and the sections and
/// symbols it provided will no longer be available. No attempt is made to
/// indirectly) will result in undefined behavior. If dependence tracking is
/// required to detect or resolve such issues it should be added at a higher
/// layer.
- Error removeObject(ObjHandleT H) {
+ Error removeObject(VModuleKey K) {
+ assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
// How do we invalidate the symbols in H?
- LinkedObjList.erase(H);
+ LinkedObjects.erase(K);
return Error::success();
}
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it exists.
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E;
- ++I)
- if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
- return Symbol;
+ for (auto &KV : LinkedObjects)
+ if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly))
+ return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return nullptr;
}
/// @brief Search for the given named symbol in the context of the loaded
- /// object represented by the handle H.
- /// @param H The handle for the object to search in.
+ /// object represented by the VModuleKey K.
+ /// @param K The VModuleKey for the object to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given object.
- JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
+ JITSymbol findSymbolIn(VModuleKey K, StringRef Name,
bool ExportedSymbolsOnly) {
- return (*H)->getSymbol(Name, ExportedSymbolsOnly);
+ assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
+ return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
}
- /// @brief Map section addresses for the object associated with the handle H.
- void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
+ /// @brief Map section addresses for the object associated with the
+ /// VModuleKey K.
+ void mapSectionAddress(VModuleKey K, const void *LocalAddress,
JITTargetAddress TargetAddr) {
- (*H)->mapSectionAddress(LocalAddress, TargetAddr);
+ assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
+ LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
}
/// @brief Immediately emit and finalize the object represented by the given
- /// handle.
- /// @param H Handle for object to emit/finalize.
- Error emitAndFinalize(ObjHandleT H) { return (*H)->finalize(); }
+ /// VModuleKey.
+ /// @param K VModuleKey for object to emit/finalize.
+ Error emitAndFinalize(VModuleKey K) {
+ assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
+ return LinkedObjects[K]->finalize();
+ }
private:
ExecutionSession &ES;
- LinkedObjectListT LinkedObjList;
+
+ std::map<VModuleKey, std::unique_ptr<LinkedObject>> LinkedObjects;
MemoryManagerGetter GetMemMgr;
ResolverGetter GetResolver;
NotifyLoadedFtor NotifyLoaded;
#include <algorithm>
#include <cstdint>
#include <functional>
+#include <map>
#include <memory>
#include <set>
#include <string>
namespace detail {
+// FIXME: Kill this off once the Layer concept becomes an interface.
+class GenericLayer {
+public:
+ virtual ~GenericLayer() = default;
- class GenericHandle {
- public:
- GenericHandle(orc::VModuleKey K) : K(K) {}
-
- virtual ~GenericHandle() = default;
-
- virtual JITSymbol findSymbolIn(const std::string &Name,
- bool ExportedSymbolsOnly) = 0;
- virtual Error removeModule(orc::ExecutionSession &ES) = 0;
-
- orc::VModuleKey K;
+ 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,
- orc::VModuleKey K)
- : GenericHandle(std::move(K)), 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(orc::ExecutionSession &ES) override {
- auto Err = Layer.removeModule(Handle);
- ES.releaseVModule(K);
- return Err;
+ 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:
- GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle,
- orc::VModuleKey K)
- : GenericHandle(std::move(K)), 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(orc::ExecutionSession &ES) override {
- auto Err = Layer.removeObject(Handle);
- ES.releaseVModule(K);
- return Err;
+ 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, orc::VModuleKey K) {
- return llvm::make_unique<GenericHandleImpl<LayerT>>(
- Layer, std::move(Handle), std::move(K));
+ template <typename LayerT>
+ std::unique_ptr<GenericLayerImpl<LayerT>> createGenericLayer(LayerT &Layer) {
+ return llvm::make_unique<GenericLayerImpl<LayerT>>(Layer);
}
} // end namespace detail
};
public:
- using ModuleHandleT = unsigned;
OrcCBindingsStack(TargetMachine &TM,
std::unique_ptr<CompileCallbackMgr> CCMgr,
}
template <typename LayerT>
LLVMOrcErrorCode
- addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
- std::shared_ptr<Module> M,
+ addIRModule(orc::VModuleKey &RetKey, LayerT &Layer, std::shared_ptr<Module> M,
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
LLVMOrcSymbolResolverFn ExternalResolver,
void *ExternalResolverCtx) {
DtorNames.push_back(mangle(Dtor.Func->getName()));
// Add the module to the JIT.
- ModuleHandleT H;
- orc::VModuleKey K = ES.allocateVModule();
- Resolvers[K] = std::make_shared<CBindingsResolver>(*this, ExternalResolver,
- ExternalResolverCtx);
- if (auto LHOrErr = Layer.addModule(K, std::move(M)))
- H = createHandle(Layer, *LHOrErr, K);
- 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,
+ LLVMOrcErrorCode addIRModuleEager(orc::VModuleKey &RetKey,
std::shared_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,
+ LLVMOrcErrorCode addIRModuleLazy(orc::VModuleKey &RetKey,
std::shared_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(ES))
+ 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) {
auto OwningObj =
std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
- orc::VModuleKey K = ES.allocateVModule();
- Resolvers[K] = std::make_shared<CBindingsResolver>(
+ RetKey = ES.allocateVModule();
+ Resolvers[RetKey] = std::make_shared<CBindingsResolver>(
*this, ExternalResolver, ExternalResolverCtx);
- ModuleHandleT H;
- if (auto HOrErr = ObjectLayer.addObject(K, std::move(OwningObj)))
- H = createHandle(ObjectLayer, *HOrErr, K);
- else
- return mapError(HOrErr.takeError());
+ if (auto Err = ObjectLayer.addObject(RetKey, std::move(OwningObj)))
+ return mapError(std::move(Err));
- RetHandle = H;
+ KeyLayers[RetKey] = detail::createGenericLayer(ObjectLayer);
return LLVMOrcErrSuccess;
} else
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);
+ return KeyLayers[K]->findSymbolIn(K, Name, ExportedSymbolsOnly);
}
LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr,
const std::string &getErrorMessage() const { return ErrMsg; }
private:
- template <typename LayerT, typename HandleT>
- unsigned createHandle(LayerT &Layer, HandleT Handle, orc::VModuleKey K) {
- unsigned NewHandle;
- if (!FreeHandleIndexes.empty()) {
- NewHandle = FreeHandleIndexes.back();
- FreeHandleIndexes.pop_back();
- GenericHandles[NewHandle] =
- detail::createGenericHandle(Layer, std::move(Handle), std::move(K));
- return NewHandle;
- } else {
- NewHandle = GenericHandles.size();
- GenericHandles.push_back(
- detail::createGenericHandle(Layer, std::move(Handle), std::move(K)));
- }
- return NewHandle;
- }
LLVMOrcErrorCode mapError(Error Err) {
LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
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;
NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
- void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H,
+ void operator()(VModuleKey K,
const RTDyldObjectLinkingLayer::ObjectPtr &Obj,
const RuntimeDyld::LoadedObjectInfo &Info) const {
- M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
+ M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad);
M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
M.MemMgr->notifyObjectLoaded(&M, *Obj->getBinary());
}
public:
NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
- void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H) {
- M.UnfinalizedSections.erase(H);
- }
+ void operator()(VModuleKey K) { M.UnfinalizedSections.erase(K); }
private:
OrcMCJITReplacement &M;
// that have been emitted but not yet finalized so that we can forward the
// mapSectionAddress calls appropriately.
using SectionAddrSet = std::set<const void *>;
- struct ObjHandleCompare {
- bool operator()(ObjectLayerT::ObjHandleT H1,
- ObjectLayerT::ObjHandleT H2) const {
- return &*H1 < &*H2;
- }
- };
SectionAddrSet SectionsAllocatedSinceLastLoad;
- std::map<ObjectLayerT::ObjHandleT, SectionAddrSet, ObjHandleCompare>
- UnfinalizedSections;
+ std::map<VModuleKey, SectionAddrSet> UnfinalizedSections;
std::vector<object::OwningBinary<object::Archive>> Archives;
};
using IRDumpLayerT = orc::IRTransformLayer<CompileLayerT, TransformFtor>;
using CODLayerT = orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr>;
using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
- using ModuleHandleT = CODLayerT::ModuleHandleT;
OrcLazyJIT(std::unique_ptr<TargetMachine> TM,
std::unique_ptr<CompileCallbackMgr> CCMgr,
// 1) Search the JIT symbols.
// 2) Check for C++ runtime overrides.
// 3) Search the host process (LLI)'s symbol table.
- if (!ModulesHandle) {
+ if (!ModulesKey) {
auto LegacyLookupInDylib = [this](const std::string &Name) -> JITSymbol {
if (auto Sym = CODLayer.findSymbol(Name, true))
return Sym;
return nullptr;
};
- auto K = ES.allocateVModule();
- assert(!Resolvers.count(K) && "Resolver already present");
- Resolvers[K] = orc::createSymbolResolver(
+ ModulesKey = ES.allocateVModule();
+ assert(!Resolvers.count(*ModulesKey) && "Resolver already present");
+ Resolvers[*ModulesKey] = orc::createSymbolResolver(
[LegacyLookupInDylib](orc::SymbolFlagsMap &SymbolFlags,
const orc::SymbolNameSet &Symbols) {
auto NotFoundViaLegacyLookup = lookupFlagsWithLegacyFn(
});
// Add the module to the JIT.
- if (auto ModulesHandleOrErr =
- CODLayer.addModule(std::move(K), std::move(M)))
- ModulesHandle = std::move(*ModulesHandleOrErr);
- else
- return ModulesHandleOrErr.takeError();
+ if (auto Err = CODLayer.addModule(*ModulesKey, std::move(M)))
+ return Err;
- } else if (auto Err = CODLayer.addExtraModule(*ModulesHandle, std::move(M)))
+ } else if (auto Err = CODLayer.addExtraModule(*ModulesKey, std::move(M)))
return Err;
// Run the static constructors, and save the static destructor runner for
// execution when the JIT is torn down.
orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames),
- *ModulesHandle);
+ *ModulesKey);
if (auto Err = CtorRunner.runViaLayer(CODLayer))
return Err;
- IRStaticDestructorRunners.emplace_back(std::move(DtorNames),
- *ModulesHandle);
+ IRStaticDestructorRunners.emplace_back(std::move(DtorNames), *ModulesKey);
return Error::success();
}
return CODLayer.findSymbol(mangle(Name), true);
}
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
- return CODLayer.findSymbolIn(H, mangle(Name), true);
+ JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name) {
+ return CODLayer.findSymbolIn(K, mangle(Name), true);
}
private:
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners;
- llvm::Optional<CODLayerT::ModuleHandleT> ModulesHandle;
+ llvm::Optional<orc::VModuleKey> ModulesKey;
};
int runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms,
// transform layer called the base layer and forwarded any return value.
class MockBaseLayer {
public:
- typedef int ObjHandleT;
-
MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
- template <typename ObjPtrT>
- llvm::Expected<ObjHandleT> addObject(VModuleKey K, ObjPtrT Obj) {
+ template <typename ObjPtrT> llvm::Error addObject(VModuleKey K, ObjPtrT Obj) {
EXPECT_EQ(MockKey, K) << "Key should pass through";
EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
LastCalled = "addObject";
- MockObjHandle = 111;
- return MockObjHandle;
+ return llvm::Error::success();
}
template <typename ObjPtrT> void expectAddObject(VModuleKey K, ObjPtrT Obj) {
MockObject = *Obj;
}
-
- void verifyAddObject(ObjHandleT Returned) {
+ void verifyAddObject() {
EXPECT_EQ("addObject", LastCalled);
- EXPECT_EQ(MockObjHandle, Returned) << "Return should pass through";
resetExpectations();
}
- llvm::Error removeObject(ObjHandleT H) {
- EXPECT_EQ(MockObjHandle, H);
+ llvm::Error removeObject(VModuleKey K) {
+ EXPECT_EQ(MockKey, K);
LastCalled = "removeObject";
return llvm::Error::success();
}
- void expectRemoveObject(ObjHandleT H) { MockObjHandle = H; }
+ void expectRemoveObject(VModuleKey K) { MockKey = K; }
void verifyRemoveObject() {
EXPECT_EQ("removeObject", LastCalled);
resetExpectations();
resetExpectations();
}
- llvm::JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
+ llvm::JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
+ EXPECT_EQ(MockKey, K) << "VModuleKey should pass through";
EXPECT_EQ(MockName, Name) << "Name should pass through";
EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
LastCalled = "findSymbolIn";
MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
}
- void expectFindSymbolIn(ObjHandleT H, const std::string &Name,
+ void expectFindSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- MockObjHandle = H;
+ MockKey = K;
MockName = Name;
MockBool = ExportedSymbolsOnly;
}
resetExpectations();
}
- llvm::Error emitAndFinalize(ObjHandleT H) {
- EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
+ llvm::Error emitAndFinalize(VModuleKey K) {
+ EXPECT_EQ(MockKey, K) << "VModuleKey should pass through";
LastCalled = "emitAndFinalize";
return llvm::Error::success();
}
- void expectEmitAndFinalize(ObjHandleT H) { MockObjHandle = H; }
+ void expectEmitAndFinalize(VModuleKey K) { MockKey = K; }
void verifyEmitAndFinalize() {
EXPECT_EQ("emitAndFinalize", LastCalled);
resetExpectations();
}
- void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
+ void mapSectionAddress(VModuleKey K, const void *LocalAddress,
llvm::JITTargetAddress TargetAddr) {
- EXPECT_EQ(MockObjHandle, H);
+ EXPECT_EQ(MockKey, K);
EXPECT_EQ(MockLocalAddress, LocalAddress);
EXPECT_EQ(MockTargetAddress, TargetAddr);
LastCalled = "mapSectionAddress";
}
- void expectMapSectionAddress(ObjHandleT H, const void *LocalAddress,
+ void expectMapSectionAddress(VModuleKey K, const void *LocalAddress,
llvm::JITTargetAddress TargetAddr) {
- MockObjHandle = H;
+ MockKey = K;
MockLocalAddress = LocalAddress;
MockTargetAddress = TargetAddr;
}
std::string LastCalled;
VModuleKey MockKey;
MockObjectFile MockObject;
- ObjHandleT MockObjHandle;
std::string MockName;
bool MockBool;
llvm::JITSymbol MockSymbol;
LastCalled = "nothing";
MockKey = 0;
MockObject = 0;
- MockObjHandle = 0;
MockName = "bogus";
MockSymbol = llvm::JITSymbol(nullptr);
MockLocalAddress = nullptr;
auto K1 = ES.allocateVModule();
auto Obj1 = std::make_shared<MockObjectFile>(211);
M.expectAddObject(K1, Obj1);
- auto H = cantFail(T1.addObject(K1, std::move(Obj1)));
- M.verifyAddObject(H);
+ cantFail(T1.addObject(K1, std::move(Obj1)));
+ M.verifyAddObject();
// Test addObjectSet with T2 (mutating)
auto K2 = ES.allocateVModule();
auto Obj2 = std::make_shared<MockObjectFile>(222);
M.expectAddObject(K2, Obj2);
- H = cantFail(T2.addObject(K2, Obj2));
- M.verifyAddObject(H);
+ cantFail(T2.addObject(K2, Obj2));
+ M.verifyAddObject();
EXPECT_EQ(223, *Obj2) << "Expected mutation";
// Test removeObjectSet
- M.expectRemoveObject(H);
- cantFail(T1.removeObject(H));
+ M.expectRemoveObject(K2);
+ cantFail(T1.removeObject(K2));
M.verifyRemoveObject();
// Test findSymbol
// Test findSymbolIn
Name = "bar";
ExportedOnly = false;
- M.expectFindSymbolIn(H, Name, ExportedOnly);
- llvm::JITSymbol Sym2 = T1.findSymbolIn(H, Name, ExportedOnly);
+ M.expectFindSymbolIn(K1, Name, ExportedOnly);
+ llvm::JITSymbol Sym2 = T1.findSymbolIn(K1, Name, ExportedOnly);
M.verifyFindSymbolIn(std::move(Sym2));
// Test emitAndFinalize
- M.expectEmitAndFinalize(H);
- cantFail(T2.emitAndFinalize(H));
+ M.expectEmitAndFinalize(K1);
+ cantFail(T2.emitAndFinalize(K1));
M.verifyEmitAndFinalize();
// Test mapSectionAddress
char Buffer[24];
llvm::JITTargetAddress MockAddress = 255;
- M.expectMapSectionAddress(H, Buffer, MockAddress);
- T1.mapSectionAddress(H, Buffer, MockAddress);
+ M.expectMapSectionAddress(K1, Buffer, MockAddress);
+ T1.mapSectionAddress(K1, Buffer, MockAddress);
M.verifyMapSectionAddress();
// Verify transform getter (non-const)
// Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
// compile.
- decltype(TransformLayer)::ObjHandleT H2;
- cantFail(TransformLayer.emitAndFinalize(H2));
- TransformLayer.findSymbolIn(H2, Name, false);
+ VModuleKey DummyKey = ES.allocateVModule();
+ cantFail(TransformLayer.emitAndFinalize(DummyKey));
+ TransformLayer.findSymbolIn(DummyKey, Name, false);
TransformLayer.findSymbol(Name, true);
- TransformLayer.mapSectionAddress(H2, nullptr, 0);
- cantFail(TransformLayer.removeObject(H2));
+ TransformLayer.mapSectionAddress(DummyKey, nullptr, 0);
+ cantFail(TransformLayer.removeObject(DummyKey));
}
}
{
// Test with ProcessAllSections = false (the default).
- auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), Obj));
- cantFail(ObjLayer.emitAndFinalize(H));
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.addObject(K, Obj));
+ cantFail(ObjLayer.emitAndFinalize(K));
EXPECT_EQ(DebugSectionSeen, false)
<< "Unexpected debug info section";
- cantFail(ObjLayer.removeObject(H));
+ cantFail(ObjLayer.removeObject(K));
}
{
// Test with ProcessAllSections = true.
ObjLayer.setProcessAllSections(true);
- auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), Obj));
- cantFail(ObjLayer.emitAndFinalize(H));
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.addObject(K, Obj));
+ cantFail(ObjLayer.emitAndFinalize(K));
EXPECT_EQ(DebugSectionSeen, true)
<< "Expected debug info section not seen";
- cantFail(ObjLayer.removeObject(H));
+ cantFail(ObjLayer.removeObject(K));
}
}
return lookupWithLegacyFn(Query, Symbols, LegacyLookup);
});
- auto H = cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
- cantFail(ObjLayer.emitAndFinalize(H));
- cantFail(ObjLayer.removeObject(H));
+ cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
+ cantFail(ObjLayer.emitAndFinalize(K2));
+ cantFail(ObjLayer.removeObject(K2));
// Finalization of module 2 should trigger finalization of module 1.
// Verify that finalize on SMMW is only called once.
std::make_shared<object::OwningBinary<object::ObjectFile>>(
Compile(*MB2.getModule()));
- auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj1)));
+ auto K = ES.allocateVModule();
+ cantFail(ObjLayer.addObject(K, std::move(Obj1)));
cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj2)));
- cantFail(ObjLayer.emitAndFinalize(H));
- cantFail(ObjLayer.removeObject(H));
+ cantFail(ObjLayer.emitAndFinalize(K));
+ cantFail(ObjLayer.removeObject(K));
// Only one call to needsToReserveAllocationSpace should have been made.
EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)
RTDyldObjectLinkingLayer ObjLayer(
ES, [](VModuleKey) { return nullptr; },
[](VModuleKey) { return std::make_shared<NullResolver>(); },
- [](RTDyldObjectLinkingLayer::ObjHandleT,
- const RTDyldObjectLinkingLayer::ObjectPtr &obj,
+ [](VModuleKey, const RTDyldObjectLinkingLayer::ObjectPtr &obj,
const RuntimeDyld::LoadedObjectInfo &info) {});
}