10#include "llvm/Config/llvm-config.h"
17#if defined(LLVM_ON_UNIX)
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());
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);
126 Reservations[Addr].Size =
Size;
128 Reservations[Addr].SharedMemoryFile = SharedMemoryFile;
133 std::move(SharedMemoryName));
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);
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);
228 Allocations.erase(
Base);
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 *>());
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));
325ExecutorSharedMemoryMapperService::reserveWrapper(
const char *ArgData,
328 WrapperFunction<rt::sps_ci::SharedMemoryMapperReserve::SPSSig>::handle(
336ExecutorSharedMemoryMapperService::initializeWrapper(
const char *ArgData,
339 WrapperFunction<rt::sps_ci::SharedMemoryMapperInitialize::SPSSig>::handle(
347ExecutorSharedMemoryMapperService::deinitializeWrapper(
const char *ArgData,
349 return shared::WrapperFunction<
351 handle(ArgData, ArgSize,
358ExecutorSharedMemoryMapperService::releaseWrapper(
const char *ArgData,
361 WrapperFunction<rt::sps_ci::SharedMemoryMapperRelease::SPSSig>::handle(
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Provides a library for accessing information about this process and other processes on the operating ...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
static BLAKE3Result< NumBytes > hash(ArrayRef< uint8_t > Data)
Returns a BLAKE3 hash for the given data.
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.
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.
constexpr char SharedMemoryMapperInstanceName[]
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
LLVM_ABI Error runDeallocActions(ArrayRef< WrapperFunctionCall > DAs)
Run deallocation actions.
LLVM_ABI 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.
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_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
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.
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSSig
static constexpr char Name[]
static constexpr char Name[]
static constexpr char Name[]
static constexpr char Name[]
std::vector< SharedMemorySegFinalizeRequest > Segments
shared::AllocActions Actions