19 Expected<std::unique_ptr<JITLinkMemoryManager::Allocation>>
27 IPMMAlloc(AllocationMap SegBlocks) : SegBlocks(std::move(SegBlocks)) {}
29 assert(SegBlocks.count(Seg) &&
"No allocation for segment");
30 return {
static_cast<char *
>(SegBlocks[Seg].base()),
31 SegBlocks[Seg].allocatedSize()};
34 assert(SegBlocks.count(Seg) &&
"No allocation for segment");
37 void finalizeAsync(FinalizeContinuation OnFinalize)
override {
38 OnFinalize(applyProtections());
40 Error deallocate()
override {
41 if (SegBlocks.empty())
43 void *SlabStart = SegBlocks.begin()->second.base();
44 char *SlabEnd = (
char *)SlabStart;
45 for (
auto &KV : SegBlocks) {
46 SlabStart = std::min(SlabStart, KV.second.base());
47 SlabEnd =
std::max(SlabEnd, (
char *)(KV.second.base()) +
48 KV.second.allocatedSize());
50 size_t SlabSize = SlabEnd - (
char *)SlabStart;
52 "Slab size is not a multiple of page size");
60 Error applyProtections() {
61 for (
auto &KV : SegBlocks) {
62 auto &Prot = KV.first;
63 auto &
Block = KV.second;
68 Block.allocatedSize());
73 AllocationMap SegBlocks;
77 return make_error<StringError>(
"Page size is not a power of 2",
87 for (
auto &KV : Request) {
88 const auto &Seg = KV.second;
91 return make_error<StringError>(
"Cannot request higher than page " 96 TotalSize += Seg.getContentSize();
97 TotalSize += Seg.getZeroFillSize();
109 for (
auto &KV : Request) {
111 const auto &Seg = KV.second;
113 uint64_t SegmentSize =
alignTo(Seg.getContentSize() + Seg.getZeroFillSize(),
117 SlabRemaining =
sys::MemoryBlock((
char *)SlabRemaining.base() + SegmentSize,
121 memset(static_cast<char *>(SegMem.base()) + Seg.getContentSize(), 0,
122 Seg.getZeroFillSize());
125 Blocks[KV.first] = std::move(SegMem);
127 return std::unique_ptr<InProcessMemoryManager::Allocation>(
128 new IPMMAlloc(std::move(Blocks)));
This class represents lattice values for constants.
static std::error_code releaseMappedMemory(MemoryBlock &Block)
This method releases a block of memory that was allocated with the allocateMappedMemory method...
virtual ~JITLinkMemoryManager()
An Addressable with content and edges.
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...
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 unsigned getPageSizeEstimate()
Get the process's estimated page size.
uint64_t JITTargetAddress
Represents an address in the target process's address space.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Expected< std::unique_ptr< Allocation > > allocate(const SegmentsRequestMap &Request) override
Create an Allocation object.
static ErrorSuccess success()
Create a success value.
Align max(MaybeAlign Lhs, Align Rhs)
This class encapsulates the notion of a memory block which has an address and a size.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Provides a library for accessing information about this process and other processes on the operating ...
Represents an allocation created by the memory manager.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
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...