Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:54

0001 //===- MemoryMapper.h - Cross-process memory mapper -------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Cross-process (and in-process) memory mapping and transfer
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
0014 #define LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
0015 
0016 #include "llvm/ExecutionEngine/Orc/Core.h"
0017 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
0018 #include "llvm/Support/Process.h"
0019 
0020 #include <mutex>
0021 
0022 namespace llvm {
0023 namespace orc {
0024 
0025 /// Manages mapping, content transfer and protections for JIT memory
0026 class MemoryMapper {
0027 public:
0028   /// Represents a single allocation containing multiple segments and
0029   /// initialization and deinitialization actions
0030   struct AllocInfo {
0031     struct SegInfo {
0032       ExecutorAddrDiff Offset;
0033       const char *WorkingMem;
0034       size_t ContentSize;
0035       size_t ZeroFillSize;
0036       AllocGroup AG;
0037     };
0038 
0039     ExecutorAddr MappingBase;
0040     std::vector<SegInfo> Segments;
0041     shared::AllocActions Actions;
0042   };
0043 
0044   using OnReservedFunction = unique_function<void(Expected<ExecutorAddrRange>)>;
0045 
0046   // Page size of the target process
0047   virtual unsigned int getPageSize() = 0;
0048 
0049   /// Reserves address space in executor process
0050   virtual void reserve(size_t NumBytes, OnReservedFunction OnReserved) = 0;
0051 
0052   /// Provides working memory
0053   virtual char *prepare(ExecutorAddr Addr, size_t ContentSize) = 0;
0054 
0055   using OnInitializedFunction = unique_function<void(Expected<ExecutorAddr>)>;
0056 
0057   /// Ensures executor memory is synchronized with working copy memory, sends
0058   /// functions to be called after initilization and before deinitialization and
0059   /// applies memory protections
0060   /// Returns a unique address identifying the allocation. This address should
0061   /// be passed to deinitialize to run deallocation actions (and reset
0062   /// permissions where possible).
0063   virtual void initialize(AllocInfo &AI,
0064                           OnInitializedFunction OnInitialized) = 0;
0065 
0066   using OnDeinitializedFunction = unique_function<void(Error)>;
0067 
0068   /// Runs previously specified deinitialization actions
0069   /// Executor addresses returned by initialize should be passed
0070   virtual void deinitialize(ArrayRef<ExecutorAddr> Allocations,
0071                             OnDeinitializedFunction OnDeInitialized) = 0;
0072 
0073   using OnReleasedFunction = unique_function<void(Error)>;
0074 
0075   /// Release address space acquired through reserve()
0076   virtual void release(ArrayRef<ExecutorAddr> Reservations,
0077                        OnReleasedFunction OnRelease) = 0;
0078 
0079   virtual ~MemoryMapper();
0080 };
0081 
0082 class InProcessMemoryMapper : public MemoryMapper {
0083 public:
0084   InProcessMemoryMapper(size_t PageSize);
0085 
0086   static Expected<std::unique_ptr<InProcessMemoryMapper>> Create();
0087 
0088   unsigned int getPageSize() override { return PageSize; }
0089 
0090   void reserve(size_t NumBytes, OnReservedFunction OnReserved) override;
0091 
0092   void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override;
0093 
0094   char *prepare(ExecutorAddr Addr, size_t ContentSize) override;
0095 
0096   void deinitialize(ArrayRef<ExecutorAddr> Allocations,
0097                     OnDeinitializedFunction OnDeInitialized) override;
0098 
0099   void release(ArrayRef<ExecutorAddr> Reservations,
0100                OnReleasedFunction OnRelease) override;
0101 
0102   ~InProcessMemoryMapper() override;
0103 
0104 private:
0105   struct Allocation {
0106     size_t Size;
0107     std::vector<shared::WrapperFunctionCall> DeinitializationActions;
0108   };
0109   using AllocationMap = DenseMap<ExecutorAddr, Allocation>;
0110 
0111   struct Reservation {
0112     size_t Size;
0113     std::vector<ExecutorAddr> Allocations;
0114   };
0115   using ReservationMap = DenseMap<void *, Reservation>;
0116 
0117   std::mutex Mutex;
0118   ReservationMap Reservations;
0119   AllocationMap Allocations;
0120 
0121   size_t PageSize;
0122 };
0123 
0124 class SharedMemoryMapper final : public MemoryMapper {
0125 public:
0126   struct SymbolAddrs {
0127     ExecutorAddr Instance;
0128     ExecutorAddr Reserve;
0129     ExecutorAddr Initialize;
0130     ExecutorAddr Deinitialize;
0131     ExecutorAddr Release;
0132   };
0133 
0134   SharedMemoryMapper(ExecutorProcessControl &EPC, SymbolAddrs SAs,
0135                      size_t PageSize);
0136 
0137   static Expected<std::unique_ptr<SharedMemoryMapper>>
0138   Create(ExecutorProcessControl &EPC, SymbolAddrs SAs);
0139 
0140   unsigned int getPageSize() override { return PageSize; }
0141 
0142   void reserve(size_t NumBytes, OnReservedFunction OnReserved) override;
0143 
0144   char *prepare(ExecutorAddr Addr, size_t ContentSize) override;
0145 
0146   void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override;
0147 
0148   void deinitialize(ArrayRef<ExecutorAddr> Allocations,
0149                     OnDeinitializedFunction OnDeInitialized) override;
0150 
0151   void release(ArrayRef<ExecutorAddr> Reservations,
0152                OnReleasedFunction OnRelease) override;
0153 
0154   ~SharedMemoryMapper() override;
0155 
0156 private:
0157   struct Reservation {
0158     void *LocalAddr;
0159     size_t Size;
0160   };
0161 
0162   ExecutorProcessControl &EPC;
0163   SymbolAddrs SAs;
0164 
0165   std::mutex Mutex;
0166 
0167   std::map<ExecutorAddr, Reservation> Reservations;
0168 
0169   size_t PageSize;
0170 };
0171 
0172 } // namespace orc
0173 } // end namespace llvm
0174 
0175 #endif // LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H