Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
ExecutorSharedMemoryMapperService.cpp
Go to the documentation of this file.
1//===---------- ExecutorSharedMemoryMapperService.cpp -----------*- 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#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.h"
10#include "llvm/Config/llvm-config.h"// for LLVM_ON_UNIX
11#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12#include "llvm/Support/Process.h"
13#include "llvm/Support/WindowsError.h"
14#include <sstream>
15
16#if defined(LLVM_ON_UNIX)
17#include <errno.h>
18#include <fcntl.h>
19#include <sys/mman.h>
20#if defined(__MVS__)
21#include "llvm/Support/BLAKE3.h"
22#include <sys/shm.h>
23#endif
24#include <unistd.h>
25#endif
26
27namespacellvm {
28namespaceorc {
29namespacert_bootstrap {
30
31#if defined(_WIN32)
32staticDWORD getWindowsProtectionFlags(MemProt MP) {
33if (MP ==MemProt::Read)
34return PAGE_READONLY;
35if (MP ==MemProt::Write ||
36 MP == (MemProt::Write |MemProt::Read)) {
37// Note: PAGE_WRITE is not supported by VirtualProtect
38return PAGE_READWRITE;
39 }
40if (MP == (MemProt::Read |MemProt::Exec))
41return PAGE_EXECUTE_READ;
42if (MP == (MemProt::Read |MemProt::Write |MemProt::Exec))
43return PAGE_EXECUTE_READWRITE;
44if (MP ==MemProt::Exec)
45return PAGE_EXECUTE;
46
47return PAGE_NOACCESS;
48}
49#endif
50
51Expected<std::pair<ExecutorAddr, std::string>>
52ExecutorSharedMemoryMapperService::reserve(uint64_tSize) {
53#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
54
55#if defined(LLVM_ON_UNIX)
56
57 std::string SharedMemoryName;
58 {
59 std::stringstream SharedMemoryNameStream;
60 SharedMemoryNameStream <<"/jitlink_" <<sys::Process::getProcessId() <<'_'
61 << (++SharedMemoryCount);
62 SharedMemoryName = SharedMemoryNameStream.str();
63 }
64
65#if defined(__MVS__)
66ArrayRef<uint8_t>Data(
67reinterpret_cast<constuint8_t *>(SharedMemoryName.c_str()),
68 SharedMemoryName.size());
69auto HashedName = BLAKE3::hash<sizeof(key_t)>(Data);
70 key_t Key = *reinterpret_cast<key_t *>(HashedName.data());
71int SharedMemoryId =
72 shmget(Key,Size, IPC_CREAT | IPC_EXCL | __IPC_SHAREAS | 0700);
73if (SharedMemoryId < 0)
74returnerrorCodeToError(errnoAsErrorCode());
75
76void *Addr = shmat(SharedMemoryId,nullptr, 0);
77if (Addr ==reinterpret_cast<void *>(-1))
78returnerrorCodeToError(errnoAsErrorCode());
79#else
80int SharedMemoryFile =
81 shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
82if (SharedMemoryFile < 0)
83returnerrorCodeToError(errnoAsErrorCode());
84
85// by default size is 0
86if (ftruncate(SharedMemoryFile,Size) < 0)
87returnerrorCodeToError(errnoAsErrorCode());
88
89void *Addr = mmap(nullptr,Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
90if (Addr == MAP_FAILED)
91returnerrorCodeToError(errnoAsErrorCode());
92
93 close(SharedMemoryFile);
94#endif
95
96#elif defined(_WIN32)
97
98 std::string SharedMemoryName;
99 {
100 std::stringstream SharedMemoryNameStream;
101 SharedMemoryNameStream <<"jitlink_" <<sys::Process::getProcessId() <<'_'
102 << (++SharedMemoryCount);
103 SharedMemoryName = SharedMemoryNameStream.str();
104 }
105
106 std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
107 SharedMemoryName.end());
108 HANDLE SharedMemoryFile = CreateFileMappingW(
109 INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE,Size >> 32,
110Size & 0xffffffff, WideSharedMemoryName.c_str());
111if (!SharedMemoryFile)
112returnerrorCodeToError(mapWindowsError(GetLastError()));
113
114void *Addr = MapViewOfFile(SharedMemoryFile,
115 FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
116if (!Addr) {
117 CloseHandle(SharedMemoryFile);
118returnerrorCodeToError(mapWindowsError(GetLastError()));
119 }
120
121#endif
122
123 {
124 std::lock_guard<std::mutex> Lock(Mutex);
125 Reservations[Addr].Size =Size;
126#if defined(_WIN32)
127 Reservations[Addr].SharedMemoryFile = SharedMemoryFile;
128#endif
129 }
130
131return std::make_pair(ExecutorAddr::fromPtr(Addr),
132 std::move(SharedMemoryName));
133#else
134return make_error<StringError>(
135"SharedMemoryMapper is not supported on this platform yet",
136inconvertibleErrorCode());
137#endif
138}
139
140Expected<ExecutorAddr>ExecutorSharedMemoryMapperService::initialize(
141ExecutorAddr Reservation,tpctypes::SharedMemoryFinalizeRequest &FR) {
142#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
143
144ExecutorAddr MinAddr(~0ULL);
145
146// Contents are already in place
147for (auto &Segment : FR.Segments) {
148if (Segment.Addr < MinAddr)
149 MinAddr = Segment.Addr;
150
151#if defined(LLVM_ON_UNIX)
152
153#if defined(__MVS__)
154// TODO Is it possible to change the protection level?
155#else
156int NativeProt = 0;
157if ((Segment.RAG.Prot &MemProt::Read) ==MemProt::Read)
158 NativeProt |= PROT_READ;
159if ((Segment.RAG.Prot &MemProt::Write) ==MemProt::Write)
160 NativeProt |= PROT_WRITE;
161if ((Segment.RAG.Prot &MemProt::Exec) ==MemProt::Exec)
162 NativeProt |= PROT_EXEC;
163
164if (mprotect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt))
165returnerrorCodeToError(errnoAsErrorCode());
166#endif
167
168#elif defined(_WIN32)
169
170 DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
171
172if (!VirtualProtect(Segment.Addr.toPtr<void *>(), Segment.Size, NativeProt,
173 &NativeProt))
174returnerrorCodeToError(mapWindowsError(GetLastError()));
175
176#endif
177
178if ((Segment.RAG.Prot &MemProt::Exec) ==MemProt::Exec)
179sys::Memory::InvalidateInstructionCache(Segment.Addr.toPtr<void *>(),
180 Segment.Size);
181 }
182
183// Run finalization actions and get deinitlization action list.
184auto DeinitializeActions =shared::runFinalizeActions(FR.Actions);
185if (!DeinitializeActions) {
186return DeinitializeActions.takeError();
187 }
188
189 {
190 std::lock_guard<std::mutex> Lock(Mutex);
191 Allocations[MinAddr].DeinitializationActions =
192 std::move(*DeinitializeActions);
193 Reservations[Reservation.toPtr<void *>()].Allocations.push_back(MinAddr);
194 }
195
196return MinAddr;
197
198#else
199return make_error<StringError>(
200"SharedMemoryMapper is not supported on this platform yet",
201inconvertibleErrorCode());
202#endif
203}
204
205ErrorExecutorSharedMemoryMapperService::deinitialize(
206const std::vector<ExecutorAddr> &Bases) {
207Error AllErr =Error::success();
208
209 {
210 std::lock_guard<std::mutex> Lock(Mutex);
211
212for (autoBase :llvm::reverse(Bases)) {
213if (Error Err =shared::runDeallocActions(
214 Allocations[Base].DeinitializationActions)) {
215 AllErr =joinErrors(std::move(AllErr), std::move(Err));
216 }
217
218// Remove the allocation from the allocation list of its reservation
219for (auto &Reservation : Reservations) {
220auto AllocationIt =llvm::find(Reservation.second.Allocations,Base);
221if (AllocationIt != Reservation.second.Allocations.end()) {
222 Reservation.second.Allocations.erase(AllocationIt);
223break;
224 }
225 }
226
227 Allocations.erase(Base);
228 }
229 }
230
231return AllErr;
232}
233
234ErrorExecutorSharedMemoryMapperService::release(
235const std::vector<ExecutorAddr> &Bases) {
236#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
237Error Err =Error::success();
238
239for (autoBase : Bases) {
240 std::vector<ExecutorAddr> AllocAddrs;
241size_tSize;
242
243#if defined(_WIN32)
244 HANDLE SharedMemoryFile;
245#endif
246
247 {
248 std::lock_guard<std::mutex> Lock(Mutex);
249auto &R = Reservations[Base.toPtr<void *>()];
250Size = R.Size;
251
252#if defined(_WIN32)
253 SharedMemoryFile = R.SharedMemoryFile;
254#endif
255
256 AllocAddrs.swap(R.Allocations);
257 }
258
259// deinitialize sub allocations
260if (ErrorE =deinitialize(AllocAddrs))
261 Err =joinErrors(std::move(Err), std::move(E));
262
263#if defined(LLVM_ON_UNIX)
264
265#if defined(__MVS__)
266 (void)Size;
267
268if (shmdt(Base.toPtr<void *>()) < 0)
269 Err =joinErrors(std::move(Err),errorCodeToError(errnoAsErrorCode()));
270#else
271if (munmap(Base.toPtr<void *>(),Size) != 0)
272 Err =joinErrors(std::move(Err),errorCodeToError(errnoAsErrorCode()));
273#endif
274
275#elif defined(_WIN32)
276 (void)Size;
277
278if (!UnmapViewOfFile(Base.toPtr<void *>()))
279 Err =joinErrors(std::move(Err),
280errorCodeToError(mapWindowsError(GetLastError())));
281
282 CloseHandle(SharedMemoryFile);
283
284#endif
285
286 std::lock_guard<std::mutex> Lock(Mutex);
287 Reservations.erase(Base.toPtr<void *>());
288 }
289
290return Err;
291#else
292return make_error<StringError>(
293"SharedMemoryMapper is not supported on this platform yet",
294inconvertibleErrorCode());
295#endif
296}
297
298ErrorExecutorSharedMemoryMapperService::shutdown() {
299if (Reservations.empty())
300returnError::success();
301
302 std::vector<ExecutorAddr> ReservationAddrs;
303 ReservationAddrs.reserve(Reservations.size());
304for (constauto &R : Reservations)
305 ReservationAddrs.push_back(ExecutorAddr::fromPtr(R.getFirst()));
306
307returnrelease(std::move(ReservationAddrs));
308}
309
310voidExecutorSharedMemoryMapperService::addBootstrapSymbols(
311StringMap<ExecutorAddr> &M) {
312 M[rt::ExecutorSharedMemoryMapperServiceInstanceName] =
313ExecutorAddr::fromPtr(this);
314 M[rt::ExecutorSharedMemoryMapperServiceReserveWrapperName] =
315ExecutorAddr::fromPtr(&reserveWrapper);
316 M[rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName] =
317ExecutorAddr::fromPtr(&initializeWrapper);
318 M[rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName] =
319ExecutorAddr::fromPtr(&deinitializeWrapper);
320 M[rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName] =
321ExecutorAddr::fromPtr(&releaseWrapper);
322}
323
324llvm::orc::shared::CWrapperFunctionResult
325ExecutorSharedMemoryMapperService::reserveWrapper(constchar *ArgData,
326size_t ArgSize) {
327returnshared::WrapperFunction<
328rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>::
329 handle(ArgData, ArgSize,
330shared::makeMethodWrapperHandler(
331 &ExecutorSharedMemoryMapperService::reserve))
332 .release();
333}
334
335llvm::orc::shared::CWrapperFunctionResult
336ExecutorSharedMemoryMapperService::initializeWrapper(constchar *ArgData,
337size_t ArgSize) {
338returnshared::WrapperFunction<
339rt::SPSExecutorSharedMemoryMapperServiceInitializeSignature>::
340 handle(ArgData, ArgSize,
341shared::makeMethodWrapperHandler(
342 &ExecutorSharedMemoryMapperService::initialize))
343 .release();
344}
345
346llvm::orc::shared::CWrapperFunctionResult
347ExecutorSharedMemoryMapperService::deinitializeWrapper(constchar *ArgData,
348size_t ArgSize) {
349return shared::WrapperFunction<
350rt::SPSExecutorSharedMemoryMapperServiceDeinitializeSignature>::
351 handle(ArgData, ArgSize,
352shared::makeMethodWrapperHandler(
353 &ExecutorSharedMemoryMapperService::deinitialize))
354 .release();
355}
356
357llvm::orc::shared::CWrapperFunctionResult
358ExecutorSharedMemoryMapperService::releaseWrapper(constchar *ArgData,
359size_t ArgSize) {
360return shared::WrapperFunction<
361rt::SPSExecutorSharedMemoryMapperServiceReleaseSignature>::
362 handle(ArgData, ArgSize,
363shared::makeMethodWrapperHandler(
364 &ExecutorSharedMemoryMapperService::release))
365 .release();
366}
367
368}// namespace rt_bootstrap
369}// end namespace orc
370}// end namespace llvm
BLAKE3.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Addr
uint64_t Addr
Definition:ELFObjHandler.cpp:79
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
ExecutorSharedMemoryMapperService.h
OrcRTBridge.h
Process.h
Provides a library for accessing information about this process and other processes on the operating ...
WindowsError.h
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition:DenseMap.h:321
llvm::DenseMapBase::size
unsigned size() const
Definition:DenseMap.h:99
llvm::DenseMapBase::empty
bool empty() const
Definition:DenseMap.h:98
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition:StringMap.h:128
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition:ExecutorAddress.h:34
llvm::orc::ExecutorAddr::fromPtr
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
Definition:ExecutorAddress.h:111
llvm::orc::ExecutorAddr::toPtr
std::enable_if_t< std::is_pointer< T >::value, T > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given type.
Definition:ExecutorAddress.h:120
llvm::orc::rt_bootstrap::ExecutorSharedMemoryMapperService::addBootstrapSymbols
void addBootstrapSymbols(StringMap< ExecutorAddr > &M) override
Definition:ExecutorSharedMemoryMapperService.cpp:310
llvm::orc::rt_bootstrap::ExecutorSharedMemoryMapperService::deinitialize
Error deinitialize(const std::vector< ExecutorAddr > &Bases)
Definition:ExecutorSharedMemoryMapperService.cpp:205
llvm::orc::rt_bootstrap::ExecutorSharedMemoryMapperService::release
Error release(const std::vector< ExecutorAddr > &Bases)
Definition:ExecutorSharedMemoryMapperService.cpp:234
llvm::orc::rt_bootstrap::ExecutorSharedMemoryMapperService::reserve
Expected< std::pair< ExecutorAddr, std::string > > reserve(uint64_t Size)
Definition:ExecutorSharedMemoryMapperService.cpp:52
llvm::orc::rt_bootstrap::ExecutorSharedMemoryMapperService::shutdown
Error shutdown() override
Definition:ExecutorSharedMemoryMapperService.cpp:298
llvm::orc::rt_bootstrap::ExecutorSharedMemoryMapperService::initialize
Expected< ExecutorAddr > initialize(ExecutorAddr Reservation, tpctypes::SharedMemoryFinalizeRequest &FR)
Definition:ExecutorSharedMemoryMapperService.cpp:140
llvm::orc::shared::WrapperFunction
Definition:WrapperFunctionUtils.h:434
llvm::sys::Memory::InvalidateInstructionCache
static void InvalidateInstructionCache(const void *Addr, size_t Len)
InvalidateInstructionCache - Before the JIT can run a block of code that has been emitted it must inv...
llvm::sys::Process::getProcessId
static Pid getProcessId()
Get the process's identifier.
llvm::sys::SmartMutex< false >
uint64_t
uint8_t
llvm::AMDGPU::SDWA::DWORD
@ DWORD
Definition:SIDefines.h:910
llvm::orc::rt::SPSExecutorSharedMemoryMapperServiceInitializeSignature
shared::SPSExpected< shared::SPSExecutorAddr >(shared::SPSExecutorAddr, shared::SPSExecutorAddr, shared::SPSSharedMemoryFinalizeRequest) SPSExecutorSharedMemoryMapperServiceInitializeSignature
Definition:OrcRTBridge.h:79
llvm::orc::rt::ExecutorSharedMemoryMapperServiceInstanceName
const char * ExecutorSharedMemoryMapperServiceInstanceName
Definition:OrcRTBridge.cpp:31
llvm::orc::rt::SPSExecutorSharedMemoryMapperServiceReleaseSignature
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSExecutorSharedMemoryMapperServiceReleaseSignature
Definition:OrcRTBridge.h:84
llvm::orc::rt::ExecutorSharedMemoryMapperServiceReserveWrapperName
const char * ExecutorSharedMemoryMapperServiceReserveWrapperName
Definition:OrcRTBridge.cpp:33
llvm::orc::rt::SPSExecutorSharedMemoryMapperServiceReserveSignature
shared::SPSExpected< shared::SPSTuple< shared::SPSExecutorAddr, shared::SPSString > >(shared::SPSExecutorAddr, uint64_t) SPSExecutorSharedMemoryMapperServiceReserveSignature
Definition:OrcRTBridge.h:75
llvm::orc::rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName
const char * ExecutorSharedMemoryMapperServiceDeinitializeWrapperName
Definition:OrcRTBridge.cpp:37
llvm::orc::rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName
const char * ExecutorSharedMemoryMapperServiceReleaseWrapperName
Definition:OrcRTBridge.cpp:39
llvm::orc::rt::SPSExecutorSharedMemoryMapperServiceDeinitializeSignature
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSExecutorSharedMemoryMapperServiceDeinitializeSignature
Definition:OrcRTBridge.h:82
llvm::orc::rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName
const char * ExecutorSharedMemoryMapperServiceInitializeWrapperName
Definition:OrcRTBridge.cpp:35
llvm::orc::shared::makeMethodWrapperHandler
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
Definition:WrapperFunctionUtils.h:619
llvm::orc::shared::runDeallocActions
Error runDeallocActions(ArrayRef< WrapperFunctionCall > DAs)
Run deallocation actions.
Definition:AllocationActions.cpp:33
llvm::orc::shared::runFinalizeActions
Expected< std::vector< WrapperFunctionCall > > runFinalizeActions(AllocActions &AAs)
Run finalize actions.
Definition:AllocationActions.cpp:16
llvm::orc::MemProt
MemProt
Describes Read/Write/Exec permissions for memory.
Definition:MemoryFlags.h:27
llvm::orc::MemProt::Write
@ Write
llvm::orc::MemProt::Read
@ Read
llvm::orc::MemProt::Exec
@ Exec
llvm::sampleprof::Base
@ Base
Definition:Discriminator.h:58
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1759
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition:Error.cpp:98
llvm::AtomicOrderingCABI::release
@ release
llvm::reverse
auto reverse(ContainerTy &&C)
Definition:STLExtras.h:420
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition:Error.h:438
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition:Error.cpp:111
llvm::errnoAsErrorCode
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
Definition:Error.h:1226
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::mapWindowsError
std::error_code mapWindowsError(unsigned EV)
llvm::orc::shared::CWrapperFunctionResult
Definition:WrapperFunctionUtils.h:33
llvm::orc::tpctypes::SharedMemoryFinalizeRequest
Definition:TargetProcessControlTypes.h:67
llvm::orc::tpctypes::SharedMemoryFinalizeRequest::Segments
std::vector< SharedMemorySegFinalizeRequest > Segments
Definition:TargetProcessControlTypes.h:68
llvm::orc::tpctypes::SharedMemoryFinalizeRequest::Actions
shared::AllocActions Actions
Definition:TargetProcessControlTypes.h:69

Generated on Fri Jul 18 2025 11:28:07 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp