xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MemoryMapper.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- MemoryMapper.h - Cross-process memory mapper -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Cross-process (and in-process) memory mapping and transfer
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
14 #define LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
15 
16 #include "llvm/ExecutionEngine/Orc/Core.h"
17 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/Process.h"
20 
21 #include <mutex>
22 
23 namespace llvm {
24 namespace orc {
25 
26 /// Manages mapping, content transfer and protections for JIT memory
27 class LLVM_ABI MemoryMapper {
28 public:
29   /// Represents a single allocation containing multiple segments and
30   /// initialization and deinitialization actions
31   struct AllocInfo {
32     struct SegInfo {
33       ExecutorAddrDiff Offset;
34       const char *WorkingMem;
35       size_t ContentSize;
36       size_t ZeroFillSize;
37       AllocGroup AG;
38     };
39 
40     ExecutorAddr MappingBase;
41     std::vector<SegInfo> Segments;
42     shared::AllocActions Actions;
43   };
44 
45   using OnReservedFunction = unique_function<void(Expected<ExecutorAddrRange>)>;
46 
47   // Page size of the target process
48   virtual unsigned int getPageSize() = 0;
49 
50   /// Reserves address space in executor process
51   virtual void reserve(size_t NumBytes, OnReservedFunction OnReserved) = 0;
52 
53   /// Provides working memory
54   virtual char *prepare(ExecutorAddr Addr, size_t ContentSize) = 0;
55 
56   using OnInitializedFunction = unique_function<void(Expected<ExecutorAddr>)>;
57 
58   /// Ensures executor memory is synchronized with working copy memory, sends
59   /// functions to be called after initilization and before deinitialization and
60   /// applies memory protections
61   /// Returns a unique address identifying the allocation. This address should
62   /// be passed to deinitialize to run deallocation actions (and reset
63   /// permissions where possible).
64   virtual void initialize(AllocInfo &AI,
65                           OnInitializedFunction OnInitialized) = 0;
66 
67   using OnDeinitializedFunction = unique_function<void(Error)>;
68 
69   /// Runs previously specified deinitialization actions
70   /// Executor addresses returned by initialize should be passed
71   virtual void deinitialize(ArrayRef<ExecutorAddr> Allocations,
72                             OnDeinitializedFunction OnDeInitialized) = 0;
73 
74   using OnReleasedFunction = unique_function<void(Error)>;
75 
76   /// Release address space acquired through reserve()
77   virtual void release(ArrayRef<ExecutorAddr> Reservations,
78                        OnReleasedFunction OnRelease) = 0;
79 
80   virtual ~MemoryMapper();
81 };
82 
83 class LLVM_ABI InProcessMemoryMapper : public MemoryMapper {
84 public:
85   InProcessMemoryMapper(size_t PageSize);
86 
87   static Expected<std::unique_ptr<InProcessMemoryMapper>> Create();
88 
getPageSize()89   unsigned int getPageSize() override { return PageSize; }
90 
91   void reserve(size_t NumBytes, OnReservedFunction OnReserved) override;
92 
93   void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override;
94 
95   char *prepare(ExecutorAddr Addr, size_t ContentSize) override;
96 
97   void deinitialize(ArrayRef<ExecutorAddr> Allocations,
98                     OnDeinitializedFunction OnDeInitialized) override;
99 
100   void release(ArrayRef<ExecutorAddr> Reservations,
101                OnReleasedFunction OnRelease) override;
102 
103   ~InProcessMemoryMapper() override;
104 
105 private:
106   struct Allocation {
107     size_t Size;
108     std::vector<shared::WrapperFunctionCall> DeinitializationActions;
109   };
110   using AllocationMap = DenseMap<ExecutorAddr, Allocation>;
111 
112   struct Reservation {
113     size_t Size;
114     std::vector<ExecutorAddr> Allocations;
115   };
116   using ReservationMap = DenseMap<void *, Reservation>;
117 
118   std::mutex Mutex;
119   ReservationMap Reservations;
120   AllocationMap Allocations;
121 
122   size_t PageSize;
123 };
124 
125 class LLVM_ABI SharedMemoryMapper final : public MemoryMapper {
126 public:
127   struct SymbolAddrs {
128     ExecutorAddr Instance;
129     ExecutorAddr Reserve;
130     ExecutorAddr Initialize;
131     ExecutorAddr Deinitialize;
132     ExecutorAddr Release;
133   };
134 
135   SharedMemoryMapper(ExecutorProcessControl &EPC, SymbolAddrs SAs,
136                      size_t PageSize);
137 
138   static Expected<std::unique_ptr<SharedMemoryMapper>>
139   Create(ExecutorProcessControl &EPC, SymbolAddrs SAs);
140 
getPageSize()141   unsigned int getPageSize() override { return PageSize; }
142 
143   void reserve(size_t NumBytes, OnReservedFunction OnReserved) override;
144 
145   char *prepare(ExecutorAddr Addr, size_t ContentSize) override;
146 
147   void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override;
148 
149   void deinitialize(ArrayRef<ExecutorAddr> Allocations,
150                     OnDeinitializedFunction OnDeInitialized) override;
151 
152   void release(ArrayRef<ExecutorAddr> Reservations,
153                OnReleasedFunction OnRelease) override;
154 
155   ~SharedMemoryMapper() override;
156 
157 private:
158   struct Reservation {
159     void *LocalAddr;
160     size_t Size;
161     int SharedMemoryId;
162   };
163 
164   ExecutorProcessControl &EPC;
165   SymbolAddrs SAs;
166 
167   std::mutex Mutex;
168 
169   std::map<ExecutorAddr, Reservation> Reservations;
170 
171   size_t PageSize;
172 };
173 
174 } // namespace orc
175 } // end namespace llvm
176 
177 #endif // LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
178