1
//===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- 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
// This file defines the JITMemoryManagerInterface
12
//===----------------------------------------------------------------------===//
14
#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
15
#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
17
#include "llvm/System/DataTypes.h"
25
/// JITMemoryManager - This interface is used by the JIT to allocate and manage
26
/// memory for the code generated by the JIT. This can be reimplemented by
27
/// clients that have a strong desire to control how the layout of JIT'd memory
29
class JITMemoryManager {
35
JITMemoryManager() : HasGOT(false), SizeRequired(false) {}
36
virtual ~JITMemoryManager();
38
/// CreateDefaultMemManager - This is used to create the default
39
/// JIT Memory Manager if the client does not provide one to the JIT.
40
static JITMemoryManager *CreateDefaultMemManager();
42
/// setMemoryWritable - When code generation is in progress,
43
/// the code pages may need permissions changed.
44
virtual void setMemoryWritable() = 0;
46
/// setMemoryExecutable - When code generation is done and we're ready to
47
/// start execution, the code pages may need permissions changed.
48
virtual void setMemoryExecutable() = 0;
50
/// setPoisonMemory - Setting this flag to true makes the memory manager
51
/// garbage values over freed memory. This is useful for testing and
52
/// debugging, and is be turned on by default in debug mode.
53
virtual void setPoisonMemory(bool poison) = 0;
55
//===--------------------------------------------------------------------===//
56
// Global Offset Table Management
57
//===--------------------------------------------------------------------===//
59
/// AllocateGOT - If the current table requires a Global Offset Table, this
60
/// method is invoked to allocate it. This method is required to set HasGOT
62
virtual void AllocateGOT() = 0;
64
/// isManagingGOT - Return true if the AllocateGOT method is called.
66
bool isManagingGOT() const {
70
/// getGOTBase - If this is managing a Global Offset Table, this method should
71
/// return a pointer to its base.
72
virtual uint8_t *getGOTBase() const = 0;
74
/// NeedsExactSize - If the memory manager requires to know the size of the
75
/// objects to be emitted
76
bool NeedsExactSize() const {
80
//===--------------------------------------------------------------------===//
81
// Main Allocation Functions
82
//===--------------------------------------------------------------------===//
84
/// startFunctionBody - When we start JITing a function, the JIT calls this
85
/// method to allocate a block of free RWX memory, which returns a pointer to
86
/// it. If the JIT wants to request a block of memory of at least a certain
87
/// size, it passes that value as ActualSize, and this method returns a block
88
/// with at least that much space. If the JIT doesn't know ahead of time how
89
/// much space it will need to emit the function, it passes 0 for the
90
/// ActualSize. In either case, this method is required to pass back the size
91
/// of the allocated block through ActualSize. The JIT will be careful to
92
/// not write more than the returned ActualSize bytes of memory.
93
virtual uint8_t *startFunctionBody(const Function *F,
94
uintptr_t &ActualSize) = 0;
96
/// allocateStub - This method is called by the JIT to allocate space for a
97
/// function stub (used to handle limited branch displacements) while it is
98
/// JIT compiling a function. For example, if foo calls bar, and if bar
99
/// either needs to be lazily compiled or is a native function that exists too
100
/// far away from the call site to work, this method will be used to make a
101
/// thunk for it. The stub should be "close" to the current function body,
102
/// but should not be included in the 'actualsize' returned by
103
/// startFunctionBody.
104
virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
105
unsigned Alignment) = 0;
107
/// endFunctionBody - This method is called when the JIT is done codegen'ing
108
/// the specified function. At this point we know the size of the JIT
109
/// compiled function. This passes in FunctionStart (which was returned by
110
/// the startFunctionBody method) and FunctionEnd which is a pointer to the
111
/// actual end of the function. This method should mark the space allocated
112
/// and remember where it is in case the client wants to deallocate it.
113
virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
114
uint8_t *FunctionEnd) = 0;
116
/// allocateSpace - Allocate a memory block of the given size. This method
117
/// cannot be called between calls to startFunctionBody and endFunctionBody.
118
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) = 0;
120
/// allocateGlobal - Allocate memory for a global.
122
virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0;
124
/// deallocateFunctionBody - Free the specified function body. The argument
125
/// must be the return value from a call to startFunctionBody() that hasn't
126
/// been deallocated yet. This is never called when the JIT is currently
127
/// emitting a function.
128
virtual void deallocateFunctionBody(void *Body) = 0;
130
/// startExceptionTable - When we finished JITing the function, if exception
131
/// handling is set, we emit the exception table.
132
virtual uint8_t* startExceptionTable(const Function* F,
133
uintptr_t &ActualSize) = 0;
135
/// endExceptionTable - This method is called when the JIT is done emitting
136
/// the exception table.
137
virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
138
uint8_t *TableEnd, uint8_t* FrameRegister) = 0;
140
/// deallocateExceptionTable - Free the specified exception table's memory.
141
/// The argument must be the return value from a call to startExceptionTable()
142
/// that hasn't been deallocated yet. This is never called when the JIT is
143
/// currently emitting an exception table.
144
virtual void deallocateExceptionTable(void *ET) = 0;
146
/// CheckInvariants - For testing only. Return true if all internal
147
/// invariants are preserved, or return false and set ErrorStr to a helpful
149
virtual bool CheckInvariants(std::string &) {
153
/// GetDefaultCodeSlabSize - For testing only. Returns DefaultCodeSlabSize
154
/// from DefaultJITMemoryManager.
155
virtual size_t GetDefaultCodeSlabSize() {
159
/// GetDefaultDataSlabSize - For testing only. Returns DefaultCodeSlabSize
160
/// from DefaultJITMemoryManager.
161
virtual size_t GetDefaultDataSlabSize() {
165
/// GetDefaultStubSlabSize - For testing only. Returns DefaultCodeSlabSize
166
/// from DefaultJITMemoryManager.
167
virtual size_t GetDefaultStubSlabSize() {
171
/// GetNumCodeSlabs - For testing only. Returns the number of MemoryBlocks
172
/// allocated for code.
173
virtual unsigned GetNumCodeSlabs() {
177
/// GetNumDataSlabs - For testing only. Returns the number of MemoryBlocks
178
/// allocated for data.
179
virtual unsigned GetNumDataSlabs() {
183
/// GetNumStubSlabs - For testing only. Returns the number of MemoryBlocks
184
/// allocated for function stubs.
185
virtual unsigned GetNumStubSlabs() {
190
} // end namespace llvm.