1 //===-- OrcArchitectureSupport.h - Architecture support code ---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Architecture specific code for Orc, e.g. callback assembly.
12 // Architecture classes should be part of the JIT *target* process, not the host
13 // process (except where you're doing hosted JITing and the two are one and the
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_EXECUTIONENGINE_ORC_ORCARCHITECTURESUPPORT_H
19 #define LLVM_EXECUTIONENGINE_ORC_ORCARCHITECTURESUPPORT_H
21 #include "IndirectionUtils.h"
22 #include "llvm/Support/Memory.h"
23 #include "llvm/Support/Process.h"
28 /// Generic ORC Architecture support.
30 /// This class can be substituted as the target architecure support class for
31 /// ORC templates that require one (e.g. IndirectStubsManagers). It does not
32 /// support lazy JITing however, and any attempt to use that functionality
33 /// will result in execution of an llvm_unreachable.
34 class OrcGenericArchitecture {
36 static const unsigned PointerSize = sizeof(uintptr_t);
37 static const unsigned TrampolineSize = 1;
38 static const unsigned ResolverCodeSize = 1;
40 typedef TargetAddress (*JITReentryFn)(void *CallbackMgr, void *TrampolineId);
42 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
44 llvm_unreachable("writeResolverCode is not supported by the generic host "
48 static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
49 unsigned NumTrampolines) {
50 llvm_unreachable("writeTrampolines is not supported by the generic host "
54 class IndirectStubsInfo {
56 const static unsigned StubSize = 1;
57 unsigned getNumStubs() const { llvm_unreachable("Not supported"); }
58 void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); }
59 void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); }
62 static std::error_code emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
64 void *InitialPtrVal) {
65 llvm_unreachable("emitIndirectStubsBlock is not supported by the generic "
66 "host support class");
70 /// @brief X86_64 support.
72 /// X86_64 supports lazy JITing.
75 static const unsigned PointerSize = 8;
76 static const unsigned TrampolineSize = 8;
77 static const unsigned ResolverCodeSize = 0x78;
79 typedef TargetAddress (*JITReentryFn)(void *CallbackMgr, void *TrampolineId);
81 /// @brief Write the resolver code into the given memory. The user is be
82 /// responsible for allocating the memory and setting permissions.
83 static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
86 /// @brief Write the requsted number of trampolines into the given memory,
87 /// which must be big enough to hold 1 pointer, plus NumTrampolines
89 static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
90 unsigned NumTrampolines);
92 /// @brief Provide information about stub blocks generated by the
93 /// makeIndirectStubsBlock function.
94 class IndirectStubsInfo {
95 friend class OrcX86_64;
98 const static unsigned StubSize = 8;
100 IndirectStubsInfo() : NumStubs(0) {}
101 IndirectStubsInfo(IndirectStubsInfo &&Other)
102 : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
105 IndirectStubsInfo &operator=(IndirectStubsInfo &&Other) {
106 NumStubs = Other.NumStubs;
108 StubsMem = std::move(Other.StubsMem);
112 /// @brief Number of stubs in this block.
113 unsigned getNumStubs() const { return NumStubs; }
115 /// @brief Get a pointer to the stub at the given index, which must be in
116 /// the range 0 .. getNumStubs() - 1.
117 void *getStub(unsigned Idx) const {
118 return static_cast<uint64_t *>(StubsMem.base()) + Idx;
121 /// @brief Get a pointer to the implementation-pointer at the given index,
122 /// which must be in the range 0 .. getNumStubs() - 1.
123 void **getPtr(unsigned Idx) const {
125 static_cast<char *>(StubsMem.base()) + NumStubs * StubSize;
126 return reinterpret_cast<void **>(PtrsBase) + Idx;
131 sys::OwningMemoryBlock StubsMem;
134 /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
135 /// the nearest page size.
137 /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
138 /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
139 /// will return a block of 1024 (2-pages worth).
140 static std::error_code emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
142 void *InitialPtrVal);
145 } // End namespace orc.
146 } // End namespace llvm.
148 #endif // LLVM_EXECUTIONENGINE_ORC_ORCARCHITECTURESUPPORT_H