17#if defined(LLVM_ON_UNIX)
26namespace rt_bootstrap {
35 return PAGE_READWRITE;
38 return PAGE_EXECUTE_READ;
40 return PAGE_EXECUTE_READWRITE;
48Expected<std::pair<ExecutorAddr, std::string>>
50#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
52#if defined(LLVM_ON_UNIX)
54 std::string SharedMemoryName;
56 std::stringstream SharedMemoryNameStream;
58 << (++SharedMemoryCount);
59 SharedMemoryName = SharedMemoryNameStream.str();
62 int SharedMemoryFile =
63 shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0700);
64 if (SharedMemoryFile < 0)
68 if (ftruncate(SharedMemoryFile,
Size) < 0)
71 void *
Addr = mmap(
nullptr,
Size, PROT_NONE, MAP_SHARED, SharedMemoryFile, 0);
72 if (
Addr == MAP_FAILED)
75 close(SharedMemoryFile);
79 std::string SharedMemoryName;
81 std::stringstream SharedMemoryNameStream;
83 << (++SharedMemoryCount);
84 SharedMemoryName = SharedMemoryNameStream.str();
87 std::wstring WideSharedMemoryName(SharedMemoryName.begin(),
88 SharedMemoryName.end());
89 HANDLE SharedMemoryFile = CreateFileMappingW(
90 INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE,
Size >> 32,
91 Size & 0xffffffff, WideSharedMemoryName.c_str());
92 if (!SharedMemoryFile)
95 void *
Addr = MapViewOfFile(SharedMemoryFile,
96 FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
98 CloseHandle(SharedMemoryFile);
105 std::lock_guard<std::mutex> Lock(
Mutex);
108 Reservations[
Addr].SharedMemoryFile = SharedMemoryFile;
113 std::move(SharedMemoryName));
115 return make_error<StringError>(
116 "SharedMemoryMapper is not supported on this platform yet",
123#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
129 if (Segment.Addr < MinAddr)
130 MinAddr = Segment.Addr;
132#if defined(LLVM_ON_UNIX)
136 NativeProt |= PROT_READ;
138 NativeProt |= PROT_WRITE;
140 NativeProt |= PROT_EXEC;
142 if (mprotect(Segment.Addr.toPtr<
void *>(), Segment.Size, NativeProt))
147 DWORD NativeProt = getWindowsProtectionFlags(Segment.RAG.Prot);
149 if (!VirtualProtect(Segment.Addr.toPtr<
void *>(), Segment.Size, NativeProt,
162 if (!DeinitializeActions) {
163 return DeinitializeActions.takeError();
167 std::lock_guard<std::mutex> Lock(
Mutex);
168 Allocations[MinAddr].DeinitializationActions =
169 std::move(*DeinitializeActions);
170 Reservations[Reservation.
toPtr<
void *>()].Allocations.push_back(MinAddr);
176 return make_error<StringError>(
177 "SharedMemoryMapper is not supported on this platform yet",
183 const std::vector<ExecutorAddr> &Bases) {
187 std::lock_guard<std::mutex> Lock(
Mutex);
191 Allocations[
Base].DeinitializationActions)) {
192 AllErr =
joinErrors(std::move(AllErr), std::move(Err));
196 for (
auto &Reservation : Reservations) {
198 std::find(Reservation.second.Allocations.begin(),
199 Reservation.second.Allocations.end(),
Base);
200 if (AllocationIt != Reservation.second.Allocations.end()) {
201 Reservation.second.Allocations.erase(AllocationIt);
214 const std::vector<ExecutorAddr> &Bases) {
215#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
218 for (
auto Base : Bases) {
219 std::vector<ExecutorAddr> AllocAddrs;
223 HANDLE SharedMemoryFile;
227 std::lock_guard<std::mutex> Lock(
Mutex);
228 auto &R = Reservations[
Base.toPtr<
void *>()];
232 SharedMemoryFile = R.SharedMemoryFile;
235 AllocAddrs.swap(R.Allocations);
242#if defined(LLVM_ON_UNIX)
244 if (munmap(
Base.toPtr<
void *>(),
Size) != 0)
246 errno, std::generic_category())));
251 if (!UnmapViewOfFile(
Base.toPtr<
void *>()))
255 CloseHandle(SharedMemoryFile);
259 std::lock_guard<std::mutex> Lock(
Mutex);
260 Reservations.
erase(
Base.toPtr<
void *>());
265 return make_error<StringError>(
266 "SharedMemoryMapper is not supported on this platform yet",
272 if (Reservations.
empty())
275 std::vector<ExecutorAddr> ReservationAddrs;
276 ReservationAddrs.reserve(Reservations.
size());
277 for (
const auto &R : Reservations)
280 return release(std::move(ReservationAddrs));
298ExecutorSharedMemoryMapperService::reserveWrapper(
const char *ArgData,
302 handle(ArgData, ArgSize,
309ExecutorSharedMemoryMapperService::initializeWrapper(
const char *ArgData,
313 handle(ArgData, ArgSize,
320ExecutorSharedMemoryMapperService::deinitializeWrapper(
const char *ArgData,
322 return shared::WrapperFunction<
324 handle(ArgData, ArgSize,
331ExecutorSharedMemoryMapperService::releaseWrapper(
const char *ArgData,
333 return shared::WrapperFunction<
335 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 ...
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.
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 mapWindowsError(unsigned EV)
std::vector< SharedMemorySegFinalizeRequest > Segments
shared::AllocActions Actions