22static DWORD getWindowsProtectionFlags(
unsigned Flags) {
30 return PAGE_READWRITE;
32 return PAGE_READWRITE;
34 return PAGE_EXECUTE_READ;
37 return PAGE_EXECUTE_READWRITE;
50static size_t getAllocationGranularity() {
52 ::GetSystemInfo(&
Info);
53 if (
Info.dwPageSize >
Info.dwAllocationGranularity)
54 return Info.dwPageSize;
56 return Info.dwAllocationGranularity;
63static size_t enableProcessLargePages() {
65 size_t LargePageMin = GetLargePageMinimum();
67 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
72 if (!LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &Luid)) {
76 TOKEN_PRIVILEGES TP{};
77 TP.PrivilegeCount = 1;
78 TP.Privileges[0].Luid = Luid;
79 TP.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
80 if (!AdjustTokenPrivileges(Token, FALSE, &TP, 0, 0, 0)) {
86 if (
E == ERROR_SUCCESS)
100 const MemoryBlock *
const NearBlock,
101 unsigned Flags, std::error_code &EC) {
102 EC = std::error_code();
104 return MemoryBlock();
106 static size_t DefaultGranularity = getAllocationGranularity();
107 static size_t LargePageGranularity = enableProcessLargePages();
110 bool HugePages =
false;
111 size_t Granularity = DefaultGranularity;
113 if ((Flags &
MF_HUGE_HINT) && LargePageGranularity > 0) {
116 Granularity = LargePageGranularity;
119 size_t NumBlocks = (NumBytes + Granularity - 1) / Granularity;
121 uintptr_t Start = NearBlock ?
reinterpret_cast<uintptr_t
>(NearBlock->base()) +
122 NearBlock->allocatedSize()
127 if (Start && Start % Granularity != 0)
128 Start += Granularity - Start % Granularity;
130 DWORD Protect = getWindowsProtectionFlags(Flags);
132 size_t AllocSize = NumBlocks * Granularity;
133 void *PA = ::VirtualAlloc(
reinterpret_cast<void *
>(Start), AllocSize,
136 if (NearBlock || HugePages) {
141 return MemoryBlock();
146 Result.AllocatedSize = AllocSize;
156 if (
M.Address == 0 ||
M.AllocatedSize == 0)
157 return std::error_code();
159 if (!VirtualFree(
M.Address, 0, MEM_RELEASE))
165 return std::error_code();
170 if (
M.Address == 0 ||
M.AllocatedSize == 0)
171 return std::error_code();
173 DWORD Protect = getWindowsProtectionFlags(Flags);
176 if (!VirtualProtect(
M.Address,
M.AllocatedSize, Protect, &OldFlags))
182 return std::error_code();
189 FlushInstructionCache(GetCurrentProcess(),
Addr, Len);
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Provides a library for accessing information about this process and other processes on the operating ...
static std::error_code releaseMappedMemory(MemoryBlock &Block)
This method releases a block of memory that was allocated with the allocateMappedMemory method.
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)
This method allocates a block of memory that is suitable for loading dynamically generated code (e....
@ MF_HUGE_HINT
The MF_HUGE_HINT flag is used to indicate that the request for a memory block should be satisfied wit...
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 std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
This method sets the protection flags for a block of memory to the state specified by /p Flags.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
std::error_code mapWindowsError(unsigned EV)