Allow more than one stub to be being generated at the same time.

It's probably better in the long run to replace the
indirect-GlobalVariable system. That'll be done after a subsequent
patch.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89708 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jeffrey Yasskin
2009-11-23 22:49:00 +00:00
parent f81bf15552
commit 0261d795f8
7 changed files with 97 additions and 73 deletions

View File

@@ -68,23 +68,29 @@ public:
///
virtual bool finishFunction(MachineFunction &F) = 0;
/// startGVStub - This callback is invoked when the JIT needs the
/// address of a GV (e.g. function) that has not been code generated yet.
/// The StubSize specifies the total size required by the stub.
/// startGVStub - This callback is invoked when the JIT needs the address of a
/// GV (e.g. function) that has not been code generated yet. The StubSize
/// specifies the total size required by the stub. The BufferState must be
/// passed to finishGVStub, and start/finish pairs with the same BufferState
/// must be properly nested.
///
virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
unsigned Alignment = 1) = 0;
virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
unsigned StubSize, unsigned Alignment = 1) = 0;
/// startGVStub - This callback is invoked when the JIT needs the address of a
/// startGVStub - This callback is invoked when the JIT needs the address of a
/// GV (e.g. function) that has not been code generated yet. Buffer points to
/// memory already allocated for this stub.
/// memory already allocated for this stub. The BufferState must be passed to
/// finishGVStub, and start/finish pairs with the same BufferState must be
/// properly nested.
///
virtual void startGVStub(const GlobalValue* GV, void *Buffer,
virtual void startGVStub(BufferState &BS, void *Buffer,
unsigned StubSize) = 0;
/// finishGVStub - This callback is invoked to terminate a GV stub.
/// finishGVStub - This callback is invoked to terminate a GV stub and returns
/// the start address of the stub. The BufferState must first have been
/// passed to startGVStub.
///
virtual void *finishGVStub(const GlobalValue* F) = 0;
virtual void *finishGVStub(BufferState &BS) = 0;
/// emitByte - This callback is invoked when a byte needs to be written to the
/// output stream.

View File

@@ -48,17 +48,41 @@ class Function;
/// occurred, more memory is allocated, and we reemit the code into it.
///
class MachineCodeEmitter {
public:
class BufferState {
friend class MachineCodeEmitter;
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
/// allocated for this code buffer.
uint8_t *BufferBegin, *BufferEnd;
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
/// this pointer is at BufferEnd, it will never move due to code emission,
/// and all code emission requests will be ignored (this is the buffer
/// overflow condition).
uint8_t *CurBufferPtr;
public:
BufferState() : BufferBegin(NULL), BufferEnd(NULL), CurBufferPtr(NULL) {}
};
protected:
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
/// allocated for this code buffer.
uint8_t *BufferBegin, *BufferEnd;
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
/// this pointer is at BufferEnd, it will never move due to code emission, and
/// all code emission requests will be ignored (this is the buffer overflow
/// condition).
uint8_t *CurBufferPtr;
/// These have the same meanings as the fields in BufferState
uint8_t *BufferBegin, *BufferEnd, *CurBufferPtr;
/// Save or restore the current buffer state. The BufferState objects must be
/// used as a stack.
void SaveStateTo(BufferState &BS) {
assert(BS.BufferBegin == NULL &&
"Can't save state into the same BufferState twice.");
BS.BufferBegin = BufferBegin;
BS.BufferEnd = BufferEnd;
BS.CurBufferPtr = CurBufferPtr;
}
void RestoreStateFrom(BufferState &BS) {
BufferBegin = BS.BufferBegin;
BufferEnd = BS.BufferEnd;
CurBufferPtr = BS.CurBufferPtr;
}
public:
virtual ~MachineCodeEmitter() {}