1fcaf7f86SDimitry Andric //===---------- ExecutorSharedMemoryMapperService.cpp -----------*- C++ -*-===//
2fcaf7f86SDimitry Andric //
3fcaf7f86SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fcaf7f86SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fcaf7f86SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fcaf7f86SDimitry Andric //
7fcaf7f86SDimitry Andric //===----------------------------------------------------------------------===//
8fcaf7f86SDimitry Andric 
9fcaf7f86SDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"
10fcaf7f86SDimitry Andric 
11fcaf7f86SDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12fcaf7f86SDimitry Andric #include "llvm/Support/Process.h"
13fcaf7f86SDimitry Andric #include "llvm/Support/WindowsError.h"
14fcaf7f86SDimitry Andric 
15fcaf7f86SDimitry Andric #include <sstream>
16fcaf7f86SDimitry Andric 
17fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
18fcaf7f86SDimitry Andric #include <errno.h>
19fcaf7f86SDimitry Andric #include <fcntl.h>
20fcaf7f86SDimitry Andric #include <sys/mman.h>
21*0fca6ea1SDimitry Andric #if defined(__MVS__)
22*0fca6ea1SDimitry Andric #include "llvm/Support/BLAKE3.h"
23*0fca6ea1SDimitry Andric #include <sys/shm.h>
24*0fca6ea1SDimitry Andric #endif
25fcaf7f86SDimitry Andric #include <unistd.h>
26fcaf7f86SDimitry Andric #endif
27fcaf7f86SDimitry Andric 
28fcaf7f86SDimitry Andric namespace llvm {
29fcaf7f86SDimitry Andric namespace orc {
30fcaf7f86SDimitry Andric namespace rt_bootstrap {
31fcaf7f86SDimitry Andric 
32bdd1243dSDimitry Andric #if defined(_WIN32)
33bdd1243dSDimitry Andric static DWORD getWindowsProtectionFlags(MemProt MP) {
34bdd1243dSDimitry Andric   if (MP == MemProt::Read)
35bdd1243dSDimitry Andric     return PAGE_READONLY;
36bdd1243dSDimitry Andric   if (MP == MemProt::Write ||
37bdd1243dSDimitry Andric       MP == (MemProt::Write | MemProt::Read)) {
38bdd1243dSDimitry Andric     // Note: PAGE_WRITE is not supported by VirtualProtect
39bdd1243dSDimitry Andric     return PAGE_READWRITE;
40bdd1243dSDimitry Andric   }
41bdd1243dSDimitry Andric   if (MP == (MemProt::Read | MemProt::Exec))
42bdd1243dSDimitry Andric     return PAGE_EXECUTE_READ;
43bdd1243dSDimitry Andric   if (MP == (MemProt::Read | MemProt::Write | MemProt::Exec))
44bdd1243dSDimitry Andric     return PAGE_EXECUTE_READWRITE;
45bdd1243dSDimitry Andric   if (MP == MemProt::Exec)
46bdd1243dSDimitry Andric     return PAGE_EXECUTE;
47bdd1243dSDimitry Andric 
48bdd1243dSDimitry Andric   return PAGE_NOACCESS;
49bdd1243dSDimitry Andric }
50bdd1243dSDimitry Andric #endif
51bdd1243dSDimitry Andric 
52fcaf7f86SDimitry Andric Expected<std::pair<ExecutorAddr, std::string>>
53fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
5461cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
55fcaf7f86SDimitry Andric 
56fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
57fcaf7f86SDimitry Andric 
58fcaf7f86SDimitry Andric   std::string SharedMemoryName;
59fcaf7f86SDimitry Andric   {
60fcaf7f86SDimitry Andric     std::stringstream SharedMemoryNameStream;
61fcaf7f86SDimitry Andric     SharedMemoryNameStream << "/jitlink_" << sys::Process::getProcessId() << '_'
62fcaf7f86SDimitry Andric                            << (++SharedMemoryCount);
63fcaf7f86SDimitry Andric     SharedMemoryName = SharedMemoryNameStream.str();
64fcaf7f86SDimitry Andric   }
65fcaf7f86SDimitry Andric 
66*0fca6ea1SDimitry Andric #if defined(__MVS__)
67*0fca6ea1SDimitry Andric   ArrayRef<uint8_t> Data(
68*0fca6ea1SDimitry Andric       reinterpret_cast<const uint8_t *>(SharedMemoryName.c_str()),
69*0fca6ea1SDimitry Andric       SharedMemoryName.size());
70*0fca6ea1SDimitry Andric   auto HashedName = BLAKE3::hash<sizeof(key_t)>(Data);
71*0fca6ea1SDimitry Andric   key_t Key = *reinterpret_cast<key_t *>(HashedName.data());
72*0fca6ea1SDimitry Andric   int SharedMemoryId =
73*0fca6ea1SDimitry Andric       shmget(Key, Size, IPC_CREAT | IPC_EXCL | __IPC_SHAREAS | 0700);
74*0fca6ea1SDimitry Andric   if (SharedMemoryId < 0)
75*0fca6ea1SDimitry Andric     return errorCodeToError(errnoAsErrorCode());
76*0fca6ea1SDimitry Andric 
77*0fca6ea1SDimitry Andric   void *Addr = shmat(SharedMemoryId, nullptr, 0);
78*0fca6ea1SDimitry Andric   if (Addr == reinterpret_cast<void *>(-1))
79*0fca6ea1SDimitry Andric     return errorCodeToError(errnoAsErrorCode());
80*0fca6ea1SDimitry Andric #else
81fcaf7f86SDimitry Andric   int SharedMemoryFile =
82fcaf7f86SDimitry Andric       shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
83fcaf7f86SDimitry Andric   if (SharedMemoryFile < 0)
84*0fca6ea1SDimitry Andric     return errorCodeToError(errnoAsErrorCode());
85fcaf7f86SDimitry Andric 
86fcaf7f86SDimitry Andric   // by default size is 0
87fcaf7f86SDimitry Andric   if (ftruncate(SharedMemoryFile, Size) < 0)
88*0fca6ea1SDimitry Andric     return errorCodeToError(errnoAsErrorCode());
89fcaf7f86SDimitry Andric 
90fcaf7f86SDimitry Andric   void *Addr = mmap(nullptr, Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
91fcaf7f86SDimitry Andric   if (Addr == MAP_FAILED)
92*0fca6ea1SDimitry Andric     return errorCodeToError(errnoAsErrorCode());
93fcaf7f86SDimitry Andric 
94fcaf7f86SDimitry Andric   close(SharedMemoryFile);
95*0fca6ea1SDimitry Andric #endif
96fcaf7f86SDimitry Andric 
97fcaf7f86SDimitry Andric #elif defined(_WIN32)
98fcaf7f86SDimitry Andric 
99fcaf7f86SDimitry Andric   std::string SharedMemoryName;
100fcaf7f86SDimitry Andric   {
101fcaf7f86SDimitry Andric     std::stringstream SharedMemoryNameStream;
102fcaf7f86SDimitry Andric     SharedMemoryNameStream << "jitlink_" << sys::Process::getProcessId() << '_'
103fcaf7f86SDimitry Andric                            << (++SharedMemoryCount);
104fcaf7f86SDimitry Andric     SharedMemoryName = SharedMemoryNameStream.str();
105fcaf7f86SDimitry Andric   }
106fcaf7f86SDimitry Andric 
107fcaf7f86SDimitry Andric   std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
108fcaf7f86SDimitry Andric                                     SharedMemoryName.end());
109fcaf7f86SDimitry Andric   HANDLE SharedMemoryFile = CreateFileMappingW(
110fcaf7f86SDimitry Andric       INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, Size >> 32,
111fcaf7f86SDimitry Andric       Size & 0xffffffff, WideSharedMemoryName.c_str());
112fcaf7f86SDimitry Andric   if (!SharedMemoryFile)
113fcaf7f86SDimitry Andric     return errorCodeToError(mapWindowsError(GetLastError()));
114fcaf7f86SDimitry Andric 
115fcaf7f86SDimitry Andric   void *Addr = MapViewOfFile(SharedMemoryFile,
116fcaf7f86SDimitry Andric                              FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
117fcaf7f86SDimitry Andric   if (!Addr) {
118fcaf7f86SDimitry Andric     CloseHandle(SharedMemoryFile);
119fcaf7f86SDimitry Andric     return errorCodeToError(mapWindowsError(GetLastError()));
120fcaf7f86SDimitry Andric   }
121fcaf7f86SDimitry Andric 
122fcaf7f86SDimitry Andric #endif
123fcaf7f86SDimitry Andric 
124fcaf7f86SDimitry Andric   {
125fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
126fcaf7f86SDimitry Andric     Reservations[Addr].Size = Size;
127fcaf7f86SDimitry Andric #if defined(_WIN32)
128fcaf7f86SDimitry Andric     Reservations[Addr].SharedMemoryFile = SharedMemoryFile;
129fcaf7f86SDimitry Andric #endif
130fcaf7f86SDimitry Andric   }
131fcaf7f86SDimitry Andric 
132fcaf7f86SDimitry Andric   return std::make_pair(ExecutorAddr::fromPtr(Addr),
133fcaf7f86SDimitry Andric                         std::move(SharedMemoryName));
134fcaf7f86SDimitry Andric #else
135fcaf7f86SDimitry Andric   return make_error<StringError>(
136fcaf7f86SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
137fcaf7f86SDimitry Andric       inconvertibleErrorCode());
138fcaf7f86SDimitry Andric #endif
139fcaf7f86SDimitry Andric }
140fcaf7f86SDimitry Andric 
141fcaf7f86SDimitry Andric Expected<ExecutorAddr> ExecutorSharedMemoryMapperService::initialize(
142fcaf7f86SDimitry Andric     ExecutorAddr Reservation, tpctypes::SharedMemoryFinalizeRequest &FR) {
14361cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
144fcaf7f86SDimitry Andric 
145fcaf7f86SDimitry Andric   ExecutorAddr MinAddr(~0ULL);
146fcaf7f86SDimitry Andric 
147fcaf7f86SDimitry Andric   // Contents are already in place
148fcaf7f86SDimitry Andric   for (auto &Segment : FR.Segments) {
149fcaf7f86SDimitry Andric     if (Segment.Addr < MinAddr)
150fcaf7f86SDimitry Andric       MinAddr = Segment.Addr;
151fcaf7f86SDimitry Andric 
152fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
153fcaf7f86SDimitry Andric 
154*0fca6ea1SDimitry Andric #if defined(__MVS__)
155*0fca6ea1SDimitry Andric       // TODO Is it possible to change the protection level?
156*0fca6ea1SDimitry Andric #else
157fcaf7f86SDimitry Andric     int NativeProt = 0;
15806c3fb27SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Read) == MemProt::Read)
159fcaf7f86SDimitry Andric       NativeProt |= PROT_READ;
16006c3fb27SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Write) == MemProt::Write)
161fcaf7f86SDimitry Andric       NativeProt |= PROT_WRITE;
16206c3fb27SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
163fcaf7f86SDimitry Andric       NativeProt |= PROT_EXEC;
164fcaf7f86SDimitry Andric 
165fcaf7f86SDimitry Andric     if (mprotect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt))
166*0fca6ea1SDimitry Andric       return errorCodeToError(errnoAsErrorCode());
167*0fca6ea1SDimitry Andric #endif
168fcaf7f86SDimitry Andric 
169fcaf7f86SDimitry Andric #elif defined(_WIN32)
170fcaf7f86SDimitry Andric 
17106c3fb27SDimitry Andric     DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
172fcaf7f86SDimitry Andric 
173fcaf7f86SDimitry Andric     if (!VirtualProtect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt,
174fcaf7f86SDimitry Andric                         &NativeProt))
175fcaf7f86SDimitry Andric       return errorCodeToError(mapWindowsError(GetLastError()));
176fcaf7f86SDimitry Andric 
177fcaf7f86SDimitry Andric #endif
178fcaf7f86SDimitry Andric 
17906c3fb27SDimitry Andric     if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
180fcaf7f86SDimitry Andric       sys::Memory::InvalidateInstructionCache(Segment.Addr.toPtr<void *>(),
181fcaf7f86SDimitry Andric                                               Segment.Size);
182fcaf7f86SDimitry Andric   }
183fcaf7f86SDimitry Andric 
184fcaf7f86SDimitry Andric   // Run finalization actions and get deinitlization action list.
185fcaf7f86SDimitry Andric   auto DeinitializeActions = shared::runFinalizeActions(FR.Actions);
186fcaf7f86SDimitry Andric   if (!DeinitializeActions) {
187fcaf7f86SDimitry Andric     return DeinitializeActions.takeError();
188fcaf7f86SDimitry Andric   }
189fcaf7f86SDimitry Andric 
190fcaf7f86SDimitry Andric   {
191fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
192fcaf7f86SDimitry Andric     Allocations[MinAddr].DeinitializationActions =
193fcaf7f86SDimitry Andric         std::move(*DeinitializeActions);
194fcaf7f86SDimitry Andric     Reservations[Reservation.toPtr<void *>()].Allocations.push_back(MinAddr);
195fcaf7f86SDimitry Andric   }
196fcaf7f86SDimitry Andric 
197fcaf7f86SDimitry Andric   return MinAddr;
198fcaf7f86SDimitry Andric 
199fcaf7f86SDimitry Andric #else
200fcaf7f86SDimitry Andric   return make_error<StringError>(
201fcaf7f86SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
202fcaf7f86SDimitry Andric       inconvertibleErrorCode());
203fcaf7f86SDimitry Andric #endif
204fcaf7f86SDimitry Andric }
205fcaf7f86SDimitry Andric 
206fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::deinitialize(
207fcaf7f86SDimitry Andric     const std::vector<ExecutorAddr> &Bases) {
208fcaf7f86SDimitry Andric   Error AllErr = Error::success();
209fcaf7f86SDimitry Andric 
210fcaf7f86SDimitry Andric   {
211fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
212fcaf7f86SDimitry Andric 
213bdd1243dSDimitry Andric     for (auto Base : llvm::reverse(Bases)) {
214fcaf7f86SDimitry Andric       if (Error Err = shared::runDeallocActions(
215fcaf7f86SDimitry Andric               Allocations[Base].DeinitializationActions)) {
216fcaf7f86SDimitry Andric         AllErr = joinErrors(std::move(AllErr), std::move(Err));
217fcaf7f86SDimitry Andric       }
218fcaf7f86SDimitry Andric 
219bdd1243dSDimitry Andric       // Remove the allocation from the allocation list of its reservation
220bdd1243dSDimitry Andric       for (auto &Reservation : Reservations) {
2215f757f3fSDimitry Andric         auto AllocationIt = llvm::find(Reservation.second.Allocations, Base);
222bdd1243dSDimitry Andric         if (AllocationIt != Reservation.second.Allocations.end()) {
223bdd1243dSDimitry Andric           Reservation.second.Allocations.erase(AllocationIt);
224bdd1243dSDimitry Andric           break;
225bdd1243dSDimitry Andric         }
226bdd1243dSDimitry Andric       }
227bdd1243dSDimitry Andric 
228fcaf7f86SDimitry Andric       Allocations.erase(Base);
229fcaf7f86SDimitry Andric     }
230fcaf7f86SDimitry Andric   }
231fcaf7f86SDimitry Andric 
232fcaf7f86SDimitry Andric   return AllErr;
233fcaf7f86SDimitry Andric }
234fcaf7f86SDimitry Andric 
235fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::release(
236fcaf7f86SDimitry Andric     const std::vector<ExecutorAddr> &Bases) {
23761cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
238fcaf7f86SDimitry Andric   Error Err = Error::success();
239fcaf7f86SDimitry Andric 
240fcaf7f86SDimitry Andric   for (auto Base : Bases) {
241fcaf7f86SDimitry Andric     std::vector<ExecutorAddr> AllocAddrs;
242fcaf7f86SDimitry Andric     size_t Size;
243fcaf7f86SDimitry Andric 
244fcaf7f86SDimitry Andric #if defined(_WIN32)
245fcaf7f86SDimitry Andric     HANDLE SharedMemoryFile;
246fcaf7f86SDimitry Andric #endif
247fcaf7f86SDimitry Andric 
248fcaf7f86SDimitry Andric     {
249fcaf7f86SDimitry Andric       std::lock_guard<std::mutex> Lock(Mutex);
250fcaf7f86SDimitry Andric       auto &R = Reservations[Base.toPtr<void *>()];
251fcaf7f86SDimitry Andric       Size = R.Size;
252fcaf7f86SDimitry Andric 
253fcaf7f86SDimitry Andric #if defined(_WIN32)
254fcaf7f86SDimitry Andric       SharedMemoryFile = R.SharedMemoryFile;
255fcaf7f86SDimitry Andric #endif
256fcaf7f86SDimitry Andric 
257fcaf7f86SDimitry Andric       AllocAddrs.swap(R.Allocations);
258fcaf7f86SDimitry Andric     }
259fcaf7f86SDimitry Andric 
260fcaf7f86SDimitry Andric     // deinitialize sub allocations
261fcaf7f86SDimitry Andric     if (Error E = deinitialize(AllocAddrs))
262fcaf7f86SDimitry Andric       Err = joinErrors(std::move(Err), std::move(E));
263fcaf7f86SDimitry Andric 
264fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
265fcaf7f86SDimitry Andric 
266*0fca6ea1SDimitry Andric #if defined(__MVS__)
267*0fca6ea1SDimitry Andric     (void)Size;
268*0fca6ea1SDimitry Andric 
269*0fca6ea1SDimitry Andric     if (shmdt(Base.toPtr<void *>()) < 0)
270*0fca6ea1SDimitry Andric       Err = joinErrors(std::move(Err), errorCodeToError(errnoAsErrorCode()));
271*0fca6ea1SDimitry Andric #else
272fcaf7f86SDimitry Andric     if (munmap(Base.toPtr<void *>(), Size) != 0)
273*0fca6ea1SDimitry Andric       Err = joinErrors(std::move(Err), errorCodeToError(errnoAsErrorCode()));
274*0fca6ea1SDimitry Andric #endif
275fcaf7f86SDimitry Andric 
276fcaf7f86SDimitry Andric #elif defined(_WIN32)
27761cfbce3SDimitry Andric     (void)Size;
278fcaf7f86SDimitry Andric 
279fcaf7f86SDimitry Andric     if (!UnmapViewOfFile(Base.toPtr<void *>()))
280fcaf7f86SDimitry Andric       Err = joinErrors(std::move(Err),
281fcaf7f86SDimitry Andric                        errorCodeToError(mapWindowsError(GetLastError())));
282fcaf7f86SDimitry Andric 
283fcaf7f86SDimitry Andric     CloseHandle(SharedMemoryFile);
284fcaf7f86SDimitry Andric 
285fcaf7f86SDimitry Andric #endif
286fcaf7f86SDimitry Andric 
287fcaf7f86SDimitry Andric     std::lock_guard<std::mutex> Lock(Mutex);
288fcaf7f86SDimitry Andric     Reservations.erase(Base.toPtr<void *>());
289fcaf7f86SDimitry Andric   }
290fcaf7f86SDimitry Andric 
291fcaf7f86SDimitry Andric   return Err;
292fcaf7f86SDimitry Andric #else
293fcaf7f86SDimitry Andric   return make_error<StringError>(
294fcaf7f86SDimitry Andric       "SharedMemoryMapper is not supported on this platform yet",
295fcaf7f86SDimitry Andric       inconvertibleErrorCode());
296fcaf7f86SDimitry Andric #endif
297fcaf7f86SDimitry Andric }
298fcaf7f86SDimitry Andric 
299fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::shutdown() {
300bdd1243dSDimitry Andric   if (Reservations.empty())
301fcaf7f86SDimitry Andric     return Error::success();
302bdd1243dSDimitry Andric 
303bdd1243dSDimitry Andric   std::vector<ExecutorAddr> ReservationAddrs;
304bdd1243dSDimitry Andric   ReservationAddrs.reserve(Reservations.size());
305bdd1243dSDimitry Andric   for (const auto &R : Reservations)
306bdd1243dSDimitry Andric     ReservationAddrs.push_back(ExecutorAddr::fromPtr(R.getFirst()));
307bdd1243dSDimitry Andric 
308bdd1243dSDimitry Andric   return release(std::move(ReservationAddrs));
309fcaf7f86SDimitry Andric }
310fcaf7f86SDimitry Andric 
311fcaf7f86SDimitry Andric void ExecutorSharedMemoryMapperService::addBootstrapSymbols(
312fcaf7f86SDimitry Andric     StringMap<ExecutorAddr> &M) {
313fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceInstanceName] =
314fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(this);
315fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName] =
316fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&reserveWrapper);
317fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName] =
318fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&initializeWrapper);
319fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName] =
320fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&deinitializeWrapper);
321fcaf7f86SDimitry Andric   M[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName] =
322fcaf7f86SDimitry Andric       ExecutorAddr::fromPtr(&releaseWrapper);
323fcaf7f86SDimitry Andric }
324fcaf7f86SDimitry Andric 
325fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
326fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::reserveWrapper(const char *ArgData,
327fcaf7f86SDimitry Andric                                                   size_t ArgSize) {
328fcaf7f86SDimitry Andric   return shared::WrapperFunction<
329fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>::
330fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
331fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
332fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::reserve))
333fcaf7f86SDimitry Andric           .release();
334fcaf7f86SDimitry Andric }
335fcaf7f86SDimitry Andric 
336fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
337fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::initializeWrapper(const char *ArgData,
338fcaf7f86SDimitry Andric                                                      size_t ArgSize) {
339fcaf7f86SDimitry Andric   return shared::WrapperFunction<
340fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceInitializeSignature>::
341fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
342fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
343fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::initialize))
344fcaf7f86SDimitry Andric           .release();
345fcaf7f86SDimitry Andric }
346fcaf7f86SDimitry Andric 
347fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
348fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::deinitializeWrapper(const char *ArgData,
349fcaf7f86SDimitry Andric                                                        size_t ArgSize) {
350fcaf7f86SDimitry Andric   return shared::WrapperFunction<
351fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceDeinitializeSignature>::
352fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
353fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
354fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::deinitialize))
355fcaf7f86SDimitry Andric           .release();
356fcaf7f86SDimitry Andric }
357fcaf7f86SDimitry Andric 
358fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
359fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::releaseWrapper(const char *ArgData,
360fcaf7f86SDimitry Andric                                                   size_t ArgSize) {
361fcaf7f86SDimitry Andric   return shared::WrapperFunction<
362fcaf7f86SDimitry Andric              rt::SPSExecutorSharedMemoryMapperServiceReleaseSignature>::
363fcaf7f86SDimitry Andric       handle(ArgData, ArgSize,
364fcaf7f86SDimitry Andric              shared::makeMethodWrapperHandler(
365fcaf7f86SDimitry Andric                  &ExecutorSharedMemoryMapperService::release))
366fcaf7f86SDimitry Andric           .release();
367fcaf7f86SDimitry Andric }
368fcaf7f86SDimitry Andric 
369fcaf7f86SDimitry Andric } // namespace rt_bootstrap
370fcaf7f86SDimitry Andric } // end namespace orc
371fcaf7f86SDimitry Andric } // end namespace llvm
372