[llvm] 916ef9b - [C-API] LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 16 19:15:14 PST 2022


Author: Lang Hames
Date: 2022-12-17T14:15:07+11:00
New Revision: 916ef9b0249f41886fba31168d8cadad8c5f8fbb

URL: https://github.com/llvm/llvm-project/commit/916ef9b0249f41886fba31168d8cadad8c5f8fbb
DIFF: https://github.com/llvm/llvm-project/commit/916ef9b0249f41886fba31168d8cadad8c5f8fbb.diff

LOG: [C-API] LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks

Adds a LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks
function that can be used to create an RTDyldObjectLinkingLayer using callbacks
that are similar (but not identical) to those used in
LLVMCreateSimpleMCJITMemoryManager. This is intended to ease the transition to
ORC for MCJIT C-API clients.

Differential Revision: https://reviews.llvm.org/D139393

Added: 
    

Modified: 
    llvm/include/llvm-c/OrcEE.h
    llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
    llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
    llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm-c/OrcEE.h b/llvm/include/llvm-c/OrcEE.h
index e7ae0f5e6be20..d451187aaef59 100644
--- a/llvm/include/llvm-c/OrcEE.h
+++ b/llvm/include/llvm-c/OrcEE.h
@@ -32,6 +32,9 @@
 
 LLVM_C_EXTERN_C_BEGIN
 
+typedef void *(*LLVMMemoryManagerCreateContextCallback)(void *CtxCtx);
+typedef void (*LLVMMemoryManagerNotifyTerminatingCallback)(void *CtxCtx);
+
 /**
  * @defgroup LLVMCExecutionEngineORCEE ExecutionEngine-based ORC Utils
  * @ingroup LLVMCExecutionEngine
@@ -47,6 +50,40 @@ LLVMOrcObjectLayerRef
 LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
     LLVMOrcExecutionSessionRef ES);
 
+/**
+ * Create a RTDyldObjectLinkingLayer instance using MCJIT-memory-manager-like
+ * callbacks.
+ *
+ * This is intended to simplify transitions for existing MCJIT clients. The
+ * callbacks used are similar (but not identical) to the callbacks for
+ * LLVMCreateSimpleMCJITMemoryManager: Unlike MCJIT, RTDyldObjectLinkingLayer
+ * will create a new memory manager for each object linked by calling the given
+ * CreateContext callback. This allows for code removal by destroying each
+ * allocator individually. Every allocator will be destroyed (if it has not been
+ * already) at RTDyldObjectLinkingLayer destruction time, and the
+ * NotifyTerminating callback will be called to indicate that no further
+ * allocation contexts will be created.
+ *
+ * To implement MCJIT-like behavior clients can implement CreateContext,
+ * NotifyTerminating, and Destroy as:
+ *
+ *   void *CreateContext(void *CtxCtx) { return CtxCtx; }
+ *   void NotifyTerminating(void *CtxCtx) { MyOriginalDestroy(CtxCtx); }
+ *   void Destroy(void *Ctx) { }
+ *
+ * This scheme simply reuses the CreateContextCtx pointer as the one-and-only
+ * allocation context.
+ */
+LLVMOrcObjectLayerRef
+LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks(
+    LLVMOrcExecutionSessionRef ES, void *CreateContextCtx,
+    LLVMMemoryManagerCreateContextCallback CreateContext,
+    LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating,
+    LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
+    LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
+    LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
+    LLVMMemoryManagerDestroyCallback Destroy);
+
 /**
  * Add the given listener to the given RTDyldObjectLinkingLayer.
  *

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index 78f85e827c053..d5a55182aeb6e 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -50,7 +50,7 @@ class RTDyldObjectLinkingLayer
       MaterializationResponsibility &R, std::unique_ptr<MemoryBuffer>)>;
 
   using GetMemoryManagerFunction =
-      std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
+      unique_function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
 
   /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
   ///        and NotifyEmitted functors.

diff  --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
index 6575bf3e89235..b823197b404f6 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp
@@ -1069,6 +1069,116 @@ LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
       *unwrap(ES), [] { return std::make_unique<SectionMemoryManager>(); }));
 }
 
+LLVMOrcObjectLayerRef
+LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks(
+    LLVMOrcExecutionSessionRef ES, void *CreateContextCtx,
+    LLVMMemoryManagerCreateContextCallback CreateContext,
+    LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating,
+    LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
+    LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
+    LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
+    LLVMMemoryManagerDestroyCallback Destroy) {
+
+  struct MCJITMemoryManagerLikeCallbacks {
+    MCJITMemoryManagerLikeCallbacks() = default;
+    MCJITMemoryManagerLikeCallbacks(
+        void *CreateContextCtx,
+        LLVMMemoryManagerCreateContextCallback CreateContext,
+        LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating,
+        LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
+        LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
+        LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
+        LLVMMemoryManagerDestroyCallback Destroy)
+        : CreateContextCtx(CreateContextCtx), CreateContext(CreateContext),
+          NotifyTerminating(NotifyTerminating),
+          AllocateCodeSection(AllocateCodeSection),
+          AllocateDataSection(AllocateDataSection),
+          FinalizeMemory(FinalizeMemory), Destroy(Destroy) {}
+
+    MCJITMemoryManagerLikeCallbacks(MCJITMemoryManagerLikeCallbacks &&Other) {
+      std::swap(CreateContextCtx, Other.CreateContextCtx);
+      std::swap(CreateContext, Other.CreateContext);
+      std::swap(NotifyTerminating, Other.NotifyTerminating);
+      std::swap(AllocateCodeSection, Other.AllocateCodeSection);
+      std::swap(AllocateDataSection, Other.AllocateDataSection);
+      std::swap(FinalizeMemory, Other.FinalizeMemory);
+      std::swap(Destroy, Other.Destroy);
+    }
+
+    ~MCJITMemoryManagerLikeCallbacks() {
+      if (NotifyTerminating)
+        NotifyTerminating(CreateContextCtx);
+    }
+
+    void *CreateContextCtx = nullptr;
+    LLVMMemoryManagerCreateContextCallback CreateContext = nullptr;
+    LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating = nullptr;
+    LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection = nullptr;
+    LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection = nullptr;
+    LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory = nullptr;
+    LLVMMemoryManagerDestroyCallback Destroy = nullptr;
+  };
+
+  class MCJITMemoryManagerLikeCallbacksMemMgr : public RTDyldMemoryManager {
+  public:
+    MCJITMemoryManagerLikeCallbacksMemMgr(
+        const MCJITMemoryManagerLikeCallbacks &CBs)
+        : CBs(CBs) {
+      Opaque = CBs.CreateContext(CBs.CreateContextCtx);
+    }
+    ~MCJITMemoryManagerLikeCallbacksMemMgr() override { CBs.Destroy(Opaque); }
+
+    uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+                                 unsigned SectionID,
+                                 StringRef SectionName) override {
+      return CBs.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
+                                     SectionName.str().c_str());
+    }
+
+    uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+                                 unsigned SectionID, StringRef SectionName,
+                                 bool isReadOnly) override {
+      return CBs.AllocateDataSection(Opaque, Size, Alignment, SectionID,
+                                     SectionName.str().c_str(), isReadOnly);
+    }
+
+    bool finalizeMemory(std::string *ErrMsg) override {
+      char *ErrMsgCString = nullptr;
+      bool Result = CBs.FinalizeMemory(Opaque, &ErrMsgCString);
+      assert((Result || !ErrMsgCString) &&
+             "Did not expect an error message if FinalizeMemory succeeded");
+      if (ErrMsgCString) {
+        if (ErrMsg)
+          *ErrMsg = ErrMsgCString;
+        free(ErrMsgCString);
+      }
+      return Result;
+    }
+
+  private:
+    const MCJITMemoryManagerLikeCallbacks &CBs;
+    void *Opaque = nullptr;
+  };
+
+  assert(ES && "ES must not be null");
+  assert(CreateContext && "CreateContext must not be null");
+  assert(NotifyTerminating && "NotifyTerminating must not be null");
+  assert(AllocateCodeSection && "AllocateCodeSection must not be null");
+  assert(AllocateDataSection && "AllocateDataSection must not be null");
+  assert(FinalizeMemory && "FinalizeMemory must not be null");
+  assert(Destroy && "Destroy must not be null");
+
+  MCJITMemoryManagerLikeCallbacks CBs(
+      CreateContextCtx, CreateContext, NotifyTerminating, AllocateCodeSection,
+      AllocateDataSection, FinalizeMemory, Destroy);
+
+  return wrap(new RTDyldObjectLinkingLayer(*unwrap(ES), [CBs = std::move(CBs)] {
+    return std::make_unique<MCJITMemoryManagerLikeCallbacksMemMgr>(CBs);
+  }));
+
+  return nullptr;
+}
+
 void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
     LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
     LLVMJITEventListenerRef Listener) {

diff  --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
index e55a607cba1da..8e9d4cda1c237 100644
--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
@@ -81,7 +81,7 @@ using BaseT = RTTIExtends<RTDyldObjectLinkingLayer, ObjectLayer>;
 
 RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
     ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager)
-    : BaseT(ES), GetMemoryManager(GetMemoryManager) {
+    : BaseT(ES), GetMemoryManager(std::move(GetMemoryManager)) {
   ES.registerResourceManager(*this);
 }
 


        


More information about the llvm-commits mailing list