16 #include "llvm/Config/config.h" 42 uint8_t *SectionMemoryManager::allocateSection(
48 assert(!(Alignment & (Alignment - 1)) &&
"Alignment must be a power of two.");
50 uintptr_t RequiredSize = Alignment * ((Size + Alignment - 1) / Alignment + 1);
53 MemoryGroup &MemGroup = [&]() -> MemoryGroup & {
67 for (FreeMemBlock &FreeMB : MemGroup.FreeMem) {
68 if (FreeMB.Free.size() >= RequiredSize) {
69 Addr = (uintptr_t)FreeMB.Free.base();
70 uintptr_t EndOfBlock = Addr + FreeMB.Free.size();
72 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
74 if (FreeMB.PendingPrefixIndex == (
unsigned)-1) {
80 FreeMB.PendingPrefixIndex = MemGroup.PendingMem.size() - 1;
83 MemGroup.PendingMem[FreeMB.PendingPrefixIndex];
85 Addr + Size - (uintptr_t)PendingMB.
base());
91 return (uint8_t *)Addr;
106 Purpose, RequiredSize, &MemGroup.Near,
117 MemGroup.AllocatedMem.push_back(MB);
118 Addr = (uintptr_t)MB.
base();
119 uintptr_t EndOfBlock = Addr + MB.
size();
122 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
129 unsigned FreeSize = EndOfBlock - Addr -
Size;
133 FreeMB.PendingPrefixIndex = (
unsigned)-1;
134 MemGroup.FreeMem.push_back(FreeMB);
138 return (uint8_t *)Addr;
146 ec = applyMemoryGroupPermissions(CodeMem,
150 *ErrMsg = ec.message();
156 ec = applyMemoryGroupPermissions(RODataMem,
160 *ErrMsg = ec.message();
178 size_t StartOverlap =
181 size_t TrimmedSize = M.
size();
182 TrimmedSize -= StartOverlap;
183 TrimmedSize -= TrimmedSize %
PageSize;
196 SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup,
197 unsigned Permissions) {
202 MemGroup.PendingMem.clear();
206 for (FreeMemBlock &FreeMB : MemGroup.FreeMem) {
209 FreeMB.PendingPrefixIndex = (
unsigned)-1;
213 MemGroup.FreeMem.erase(
215 [](FreeMemBlock &FreeMB) { return FreeMB.Free.size() == 0; }),
216 MemGroup.FreeMem.end());
218 return std::error_code();
227 for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) {
235 void SectionMemoryManager::anchor() {}
245 unsigned Flags, std::error_code &EC)
override {
250 unsigned Flags)
override {
259 DefaultMMapper DefaultMMapperInstance;
263 : MMapper(MM ? *MM : DefaultMMapperInstance) {}
virtual std::error_code releaseMappedMemory(sys::MemoryBlock &M)=0
This method releases a block of memory that was allocated with the allocateMappedMemory method...
This class represents lattice values for constants.
SectionMemoryManager(MemoryMapper *MM=nullptr)
Creates a SectionMemoryManager instance with MM as the associated memory mapper.
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...
Implementations of this interface are used by SectionMemoryManager to request pages from the operatin...
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...
~SectionMemoryManager() override
AllocationPurpose
This enum describes the various reasons to allocate pages from allocateMappedMemory.
virtual void invalidateInstructionCache()
Invalidate instruction cache for code sections.
uint8_t * allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) override
Allocates a memory block of (at least) the given size suitable for executable code.
uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool isReadOnly) override
Allocates a memory block of (at least) the given size suitable for executable code.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getPageSize()
static sys::MemoryBlock trimBlockToPageSize(sys::MemoryBlock M)
This class encapsulates the notion of a memory block which has an address and a size.
virtual sys::MemoryBlock allocateMappedMemory(AllocationPurpose Purpose, size_t NumBytes, const sys::MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)=0
This method attempts to allocate NumBytes bytes of virtual memory for Purpose.
Provides a library for accessing information about this process and other processes on the operating ...
bool finalizeMemory(std::string *ErrMsg=nullptr) override
Update section-specific memory permissions and other attributes.
virtual std::error_code protectMappedMemory(const sys::MemoryBlock &Block, unsigned Flags)=0
This method sets the protection flags for a block of memory to the state specified by Flags...
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
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...