diff options
Diffstat (limited to 'include/llvm/ExecutionEngine/JITSymbol.h')
| -rw-r--r-- | include/llvm/ExecutionEngine/JITSymbol.h | 131 |
1 files changed, 98 insertions, 33 deletions
diff --git a/include/llvm/ExecutionEngine/JITSymbol.h b/include/llvm/ExecutionEngine/JITSymbol.h index 933b3ea8e13d..53037c3dbc72 100644 --- a/include/llvm/ExecutionEngine/JITSymbol.h +++ b/include/llvm/ExecutionEngine/JITSymbol.h @@ -19,8 +19,11 @@ #include <cstddef> #include <cstdint> #include <functional> +#include <map> +#include <set> #include <string> +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" namespace llvm { @@ -33,10 +36,10 @@ class BasicSymbolRef; } // end namespace object -/// @brief Represents an address in the target process's address space. +/// Represents an address in the target process's address space. using JITTargetAddress = uint64_t; -/// @brief Flags for symbols in the JIT. +/// Flags for symbols in the JIT. class JITSymbolFlags { public: using UnderlyingType = uint8_t; @@ -48,55 +51,74 @@ public: Weak = 1U << 1, Common = 1U << 2, Absolute = 1U << 3, - Exported = 1U << 4 + Exported = 1U << 4, + Lazy = 1U << 5, + Materializing = 1U << 6 }; - /// @brief Default-construct a JITSymbolFlags instance. + static JITSymbolFlags stripTransientFlags(JITSymbolFlags Orig) { + return static_cast<FlagNames>(Orig.Flags & ~Lazy & ~Materializing); + } + + /// Default-construct a JITSymbolFlags instance. JITSymbolFlags() = default; - /// @brief Construct a JITSymbolFlags instance from the given flags. + /// Construct a JITSymbolFlags instance from the given flags. JITSymbolFlags(FlagNames Flags) : Flags(Flags) {} - /// @brief Construct a JITSymbolFlags instance from the given flags and target + /// Construct a JITSymbolFlags instance from the given flags and target /// flags. JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags) : Flags(Flags), TargetFlags(TargetFlags) {} - /// @brief Return true if there was an error retrieving this symbol. + /// Return true if there was an error retrieving this symbol. bool hasError() const { return (Flags & HasError) == HasError; } - /// @brief Returns true if the Weak flag is set. + /// Returns true if this is a lazy symbol. + /// This flag is used internally by the JIT APIs to track + /// materialization states. + bool isLazy() const { return Flags & Lazy; } + + /// Returns true if this symbol is in the process of being + /// materialized. + bool isMaterializing() const { return Flags & Materializing; } + + /// Returns true if this symbol is fully materialized. + /// (i.e. neither lazy, nor materializing). + bool isMaterialized() const { return !(Flags & (Lazy | Materializing)); } + + /// Returns true if the Weak flag is set. bool isWeak() const { return (Flags & Weak) == Weak; } - /// @brief Returns true if the Common flag is set. + /// Returns true if the Common flag is set. bool isCommon() const { return (Flags & Common) == Common; } - /// @brief Returns true if the symbol isn't weak or common. - bool isStrongDefinition() const { + /// Returns true if the symbol isn't weak or common. + bool isStrong() const { return !isWeak() && !isCommon(); } - /// @brief Returns true if the Exported flag is set. + /// Returns true if the Exported flag is set. bool isExported() const { return (Flags & Exported) == Exported; } - /// @brief Implicitly convert to the underlying flags type. + /// Implicitly convert to the underlying flags type. operator UnderlyingType&() { return Flags; } - /// @brief Implicitly convert to the underlying flags type. + /// Implicitly convert to the underlying flags type. operator const UnderlyingType&() const { return Flags; } - /// @brief Return a reference to the target-specific flags. + /// Return a reference to the target-specific flags. TargetFlagsType& getTargetFlags() { return TargetFlags; } - /// @brief Return a reference to the target-specific flags. + /// Return a reference to the target-specific flags. const TargetFlagsType& getTargetFlags() const { return TargetFlags; } /// Construct a JITSymbolFlags value based on the flags of the given global @@ -112,7 +134,7 @@ private: TargetFlagsType TargetFlags = 0; }; -/// @brief ARM-specific JIT symbol flags. +/// ARM-specific JIT symbol flags. /// FIXME: This should be moved into a target-specific header. class ARMJITSymbolFlags { public: @@ -131,54 +153,59 @@ private: JITSymbolFlags::TargetFlagsType Flags = 0; }; -/// @brief Represents a symbol that has been evaluated to an address already. +/// Represents a symbol that has been evaluated to an address already. class JITEvaluatedSymbol { public: - /// @brief Create a 'null' symbol. + JITEvaluatedSymbol() = default; + + /// Create a 'null' symbol. JITEvaluatedSymbol(std::nullptr_t) {} - /// @brief Create a symbol for the given address and flags. + /// Create a symbol for the given address and flags. JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags) : Address(Address), Flags(Flags) {} - /// @brief An evaluated symbol converts to 'true' if its address is non-zero. + /// An evaluated symbol converts to 'true' if its address is non-zero. explicit operator bool() const { return Address != 0; } - /// @brief Return the address of this symbol. + /// Return the address of this symbol. JITTargetAddress getAddress() const { return Address; } - /// @brief Return the flags for this symbol. + /// Return the flags for this symbol. JITSymbolFlags getFlags() const { return Flags; } + /// Set the flags for this symbol. + void setFlags(JITSymbolFlags Flags) { this->Flags = std::move(Flags); } + private: JITTargetAddress Address = 0; JITSymbolFlags Flags; }; -/// @brief Represents a symbol in the JIT. +/// Represents a symbol in the JIT. class JITSymbol { public: using GetAddressFtor = std::function<Expected<JITTargetAddress>()>; - /// @brief Create a 'null' symbol, used to represent a "symbol not found" + /// Create a 'null' symbol, used to represent a "symbol not found" /// result from a successful (non-erroneous) lookup. JITSymbol(std::nullptr_t) : CachedAddr(0) {} - /// @brief Create a JITSymbol representing an error in the symbol lookup + /// Create a JITSymbol representing an error in the symbol lookup /// process (e.g. a network failure during a remote lookup). JITSymbol(Error Err) : Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {} - /// @brief Create a symbol for a definition with a known address. + /// Create a symbol for a definition with a known address. JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags) : CachedAddr(Addr), Flags(Flags) {} - /// @brief Construct a JITSymbol from a JITEvaluatedSymbol. + /// Construct a JITSymbol from a JITEvaluatedSymbol. JITSymbol(JITEvaluatedSymbol Sym) : CachedAddr(Sym.getAddress()), Flags(Sym.getFlags()) {} - /// @brief Create a symbol for a definition that doesn't have a known address + /// Create a symbol for a definition that doesn't have a known address /// yet. /// @param GetAddress A functor to materialize a definition (fixing the /// address) on demand. @@ -218,19 +245,19 @@ public: CachedAddr.~JITTargetAddress(); } - /// @brief Returns true if the symbol exists, false otherwise. + /// Returns true if the symbol exists, false otherwise. explicit operator bool() const { return !Flags.hasError() && (CachedAddr || GetAddress); } - /// @brief Move the error field value out of this JITSymbol. + /// Move the error field value out of this JITSymbol. Error takeError() { if (Flags.hasError()) return std::move(Err); return Error::success(); } - /// @brief Get the address of the symbol in the target address space. Returns + /// Get the address of the symbol in the target address space. Returns /// '0' if the symbol does not exist. Expected<JITTargetAddress> getAddress() { assert(!Flags.hasError() && "getAddress called on error value"); @@ -256,11 +283,49 @@ private: JITSymbolFlags Flags; }; -/// \brief Symbol resolution. +/// Symbol resolution interface. +/// +/// Allows symbol flags and addresses to be looked up by name. +/// Symbol queries are done in bulk (i.e. you request resolution of a set of +/// symbols, rather than a single one) to reduce IPC overhead in the case of +/// remote JITing, and expose opportunities for parallel compilation. class JITSymbolResolver { public: + using LookupSet = std::set<StringRef>; + using LookupResult = std::map<StringRef, JITEvaluatedSymbol>; + using LookupFlagsResult = std::map<StringRef, JITSymbolFlags>; + virtual ~JITSymbolResolver() = default; + /// Returns the fully resolved address and flags for each of the given + /// symbols. + /// + /// This method will return an error if any of the given symbols can not be + /// resolved, or if the resolution process itself triggers an error. + virtual Expected<LookupResult> lookup(const LookupSet &Symbols) = 0; + + /// Returns the symbol flags for each of the given symbols. + /// + /// This method does NOT return an error if any of the given symbols is + /// missing. Instead, that symbol will be left out of the result map. + virtual Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) = 0; + +private: + virtual void anchor(); +}; + +/// Legacy symbol resolution interface. +class LegacyJITSymbolResolver : public JITSymbolResolver { +public: + /// Performs lookup by, for each symbol, first calling + /// findSymbolInLogicalDylib and if that fails calling + /// findSymbol. + Expected<LookupResult> lookup(const LookupSet &Symbols) final; + + /// Performs flags lookup by calling findSymbolInLogicalDylib and + /// returning the flags value for that symbol. + Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) final; + /// This method returns the address of the specified symbol if it exists /// within the logical dynamic library represented by this JITSymbolResolver. /// Unlike findSymbol, queries through this interface should return addresses |
