14#ifndef LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
15#define LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
32class EPCIndirectionUtils {
40 ABISupport(
unsigned PointerSize,
unsigned TrampolineSize,
unsigned StubSize,
41 unsigned StubToPointerMaxDisplacement,
unsigned ResolverCodeSize)
42 : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
44 StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
45 ResolverCodeSize(ResolverCodeSize) {}
54 return StubToPointerMaxDisplacement;
66 unsigned NumTrampolines)
const = 0;
69 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
70 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs)
const = 0;
73 unsigned PointerSize = 0;
74 unsigned TrampolineSize = 0;
75 unsigned StubSize = 0;
76 unsigned StubToPointerMaxDisplacement = 0;
77 unsigned ResolverCodeSize = 0;
81 template <
typename ORCABI>
82 static std::unique_ptr<EPCIndirectionUtils>
131 assert(LCTM &&
"createLazyCallThroughManager must be called first");
138 struct IndirectStubInfo {
139 IndirectStubInfo() =
default;
141 : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
142 ExecutorAddr StubAddress;
143 ExecutorAddr PointerAddress;
146 using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
149 EPCIndirectionUtils(ExecutorProcessControl &EPC,
150 jitlink::JITLinkMemoryManager &MemMgr,
151 MemoryAccess &MemAccess, std::unique_ptr<ABISupport> ABI);
153 Expected<IndirectStubInfoVector> getIndirectStubs(
unsigned NumStubs);
155 std::mutex EPCUIMutex;
156 ExecutorProcessControl &EPC;
157 jitlink::JITLinkMemoryManager &MemMgr;
158 MemoryAccess &MemAccess;
159 std::unique_ptr<ABISupport> ABI;
160 ExecutorAddr ResolverBlockAddr;
161 FinalizedAlloc ResolverBlock;
162 std::unique_ptr<TrampolinePool> TP;
163 std::unique_ptr<LazyCallThroughManager> LCTM;
165 std::vector<IndirectStubInfo> AvailableIndirectStubs;
166 std::vector<FinalizedAlloc> IndirectStubAllocs;
184template <
typename ORCABI>
188 :
ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
189 ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
190 ORCABI::ResolverCodeSize) {}
196 ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
197 ReentryFnAddr, ReentryCtxAddr);
203 unsigned NumTrampolines)
const override {
204 ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
205 TrampolineBlockTargetAddr, ResolverAddr,
212 unsigned NumStubs)
const override {
213 ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
214 StubsBlockTargetAddress,
215 PointersBlockTargetAddress, NumStubs);
221template <
typename ORCABI>
222std::unique_ptr<EPCIndirectionUtils>
226 return std::unique_ptr<EPCIndirectionUtils>(
new EPCIndirectionUtils(
227 EPC, MemMgr, MemAccess,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Represents a finalized allocation.
Manages allocations of JIT memory.
virtual void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) const =0
ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize, unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
unsigned getStubSize() const
virtual void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddr, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr) const =0
unsigned getResolverCodeSize() const
virtual void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTragetAddr, ExecutorAddr ResolverAddr, unsigned NumTrampolines) const =0
unsigned getStubToPointerMaxDisplacement() const
unsigned getPointerSize() const
unsigned getTrampolineSize() const
Provides ExecutorProcessControl based indirect stubs, trampoline pool and lazy call through manager.
LLVM_ABI std::unique_ptr< IndirectStubsManager > createIndirectStubsManager()
Create an IndirectStubsManager for the executor process.
LLVM_ABI Expected< ExecutorAddr > writeResolverBlock(ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write resolver code to the executor process and return its address.
LazyCallThroughManager & getLazyCallThroughManager()
Create a LazyCallThroughManager for the executor process.
MemoryAccess & getMemoryAccess() const
Return a reference to the MemoryAccess object for this instance.
ExecutorProcessControl & getExecutorProcessControl() const
Return a reference to the ExecutorProcessControl object.
jitlink::JITLinkMemoryManager & getMemManager() const
Return a reference to the JITLinkMemoryManager object for this instance.
static LLVM_ABI Expected< std::unique_ptr< EPCIndirectionUtils > > Create(ExecutorProcessControl &EPC, jitlink::JITLinkMemoryManager &MemMgr, MemoryAccess &MemAccess)
Create based on the ExecutorProcessControl triple.
LLVM_ABI LazyCallThroughManager & createLazyCallThroughManager(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr)
Create a LazyCallThroughManager.
LLVM_ABI Error cleanup()
Release memory for resources held by this instance.
LLVM_ABI TrampolinePool & getTrampolinePool()
Create a TrampolinePool for the executor process.
static std::unique_ptr< EPCIndirectionUtils > CreateWithABI(ExecutorProcessControl &EPC, jitlink::JITLinkMemoryManager &MemMgr, MemoryAccess &MemAccess)
Create using the given ABI class.
friend class EPCIndirectionUtilsAccess
ABISupport & getABISupport() const
Return a reference to the ABISupport object for this instance.
ExecutorAddr getResolverBlockAddress() const
Returns the address of the Resolver block.
An ExecutionSession represents a running JIT program.
Represents an address in the executor process.
ExecutorProcessControl supports interaction with a JIT target process.
Manages a set of 'lazy call-through' trampolines.
APIs for manipulating memory in the target process.
Base class for pools of compiler re-entry trampolines.
void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddr, ExecutorAddr ResolverAddr, unsigned NumTrampolines) const override
void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) const override
void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddr, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr) const override
LLVM_ABI Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU)
This will call writeResolver on the given EPCIndirectionUtils instance to set up re-entry via a funct...
This is an optimization pass for GlobalISel generic memory operations.