diff options
10 files changed, 227 insertions, 163 deletions
diff --git a/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp b/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp index f075af156c2..0940578ec0b 100644 --- a/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp +++ b/llvm/examples/Kaleidoscope/Orc/initial/toy.cpp @@ -1149,8 +1149,8 @@ public: // new module. Create one that resolves symbols by looking back into the JIT. auto MM = createLookasideRTDyldMM<SectionMemoryManager>( [&](const std::string &S) { - return getMangledSymbolAddress(S); - }, + return findMangledSymbol(S).getAddress(); + }, [](const std::string &S) { return 0; } ); return CompileLayer.addModuleSet(std::move(S), std::move(MM)); @@ -1158,17 +1158,17 @@ public: void removeModule(ModuleHandleT H) { CompileLayer.removeModuleSet(H); } - uint64_t getMangledSymbolAddress(const std::string &Name) { - return CompileLayer.getSymbolAddress(Name, false); + JITSymbol findMangledSymbol(const std::string &Name) { + return CompileLayer.findSymbol(Name, false); } - uint64_t getSymbolAddress(const std::string Name) { + JITSymbol findSymbol(const std::string Name) { std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); Mang.getNameWithPrefix(MangledNameStream, Name); } - return getMangledSymbolAddress(MangledName); + return findMangledSymbol(MangledName); } private: @@ -1228,11 +1228,11 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { auto H = J.addModule(C.takeM()); // Get the address of the JIT'd function in memory. - uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr"); + auto ExprSymbol = J.findSymbol("__anon_expr"); // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr; + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); #ifdef MINIMAL_STDERR_OUTPUT FP(); #else diff --git a/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp b/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp index 1a2043f5933..7125cba0f40 100644 --- a/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp +++ b/llvm/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp @@ -1150,8 +1150,8 @@ public: // new module. Create one that resolves symbols by looking back into the JIT. auto MM = createLookasideRTDyldMM<SectionMemoryManager>( [&](const std::string &S) { - return getMangledSymbolAddress(S); - }, + return findMangledSymbol(S).getAddress(); + }, [](const std::string &S) { return 0; } ); return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM)); @@ -1159,17 +1159,17 @@ public: void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); } - uint64_t getMangledSymbolAddress(const std::string &Name) { - return LazyEmitLayer.getSymbolAddress(Name, false); + JITSymbol findMangledSymbol(const std::string &Name) { + return LazyEmitLayer.findSymbol(Name, false); } - uint64_t getSymbolAddress(const std::string Name) { + JITSymbol findSymbol(const std::string Name) { std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); Mang.getNameWithPrefix(MangledNameStream, Name); } - return getMangledSymbolAddress(MangledName); + return findMangledSymbol(MangledName); } private: @@ -1230,11 +1230,11 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { auto H = J.addModule(C.takeM()); // Get the address of the JIT'd function in memory. - uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr"); + auto ExprSymbol = J.findSymbol("__anon_expr"); // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr; + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); #ifdef MINIMAL_STDERR_OUTPUT FP(); #else diff --git a/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp b/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp index 2963f30e2ed..11a17dd9aee 100644 --- a/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp +++ b/llvm/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp @@ -1174,8 +1174,8 @@ public: auto MM = createLookasideRTDyldMM<SectionMemoryManager>( [&](const std::string &Name) -> uint64_t { // First try to find 'Name' within the JIT. - if (uint64_t Addr = getMangledSymbolAddress(Name)) - return Addr; + if (auto Symbol = findMangledSymbol(Name)) + return Symbol.getAddress(); // If we don't find 'Name' in the JIT, see if we have some AST // for it. @@ -1192,8 +1192,8 @@ public: // finished with it. Session.FunctionDefs.erase(DefI); - return getMangledSymbolAddress(Name); - }, + return findMangledSymbol(Name).getAddress(); + }, [](const std::string &S) { return 0; } ); return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM)); @@ -1201,12 +1201,12 @@ public: void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); } - uint64_t getMangledSymbolAddress(const std::string &Name) { - return LazyEmitLayer.getSymbolAddress(Name, false); + JITSymbol findMangledSymbol(const std::string &Name) { + return LazyEmitLayer.findSymbol(Name, false); } - uint64_t getSymbolAddress(const std::string &Name) { - return getMangledSymbolAddress(Mangle(Name)); + JITSymbol findSymbol(const std::string &Name) { + return findMangledSymbol(Mangle(Name)); } private: @@ -1253,11 +1253,11 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { auto H = J.addModule(C.takeM()); // Get the address of the JIT'd function in memory. - uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr"); + auto ExprSymbol = J.findSymbol("__anon_expr"); // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr; + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); #ifdef MINIMAL_STDERR_OUTPUT FP(); #else diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 31eb1430943..25381f1bdd8 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -78,24 +78,25 @@ public: void removeLogicalModule(LMHandle LMH) { Handles.erase(LMH); } /// @brief Look up a symbol in this context. - uint64_t lookup(LMHandle LMH, const std::string &Name) { - if (uint64_t Addr = lookupOnlyIn(LMH, Name)) - return Addr; + JITSymbol findSymbol(LMHandle LMH, const std::string &Name) { + if (auto Symbol = findSymbolIn(LMH, Name)) + return Symbol; for (auto I = Handles.begin(), E = Handles.end(); I != E; ++I) if (I != LMH) - if (uint64_t Addr = lookupOnlyIn(I, Name)) - return Addr; + if (auto Symbol = findSymbolIn(I, Name)) + return Symbol; - return 0; + return nullptr; } private: - uint64_t lookupOnlyIn(LMHandle LMH, const std::string &Name) { + + JITSymbol findSymbolIn(LMHandle LMH, const std::string &Name) { for (auto H : *LMH) - if (uint64_t Addr = BaseLayer.lookupSymbolAddressIn(H, Name, false)) - return Addr; - return 0; + if (auto Symbol = BaseLayer.findSymbolIn(H, Name, false)) + return Symbol; + return nullptr; } BaseLayerT &BaseLayer; @@ -190,7 +191,9 @@ public: MSI.JITResolveCallbackHandlers.push_back( createCallbackHandlerFromJITIndirections( Indirections, MSI.PersistentManglers.back(), - [=](StringRef S) { return DylibLookup->lookup(LMH, S); })); + [=](StringRef S) { + return DylibLookup->findSymbol(LMH, S).getAddress(); + })); // Insert callback asm code into the first module. InsertCallbackAsm(*ExplodedModules[0], @@ -209,12 +212,12 @@ public: std::move(MSet), createLookasideRTDyldMM<SectionMemoryManager>( [=](const std::string &Name) { - if (uint64_t Addr = DylibLookup->lookup(LMH, Name)) - return Addr; - return getSymbolAddress(Name, true); + if (auto Symbol = DylibLookup->findSymbol(LMH, Name)) + return Symbol.getAddress(); + return findSymbol(Name, true).getAddress(); }, [=](const std::string &Name) { - return DylibLookup->lookup(LMH, Name); + return DylibLookup->findSymbol(LMH, Name).getAddress(); })); DylibLookup->addToLogicalModule(LMH, H); MSI.BaseLayerModuleSetHandles.push_back(H); @@ -222,7 +225,7 @@ public: initializeFuncAddrs(*MSI.JITResolveCallbackHandlers.back(), Indirections, MSI.PersistentManglers.back(), [=](StringRef S) { - return DylibLookup->lookup(LMH, S); + return DylibLookup->findSymbol(LMH, S).getAddress(); }); } @@ -238,23 +241,24 @@ public: ModuleSetInfos.erase(H); } - /// @brief Get the address of a symbol provided by this layer, or some layer - /// below this one. - uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) { - return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly); + /// @brief Search for the given named symbol. + /// @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 exists. + JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { + return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } /// @brief Get the address of a symbol provided by this layer, or some layer /// below this one. - uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name, - bool ExportedSymbolsOnly) { + JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + bool ExportedSymbolsOnly) { BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second; for (auto &BH : BaseLayerHandles) { - if (uint64_t Addr = - BaseLayer.lookupSymbolAddressIn(BH, Name, ExportedSymbolsOnly)) - return Addr; + if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly)) + return Symbol; } - return 0; + return nullptr; } private: diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index 3076c12089a..873deb67376 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H #define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H +#include "JITSymbol.h" #include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/Object/ObjectFile.h" @@ -89,18 +90,25 @@ public: /// @brief Remove the module set associated with the handle H. void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); } - /// @brief Get the address of a loaded symbol. This call is forwarded to the - /// base layer's getSymbolAddress implementation. - uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) { - return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly); + /// @brief Search for the given named symbol. + /// @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 exists. + JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { + return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } /// @brief Get the address of the given symbol in the context of the set of /// compiled modules represented by the handle H. This call is /// forwarded to the base layer's implementation. - uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name, - bool ExportedSymbolsOnly) { - return BaseLayer.lookupSymbolAddressIn(H, Name, ExportedSymbolsOnly); + /// @param H The handle for the module 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 module set. + JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + bool ExportedSymbolsOnly) { + return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } private: diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index 151b040be84..0bc71bfdf33 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H #define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H +#include "JITSymbol.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include <sstream> @@ -84,7 +85,7 @@ public: /// /// This is expected to be called by code in the JIT process itself, in /// order to resolve a function. - virtual uint64_t resolve(StubIndex StubIdx) = 0; + virtual TargetAddress resolve(StubIndex StubIdx) = 0; private: FuncNameList FuncNames; @@ -97,9 +98,9 @@ public: JITResolveCallbackHandlerImpl(LookupFtor Lookup, UpdateFtor Update) : Lookup(std::move(Lookup)), Update(std::move(Update)) {} - uint64_t resolve(StubIndex StubIdx) override { + TargetAddress resolve(StubIndex StubIdx) override { const std::string &FuncName = getFuncName(StubIdx); - uint64_t Addr = Lookup(FuncName); + TargetAddress Addr = Lookup(FuncName); Update(FuncName, Addr); return Addr; } @@ -211,10 +212,10 @@ createCallbackHandlerFromJITIndirections(const JITIndirections &Indirs, [=](const std::string &S) { return Lookup(NM.getMangledName(GetImplName(S))); }, - [=](const std::string &S, uint64_t Addr) { + [=](const std::string &S, TargetAddress Addr) { void *ImplPtr = reinterpret_cast<void *>( Lookup(NM.getMangledName(GetAddrName(S)))); - memcpy(ImplPtr, &Addr, sizeof(uint64_t)); + memcpy(ImplPtr, &Addr, sizeof(TargetAddress)); }); for (const auto &FuncName : Indirs.IndirectedNames) @@ -248,12 +249,12 @@ void initializeFuncAddrs(JITResolveCallbackHandler &J, // Now update indirects to point to the JIT resolve callback asm. for (JITResolveCallbackHandler::StubIndex I = 0; I < J.getNumFuncs(); ++I) { - uint64_t ResolveCallbackIdxAddr = + TargetAddress ResolveCallbackIdxAddr = Lookup(getJITResolveCallbackIndexLabel(I)); void *AddrPtr = reinterpret_cast<void *>( Lookup(NM.getMangledName(Indirs.GetAddrName(J.getFuncName(I))))); assert(AddrPtr && "Can't find stub addr global to initialize."); - memcpy(AddrPtr, &ResolveCallbackIdxAddr, sizeof(uint64_t)); + memcpy(AddrPtr, &ResolveCallbackIdxAddr, sizeof(TargetAddress)); } } diff --git a/llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h new file mode 100644 index 00000000000..c55e43c2a17 --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/JITSymbol.h @@ -0,0 +1,55 @@ +//===----------- JITSymbol.h - JIT symbol abstraction -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Abstraction for target process addresses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H +#define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H + +#include <functional> + +namespace llvm { + +/// @brief Represents an address in the target process's address space. +typedef uint64_t TargetAddress; + +/// @brief Represents a symbol in the JIT. +class JITSymbol { +public: + typedef std::function<TargetAddress()> GetAddressFtor; + + JITSymbol(std::nullptr_t) : CachedAddr(0) {} + + JITSymbol(GetAddressFtor GetAddress) + : CachedAddr(0), GetAddress(std::move(GetAddress)) {} + + /// @brief Returns true if the symbol exists, false otherwise. + explicit operator bool() const { return CachedAddr || GetAddress; } + + /// @brief Get the address of the symbol in the target address space. Returns + /// '0' if the symbol does not exist. + TargetAddress getAddress() { + if (GetAddress) { + CachedAddr = GetAddress(); + assert(CachedAddr && "Symbol could not be materialized."); + GetAddress = nullptr; + } + return CachedAddr; + } + +private: + TargetAddress CachedAddr; + GetAddressFtor GetAddress; +}; + +} + +#endif // LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 428a263e202..a56f8b6f9a2 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H #define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H +#include "JITSymbol.h" #include "LookasideRTDyldMM.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/IR/GlobalValue.h" @@ -26,8 +27,8 @@ namespace llvm { /// /// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does /// not immediately emit them the layer below. Instead, emissing to the base -/// layer is deferred until some symbol in the module set is requested via -/// getSymbolAddress. +/// layer 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: typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT; @@ -38,32 +39,37 @@ private: EmissionDeferredSet() : EmitState(NotEmitted) {} virtual ~EmissionDeferredSet() {} - uint64_t Search(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { + JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { - case NotEmitted: - if (Provides(Name, ExportedSymbolsOnly)) { - EmitState = Emitting; - Handle = Emit(B); - EmitState = Emitted; - } else - return 0; - break; - case Emitting: - // The module has been added to the base layer but we haven't gotten a - // handle back yet so we can't use lookupSymbolAddressIn. Just return - // '0' here - LazyEmittingLayer::getSymbolAddress will do a global - // search in the base layer when it doesn't find the symbol here, so - // we'll find it in the end. - return 0; - case Emitted: - // Nothing to do. Go ahead and search the base layer. - break; + case NotEmitted: + if (provides(Name, ExportedSymbolsOnly)) + return JITSymbol( + [this,ExportedSymbolsOnly,Name,&B]() -> TargetAddress { + if (EmitState == Emitting) + return 0; + else if (EmitState != Emitted) { + EmitState = Emitting; + Handle = emit(B); + EmitState = Emitted; + } + return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly) + .getAddress(); + }); + else + return nullptr; + case Emitting: + // Calling "emit" can trigger external symbol lookup (e.g. to check for + // pre-existing definitions of common-symbol), but it will never find in + // this module that it would not have found already, so return null from + // here. + return nullptr; + case Emitted: + return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly); } - - return B.lookupSymbolAddressIn(Handle, Name, ExportedSymbolsOnly); + llvm_unreachable("Invalid emit-state."); } - void RemoveModulesFromBaseLayer(BaseLayerT &BaseLayer) { + void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { if (EmitState != NotEmitted) BaseLayer.removeModuleSet(Handle); } @@ -74,8 +80,8 @@ private: std::unique_ptr<RTDyldMemoryManager> MM); protected: - virtual bool Provides(StringRef Name, bool ExportedSymbolsOnly) const = 0; - virtual BaseLayerHandleT Emit(BaseLayerT &BaseLayer) = 0; + virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0; + virtual BaseLayerHandleT emit(BaseLayerT &BaseLayer) = 0; private: enum { NotEmitted, Emitting, Emitted } EmitState; @@ -90,14 +96,14 @@ private: : Ms(std::move(Ms)), MM(std::move(MM)) {} protected: - BaseLayerHandleT Emit(BaseLayerT &BaseLayer) override { + BaseLayerHandleT emit(BaseLayerT &BaseLayer) override { // 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. MangledNames.reset(); return BaseLayer.addModuleSet(std::move(Ms), std::move(MM)); } - bool Provides(StringRef Name, bool ExportedSymbolsOnly) const override { + bool provides(StringRef Name, bool ExportedSymbolsOnly) const override { // FIXME: We could clean all this up if we had a way to reliably demangle // names: We could just demangle name and search, rather than // mangling everything else. @@ -190,12 +196,6 @@ public: LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} /// @brief Add the given set of modules to the lazy emitting layer. - /// - /// This method stores the set of modules in a side table, rather than - /// immediately emitting them to the next layer of the JIT. When the address - /// of a symbol provided by this set is requested (via getSymbolAddress) it - /// triggers the emission of this set to the layer below (along with the given - /// memory manager instance), and returns the address of the requested symbol. template <typename ModuleSetT> ModuleSetHandleT addModuleSet(ModuleSetT Ms, std::unique_ptr<RTDyldMemoryManager> MM) { @@ -209,39 +209,35 @@ public: /// This method will free the memory associated with the given module set, /// both in this layer, and the base layer. void removeModuleSet(ModuleSetHandleT H) { - (*H)->RemoveModulesFromBaseLayer(BaseLayer); + (*H)->removeModulesFromBaseLayer(BaseLayer); ModuleSetList.erase(H); } - /// @brief Get the address of a symbol provided by this layer, or some layer - /// below this one. - /// - /// When called for a symbol that has been added to this layer (via - /// addModuleSet) but not yet emitted, this will trigger the emission of the - /// module set containing the definiton of the symbol. - uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) { - // Look up symbol among existing definitions. - if (uint64_t Addr = BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly)) - return Addr; - - // If not found then search the deferred sets. The call to 'Search' will - // cause the set to be emitted to the next layer if it provides a definition - // of 'Name'. + /// @brief Search for the given named symbol. + /// @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 exists. + JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { + // Look for the symbol among existing definitions. + if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly)) + return Symbol; + + // If not found then search the deferred sets. 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 &DeferredSet : ModuleSetList) - if (uint64_t Addr = - DeferredSet->Search(Name, ExportedSymbolsOnly, BaseLayer)) - return Addr; + if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer)) + return Symbol; - // If no definition found anywhere return 0. - return 0; + // If no definition found anywhere return a null symbol. + return nullptr; } /// @brief Get the address of the given symbol in the context of the set of - /// compiled modules represented by the handle H. This call is - /// forwarded to the base layer's implementation. - uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name, - bool ExportedSymbolsOnly) { - return (*H)->Search(Name, ExportedSymbolsOnly, BaseLayer); + /// compiled modules represented by the handle H. + JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + bool ExportedSymbolsOnly) { + return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer); } }; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index 957fec40ad3..ce306e67dde 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H #define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H +#include "JITSymbol.h" #include "LookasideRTDyldMM.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" @@ -24,6 +25,7 @@ namespace llvm { class ObjectLinkingLayerBase { protected: + /// @brief Holds a set of objects to be allocated/linked as a unit in the JIT. /// /// An instance of this class will be created for each set of objects added @@ -48,7 +50,7 @@ protected: return RTDyld->loadObject(Obj); } - uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) { + TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) { if (ExportedSymbolsOnly) return RTDyld->getExportedSymbolLoadAddress(Name); return RTDyld->getSymbolLoadAddress(Name); @@ -65,10 +67,10 @@ protected: State = Finalized; } - void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) { + void mapSectionAddress(const void *LocalAddress, TargetAddress TargetAddr) { assert((State != Finalized) && "Attempting to remap sections for finalized objects."); - RTDyld->mapSectionAddress(LocalAddress, TargetAddress); + RTDyld->mapSectionAddress(LocalAddress, TargetAddr); } void takeOwnershipOfBuffer(std::unique_ptr<MemoryBuffer> B) { @@ -178,8 +180,8 @@ public: /// @brief Map section addresses for the objects associated with the handle H. void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress, - uint64_t TargetAddress) { - H->mapSectionAddress(LocalAddress, TargetAddress); + TargetAddress TargetAddr) { + H->mapSectionAddress(LocalAddress, TargetAddr); } /// @brief Remove the set of objects associated with handle H. @@ -195,42 +197,40 @@ public: LinkedObjSetList.erase(H); } - /// @brief Get the address of a loaded symbol. - /// - /// @return The address in the target process's address space of the named - /// symbol. Null if no such symbol is known. - /// - /// This method will trigger the finalization of the linked object set - /// containing the definition of the given symbol, if it is found. - uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) { + /// @brief Search for the given named symbol. + /// @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 exists. + JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E; ++I) - if (uint64_t Addr = lookupSymbolAddressIn(I, Name, ExportedSymbolsOnly)) - return Addr; + if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly)) + return Symbol; - return 0; + return nullptr; } - /// @brief Search for a given symbol in the context of the set of loaded - /// objects represented by the handle H. - /// - /// @return The address in the target process's address space of the named - /// symbol. Null if the given object set does not contain a definition - /// of this symbol. - /// - /// This method will trigger the finalization of the linked object set - /// represented by the handle H if that set contains the requested symbol. - uint64_t lookupSymbolAddressIn(ObjSetHandleT H, StringRef Name, - bool ExportedSymbolsOnly) { - if (uint64_t Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) { - if (H->NeedsFinalization()) { - H->Finalize(); - if (NotifyFinalized) - NotifyFinalized(H); - } - return Addr; - } - return 0; + /// @brief Search for the given named symbol in the context of the set of + /// loaded objects represented by the handle H. + /// @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(ObjSetHandleT H, StringRef Name, + bool ExportedSymbolsOnly) { + if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) + return JITSymbol( + [this, Addr, H](){ + if (H->NeedsFinalization()) { + H->Finalize(); + if (NotifyFinalized) + NotifyFinalized(H); + } + return Addr; + }); + + return nullptr; } private: diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index ddbc73251c7..f09d13e87bd 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -213,7 +213,7 @@ public: private: uint64_t getSymbolAddressWithoutMangling(StringRef Name) { - if (uint64_t Addr = LazyEmitLayer.getSymbolAddress(Name, false)) + if (uint64_t Addr = LazyEmitLayer.findSymbol(Name, false).getAddress()) return Addr; if (uint64_t Addr = MM->getSymbolAddress(Name)) return Addr; @@ -241,7 +241,7 @@ private: static_cast<object::ObjectFile *>(ChildBin.release()))); ObjectLayer.addObjectSet( std::move(ObjSet), llvm::make_unique<ForwardingRTDyldMM>(*this)); - if (uint64_t Addr = ObjectLayer.getSymbolAddress(Name, true)) + if (uint64_t Addr = ObjectLayer.findSymbol(Name, true).getAddress()) return Addr; } } |

