diff options
| author | Lang Hames <lhames@gmail.com> | 2018-02-06 21:25:11 +0000 |
|---|---|---|
| committer | Lang Hames <lhames@gmail.com> | 2018-02-06 21:25:11 +0000 |
| commit | 4b546c91452c5735ada1430f8a6943328e4dba4e (patch) | |
| tree | 633421ee6cc4d06fce9ce73f625992e7dbedc6fe /llvm/include | |
| parent | ffe72034a6d688efcd7035fe9caf5964f00037c0 (diff) | |
| download | bcm5719-llvm-4b546c91452c5735ada1430f8a6943328e4dba4e.tar.gz bcm5719-llvm-4b546c91452c5735ada1430f8a6943328e4dba4e.zip | |
[ORC] Start migrating ORC layers to use the new ORC Core.h APIs.
In particular this patch switches RTDyldObjectLinkingLayer to use
orc::SymbolResolver and threads the requried changse (ExecutionSession
references and VModuleKeys) through the existing layer APIs.
The purpose of the new resolver interface is to improve query performance and
better support parallelism, both in JIT'd code and within the compiler itself.
The most visibile change is switch of the <Layer>::addModule signatures from:
Expected<Handle> addModule(std::shared_ptr<ModuleType> Mod,
std::shared_ptr<JITSymbolResolver> Resolver)
to:
Expected<Handle> addModule(VModuleKey K, std::shared_ptr<ModuleType> Mod);
Typical usage of addModule will now look like:
auto K = ES.allocateVModuleKey();
Resolvers[K] = createSymbolResolver(...);
Layer.addModule(K, std::move(Mod));
See the BuildingAJIT tutorial code for example usage.
llvm-svn: 324405
Diffstat (limited to 'llvm/include')
9 files changed, 225 insertions, 117 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 3281c354676..1daff438b68 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/OrcError.h" @@ -138,8 +139,6 @@ private: }; struct LogicalDylib { - using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>; - struct SourceModuleEntry { std::shared_ptr<Module> SourceMod; std::set<Function*> StubsToClone; @@ -183,7 +182,8 @@ private: return Error::success(); } - std::shared_ptr<LegacyJITSymbolResolver> ExternalSymbolResolver; + VModuleKey K; + std::shared_ptr<SymbolResolver> BackingResolver; std::unique_ptr<IndirectStubsMgrT> StubsMgr; StaticGlobalRenamer StaticRenamer; SourceModulesList SourceModules; @@ -204,13 +204,24 @@ public: using IndirectStubsManagerBuilderT = std::function<std::unique_ptr<IndirectStubsMgrT>()>; + using SymbolResolverGetter = + std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>; + + using SymbolResolverSetter = + std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>; + /// @brief Construct a compile-on-demand layer instance. - CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition, + CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer, + SymbolResolverGetter GetSymbolResolver, + SymbolResolverSetter SetSymbolResolver, + PartitioningFtor Partition, CompileCallbackMgrT &CallbackMgr, IndirectStubsManagerBuilderT CreateIndirectStubsManager, bool CloneStubsIntoPartitions = true) - : BaseLayer(BaseLayer), Partition(std::move(Partition)), - CompileCallbackMgr(CallbackMgr), + : ES(ES), BaseLayer(BaseLayer), + GetSymbolResolver(std::move(GetSymbolResolver)), + SetSymbolResolver(std::move(SetSymbolResolver)), + Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr), CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)), CloneStubsIntoPartitions(CloneStubsIntoPartitions) {} @@ -221,16 +232,14 @@ public: } /// @brief Add a module to the compile-on-demand layer. - Expected<ModuleHandleT> - addModule(std::shared_ptr<Module> M, - std::shared_ptr<LegacyJITSymbolResolver> Resolver) { + Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) { LogicalDylibs.push_back(LogicalDylib()); auto &LD = LogicalDylibs.back(); - LD.ExternalSymbolResolver = std::move(Resolver); + LD.K = std::move(K); LD.StubsMgr = CreateIndirectStubsManager(); + LD.BackingResolver = GetSymbolResolver(LD.K); - // Process each of the modules in this module set. if (auto Err = addLogicalModule(LD, std::move(M))) return std::move(Err); @@ -454,22 +463,46 @@ private: return MaterializerErrors; // Build a resolver for the globals module and add it to the base layer. - auto GVsResolver = createLambdaResolver( - [this, &LD](const std::string &Name) -> JITSymbol { - if (auto Sym = LD.StubsMgr->findStub(Name, false)) - return Sym; - if (auto Sym = LD.findSymbol(BaseLayer, Name, false)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name); + auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol { + if (auto Sym = LD.StubsMgr->findStub(Name, false)) + return Sym; + else if (auto Err = Sym.takeError()) + return std::move(Err); + + if (auto Sym = LD.findSymbol(BaseLayer, Name, false)) + return Sym; + else if (auto Err = Sym.takeError()) + return std::move(Err); + + return nullptr; + }; + + auto GVsResolver = createSymbolResolver( + [this, &LD, LegacyLookup](SymbolFlagsMap &SymbolFlags, + const SymbolNameSet &Symbols) { + auto NotFoundViaLegacyLookup = + lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup); + + if (!NotFoundViaLegacyLookup) { + logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(), + "CODLayer/GVsResolver flags lookup failed: "); + SymbolFlags.clear(); + return SymbolNameSet(); + } + + return LD.BackingResolver->lookupFlags(SymbolFlags, + *NotFoundViaLegacyLookup); }, - [&LD](const std::string &Name) { - return LD.ExternalSymbolResolver->findSymbol(Name); + [&LD, LegacyLookup](AsynchronousSymbolQuery &Query, + SymbolNameSet Symbols) { + auto NotFoundViaLegacyLookup = + lookupWithLegacyFn(Query, Symbols, LegacyLookup); + return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup); }); - if (auto GVsHOrErr = - BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver))) + 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(); @@ -596,23 +629,42 @@ private: for (auto *F : Part) moveFunctionBody(*F, VMap, &Materializer); + auto K = ES.allocateVModule(); + + auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol { + return LD.findSymbol(BaseLayer, Name, false); + }; + // Create memory manager and symbol resolver. - auto Resolver = createLambdaResolver( - [this, &LD](const std::string &Name) -> JITSymbol { - if (auto Sym = LD.findSymbol(BaseLayer, Name, false)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name); + auto Resolver = createSymbolResolver( + [this, &LD, LegacyLookup](SymbolFlagsMap &SymbolFlags, + const SymbolNameSet &Symbols) { + auto NotFoundViaLegacyLookup = + lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup); + if (!NotFoundViaLegacyLookup) { + logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(), + "CODLayer/SubResolver flags lookup failed: "); + SymbolFlags.clear(); + return SymbolNameSet(); + } + return LD.BackingResolver->lookupFlags(SymbolFlags, + *NotFoundViaLegacyLookup); }, - [&LD](const std::string &Name) { - return LD.ExternalSymbolResolver->findSymbol(Name); + [&LD, LegacyLookup](AsynchronousSymbolQuery &Q, SymbolNameSet Symbols) { + auto NotFoundViaLegacyLookup = + lookupWithLegacyFn(Q, Symbols, LegacyLookup); + return LD.BackingResolver->lookup(Q, + std::move(NotFoundViaLegacyLookup)); }); + SetSymbolResolver(K, std::move(Resolver)); - return BaseLayer.addModule(std::move(M), std::move(Resolver)); + return BaseLayer.addModule(std::move(K), std::move(M)); } + ExecutionSession &ES; BaseLayerT &BaseLayer; + SymbolResolverGetter GetSymbolResolver; + SymbolResolverSetter SetSymbolResolver; PartitioningFtor Partition; CompileCallbackMgrT &CompileCallbackMgr; IndirectStubsManagerBuilderT CreateIndirectStubsManager; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index d9b45c6a1e2..22071ff0cb0 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -104,20 +104,27 @@ public: Error runViaLayer(JITLayerT &JITLayer) const { using CtorDtorTy = void (*)(); - for (const auto &CtorDtorName : CtorDtorNames) + for (const auto &CtorDtorName : CtorDtorNames) { + dbgs() << "Searching for ctor/dtor: " << CtorDtorName << "..."; if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) { + dbgs() << " found symbol..."; if (auto AddrOrErr = CtorDtorSym.getAddress()) { + dbgs() << " at addr " << format("0x%016x", *AddrOrErr) << "\n"; CtorDtorTy CtorDtor = reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr)); CtorDtor(); - } else + } else { + dbgs() << " failed materialization!\n"; return AddrOrErr.takeError(); + } } else { + dbgs() << " failed to find symbol..."; if (auto Err = CtorDtorSym.takeError()) return Err; else return make_error<JITSymbolNotFound>(CtorDtorName); } + } return Error::success(); } diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index fadd334bed0..94a3086a4ee 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -16,6 +16,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/Support/Error.h" #include <memory> #include <string> @@ -50,12 +51,10 @@ public: /// along with the given memory manager and symbol resolver. /// /// @return A handle for the added module. - Expected<ModuleHandleT> - addModule(std::shared_ptr<Module> M, - std::shared_ptr<JITSymbolResolver> Resolver) { + Expected<ModuleHandleT> 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(Obj), std::move(Resolver)); + return BaseLayer.addObject(std::move(K), std::move(Obj)); } /// @brief Remove the module associated with the handle H. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 476061afda5..31de6f1cd5c 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -15,6 +15,7 @@ #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include <memory> #include <string> @@ -42,10 +43,8 @@ public: /// the layer below, along with the memory manager and symbol resolver. /// /// @return A handle for the added modules. - Expected<ModuleHandleT> - addModule(std::shared_ptr<Module> M, - std::shared_ptr<JITSymbolResolver> Resolver) { - return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver)); + Expected<ModuleHandleT> 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. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index b7e462e85d9..0da6e0135b7 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" @@ -46,9 +47,8 @@ public: private: class EmissionDeferredModule { public: - EmissionDeferredModule(std::shared_ptr<Module> M, - std::shared_ptr<JITSymbolResolver> Resolver) - : M(std::move(M)), Resolver(std::move(Resolver)) {} + EmissionDeferredModule(VModuleKey K, std::shared_ptr<Module> M) + : K(std::move(K)), M(std::move(M)) {} JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { @@ -139,7 +139,7 @@ private: // 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(); - return BaseLayer.addModule(std::move(M), std::move(Resolver)); + return BaseLayer.addModule(std::move(K), std::move(M)); } // If the mangled name of the given GlobalValue matches the given search @@ -193,8 +193,8 @@ private: enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted; BaseLayerHandleT Handle; + VModuleKey K; std::shared_ptr<Module> M; - std::shared_ptr<JITSymbolResolver> Resolver; mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols; }; @@ -212,13 +212,10 @@ public: LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} /// @brief Add the given module to the lazy emitting layer. - Expected<ModuleHandleT> - addModule(std::shared_ptr<Module> M, - std::shared_ptr<JITSymbolResolver> Resolver) { + Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) { return ModuleList.insert( ModuleList.end(), - llvm::make_unique<EmissionDeferredModule>(std::move(M), - std::move(Resolver))); + llvm::make_unique<EmissionDeferredModule>(std::move(K), std::move(M))); } /// @brief Remove the module represented by the given handle. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h index e04ef93a962..ab495c6cebd 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h @@ -92,6 +92,46 @@ SymbolNameSet lookupWithLegacyFn(AsynchronousSymbolQuery &Query, return SymbolsNotFound; } +/// @brief An ORC SymbolResolver implementation that uses a legacy +/// findSymbol-like function to perform lookup; +template <typename LegacyLookupFn> +class LegacyLookupFnResolver final : public SymbolResolver { +public: + using ErrorReporter = std::function<void(Error)>; + + LegacyLookupFnResolver(LegacyLookupFn LegacyLookup, ErrorReporter ReportError) + : LegacyLookup(std::move(LegacyLookup)), + ReportError(std::move(ReportError)) {} + + SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, + const SymbolNameSet &Symbols) final { + if (auto RemainingSymbols = + lookupFlagsWithLegacyFn(Flags, Symbols, LegacyLookup)) + return std::move(*RemainingSymbols); + else { + ReportError(RemainingSymbols.takeError()); + return Symbols; + } + } + + SymbolNameSet lookup(AsynchronousSymbolQuery &Query, + SymbolNameSet Symbols) final { + return lookupWithLegacyFn(Query, Symbols, LegacyLookup); + } + +private: + LegacyLookupFn LegacyLookup; + ErrorReporter ReportError; +}; + +template <typename LegacyLookupFn> +std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>> +createLegacyLookupResolver(LegacyLookupFn LegacyLookup, + std::function<void(Error)> ErrorReporter) { + return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>( + std::move(LegacyLookup), std::move(ErrorReporter)); +}; + } // End namespace orc } // End namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h index e946b909eff..982bd868e76 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h @@ -15,11 +15,21 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H #define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H +#include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" namespace llvm { namespace orc { +class NullResolver : public SymbolResolver { +public: + SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, + const SymbolNameSet &Symbols) override; + + SymbolNameSet lookup(AsynchronousSymbolQuery &Query, + SymbolNameSet Symbols) override; +}; + /// SymbolResolver impliementation that rejects all resolution requests. /// Useful for clients that have no cross-object fixups. class NullLegacyResolver : public LegacyJITSymbolResolver { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index cb47e7520b1..46bf21437c9 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -15,6 +15,7 @@ #define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include <algorithm> #include <memory> #include <string> @@ -44,9 +45,8 @@ public: /// /// @return A handle for the added objects. template <typename ObjectPtr> - Expected<ObjHandleT> addObject(ObjectPtr Obj, - std::shared_ptr<JITSymbolResolver> Resolver) { - return BaseLayer.addObject(Transform(std::move(Obj)), std::move(Resolver)); + Expected<ObjHandleT> 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. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 246c57341f3..073d48e09d5 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -18,6 +18,8 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Legacy.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" @@ -55,7 +57,7 @@ protected: void operator=(const LinkedObject&) = delete; virtual ~LinkedObject() = default; - virtual void finalize() = 0; + virtual Error finalize() = 0; virtual JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) = 0; @@ -107,21 +109,17 @@ public: using NotifyFinalizedFtor = std::function<void(ObjHandleT)>; private: - - - template <typename MemoryManagerPtrT, typename SymbolResolverPtrT, - typename FinalizerFtor> + template <typename MemoryManagerPtrT, typename FinalizerFtor> class ConcreteLinkedObject : public LinkedObject { public: - ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver, - FinalizerFtor Finalizer, - bool ProcessAllSections) - : MemMgr(std::move(MemMgr)), - PFC(llvm::make_unique<PreFinalizeContents>(std::move(Obj), - std::move(Resolver), - std::move(Finalizer), - ProcessAllSections)) { + ConcreteLinkedObject(ExecutionSession &ES, ObjectPtr Obj, + MemoryManagerPtrT MemMgr, + std::shared_ptr<SymbolResolver> Resolver, + FinalizerFtor Finalizer, bool ProcessAllSections) + : MemMgr(std::move(MemMgr)), + PFC(llvm::make_unique<PreFinalizeContents>( + ES, std::move(Obj), std::move(Resolver), std::move(Finalizer), + ProcessAllSections)) { buildInitialSymbolTable(PFC->Obj); } @@ -133,32 +131,32 @@ private: PFC->Handle = H; } - void finalize() override { + Error finalize() override { assert(PFC && "mapSectionAddress called on finalized LinkedObject"); - RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver); + JITSymbolResolverAdapter ResolverAdapter(PFC->ES, *PFC->Resolver); + RuntimeDyld RTDyld(*MemMgr, ResolverAdapter); RTDyld.setProcessAllSections(PFC->ProcessAllSections); PFC->RTDyld = &RTDyld; this->Finalized = true; - PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj), - [&]() { - this->updateSymbolTable(RTDyld); - }); + auto Err = PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj), + [&]() { this->updateSymbolTable(RTDyld); }); // Release resources. PFC = nullptr; + return Err; } JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override { - return - [this, Name]() { - // The symbol may be materialized between the creation of this lambda - // and its execution, so we need to double check. - if (!this->Finalized) - this->finalize(); - return this->getSymbol(Name, false).getAddress(); - }; + return [this, Name]() -> Expected<JITTargetAddress> { + // The symbol may be materialized between the creation of this lambda + // and its execution, so we need to double check. + if (!this->Finalized) + if (auto Err = this->finalize()) + return std::move(Err); + return this->getSymbol(Name, false).getAddress(); + }; } void mapSectionAddress(const void *LocalAddress, @@ -194,14 +192,16 @@ private: // Contains the information needed prior to finalization: the object files, // memory manager, resolver, and flags needed for RuntimeDyld. struct PreFinalizeContents { - PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver, + PreFinalizeContents(ExecutionSession &ES, ObjectPtr Obj, + std::shared_ptr<SymbolResolver> Resolver, FinalizerFtor Finalizer, bool ProcessAllSections) - : Obj(std::move(Obj)), Resolver(std::move(Resolver)), - Finalizer(std::move(Finalizer)), - ProcessAllSections(ProcessAllSections) {} + : ES(ES), Obj(std::move(Obj)), Resolver(std::move(Resolver)), + Finalizer(std::move(Finalizer)), + ProcessAllSections(ProcessAllSections) {} + ExecutionSession &ES; ObjectPtr Obj; - SymbolResolverPtrT Resolver; + std::shared_ptr<SymbolResolver> Resolver; FinalizerFtor Finalizer; bool ProcessAllSections; ObjHandleT Handle; @@ -212,17 +212,14 @@ private: std::unique_ptr<PreFinalizeContents> PFC; }; - template <typename MemoryManagerPtrT, typename SymbolResolverPtrT, - typename FinalizerFtor> - std::unique_ptr< - ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, FinalizerFtor>> - createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver, - FinalizerFtor Finalizer, - bool ProcessAllSections) { - using LOS = ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, - FinalizerFtor>; - return llvm::make_unique<LOS>(std::move(Obj), std::move(MemMgr), + template <typename MemoryManagerPtrT, typename FinalizerFtor> + std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT, FinalizerFtor>> + createLinkedObject(ExecutionSession &ES, ObjectPtr Obj, + MemoryManagerPtrT MemMgr, + std::shared_ptr<SymbolResolver> Resolver, + FinalizerFtor Finalizer, bool ProcessAllSections) { + using LOS = ConcreteLinkedObject<MemoryManagerPtrT, FinalizerFtor>; + return llvm::make_unique<LOS>(ES, std::move(Obj), std::move(MemMgr), std::move(Resolver), std::move(Finalizer), ProcessAllSections); } @@ -231,18 +228,23 @@ public: /// @brief Functor for creating memory managers. using MemoryManagerGetter = - std::function<std::shared_ptr<RuntimeDyld::MemoryManager>()>; + std::function<std::shared_ptr<RuntimeDyld::MemoryManager>(VModuleKey)>; + + using ResolverGetter = + std::function<std::shared_ptr<SymbolResolver>(VModuleKey)>; /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded, /// and NotifyFinalized functors. RTDyldObjectLinkingLayer( - MemoryManagerGetter GetMemMgr, + ExecutionSession &ES, MemoryManagerGetter GetMemMgr, + ResolverGetter GetResolver, NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor()) - : GetMemMgr(GetMemMgr), + : ES(ES), GetMemMgr(std::move(GetMemMgr)), + GetResolver(std::move(GetResolver)), NotifyLoaded(std::move(NotifyLoaded)), - NotifyFinalized(std::move(NotifyFinalized)), - ProcessAllSections(false) {} + NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) { + } /// @brief Set the 'ProcessAllSections' flag. /// @@ -258,11 +260,10 @@ public: /// /// @return A handle that can be used to refer to the loaded object (for /// symbol searching, finalization, freeing memory, etc.). - Expected<ObjHandleT> addObject(ObjectPtr Obj, - std::shared_ptr<JITSymbolResolver> Resolver) { + Expected<ObjHandleT> addObject(VModuleKey K, ObjectPtr Obj) { auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld, const ObjectPtr &ObjToLoad, - std::function<void()> LOSHandleLoad) { + std::function<void()> LOSHandleLoad) -> Error { std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info = RTDyld.loadObject(*ObjToLoad->getBinary()); @@ -273,14 +274,19 @@ public: RTDyld.finalizeWithMemoryManagerLocking(); + if (RTDyld.hasError()) + return make_error<StringError>(RTDyld.getErrorString(), + inconvertibleErrorCode()); + if (this->NotifyFinalized) this->NotifyFinalized(H); + + return Error::success(); }; auto LO = - createLinkedObject(std::move(Obj), GetMemMgr(), - std::move(Resolver), std::move(Finalizer), - ProcessAllSections); + 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(); @@ -339,15 +345,13 @@ public: /// @brief Immediately emit and finalize the object represented by the given /// handle. /// @param H Handle for object to emit/finalize. - Error emitAndFinalize(ObjHandleT H) { - (*H)->finalize(); - return Error::success(); - } + Error emitAndFinalize(ObjHandleT H) { return (*H)->finalize(); } private: - + ExecutionSession &ES; LinkedObjectListT LinkedObjList; MemoryManagerGetter GetMemMgr; + ResolverGetter GetResolver; NotifyLoadedFtor NotifyLoaded; NotifyFinalizedFtor NotifyFinalized; bool ProcessAllSections = false; |

