LLVM 24.0.0git
EPCGenericJITLinkMemoryManager.cpp
Go to the documentation of this file.
1//===---- EPCGenericJITLinkMemoryManager.cpp -- Mem management via EPC ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
12
13#include <limits>
14
15using namespace llvm::jitlink;
16
17namespace llvm {
18namespace orc {
19
22public:
23
24 // FIXME: The C++98 initializer is an attempt to work around compile failures
25 // due to http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1397.
26 // We should be able to switch this back to member initialization once that
27 // issue is fixed.
36
38
40 ExecutorAddr AllocAddr, SegInfoMap Segs)
41 : Parent(Parent), G(G), AllocAddr(AllocAddr), Segs(std::move(Segs)) {}
42
43 void finalize(OnFinalizedFunction OnFinalize) override {
45 for (auto &KV : Segs) {
46 assert(KV.second.ContentSize <= std::numeric_limits<size_t>::max());
48 KV.first,
49 KV.second.Addr,
50 alignTo(KV.second.ContentSize + KV.second.ZeroFillSize,
51 Parent.ES.getExecutorProcessControl().getPageSize()),
52 {KV.second.WorkingMem, static_cast<size_t>(KV.second.ContentSize)}});
53 }
54
55 // Transfer allocation actions.
56 std::swap(FR.Actions, G.allocActions());
57
58 Parent.B.Initialize(
59 [OnFinalize = std::move(OnFinalize), AllocAddr = this->AllocAddr](
60 Expected<ExecutorAddr> InitializeKey) mutable {
61 // FIXME: Release abandoned alloc.
62 if (!InitializeKey)
63 return OnFinalize(InitializeKey.takeError());
64 OnFinalize(FinalizedAlloc(AllocAddr));
65 },
66 Parent.ES, Parent.B.Instance, FR);
67 }
68
69 void abandon(OnAbandonedFunction OnAbandoned) override {
70 // FIXME: Return memory to pool instead.
71 Parent.B.Release(std::move(OnAbandoned), Parent.ES, Parent.B.Instance,
72 ArrayRef<ExecutorAddr>(AllocAddr));
73 }
74
75private:
77 LinkGraph &G;
78 ExecutorAddr AllocAddr;
79 SegInfoMap Segs;
80};
81
83 LinkGraph &G,
84 OnAllocatedFunction OnAllocated) {
85 BasicLayout BL(G);
86
88 ES.getExecutorProcessControl().getPageSize());
89 if (!Pages)
90 return OnAllocated(Pages.takeError());
91
92 B.Reserve(
93 [this, BL = std::move(BL), OnAllocated = std::move(OnAllocated)](
94 Expected<ExecutorAddr> AllocAddr) mutable {
95 if (!AllocAddr)
96 return OnAllocated(AllocAddr.takeError());
97 completeAllocation(*AllocAddr, std::move(BL), std::move(OnAllocated));
98 },
99 ES, B.Instance, Pages->total());
100}
101
103 std::vector<FinalizedAlloc> Allocs, OnDeallocatedFunction OnDeallocated) {
104 std::vector<ExecutorAddr> Bases;
105 Bases.reserve(Allocs.size());
106 for (auto &A : Allocs)
107 Bases.push_back(ExecutorAddr(A.getAddress()));
108 B.Release(std::move(OnDeallocated), ES, B.Instance, Bases);
109 for (auto &A : Allocs)
110 A.release();
111}
112
113void EPCGenericJITLinkMemoryManager::completeAllocation(
114 ExecutorAddr AllocAddr, BasicLayout BL, OnAllocatedFunction OnAllocated) {
115
117
118 ExecutorAddr NextSegAddr = AllocAddr;
119 for (auto &KV : BL.segments()) {
120 const auto &AG = KV.first;
121 auto &Seg = KV.second;
122
123 Seg.Addr = NextSegAddr;
124 KV.second.WorkingMem = BL.getGraph().allocateBuffer(Seg.ContentSize).data();
125 NextSegAddr +=
126 ExecutorAddrDiff(alignTo(Seg.ContentSize + Seg.ZeroFillSize,
128
129 auto &SegInfo = SegInfos[AG];
130 SegInfo.ContentSize = Seg.ContentSize;
131 SegInfo.ZeroFillSize = Seg.ZeroFillSize;
132 SegInfo.Addr = Seg.Addr;
133 SegInfo.WorkingMem = Seg.WorkingMem;
134 }
135
136 if (auto Err = BL.apply())
137 return OnAllocated(std::move(Err));
138
139 OnAllocated(std::make_unique<InFlightAlloc>(*this, BL.getGraph(), AllocAddr,
140 std::move(SegInfos)));
141}
142
143} // end namespace orc
144} // end namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define G(x, y, z)
Definition MD5.cpp:55
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
A specialized small-map for AllocGroups.
void finalize(OnFinalizedFunction OnFinalize) override
Called to transfer working memory to the target and apply finalization.
void abandon(OnAbandonedFunction OnAbandoned) override
Called prior to finalization if the allocation should be abandoned.
InFlightAlloc(EPCGenericJITLinkMemoryManager &Parent, LinkGraph &G, ExecutorAddr AllocAddr, SegInfoMap Segs)
EPCGenericJITLinkMemoryManager(ExecutionSession &ES, Bindings B)
Create an EPCGenericJITLinkMemoryManager instance from a given set of memory-manager bindings.
void deallocate(std::vector< FinalizedAlloc > Allocs, OnDeallocatedFunction OnDeallocated) override
Deallocate a list of allocation objects.
void allocate(const jitlink::JITLinkDylib *JD, jitlink::LinkGraph &G, OnAllocatedFunction OnAllocated) override
Start the allocation process.
ExecutorProcessControl & getExecutorProcessControl()
Get the ExecutorProcessControl object associated with this ExecutionSession.
Definition Core.h:1156
Represents an address in the executor process.
unsigned getPageSize() const
Get the page size for the target process.
uint64_t ExecutorAddrDiff
This is an optimization pass for GlobalISel generic memory operations.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
std::vector< SegFinalizeRequest > Segments