class OrcX86_64 {
public:
- static const char *ResolverBlockName;
+ static const unsigned PageSize = 4096;
+ static const unsigned PointerSize = 8;
+ static const unsigned TrampolineSize = 8;
+ static const unsigned ResolverCodeSize = 0x78;
- /// @brief Insert module-level inline callback asm into module M for the
- /// symbols managed by JITResolveCallbackHandler J.
- static void insertResolverBlock(Module &M,
- JITCompileCallbackManagerBase &JCBM);
+ typedef TargetAddress (*JITReentryFn)(void *CallbackMgr,
+ void *TrampolineId);
- /// @brief Get a label name from the given index.
- typedef std::function<std::string(unsigned)> LabelNameFtor;
+ /// @brief Write the resolver code into the given memory. The user is be
+ /// responsible for allocating the memory and setting permissions.
+ static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
+ void *CallbackMgr);
- /// @brief Insert the requested number of trampolines into the given module.
- /// @param M Module to insert the call block into.
- /// @param NumCalls Number of calls to create in the call block.
- /// @param StartIndex Optional argument specifying the index suffix to start
- /// with.
- /// @return A functor that provides the symbol name for each entry in the call
- /// block.
- ///
- static LabelNameFtor insertCompileCallbackTrampolines(
- Module &M,
- TargetAddress TrampolineAddr,
- unsigned NumCalls,
- unsigned StartIndex = 0);
+ /// @brief Write the requsted number of trampolines into the given memory,
+ /// which must be big enough to hold 1 pointer, plus NumTrampolines
+ /// trampolines.
+ static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ unsigned NumTrampolines);
/// @brief Provide information about stub blocks generated by the
/// makeIndirectStubsBlock function.
const static unsigned PtrSize = 8;
IndirectStubsInfo() : NumStubs(0) {}
- ~IndirectStubsInfo();
+ IndirectStubsInfo(IndirectStubsInfo &&Other)
+ : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
+ Other.NumStubs = 0;
+ }
+ IndirectStubsInfo& operator=(IndirectStubsInfo &&Other) {
+ NumStubs = Other.NumStubs;
+ Other.NumStubs = 0;
+ StubsMem = std::move(Other.StubsMem);
+ return *this;
+ }
/// @brief Number of stubs in this block.
unsigned getNumStubs() const { return NumStubs; }
/// @brief Get a pointer to the stub at the given index, which must be in
/// the range 0 .. getNumStubs() - 1.
void* getStub(unsigned Idx) const {
- return static_cast<uint64_t*>(StubsBlock.base()) + Idx;
+ return static_cast<uint64_t*>(StubsMem.base()) + Idx;
}
/// @brief Get a pointer to the implementation-pointer at the given index,
/// which must be in the range 0 .. getNumStubs() - 1.
void** getPtr(unsigned Idx) const {
- return static_cast<void**>(PtrsBlock.base()) + Idx;
+ char *PtrsBase =
+ static_cast<char*>(StubsMem.base()) + NumStubs * StubSize;
+ return reinterpret_cast<void**>(PtrsBase) + Idx;
}
private:
unsigned NumStubs;
- sys::MemoryBlock StubsBlock;
- sys::MemoryBlock PtrsBlock;
+ sys::OwningMemoryBlock StubsMem;
};
/// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to