17#if defined(LLVM_ON_UNIX)
30namespace rt_bootstrap {
39 return PAGE_READWRITE;
42 return PAGE_EXECUTE_READ;
44 return PAGE_EXECUTE_READWRITE;
52Expected<std::pair<ExecutorAddr, std::string>>
54#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
56#if defined(LLVM_ON_UNIX)
58 std::string SharedMemoryName;
60 std::stringstream SharedMemoryNameStream;
62 << (++SharedMemoryCount);
63 SharedMemoryName = SharedMemoryNameStream.str();
68 reinterpret_cast<const uint8_t *
>(SharedMemoryName.c_str()),
69 SharedMemoryName.size());
70 auto HashedName = BLAKE3::hash<sizeof(key_t)>(
Data);
71 key_t Key = *
reinterpret_cast<key_t *
>(HashedName.data());
73 shmget(Key,
Size, IPC_CREAT | IPC_EXCL | __IPC_SHAREAS | 0700);
74 if (SharedMemoryId < 0)
77 void *
Addr = shmat(SharedMemoryId,
nullptr, 0);
78 if (
Addr ==
reinterpret_cast<void *
>(-1))
81 int SharedMemoryFile =
82 shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
83 if (SharedMemoryFile < 0)
87 if (ftruncate(SharedMemoryFile,
Size) < 0)
90 void *
Addr = mmap(
nullptr,
Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
91 if (
Addr == MAP_FAILED)
94 close(SharedMemoryFile);
99 std::string SharedMemoryName;
101 std::stringstream SharedMemoryNameStream;
103 << (++SharedMemoryCount);
104 SharedMemoryName = SharedMemoryNameStream.str();
107 std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
108 SharedMemoryName.end());
109 HANDLE SharedMemoryFile = CreateFileMappingW(
110 INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE,
Size >> 32,
111 Size & 0xffffffff, WideSharedMemoryName.c_str());
112 if (!SharedMemoryFile)
115 void *
Addr = MapViewOfFile(SharedMemoryFile,
116 FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
118 CloseHandle(SharedMemoryFile);
125 std::lock_guard<std::mutex> Lock(
Mutex);
128 Reservations[
Addr].SharedMemoryFile = SharedMemoryFile;
133 std::move(SharedMemoryName));
135 return make_error<StringError>(
136 "SharedMemoryMapper is not supported on this platform yet",
143#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
149 if (Segment.Addr < MinAddr)
150 MinAddr = Segment.Addr;
152#if defined(LLVM_ON_UNIX)
159 NativeProt |= PROT_READ;
161 NativeProt |= PROT_WRITE;
163 NativeProt |= PROT_EXEC;
165 if (mprotect(Segment.Addr.toPtr<
void *>(), Segment.Size, NativeProt))
171 DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
173 if (!VirtualProtect(Segment.Addr.toPtr<
void *>(), Segment.Size, NativeProt,
186 if (!DeinitializeActions) {
187 return DeinitializeActions.takeError();
191 std::lock_guard<std::mutex> Lock(
Mutex);
192 Allocations[MinAddr].DeinitializationActions =
193 std::move(*DeinitializeActions);
194 Reservations[Reservation.
toPtr<
void *>()].Allocations.push_back(MinAddr);
200 return make_error<StringError>(
201 "SharedMemoryMapper is not supported on this platform yet",
207 const std::vector<ExecutorAddr> &Bases) {
211 std::lock_guard<std::mutex> Lock(
Mutex);
215 Allocations[
Base].DeinitializationActions)) {
216 AllErr =
joinErrors(std::move(AllErr), std::move(Err));
220 for (
auto &Reservation : Reservations) {
221 auto AllocationIt =
llvm::find(Reservation.second.Allocations,
Base);
222 if (AllocationIt != Reservation.second.Allocations.end()) {
223 Reservation.second.Allocations.erase(AllocationIt);
236 const std::vector<ExecutorAddr> &Bases) {
237#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
240 for (
auto Base : Bases) {
241 std::vector<ExecutorAddr> AllocAddrs;
245 HANDLE SharedMemoryFile;
249 std::lock_guard<std::mutex> Lock(
Mutex);
250 auto &R = Reservations[
Base.toPtr<
void *>()];
254 SharedMemoryFile = R.SharedMemoryFile;
257 AllocAddrs.swap(R.Allocations);
264#if defined(LLVM_ON_UNIX)
269 if (shmdt(
Base.toPtr<
void *>()) < 0)
272 if (munmap(
Base.toPtr<
void *>(),
Size) != 0)
279 if (!UnmapViewOfFile(
Base.toPtr<
void *>()))
283 CloseHandle(SharedMemoryFile);
287 std::lock_guard<std::mutex> Lock(
Mutex);
288 Reservations.
erase(
Base.toPtr<
void *>());
293 return make_error<StringError>(
294 "SharedMemoryMapper is not supported on this platform yet",
300 if (Reservations.
empty())
303 std::vector<ExecutorAddr> ReservationAddrs;
304 ReservationAddrs.reserve(Reservations.
size());
305 for (
const auto &R : Reservations)
308 return release(std::move(ReservationAddrs));
326ExecutorSharedMemoryMapperService::reserveWrapper(
const char *ArgData,
330 handle(ArgData, ArgSize,
337ExecutorSharedMemoryMapperService::initializeWrapper(
const char *ArgData,
341 handle(ArgData, ArgSize,
348ExecutorSharedMemoryMapperService::deinitializeWrapper(
const char *ArgData,
350 return shared::WrapperFunction<
352 handle(ArgData, ArgSize,
359ExecutorSharedMemoryMapperService::releaseWrapper(
const char *ArgData,
361 return shared::WrapperFunction<
363 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 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 Pid getProcessId()
Get the process's identifier.
shared::SPSExpected< shared::SPSExecutorAddr >(shared::SPSExecutorAddr, shared::SPSExecutorAddr, shared::SPSSharedMemoryFinalizeRequest) SPSExecutorSharedMemoryMapperServiceInitializeSignature
const char * ExecutorSharedMemoryMapperServiceInstanceName
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSExecutorSharedMemoryMapperServiceReleaseSignature
const char * ExecutorSharedMemoryMapperServiceReserveWrapperName
shared::SPSExpected< shared::SPSTuple< shared::SPSExecutorAddr, shared::SPSString > >(shared::SPSExecutorAddr, uint64_t) SPSExecutorSharedMemoryMapperServiceReserveSignature
const char * ExecutorSharedMemoryMapperServiceDeinitializeWrapperName
const char * ExecutorSharedMemoryMapperServiceReleaseWrapperName
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSExecutorSharedMemoryMapperServiceDeinitializeSignature
const char * ExecutorSharedMemoryMapperServiceInitializeWrapperName
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
Error runDeallocActions(ArrayRef< WrapperFunctionCall > DAs)
Run deallocation actions.
Expected< std::vector< WrapperFunctionCall > > runFinalizeActions(AllocActions &AAs)
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.
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.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
std::error_code mapWindowsError(unsigned EV)
std::vector< SharedMemorySegFinalizeRequest > Segments
shared::AllocActions Actions