[ORC] Refactor TrampolinePool to reduce virtual function calls.
authorLang Hames <lhames@gmail.com>
Mon, 20 Jul 2020 05:33:27 +0000 (22:33 -0700)
committerLang Hames <lhames@gmail.com>
Mon, 20 Jul 2020 05:38:41 +0000 (22:38 -0700)
Virtual function calls are now only made when the pool needs to be
grown to accommodate o new request.

llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h
llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
llvm/lib/ExecutionEngine/Orc/TPCIndirectionUtils.cpp
llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp

index e0cfd8b..78e3cee 100644 (file)
@@ -62,14 +62,33 @@ public:
       JITTargetAddress TrampolineAddr,
       NotifyLandingResolvedFunction OnLandingResolved) const>;
 
-  virtual ~TrampolinePool() {}
+  virtual ~TrampolinePool();
 
   /// Get an available trampoline address.
   /// Returns an error if no trampoline can be created.
-  virtual Expected<JITTargetAddress> getTrampoline() = 0;
+  Expected<JITTargetAddress> getTrampoline() {
+    std::lock_guard<std::mutex> Lock(TPMutex);
+    if (AvailableTrampolines.empty()) {
+      if (auto Err = grow())
+        return std::move(Err);
+    }
+    assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
+    auto TrampolineAddr = AvailableTrampolines.back();
+    AvailableTrampolines.pop_back();
+    return TrampolineAddr;
+  }
 
-private:
-  virtual void anchor();
+  /// Returns the given trampoline to the pool for re-use.
+  void releaseTrampoline(JITTargetAddress TrampolineAddr) {
+    std::lock_guard<std::mutex> Lock(TPMutex);
+    AvailableTrampolines.push_back(TrampolineAddr);
+  }
+
+protected:
+  virtual Error grow() = 0;
+
+  std::mutex TPMutex;
+  std::vector<JITTargetAddress> AvailableTrampolines;
 };
 
 /// A trampoline pool for trampolines within the current process.
@@ -90,26 +109,6 @@ public:
     return std::move(LTP);
   }
 
-  /// Get a free trampoline. Returns an error if one can not be provided (e.g.
-  /// because the pool is empty and can not be grown).
-  Expected<JITTargetAddress> getTrampoline() override {
-    std::lock_guard<std::mutex> Lock(LTPMutex);
-    if (AvailableTrampolines.empty()) {
-      if (auto Err = grow())
-        return std::move(Err);
-    }
-    assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
-    auto TrampolineAddr = AvailableTrampolines.back();
-    AvailableTrampolines.pop_back();
-    return TrampolineAddr;
-  }
-
-  /// Returns the given trampoline to the pool for re-use.
-  void releaseTrampoline(JITTargetAddress TrampolineAddr) {
-    std::lock_guard<std::mutex> Lock(LTPMutex);
-    AvailableTrampolines.push_back(TrampolineAddr);
-  }
-
 private:
   static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
     LocalTrampolinePool<ORCABI> *TrampolinePool =
@@ -154,8 +153,8 @@ private:
     }
   }
 
-  Error grow() {
-    assert(this->AvailableTrampolines.empty() && "Growing prematurely?");
+  Error grow() override {
+    assert(AvailableTrampolines.empty() && "Growing prematurely?");
 
     std::error_code EC;
     auto TrampolineBlock =
@@ -175,7 +174,7 @@ private:
         pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
 
     for (unsigned I = 0; I < NumTrampolines; ++I)
-      this->AvailableTrampolines.push_back(pointerToJITTargetAddress(
+      AvailableTrampolines.push_back(pointerToJITTargetAddress(
           TrampolineMem + (I * ORCABI::TrampolineSize)));
 
     if (auto EC = sys::Memory::protectMappedMemory(
@@ -189,10 +188,8 @@ private:
 
   ResolveLandingFunction ResolveLanding;
 
-  std::mutex LTPMutex;
   sys::OwningMemoryBlock ResolverBlock;
   std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
-  std::vector<JITTargetAddress> AvailableTrampolines;
 };
 
 /// Target-independent base class for compile callback management.
index 86e8d5d..809e7cd 100644 (file)
@@ -453,18 +453,6 @@ public:
   public:
     RemoteTrampolinePool(OrcRemoteTargetClient &Client) : Client(Client) {}
 
-    Expected<JITTargetAddress> getTrampoline() override {
-      std::lock_guard<std::mutex> Lock(RTPMutex);
-      if (AvailableTrampolines.empty()) {
-        if (auto Err = grow())
-          return std::move(Err);
-      }
-      assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
-      auto TrampolineAddr = AvailableTrampolines.back();
-      AvailableTrampolines.pop_back();
-      return TrampolineAddr;
-    }
-
   private:
     Error grow() {
       JITTargetAddress BlockAddr = 0;
@@ -476,14 +464,12 @@ public:
 
       uint32_t TrampolineSize = Client.getTrampolineSize();
       for (unsigned I = 0; I < NumTrampolines; ++I)
-        this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
+        AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
 
       return Error::success();
     }
 
-    std::mutex RTPMutex;
     OrcRemoteTargetClient &Client;
-    std::vector<JITTargetAddress> AvailableTrampolines;
   };
 
   /// Remote compile callback manager.
index facafd8..cc0016e 100644 (file)
@@ -119,6 +119,8 @@ public:
   /// Return a MemoryAccess object for the target process.
   MemoryAccess &getMemoryAccess() const { return *MemAccess; }
 
+  /// Load the library at the given path.
+
 protected:
   TargetProcessControl(Triple TT, unsigned PageSize);
 
index 031b1af..4f7f608 100644 (file)
@@ -54,8 +54,8 @@ private:
 namespace llvm {
 namespace orc {
 
+TrampolinePool::~TrampolinePool() {}
 void IndirectStubsManager::anchor() {}
-void TrampolinePool::anchor() {}
 
 Expected<JITTargetAddress>
 JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) {
index 150040c..b4c21c3 100644 (file)
@@ -37,20 +37,16 @@ class TPCTrampolinePool : public TrampolinePool {
 public:
   TPCTrampolinePool(TPCIndirectionUtils &TPCIU);
   Error deallocatePool();
-  Expected<JITTargetAddress> getTrampoline() override;
-  void releaseTrampoline(JITTargetAddress TrampolineAddr);
 
 protected:
-  Error grow();
+  Error grow() override;
 
   using Allocation = jitlink::JITLinkMemoryManager::Allocation;
 
-  std::mutex TPMutex;
   TPCIndirectionUtils &TPCIU;
   unsigned TrampolineSize = 0;
   unsigned TrampolinesPerPage = 0;
   std::vector<std::unique_ptr<Allocation>> TrampolineBlocks;
-  std::vector<JITTargetAddress> AvailableTrampolines;
 };
 
 class TPCIndirectStubsManager : public IndirectStubsManager,
@@ -96,26 +92,8 @@ Error TPCTrampolinePool::deallocatePool() {
   return Err;
 }
 
-Expected<JITTargetAddress> TPCTrampolinePool::getTrampoline() {
-  std::lock_guard<std::mutex> Lock(TPMutex);
-  if (AvailableTrampolines.empty()) {
-    if (auto Err = grow())
-      return std::move(Err);
-  }
-
-  assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
-  auto TrampolineAddr = AvailableTrampolines.back();
-  AvailableTrampolines.pop_back();
-  return TrampolineAddr;
-}
-
-void TPCTrampolinePool::releaseTrampoline(JITTargetAddress TrampolineAddr) {
-  std::lock_guard<std::mutex> Lock(TPMutex);
-  AvailableTrampolines.push_back(TrampolineAddr);
-}
-
 Error TPCTrampolinePool::grow() {
-  assert(this->AvailableTrampolines.empty() &&
+  assert(AvailableTrampolines.empty() &&
          "Grow called with trampolines still available");
 
   auto ResolverAddress = TPCIU.getResolverBlockAddress();
@@ -144,7 +122,7 @@ Error TPCTrampolinePool::grow() {
 
   auto TargetAddr = (*Alloc)->getTargetMemory(TrampolinePagePermissions);
   for (unsigned I = 0; I < NumTrampolines; ++I)
-    this->AvailableTrampolines.push_back(TargetAddr + (I * TrampolineSize));
+    AvailableTrampolines.push_back(TargetAddr + (I * TrampolineSize));
 
   if (auto Err = (*Alloc)->finalize())
     return Err;
index a13d8bd..543c164 100644 (file)
@@ -16,10 +16,8 @@ using namespace llvm::orc;
 namespace {
 
 class DummyTrampolinePool : public orc::TrampolinePool {
-public:
-  Expected<JITTargetAddress> getTrampoline() override {
-    llvm_unreachable("Unimplemented");
-  }
+protected:
+  Error grow() override { llvm_unreachable("Unimplemented"); }
 };
 
 class DummyCallbackManager : public JITCompileCallbackManager {