10#include "llvm/Config/llvm-config.h"
18#if defined(LLVM_ON_UNIX)
31namespace rt_bootstrap {
40 return PAGE_READWRITE;
43 return PAGE_EXECUTE_READ;
45 return PAGE_EXECUTE_READWRITE;
53Expected<std::pair<ExecutorAddr, std::string>>
55#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
57#if defined(LLVM_ON_UNIX)
59 std::string SharedMemoryName;
61 std::stringstream SharedMemoryNameStream;
63 << (++SharedMemoryCount);
64 SharedMemoryName = SharedMemoryNameStream.str();
69 reinterpret_cast<const uint8_t *
>(SharedMemoryName.c_str()),
70 SharedMemoryName.size());
71 auto HashedName = BLAKE3::hash<sizeof(key_t)>(
Data);
72 key_t Key = *
reinterpret_cast<key_t *
>(HashedName.data());
74 shmget(Key,
Size, IPC_CREAT | IPC_EXCL | __IPC_SHAREAS | 0700);
75 if (SharedMemoryId < 0)
78 void *
Addr = shmat(SharedMemoryId,
nullptr, 0);
79 if (
Addr ==
reinterpret_cast<void *
>(-1))
82 int SharedMemoryFile =
83 shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
84 if (SharedMemoryFile < 0)
88 if (ftruncate(SharedMemoryFile,
Size) < 0)
91 void *
Addr = mmap(
nullptr,
Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
92 if (
Addr == MAP_FAILED)
95 close(SharedMemoryFile);
100 std::string SharedMemoryName;
102 std::stringstream SharedMemoryNameStream;
104 << (++SharedMemoryCount);
105 SharedMemoryName = SharedMemoryNameStream.str();
108 std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
109 SharedMemoryName.end());
110 HANDLE SharedMemoryFile = CreateFileMappingW(
111 INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE,
Size >> 32,
112 Size & 0xffffffff, WideSharedMemoryName.c_str());
113 if (!SharedMemoryFile)
116 void *
Addr = MapViewOfFile(SharedMemoryFile,
117 FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
119 CloseHandle(SharedMemoryFile);
126 std::lock_guard<std::mutex> Lock(
Mutex);
129 Reservations[
Addr].SharedMemoryFile = SharedMemoryFile;
134 std::move(SharedMemoryName));
136 return make_error<StringError>(
137 "SharedMemoryMapper is not supported on this platform yet",
144#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
150 if (Segment.Addr < MinAddr)
151 MinAddr = Segment.Addr;
153#if defined(LLVM_ON_UNIX)
160 NativeProt |= PROT_READ;
162 NativeProt |= PROT_WRITE;
164 NativeProt |= PROT_EXEC;
166 if (mprotect(Segment.Addr.toPtr<
void *>(), Segment.Size, NativeProt))
172 DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
174 if (!VirtualProtect(Segment.Addr.toPtr<
void *>(), Segment.Size, NativeProt,
186 std::vector<shared::WrapperFunctionCall> DeinitializeActions;
188 std::promise<MSVCPExpected<std::vector<shared::WrapperFunctionCall>>>
P;
189 auto F =
P.get_future();
191 FR.
Actions, [&](
Expected<std::vector<shared::WrapperFunctionCall>> R) {
192 P.set_value(std::move(R));
194 if (
auto DeinitializeActionsOrErr =
F.get())
195 DeinitializeActions = std::move(*DeinitializeActionsOrErr);
197 return DeinitializeActionsOrErr.takeError();
201 std::lock_guard<std::mutex> Lock(
Mutex);
202 Allocations[MinAddr].DeinitializationActions =
203 std::move(DeinitializeActions);
204 Reservations[Reservation.
toPtr<
void *>()].Allocations.push_back(MinAddr);
210 return make_error<StringError>(
211 "SharedMemoryMapper is not supported on this platform yet",
217 const std::vector<ExecutorAddr> &Bases) {
221 std::lock_guard<std::mutex> Lock(
Mutex);
225 Allocations[
Base].DeinitializationActions, [&](
Error Err) {
227 AllErr =
joinErrors(std::move(AllErr), std::move(Err));
231 for (
auto &Reservation : Reservations) {
232 auto AllocationIt =
llvm::find(Reservation.second.Allocations,
Base);
233 if (AllocationIt != Reservation.second.Allocations.end()) {
234 Reservation.second.Allocations.erase(AllocationIt);
247 const std::vector<ExecutorAddr> &Bases) {
248#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
251 for (
auto Base : Bases) {
252 std::vector<ExecutorAddr> AllocAddrs;
256 HANDLE SharedMemoryFile;
260 std::lock_guard<std::mutex> Lock(
Mutex);
261 auto &R = Reservations[
Base.toPtr<
void *>()];
265 SharedMemoryFile = R.SharedMemoryFile;
268 AllocAddrs.swap(R.Allocations);
275#if defined(LLVM_ON_UNIX)
280 if (shmdt(
Base.toPtr<
void *>()) < 0)
283 if (munmap(
Base.toPtr<
void *>(),
Size) != 0)
290 if (!UnmapViewOfFile(
Base.toPtr<
void *>()))
294 CloseHandle(SharedMemoryFile);
298 std::lock_guard<std::mutex> Lock(
Mutex);
299 Reservations.
erase(
Base.toPtr<
void *>());
304 return make_error<StringError>(
305 "SharedMemoryMapper is not supported on this platform yet",
311 if (Reservations.
empty())
314 std::vector<ExecutorAddr> ReservationAddrs;
315 ReservationAddrs.reserve(Reservations.
size());
316 for (
const auto &R : Reservations)
319 return release(std::move(ReservationAddrs));
337ExecutorSharedMemoryMapperService::reserveWrapper(
const char *ArgData,
341 handle(ArgData, ArgSize,
348ExecutorSharedMemoryMapperService::initializeWrapper(
const char *ArgData,
352 handle(ArgData, ArgSize,
359ExecutorSharedMemoryMapperService::deinitializeWrapper(
const char *ArgData,
361 return shared::WrapperFunction<
363 handle(ArgData, ArgSize,
370ExecutorSharedMemoryMapperService::releaseWrapper(
const char *ArgData,
372 return shared::WrapperFunction<
374 handle(ArgData, ArgSize,
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Provides a library for accessing information about this process and other processes on the operating ...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool erase(const KeyT &Val)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represents an address in the executor process.
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
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.
void addBootstrapSymbols(StringMap< ExecutorAddr > &M) override
Error deinitialize(const std::vector< ExecutorAddr > &Bases)
Error release(const std::vector< ExecutorAddr > &Bases)
Expected< std::pair< ExecutorAddr, std::string > > reserve(uint64_t Size)
Error shutdown() override
Expected< ExecutorAddr > initialize(ExecutorAddr Reservation, tpctypes::SharedMemoryFinalizeRequest &FR)
static LLVM_ABI 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...
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
shared::SPSExpected< shared::SPSExecutorAddr >(shared::SPSExecutorAddr, shared::SPSExecutorAddr, shared::SPSSharedMemoryFinalizeRequest) SPSExecutorSharedMemoryMapperServiceInitializeSignature
LLVM_ABI const char * ExecutorSharedMemoryMapperServiceInstanceName
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSExecutorSharedMemoryMapperServiceReleaseSignature
LLVM_ABI const char * ExecutorSharedMemoryMapperServiceReserveWrapperName
shared::SPSExpected< shared::SPSTuple< shared::SPSExecutorAddr, shared::SPSString > >(shared::SPSExecutorAddr, uint64_t) SPSExecutorSharedMemoryMapperServiceReserveSignature
LLVM_ABI const char * ExecutorSharedMemoryMapperServiceDeinitializeWrapperName
LLVM_ABI const char * ExecutorSharedMemoryMapperServiceReleaseWrapperName
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSExecutorSharedMemoryMapperServiceDeinitializeSignature
LLVM_ABI const char * ExecutorSharedMemoryMapperServiceInitializeWrapperName
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
LLVM_ABI void runDeallocActions(ArrayRef< WrapperFunctionCall > DAs, OnRunDeallocActionsComeleteFn OnComplete)
Run deallocation actions.
LLVM_ABI void runFinalizeActions(AllocActions &AAs, OnRunFinalizeActionsCompleteFn OnComplete)
Run finalize actions.
MemProt
Describes Read/Write/Exec permissions for memory.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto reverse(ContainerTy &&C)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ABI std::error_code mapWindowsError(unsigned EV)
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
std::vector< SharedMemorySegFinalizeRequest > Segments
shared::AllocActions Actions