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>
21fcaf7f86SDimitry Andric #include <unistd.h>
22fcaf7f86SDimitry Andric #endif
23fcaf7f86SDimitry Andric
24fcaf7f86SDimitry Andric namespace llvm {
25fcaf7f86SDimitry Andric namespace orc {
26fcaf7f86SDimitry Andric namespace rt_bootstrap {
27fcaf7f86SDimitry Andric
28bdd1243dSDimitry Andric #if defined(_WIN32)
getWindowsProtectionFlags(MemProt MP)29bdd1243dSDimitry Andric static DWORD getWindowsProtectionFlags(MemProt MP) {
30bdd1243dSDimitry Andric if (MP == MemProt::Read)
31bdd1243dSDimitry Andric return PAGE_READONLY;
32bdd1243dSDimitry Andric if (MP == MemProt::Write ||
33bdd1243dSDimitry Andric MP == (MemProt::Write | MemProt::Read)) {
34bdd1243dSDimitry Andric // Note: PAGE_WRITE is not supported by VirtualProtect
35bdd1243dSDimitry Andric return PAGE_READWRITE;
36bdd1243dSDimitry Andric }
37bdd1243dSDimitry Andric if (MP == (MemProt::Read | MemProt::Exec))
38bdd1243dSDimitry Andric return PAGE_EXECUTE_READ;
39bdd1243dSDimitry Andric if (MP == (MemProt::Read | MemProt::Write | MemProt::Exec))
40bdd1243dSDimitry Andric return PAGE_EXECUTE_READWRITE;
41bdd1243dSDimitry Andric if (MP == MemProt::Exec)
42bdd1243dSDimitry Andric return PAGE_EXECUTE;
43bdd1243dSDimitry Andric
44bdd1243dSDimitry Andric return PAGE_NOACCESS;
45bdd1243dSDimitry Andric }
46bdd1243dSDimitry Andric #endif
47bdd1243dSDimitry Andric
48fcaf7f86SDimitry Andric Expected<std::pair<ExecutorAddr, std::string>>
reserve(uint64_t Size)49fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
5061cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
51fcaf7f86SDimitry Andric
52fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
53fcaf7f86SDimitry Andric
54fcaf7f86SDimitry Andric std::string SharedMemoryName;
55fcaf7f86SDimitry Andric {
56fcaf7f86SDimitry Andric std::stringstream SharedMemoryNameStream;
57fcaf7f86SDimitry Andric SharedMemoryNameStream << "/jitlink_" << sys::Process::getProcessId() << '_'
58fcaf7f86SDimitry Andric << (++SharedMemoryCount);
59fcaf7f86SDimitry Andric SharedMemoryName = SharedMemoryNameStream.str();
60fcaf7f86SDimitry Andric }
61fcaf7f86SDimitry Andric
62fcaf7f86SDimitry Andric int SharedMemoryFile =
63fcaf7f86SDimitry Andric shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
64fcaf7f86SDimitry Andric if (SharedMemoryFile < 0)
65fcaf7f86SDimitry Andric return errorCodeToError(std::error_code(errno, std::generic_category()));
66fcaf7f86SDimitry Andric
67fcaf7f86SDimitry Andric // by default size is 0
68fcaf7f86SDimitry Andric if (ftruncate(SharedMemoryFile, Size) < 0)
69fcaf7f86SDimitry Andric return errorCodeToError(std::error_code(errno, std::generic_category()));
70fcaf7f86SDimitry Andric
71fcaf7f86SDimitry Andric void *Addr = mmap(nullptr, Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
72fcaf7f86SDimitry Andric if (Addr == MAP_FAILED)
73fcaf7f86SDimitry Andric return errorCodeToError(std::error_code(errno, std::generic_category()));
74fcaf7f86SDimitry Andric
75fcaf7f86SDimitry Andric close(SharedMemoryFile);
76fcaf7f86SDimitry Andric
77fcaf7f86SDimitry Andric #elif defined(_WIN32)
78fcaf7f86SDimitry Andric
79fcaf7f86SDimitry Andric std::string SharedMemoryName;
80fcaf7f86SDimitry Andric {
81fcaf7f86SDimitry Andric std::stringstream SharedMemoryNameStream;
82fcaf7f86SDimitry Andric SharedMemoryNameStream << "jitlink_" << sys::Process::getProcessId() << '_'
83fcaf7f86SDimitry Andric << (++SharedMemoryCount);
84fcaf7f86SDimitry Andric SharedMemoryName = SharedMemoryNameStream.str();
85fcaf7f86SDimitry Andric }
86fcaf7f86SDimitry Andric
87fcaf7f86SDimitry Andric std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
88fcaf7f86SDimitry Andric SharedMemoryName.end());
89fcaf7f86SDimitry Andric HANDLE SharedMemoryFile = CreateFileMappingW(
90fcaf7f86SDimitry Andric INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, Size >> 32,
91fcaf7f86SDimitry Andric Size & 0xffffffff, WideSharedMemoryName.c_str());
92fcaf7f86SDimitry Andric if (!SharedMemoryFile)
93fcaf7f86SDimitry Andric return errorCodeToError(mapWindowsError(GetLastError()));
94fcaf7f86SDimitry Andric
95fcaf7f86SDimitry Andric void *Addr = MapViewOfFile(SharedMemoryFile,
96fcaf7f86SDimitry Andric FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
97fcaf7f86SDimitry Andric if (!Addr) {
98fcaf7f86SDimitry Andric CloseHandle(SharedMemoryFile);
99fcaf7f86SDimitry Andric return errorCodeToError(mapWindowsError(GetLastError()));
100fcaf7f86SDimitry Andric }
101fcaf7f86SDimitry Andric
102fcaf7f86SDimitry Andric #endif
103fcaf7f86SDimitry Andric
104fcaf7f86SDimitry Andric {
105fcaf7f86SDimitry Andric std::lock_guard<std::mutex> Lock(Mutex);
106fcaf7f86SDimitry Andric Reservations[Addr].Size = Size;
107fcaf7f86SDimitry Andric #if defined(_WIN32)
108fcaf7f86SDimitry Andric Reservations[Addr].SharedMemoryFile = SharedMemoryFile;
109fcaf7f86SDimitry Andric #endif
110fcaf7f86SDimitry Andric }
111fcaf7f86SDimitry Andric
112fcaf7f86SDimitry Andric return std::make_pair(ExecutorAddr::fromPtr(Addr),
113fcaf7f86SDimitry Andric std::move(SharedMemoryName));
114fcaf7f86SDimitry Andric #else
115fcaf7f86SDimitry Andric return make_error<StringError>(
116fcaf7f86SDimitry Andric "SharedMemoryMapper is not supported on this platform yet",
117fcaf7f86SDimitry Andric inconvertibleErrorCode());
118fcaf7f86SDimitry Andric #endif
119fcaf7f86SDimitry Andric }
120fcaf7f86SDimitry Andric
initialize(ExecutorAddr Reservation,tpctypes::SharedMemoryFinalizeRequest & FR)121fcaf7f86SDimitry Andric Expected<ExecutorAddr> ExecutorSharedMemoryMapperService::initialize(
122fcaf7f86SDimitry Andric ExecutorAddr Reservation, tpctypes::SharedMemoryFinalizeRequest &FR) {
12361cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
124fcaf7f86SDimitry Andric
125fcaf7f86SDimitry Andric ExecutorAddr MinAddr(~0ULL);
126fcaf7f86SDimitry Andric
127fcaf7f86SDimitry Andric // Contents are already in place
128fcaf7f86SDimitry Andric for (auto &Segment : FR.Segments) {
129fcaf7f86SDimitry Andric if (Segment.Addr < MinAddr)
130fcaf7f86SDimitry Andric MinAddr = Segment.Addr;
131fcaf7f86SDimitry Andric
132fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
133fcaf7f86SDimitry Andric
134fcaf7f86SDimitry Andric int NativeProt = 0;
135fe013be4SDimitry Andric if ((Segment.RAG.Prot & MemProt::Read) == MemProt::Read)
136fcaf7f86SDimitry Andric NativeProt |= PROT_READ;
137fe013be4SDimitry Andric if ((Segment.RAG.Prot & MemProt::Write) == MemProt::Write)
138fcaf7f86SDimitry Andric NativeProt |= PROT_WRITE;
139fe013be4SDimitry Andric if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
140fcaf7f86SDimitry Andric NativeProt |= PROT_EXEC;
141fcaf7f86SDimitry Andric
142fcaf7f86SDimitry Andric if (mprotect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt))
143fcaf7f86SDimitry Andric return errorCodeToError(std::error_code(errno, std::generic_category()));
144fcaf7f86SDimitry Andric
145fcaf7f86SDimitry Andric #elif defined(_WIN32)
146fcaf7f86SDimitry Andric
147fe013be4SDimitry Andric DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
148fcaf7f86SDimitry Andric
149fcaf7f86SDimitry Andric if (!VirtualProtect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt,
150fcaf7f86SDimitry Andric &NativeProt))
151fcaf7f86SDimitry Andric return errorCodeToError(mapWindowsError(GetLastError()));
152fcaf7f86SDimitry Andric
153fcaf7f86SDimitry Andric #endif
154fcaf7f86SDimitry Andric
155fe013be4SDimitry Andric if ((Segment.RAG.Prot & MemProt::Exec) == MemProt::Exec)
156fcaf7f86SDimitry Andric sys::Memory::InvalidateInstructionCache(Segment.Addr.toPtr<void *>(),
157fcaf7f86SDimitry Andric Segment.Size);
158fcaf7f86SDimitry Andric }
159fcaf7f86SDimitry Andric
160fcaf7f86SDimitry Andric // Run finalization actions and get deinitlization action list.
161fcaf7f86SDimitry Andric auto DeinitializeActions = shared::runFinalizeActions(FR.Actions);
162fcaf7f86SDimitry Andric if (!DeinitializeActions) {
163fcaf7f86SDimitry Andric return DeinitializeActions.takeError();
164fcaf7f86SDimitry Andric }
165fcaf7f86SDimitry Andric
166fcaf7f86SDimitry Andric {
167fcaf7f86SDimitry Andric std::lock_guard<std::mutex> Lock(Mutex);
168fcaf7f86SDimitry Andric Allocations[MinAddr].DeinitializationActions =
169fcaf7f86SDimitry Andric std::move(*DeinitializeActions);
170fcaf7f86SDimitry Andric Reservations[Reservation.toPtr<void *>()].Allocations.push_back(MinAddr);
171fcaf7f86SDimitry Andric }
172fcaf7f86SDimitry Andric
173fcaf7f86SDimitry Andric return MinAddr;
174fcaf7f86SDimitry Andric
175fcaf7f86SDimitry Andric #else
176fcaf7f86SDimitry Andric return make_error<StringError>(
177fcaf7f86SDimitry Andric "SharedMemoryMapper is not supported on this platform yet",
178fcaf7f86SDimitry Andric inconvertibleErrorCode());
179fcaf7f86SDimitry Andric #endif
180fcaf7f86SDimitry Andric }
181fcaf7f86SDimitry Andric
deinitialize(const std::vector<ExecutorAddr> & Bases)182fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::deinitialize(
183fcaf7f86SDimitry Andric const std::vector<ExecutorAddr> &Bases) {
184fcaf7f86SDimitry Andric Error AllErr = Error::success();
185fcaf7f86SDimitry Andric
186fcaf7f86SDimitry Andric {
187fcaf7f86SDimitry Andric std::lock_guard<std::mutex> Lock(Mutex);
188fcaf7f86SDimitry Andric
189bdd1243dSDimitry Andric for (auto Base : llvm::reverse(Bases)) {
190fcaf7f86SDimitry Andric if (Error Err = shared::runDeallocActions(
191fcaf7f86SDimitry Andric Allocations[Base].DeinitializationActions)) {
192fcaf7f86SDimitry Andric AllErr = joinErrors(std::move(AllErr), std::move(Err));
193fcaf7f86SDimitry Andric }
194fcaf7f86SDimitry Andric
195bdd1243dSDimitry Andric // Remove the allocation from the allocation list of its reservation
196bdd1243dSDimitry Andric for (auto &Reservation : Reservations) {
197*c9157d92SDimitry Andric auto AllocationIt = llvm::find(Reservation.second.Allocations, Base);
198bdd1243dSDimitry Andric if (AllocationIt != Reservation.second.Allocations.end()) {
199bdd1243dSDimitry Andric Reservation.second.Allocations.erase(AllocationIt);
200bdd1243dSDimitry Andric break;
201bdd1243dSDimitry Andric }
202bdd1243dSDimitry Andric }
203bdd1243dSDimitry Andric
204fcaf7f86SDimitry Andric Allocations.erase(Base);
205fcaf7f86SDimitry Andric }
206fcaf7f86SDimitry Andric }
207fcaf7f86SDimitry Andric
208fcaf7f86SDimitry Andric return AllErr;
209fcaf7f86SDimitry Andric }
210fcaf7f86SDimitry Andric
release(const std::vector<ExecutorAddr> & Bases)211fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::release(
212fcaf7f86SDimitry Andric const std::vector<ExecutorAddr> &Bases) {
21361cfbce3SDimitry Andric #if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
214fcaf7f86SDimitry Andric Error Err = Error::success();
215fcaf7f86SDimitry Andric
216fcaf7f86SDimitry Andric for (auto Base : Bases) {
217fcaf7f86SDimitry Andric std::vector<ExecutorAddr> AllocAddrs;
218fcaf7f86SDimitry Andric size_t Size;
219fcaf7f86SDimitry Andric
220fcaf7f86SDimitry Andric #if defined(_WIN32)
221fcaf7f86SDimitry Andric HANDLE SharedMemoryFile;
222fcaf7f86SDimitry Andric #endif
223fcaf7f86SDimitry Andric
224fcaf7f86SDimitry Andric {
225fcaf7f86SDimitry Andric std::lock_guard<std::mutex> Lock(Mutex);
226fcaf7f86SDimitry Andric auto &R = Reservations[Base.toPtr<void *>()];
227fcaf7f86SDimitry Andric Size = R.Size;
228fcaf7f86SDimitry Andric
229fcaf7f86SDimitry Andric #if defined(_WIN32)
230fcaf7f86SDimitry Andric SharedMemoryFile = R.SharedMemoryFile;
231fcaf7f86SDimitry Andric #endif
232fcaf7f86SDimitry Andric
233fcaf7f86SDimitry Andric AllocAddrs.swap(R.Allocations);
234fcaf7f86SDimitry Andric }
235fcaf7f86SDimitry Andric
236fcaf7f86SDimitry Andric // deinitialize sub allocations
237fcaf7f86SDimitry Andric if (Error E = deinitialize(AllocAddrs))
238fcaf7f86SDimitry Andric Err = joinErrors(std::move(Err), std::move(E));
239fcaf7f86SDimitry Andric
240fcaf7f86SDimitry Andric #if defined(LLVM_ON_UNIX)
241fcaf7f86SDimitry Andric
242fcaf7f86SDimitry Andric if (munmap(Base.toPtr<void *>(), Size) != 0)
243fcaf7f86SDimitry Andric Err = joinErrors(std::move(Err), errorCodeToError(std::error_code(
244fcaf7f86SDimitry Andric errno, std::generic_category())));
245fcaf7f86SDimitry Andric
246fcaf7f86SDimitry Andric #elif defined(_WIN32)
24761cfbce3SDimitry Andric (void)Size;
248fcaf7f86SDimitry Andric
249fcaf7f86SDimitry Andric if (!UnmapViewOfFile(Base.toPtr<void *>()))
250fcaf7f86SDimitry Andric Err = joinErrors(std::move(Err),
251fcaf7f86SDimitry Andric errorCodeToError(mapWindowsError(GetLastError())));
252fcaf7f86SDimitry Andric
253fcaf7f86SDimitry Andric CloseHandle(SharedMemoryFile);
254fcaf7f86SDimitry Andric
255fcaf7f86SDimitry Andric #endif
256fcaf7f86SDimitry Andric
257fcaf7f86SDimitry Andric std::lock_guard<std::mutex> Lock(Mutex);
258fcaf7f86SDimitry Andric Reservations.erase(Base.toPtr<void *>());
259fcaf7f86SDimitry Andric }
260fcaf7f86SDimitry Andric
261fcaf7f86SDimitry Andric return Err;
262fcaf7f86SDimitry Andric #else
263fcaf7f86SDimitry Andric return make_error<StringError>(
264fcaf7f86SDimitry Andric "SharedMemoryMapper is not supported on this platform yet",
265fcaf7f86SDimitry Andric inconvertibleErrorCode());
266fcaf7f86SDimitry Andric #endif
267fcaf7f86SDimitry Andric }
268fcaf7f86SDimitry Andric
shutdown()269fcaf7f86SDimitry Andric Error ExecutorSharedMemoryMapperService::shutdown() {
270bdd1243dSDimitry Andric if (Reservations.empty())
271fcaf7f86SDimitry Andric return Error::success();
272bdd1243dSDimitry Andric
273bdd1243dSDimitry Andric std::vector<ExecutorAddr> ReservationAddrs;
274bdd1243dSDimitry Andric ReservationAddrs.reserve(Reservations.size());
275bdd1243dSDimitry Andric for (const auto &R : Reservations)
276bdd1243dSDimitry Andric ReservationAddrs.push_back(ExecutorAddr::fromPtr(R.getFirst()));
277bdd1243dSDimitry Andric
278bdd1243dSDimitry Andric return release(std::move(ReservationAddrs));
279fcaf7f86SDimitry Andric }
280fcaf7f86SDimitry Andric
addBootstrapSymbols(StringMap<ExecutorAddr> & M)281fcaf7f86SDimitry Andric void ExecutorSharedMemoryMapperService::addBootstrapSymbols(
282fcaf7f86SDimitry Andric StringMap<ExecutorAddr> &M) {
283fcaf7f86SDimitry Andric M[rt::ExecutorSharedMemoryMapperServiceInstanceName] =
284fcaf7f86SDimitry Andric ExecutorAddr::fromPtr(this);
285fcaf7f86SDimitry Andric M[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName] =
286fcaf7f86SDimitry Andric ExecutorAddr::fromPtr(&reserveWrapper);
287fcaf7f86SDimitry Andric M[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName] =
288fcaf7f86SDimitry Andric ExecutorAddr::fromPtr(&initializeWrapper);
289fcaf7f86SDimitry Andric M[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName] =
290fcaf7f86SDimitry Andric ExecutorAddr::fromPtr(&deinitializeWrapper);
291fcaf7f86SDimitry Andric M[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName] =
292fcaf7f86SDimitry Andric ExecutorAddr::fromPtr(&releaseWrapper);
293fcaf7f86SDimitry Andric }
294fcaf7f86SDimitry Andric
295fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
reserveWrapper(const char * ArgData,size_t ArgSize)296fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::reserveWrapper(const char *ArgData,
297fcaf7f86SDimitry Andric size_t ArgSize) {
298fcaf7f86SDimitry Andric return shared::WrapperFunction<
299fcaf7f86SDimitry Andric rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>::
300fcaf7f86SDimitry Andric handle(ArgData, ArgSize,
301fcaf7f86SDimitry Andric shared::makeMethodWrapperHandler(
302fcaf7f86SDimitry Andric &ExecutorSharedMemoryMapperService::reserve))
303fcaf7f86SDimitry Andric .release();
304fcaf7f86SDimitry Andric }
305fcaf7f86SDimitry Andric
306fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
initializeWrapper(const char * ArgData,size_t ArgSize)307fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::initializeWrapper(const char *ArgData,
308fcaf7f86SDimitry Andric size_t ArgSize) {
309fcaf7f86SDimitry Andric return shared::WrapperFunction<
310fcaf7f86SDimitry Andric rt::SPSExecutorSharedMemoryMapperServiceInitializeSignature>::
311fcaf7f86SDimitry Andric handle(ArgData, ArgSize,
312fcaf7f86SDimitry Andric shared::makeMethodWrapperHandler(
313fcaf7f86SDimitry Andric &ExecutorSharedMemoryMapperService::initialize))
314fcaf7f86SDimitry Andric .release();
315fcaf7f86SDimitry Andric }
316fcaf7f86SDimitry Andric
317fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
deinitializeWrapper(const char * ArgData,size_t ArgSize)318fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::deinitializeWrapper(const char *ArgData,
319fcaf7f86SDimitry Andric size_t ArgSize) {
320fcaf7f86SDimitry Andric return shared::WrapperFunction<
321fcaf7f86SDimitry Andric rt::SPSExecutorSharedMemoryMapperServiceDeinitializeSignature>::
322fcaf7f86SDimitry Andric handle(ArgData, ArgSize,
323fcaf7f86SDimitry Andric shared::makeMethodWrapperHandler(
324fcaf7f86SDimitry Andric &ExecutorSharedMemoryMapperService::deinitialize))
325fcaf7f86SDimitry Andric .release();
326fcaf7f86SDimitry Andric }
327fcaf7f86SDimitry Andric
328fcaf7f86SDimitry Andric llvm::orc::shared::CWrapperFunctionResult
releaseWrapper(const char * ArgData,size_t ArgSize)329fcaf7f86SDimitry Andric ExecutorSharedMemoryMapperService::releaseWrapper(const char *ArgData,
330fcaf7f86SDimitry Andric size_t ArgSize) {
331fcaf7f86SDimitry Andric return shared::WrapperFunction<
332fcaf7f86SDimitry Andric rt::SPSExecutorSharedMemoryMapperServiceReleaseSignature>::
333fcaf7f86SDimitry Andric handle(ArgData, ArgSize,
334fcaf7f86SDimitry Andric shared::makeMethodWrapperHandler(
335fcaf7f86SDimitry Andric &ExecutorSharedMemoryMapperService::release))
336fcaf7f86SDimitry Andric .release();
337fcaf7f86SDimitry Andric }
338fcaf7f86SDimitry Andric
339fcaf7f86SDimitry Andric } // namespace rt_bootstrap
340fcaf7f86SDimitry Andric } // end namespace orc
341fcaf7f86SDimitry Andric } // end namespace llvm
342