[llvm] [ORC] Move EPCGenericJITLinkMemoryManager to RTBridge proxies (PR #215797)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 06:09:23 PDT 2026


https://github.com/lhames created https://github.com/llvm/llvm-project/pull/215797

Reimplement EPCGenericJITLinkMemoryManager's reserve/initialize/release calls using rt::Proxy objects rather than direct
ExecutorProcessControl::callSPSWrapperAsync calls, matching EPCGenericMemoryAccess and EPCGenericDylibManager. The manager's behavior is unchanged.

Details:

* SymbolAddrs (five ExecutorAddrs) becomes Bindings: the allocator instance address plus rt::Proxy handles.

* The proxy types and SPS specs are hoisted into shared headers -- RTBridge/GenericMemoryManagerProxies.h and RTBridge/SPS/GenericMemoryManagerProxySpecs.h -- since they now need only Shared/SPS vocabulary. Deinitialize is included in the family for completeness though this manager does not call it.

* Release is a single proxy over ArrayRef<ExecutorAddr>: abandon passes the allocation base directly, deallocate extracts base addresses from its FinalizedAllocs. This retires the SPSSerializationTraits<SPSExecutorAddr, FinalizedAlloc> specialization (previously used only to serialize vector<FinalizedAlloc> in deallocate).

* The spec signatures are declared inline, duplicating the SPSSimpleExecutorMemoryManager* signatures in OrcRTBridge.h; a follow-up will retire those.

>From 62600e5867ff55447f0e5040aea0ad6e2cfbd83e Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 12 Aug 2026 22:31:39 +1000
Subject: [PATCH] [ORC] Move EPCGenericJITLinkMemoryManager to RTBridge proxies

Reimplement EPCGenericJITLinkMemoryManager's reserve/initialize/release
calls using rt::Proxy objects rather than direct
ExecutorProcessControl::callSPSWrapperAsync calls, matching
EPCGenericMemoryAccess and EPCGenericDylibManager. The manager's
behavior is unchanged.

Details:

* SymbolAddrs (five ExecutorAddrs) becomes Bindings: the allocator
  instance address plus rt::Proxy handles.

* The proxy types and SPS specs are hoisted into shared headers --
  RTBridge/GenericMemoryManagerProxies.h and
  RTBridge/SPS/GenericMemoryManagerProxySpecs.h -- since they now need
  only Shared/SPS vocabulary. Deinitialize is included in the family for
  completeness though this manager does not call it.

* Release is a single proxy over ArrayRef<ExecutorAddr>: abandon passes
  the allocation base directly, deallocate extracts base addresses from
  its FinalizedAllocs. This retires the
  SPSSerializationTraits<SPSExecutorAddr, FinalizedAlloc> specialization
  (previously used only to serialize vector<FinalizedAlloc> in
  deallocate).

* The spec signatures are declared inline, duplicating the
  SPSSimpleExecutorMemoryManager* signatures in OrcRTBridge.h; a
  follow-up will retire those.
---
 .../Orc/EPCGenericJITLinkMemoryManager.h      | 67 +++++--------
 .../RTBridge/GenericMemoryManagerProxies.h    | 44 +++++++++
 .../SPS/GenericMemoryManagerProxySpecs.h      | 62 ++++++++++++
 .../Orc/EPCGenericJITLinkMemoryManager.cpp    | 97 ++++++++-----------
 .../EPCGenericJITLinkMemoryManagerTest.cpp    | 28 ++++--
 5 files changed, 188 insertions(+), 110 deletions(-)
 create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/RTBridge/GenericMemoryManagerProxies.h
 create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/RTBridge/SPS/GenericMemoryManagerProxySpecs.h

diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
index 111a2b6c17551..b3d9acf0164e9 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Implements JITLinkMemoryManager by making remove calls via
-// ExecutorProcessControl::callWrapperAsync.
+// Implements JITLinkMemoryManager by calling executor-side wrapper functions
+// through rt::Proxy objects.
 //
 // This simplifies the implementaton of new ExecutorProcessControl instances,
 // as this implementation will always work (at the cost of some performance
@@ -20,6 +20,7 @@
 
 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/RTBridge/GenericMemoryManagerProxies.h"
 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
 #include "llvm/Support/Compiler.h"
 
@@ -29,19 +30,27 @@ namespace orc {
 class LLVM_ABI EPCGenericJITLinkMemoryManager
     : public jitlink::JITLinkMemoryManager {
 public:
-  /// Symbol addresses for memory management implementation.
-  struct SymbolAddrs {
-    ExecutorAddr Allocator;
-    ExecutorAddr Reserve;
-    ExecutorAddr Initialize;
-    ExecutorAddr Deinitialize;
-    ExecutorAddr Release;
+  /// The resolved controller-side handle to an executor-side memory manager:
+  /// the address of the allocator instance (passed as the first argument to
+  /// each call) plus the proxies for its functions. These are
+  /// protocol-agnostic: the Create methods populate them for the runtime's SPS
+  /// controller interface, but a client targeting a different protocol can
+  /// build its own Bindings and pass them to the constructor.
+  ///
+  /// Deinitialize is part of the interface but is not currently used by this
+  /// manager.
+  struct Bindings {
+    ExecutorAddr Instance;
+    rt::MemMgrReserveProxy Reserve;
+    rt::MemMgrInitializeProxy Initialize;
+    rt::MemMgrDeinitializeProxy Deinitialize;
+    rt::MemMgrReleaseProxy Release;
   };
 
   /// Create an EPCGenericJITLinkMemoryManager instance from a given set of
-  /// function addrs.
-  EPCGenericJITLinkMemoryManager(ExecutorProcessControl &EPC, SymbolAddrs SAs)
-      : EPC(EPC), SAs(SAs) {}
+  /// memory-manager bindings.
+  EPCGenericJITLinkMemoryManager(ExecutionSession &ES, Bindings B)
+      : ES(ES), B(std::move(B)) {}
 
   /// Create an EPCGenericJITLinkMemoryManager using the given implementation
   /// symbol names. These will be looked up in the given JITDylib.
@@ -74,40 +83,10 @@ class LLVM_ABI EPCGenericJITLinkMemoryManager
   void completeAllocation(ExecutorAddr AllocAddr, jitlink::BasicLayout BL,
                           OnAllocatedFunction OnAllocated);
 
-  ExecutorProcessControl &EPC;
-  SymbolAddrs SAs;
+  ExecutionSession &ES;
+  Bindings B;
 };
 
-namespace shared {
-
-/// FIXME: This specialization should be moved into TargetProcessControlTypes.h
-///        (or wherever those types get merged to) once ORC depends on JITLink.
-template <>
-class SPSSerializationTraits<SPSExecutorAddr,
-                             jitlink::JITLinkMemoryManager::FinalizedAlloc> {
-public:
-  static size_t size(const jitlink::JITLinkMemoryManager::FinalizedAlloc &FA) {
-    return SPSArgList<SPSExecutorAddr>::size(ExecutorAddr(FA.getAddress()));
-  }
-
-  static bool
-  serialize(SPSOutputBuffer &OB,
-            const jitlink::JITLinkMemoryManager::FinalizedAlloc &FA) {
-    return SPSArgList<SPSExecutorAddr>::serialize(
-        OB, ExecutorAddr(FA.getAddress()));
-  }
-
-  static bool deserialize(SPSInputBuffer &IB,
-                          jitlink::JITLinkMemoryManager::FinalizedAlloc &FA) {
-    ExecutorAddr A;
-    if (!SPSArgList<SPSExecutorAddr>::deserialize(IB, A))
-      return false;
-    FA = jitlink::JITLinkMemoryManager::FinalizedAlloc(A);
-    return true;
-  }
-};
-
-} // end namespace shared
 } // end namespace orc
 } // end namespace llvm
 
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTBridge/GenericMemoryManagerProxies.h b/llvm/include/llvm/ExecutionEngine/Orc/RTBridge/GenericMemoryManagerProxies.h
new file mode 100644
index 0000000000000..506346e212346
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/RTBridge/GenericMemoryManagerProxies.h
@@ -0,0 +1,44 @@
+//===- GenericMemoryManagerProxies.h - Proxies for mem mgmt -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Named rt::Proxy types for the executor's memory-manager operations. The
+// instance address of the executor-side manager is passed as the first
+// argument to each call.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_GENERICMEMORYMANAGERPROXIES_H
+#define LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_GENERICMEMORYMANAGERPROXIES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ExecutionEngine/Orc/RTBridge/Proxy.h"
+#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+
+#include <cstdint>
+
+namespace llvm::orc::rt {
+
+/// Reserve an address range of the given size; returns its base.
+using MemMgrReserveProxy =
+    Proxy<Expected<ExecutorAddr>(ExecutorAddr, uint64_t)>;
+
+/// Apply a finalize request; returns a key for the initialized allocation.
+using MemMgrInitializeProxy =
+    Proxy<Expected<ExecutorAddr>(ExecutorAddr, tpctypes::FinalizeRequest)>;
+
+/// Deinitialize the allocations with the given base addresses (running their
+/// deallocation actions) without releasing their memory.
+using MemMgrDeinitializeProxy =
+    Proxy<Error(ExecutorAddr, ArrayRef<ExecutorAddr>)>;
+
+/// Release the allocations with the given base addresses.
+using MemMgrReleaseProxy = Proxy<Error(ExecutorAddr, ArrayRef<ExecutorAddr>)>;
+
+} // namespace llvm::orc::rt
+
+#endif // LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_GENERICMEMORYMANAGERPROXIES_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTBridge/SPS/GenericMemoryManagerProxySpecs.h b/llvm/include/llvm/ExecutionEngine/Orc/RTBridge/SPS/GenericMemoryManagerProxySpecs.h
new file mode 100644
index 0000000000000..8dd094267238f
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/RTBridge/SPS/GenericMemoryManagerProxySpecs.h
@@ -0,0 +1,62 @@
+//===- GenericMemoryManagerProxySpecs.h - SPS specs for mem mgmt -*- C++ -*===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// SPS ProxySpecs (signatures, controller-interface names, and dispatch) for the
+// GenericMemoryManagerProxies. The controller-interface names here are the
+// runtime's SimpleNativeMemoryMap defaults (the Create methods look symbols up
+// under caller-supplied names).
+//
+// The signatures below duplicate the SPSSimpleExecutorMemoryManager* signatures
+// in OrcRTBridge.h; the intent is to retire those and have callers depend on
+// this header instead.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_SPS_GENERICMEMORYMANAGERPROXYSPECS_H
+#define LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_SPS_GENERICMEMORYMANAGERPROXYSPECS_H
+
+#include "llvm/ExecutionEngine/Orc/RTBridge/GenericMemoryManagerProxies.h"
+#include "llvm/ExecutionEngine/Orc/RTBridge/SPS/ProxySpec.h"
+
+#include <cstdint>
+
+namespace llvm::orc::rt::sps {
+
+using MemMgrReserveSPSSig = shared::SPSExpected<shared::SPSExecutorAddr>(
+    shared::SPSExecutorAddr, uint64_t);
+inline constexpr char MemMgrReserveCIName[] =
+    "orc_rt_ci_sps_SimpleNativeMemoryMap_reserve";
+using MemMgrReserveProxySpec =
+    ProxySpec<rt::MemMgrReserveProxy, MemMgrReserveSPSSig, MemMgrReserveCIName>;
+
+using MemMgrInitializeSPSSig = shared::SPSExpected<shared::SPSExecutorAddr>(
+    shared::SPSExecutorAddr, shared::SPSFinalizeRequest);
+inline constexpr char MemMgrInitializeCIName[] =
+    "orc_rt_ci_sps_SimpleNativeMemoryMap_initialize";
+using MemMgrInitializeProxySpec =
+    ProxySpec<rt::MemMgrInitializeProxy, MemMgrInitializeSPSSig,
+              MemMgrInitializeCIName>;
+
+using MemMgrDeinitializeSPSSig = shared::SPSError(
+    shared::SPSExecutorAddr, shared::SPSSequence<shared::SPSExecutorAddr>);
+inline constexpr char MemMgrDeinitializeCIName[] =
+    "orc_rt_ci_sps_SimpleNativeMemoryMap_deinitializeMultiple";
+using MemMgrDeinitializeProxySpec =
+    ProxySpec<rt::MemMgrDeinitializeProxy, MemMgrDeinitializeSPSSig,
+              MemMgrDeinitializeCIName>;
+
+using MemMgrReleaseSPSSig = shared::SPSError(
+    shared::SPSExecutorAddr, shared::SPSSequence<shared::SPSExecutorAddr>);
+inline constexpr char MemMgrReleaseCIName[] =
+    "orc_rt_ci_sps_SimpleNativeMemoryMap_releaseMultiple";
+using MemMgrReleaseProxySpec =
+    ProxySpec<rt::MemMgrReleaseProxy, MemMgrReleaseSPSSig, MemMgrReleaseCIName>;
+
+} // namespace llvm::orc::rt::sps
+
+#endif // LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_SPS_GENERICMEMORYMANAGERPROXYSPECS_H
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp b/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
index 17cb43139474f..a601f37387047 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.cpp
@@ -10,6 +10,7 @@
 
 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
 #include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
+#include "llvm/ExecutionEngine/Orc/RTBridge/SPS/GenericMemoryManagerProxySpecs.h"
 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
 
 #include <limits>
@@ -50,45 +51,28 @@ class EPCGenericJITLinkMemoryManager::InFlightAlloc
           KV.first,
           KV.second.Addr,
           alignTo(KV.second.ContentSize + KV.second.ZeroFillSize,
-                  Parent.EPC.getPageSize()),
+                  Parent.ES.getExecutorProcessControl().getPageSize()),
           {KV.second.WorkingMem, static_cast<size_t>(KV.second.ContentSize)}});
     }
 
     // Transfer allocation actions.
     std::swap(FR.Actions, G.allocActions());
 
-    Parent.EPC.callSPSWrapperAsync<
-        rt::SPSSimpleExecutorMemoryManagerInitializeSignature>(
-        Parent.SAs.Initialize,
+    Parent.B.Initialize(
         [OnFinalize = std::move(OnFinalize), AllocAddr = this->AllocAddr](
-            Error SerializationErr,
             Expected<ExecutorAddr> InitializeKey) mutable {
           // FIXME: Release abandoned alloc.
-          if (SerializationErr) {
-            cantFail(InitializeKey.takeError());
-            OnFinalize(std::move(SerializationErr));
-          } else if (!InitializeKey)
-            OnFinalize(InitializeKey.takeError());
-          else
-            OnFinalize(FinalizedAlloc(AllocAddr));
+          if (!InitializeKey)
+            return OnFinalize(InitializeKey.takeError());
+          OnFinalize(FinalizedAlloc(AllocAddr));
         },
-        Parent.SAs.Allocator, std::move(FR));
+        Parent.ES, Parent.B.Instance, FR);
   }
 
   void abandon(OnAbandonedFunction OnAbandoned) override {
     // FIXME: Return memory to pool instead.
-    Parent.EPC.callSPSWrapperAsync<
-        rt::SPSSimpleExecutorMemoryManagerReleaseSignature>(
-        Parent.SAs.Release,
-        [OnAbandoned = std::move(OnAbandoned)](Error SerializationErr,
-                                               Error DeallocateErr) mutable {
-          if (SerializationErr) {
-            cantFail(std::move(DeallocateErr));
-            OnAbandoned(std::move(SerializationErr));
-          } else
-            OnAbandoned(std::move(DeallocateErr));
-        },
-        Parent.SAs.Allocator, ArrayRef<ExecutorAddr>(AllocAddr));
+    Parent.B.Release(std::move(OnAbandoned), Parent.ES, Parent.B.Instance,
+                     ArrayRef<ExecutorAddr>(AllocAddr));
   }
 
 private:
@@ -101,20 +85,27 @@ class EPCGenericJITLinkMemoryManager::InFlightAlloc
 Expected<std::unique_ptr<EPCGenericJITLinkMemoryManager>>
 EPCGenericJITLinkMemoryManager::Create(
     JITDylib &JD, rt::SimpleExecutorMemoryManagerSymbolNames SNs) {
+  namespace sps = rt::sps;
   auto &ES = JD.getExecutionSession();
-  SymbolAddrs SAs;
+  Bindings B;
+  // The allocator instance is a data symbol passed as the first argument to
+  // each call, not a wrapper to proxy.
   if (auto Err = lookupAndRecordAddrs(
           ES, LookupKind::Static, makeJITDylibSearchOrder({&JD}),
-          {
-              {ES.intern(SNs.AllocatorName), &SAs.Allocator},
-              {ES.intern(SNs.ReserveName), &SAs.Reserve},
-              {ES.intern(SNs.InitializeName), &SAs.Initialize},
-              {ES.intern(SNs.DeinitializeName), &SAs.Deinitialize},
-              {ES.intern(SNs.ReleaseName), &SAs.Release},
-          }))
+          {{ES.intern(SNs.AllocatorName), &B.Instance}}))
+    return Err;
+  if (auto Err = rt::buildProxies(
+          JD,
+          rt::proxyInit<sps::MemMgrReserveProxySpec>(&B.Reserve,
+                                                     SNs.ReserveName),
+          rt::proxyInit<sps::MemMgrInitializeProxySpec>(&B.Initialize,
+                                                        SNs.InitializeName),
+          rt::proxyInit<sps::MemMgrDeinitializeProxySpec>(&B.Deinitialize,
+                                                          SNs.DeinitializeName),
+          rt::proxyInit<sps::MemMgrReleaseProxySpec>(&B.Release,
+                                                     SNs.ReleaseName)))
     return Err;
-  return std::make_unique<EPCGenericJITLinkMemoryManager>(
-      ES.getExecutorProcessControl(), SAs);
+  return std::make_unique<EPCGenericJITLinkMemoryManager>(ES, std::move(B));
 }
 
 Expected<std::unique_ptr<EPCGenericJITLinkMemoryManager>>
@@ -128,39 +119,28 @@ void EPCGenericJITLinkMemoryManager::allocate(const JITLinkDylib *JD,
                                               OnAllocatedFunction OnAllocated) {
   BasicLayout BL(G);
 
-  auto Pages = BL.getContiguousPageBasedLayoutSizes(EPC.getPageSize());
+  auto Pages = BL.getContiguousPageBasedLayoutSizes(
+      ES.getExecutorProcessControl().getPageSize());
   if (!Pages)
     return OnAllocated(Pages.takeError());
 
-  EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorMemoryManagerReserveSignature>(
-      SAs.Reserve,
+  B.Reserve(
       [this, BL = std::move(BL), OnAllocated = std::move(OnAllocated)](
-          Error SerializationErr, Expected<ExecutorAddr> AllocAddr) mutable {
-        if (SerializationErr) {
-          cantFail(AllocAddr.takeError());
-          return OnAllocated(std::move(SerializationErr));
-        }
+          Expected<ExecutorAddr> AllocAddr) mutable {
         if (!AllocAddr)
           return OnAllocated(AllocAddr.takeError());
-
         completeAllocation(*AllocAddr, std::move(BL), std::move(OnAllocated));
       },
-      SAs.Allocator, Pages->total());
+      ES, B.Instance, Pages->total());
 }
 
 void EPCGenericJITLinkMemoryManager::deallocate(
     std::vector<FinalizedAlloc> Allocs, OnDeallocatedFunction OnDeallocated) {
-  EPC.callSPSWrapperAsync<rt::SPSSimpleExecutorMemoryManagerReleaseSignature>(
-      SAs.Release,
-      [OnDeallocated = std::move(OnDeallocated)](Error SerErr,
-                                                 Error DeallocErr) mutable {
-        if (SerErr) {
-          cantFail(std::move(DeallocErr));
-          OnDeallocated(std::move(SerErr));
-        } else
-          OnDeallocated(std::move(DeallocErr));
-      },
-      SAs.Allocator, Allocs);
+  std::vector<ExecutorAddr> Bases;
+  Bases.reserve(Allocs.size());
+  for (auto &A : Allocs)
+    Bases.push_back(ExecutorAddr(A.getAddress()));
+  B.Release(std::move(OnDeallocated), ES, B.Instance, Bases);
   for (auto &A : Allocs)
     A.release();
 }
@@ -177,8 +157,9 @@ void EPCGenericJITLinkMemoryManager::completeAllocation(
 
     Seg.Addr = NextSegAddr;
     KV.second.WorkingMem = BL.getGraph().allocateBuffer(Seg.ContentSize).data();
-    NextSegAddr += ExecutorAddrDiff(
-        alignTo(Seg.ContentSize + Seg.ZeroFillSize, EPC.getPageSize()));
+    NextSegAddr +=
+        ExecutorAddrDiff(alignTo(Seg.ContentSize + Seg.ZeroFillSize,
+                                 ES.getExecutorProcessControl().getPageSize()));
 
     auto &SegInfo = SegInfos[AG];
     SegInfo.ContentSize = Seg.ContentSize;
diff --git a/llvm/unittests/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManagerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManagerTest.cpp
index fb1354f6e75db..3e048cfd6d9a6 100644
--- a/llvm/unittests/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManagerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManagerTest.cpp
@@ -106,16 +106,28 @@ CWrapperFunctionBuffer testRelease(const char *ArgData, size_t ArgSize) {
 }
 
 TEST(EPCGenericJITLinkMemoryManagerTest, AllocFinalizeFree) {
-  auto SelfEPC = cantFail(SelfExecutorProcessControl::Create());
+  ExecutionSession ES(cantFail(SelfExecutorProcessControl::Create()));
   SimpleAllocator SA;
 
-  EPCGenericJITLinkMemoryManager::SymbolAddrs SAs;
-  SAs.Allocator = ExecutorAddr::fromPtr(&SA);
-  SAs.Reserve = ExecutorAddr::fromPtr(&testReserve);
-  SAs.Initialize = ExecutorAddr::fromPtr(&testInitialize);
-  SAs.Release = ExecutorAddr::fromPtr(&testRelease);
+  // Register the test wrappers in the bootstrap JITDylib under the default
+  // SimpleNativeMemoryMap names so that Create resolves its proxies to them.
+  auto &SNs = rt::orc_rt_SimpleNativeMemoryMapSPSSymbols;
+  auto Exported = JITSymbolFlags::Exported;
+  cantFail(ES.getBootstrapJITDylib().define(absoluteSymbols({
+      {ES.intern(SNs.AllocatorName), {ExecutorAddr::fromPtr(&SA), Exported}},
+      {ES.intern(SNs.ReserveName),
+       {ExecutorAddr::fromPtr(&testReserve), Exported}},
+      {ES.intern(SNs.InitializeName),
+       {ExecutorAddr::fromPtr(&testInitialize), Exported}},
+      // Deinitialize is part of the interface but unused here; the release
+      // wrapper (same signature) stands in so the proxy resolves.
+      {ES.intern(SNs.DeinitializeName),
+       {ExecutorAddr::fromPtr(&testRelease), Exported}},
+      {ES.intern(SNs.ReleaseName),
+       {ExecutorAddr::fromPtr(&testRelease), Exported}},
+  })));
 
-  auto MemMgr = std::make_unique<EPCGenericJITLinkMemoryManager>(*SelfEPC, SAs);
+  auto MemMgr = cantFail(EPCGenericJITLinkMemoryManager::Create(ES));
   StringRef Hello = "hello";
   auto SSA = jitlink::SimpleSegmentAlloc::Create(
       *MemMgr, std::make_shared<SymbolStringPool>(),
@@ -138,7 +150,7 @@ TEST(EPCGenericJITLinkMemoryManagerTest, AllocFinalizeFree) {
   auto Err2 = MemMgr->deallocate(std::move(*FA));
   EXPECT_THAT_ERROR(std::move(Err2), Succeeded());
 
-  cantFail(SelfEPC->disconnect());
+  cantFail(ES.endSession());
 }
 
 TEST(EPCGenericJITLinkMemoryManagerTest, CreateFromSymbolNames) {



More information about the llvm-commits mailing list