[Orc] Add a new JITSymbol constructor to build a symbol from an existing address.
authorLang Hames <lhames@gmail.com>
Fri, 20 Feb 2015 06:48:29 +0000 (06:48 +0000)
committerLang Hames <lhames@gmail.com>
Fri, 20 Feb 2015 06:48:29 +0000 (06:48 +0000)
This constructor is more efficient for symbols that have already been emitted,
since it avoids the construction/execution of a std::function.

Update the ObjectLinkingLayer to use this new constructor where possible.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229973 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/Orc/JITSymbol.h
include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h

index c029757..c0b627e 100644 (file)
@@ -28,10 +28,25 @@ class JITSymbol {
 public:
   typedef std::function<TargetAddress()> GetAddressFtor;
 
+  /// @brief Create a 'null' symbol that represents failure to find a symbol
+  ///        definition.
   JITSymbol(std::nullptr_t) : CachedAddr(0) {}
 
+  /// @brief Create a symbol for a definition with a known address.
+  JITSymbol(TargetAddress Addr)
+    : CachedAddr(Addr) {}
+
+  /// @brief 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.
+  ///
+  ///   This constructor allows a JIT layer to provide a reference to a symbol
+  /// definition without actually materializing the definition up front. The
+  /// user can materialize the definition at any time by calling the getAddress
+  /// method.
   JITSymbol(GetAddressFtor GetAddress)
-      : CachedAddr(0), GetAddress(std::move(GetAddress)) {}
+    : CachedAddr(0), GetAddress(std::move(GetAddress)) {}
 
   /// @brief Returns true if the symbol exists, false otherwise.
   explicit operator bool() const { return CachedAddr || GetAddress; }
index 4dcb380..ad7c9eb 100644 (file)
@@ -213,16 +213,27 @@ public:
   ///         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;
-        });
+    if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
+      if (!H->NeedsFinalization()) {
+        // If this instance has already been finalized then we can just return
+        // the address.
+        return JITSymbol(Addr);
+      } else {
+        // If this instance needs finalization return a functor that will do it.
+        // The functor still needs to double-check whether finalization is
+        // required, in case someone else finalizes this set before the functor
+        // is called.
+        return JITSymbol(
+          [this, Addr, H]() {
+            if (H->NeedsFinalization()) {
+              H->Finalize();
+              if (NotifyFinalized)
+                NotifyFinalized(H);
+            }
+            return Addr;
+          });
+      }
+    }
 
     return nullptr;
   }