#include <map>
#include <vector>
#include <cassert>
+#include <climits>
+#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace llvm;
/// BlockSize - This is the size in bytes of this memory block,
/// including this header.
- uintptr_t BlockSize : (sizeof(intptr_t)*8 - 2);
+ uintptr_t BlockSize : (sizeof(intptr_t)*CHAR_BIT - 2);
/// getBlockAfter - Return the memory block immediately after this one.
// When emitting code into a memory block, this is the block.
MemoryRangeHeader *CurBlock;
- unsigned char *CurStubPtr, *StubBase;
- unsigned char *GOTBase; // Target Specific reserved memory
+ uint8_t *CurStubPtr, *StubBase;
+ uint8_t *GOTBase; // Target Specific reserved memory
+ void *DlsymTable; // Stub external symbol information
// Centralize memory block allocation.
sys::MemoryBlock getNewMemoryBlock(unsigned size);
~DefaultJITMemoryManager();
void AllocateGOT();
-
- unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment);
+ void SetDlsymTable(void *);
+
+ uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment);
/// startFunctionBody - When a function starts, allocate a block of free
/// executable memory, returning a pointer to it and its actual size.
- unsigned char *startFunctionBody(const Function *F, uintptr_t &ActualSize) {
- CurBlock = FreeMemoryList;
+ uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize) {
+
+ FreeRangeHeader* candidateBlock = FreeMemoryList;
+ FreeRangeHeader* head = FreeMemoryList;
+ FreeRangeHeader* iter = head->Next;
+
+ uintptr_t largest = candidateBlock->BlockSize;
+
+ // Search for the largest free block
+ while (iter != head) {
+ if (iter->BlockSize > largest) {
+ largest = iter->BlockSize;
+ candidateBlock = iter;
+ }
+ iter = iter->Next;
+ }
+ // Select this candidate block for allocation
+ CurBlock = candidateBlock;
+
// Allocate the entire memory block.
- FreeMemoryList = FreeMemoryList->AllocateBlock();
+ FreeMemoryList = candidateBlock->AllocateBlock();
ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader);
- return (unsigned char *)(CurBlock+1);
+ return (uint8_t *)(CurBlock+1);
}
/// endFunctionBody - The function F is now allocated, and takes the memory
/// in the range [FunctionStart,FunctionEnd).
- void endFunctionBody(const Function *F, unsigned char *FunctionStart,
- unsigned char *FunctionEnd) {
+ void endFunctionBody(const Function *F, uint8_t *FunctionStart,
+ uint8_t *FunctionEnd) {
assert(FunctionEnd > FunctionStart);
- assert(FunctionStart == (unsigned char *)(CurBlock+1) &&
+ assert(FunctionStart == (uint8_t *)(CurBlock+1) &&
"Mismatched function start/end!");
- uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock;
+ uintptr_t BlockSize = FunctionEnd - (uint8_t *)CurBlock;
FunctionBlocks[F] = CurBlock;
// Release the memory at the end of this block that isn't needed.
FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
}
-
+
+ /// allocateSpace - Allocate a memory block of the given size.
+ uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
+ CurBlock = FreeMemoryList;
+ FreeMemoryList = FreeMemoryList->AllocateBlock();
+
+ uint8_t *result = (uint8_t *)CurBlock+1;
+
+ if (Alignment == 0) Alignment = 1;
+ result = (uint8_t*)(((intptr_t)result+Alignment-1) &
+ ~(intptr_t)(Alignment-1));
+
+ uintptr_t BlockSize = result + Size - (uint8_t *)CurBlock;
+ FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
+
+ return result;
+ }
+
/// startExceptionTable - Use startFunctionBody to allocate memory for the
/// function's exception table.
- unsigned char* startExceptionTable(const Function* F,
- uintptr_t &ActualSize) {
+ uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
return startFunctionBody(F, ActualSize);
}
/// endExceptionTable - The exception table of F is now allocated,
/// and takes the memory in the range [TableStart,TableEnd).
- void endExceptionTable(const Function *F, unsigned char *TableStart,
- unsigned char *TableEnd,
- unsigned char* FrameRegister) {
+ void endExceptionTable(const Function *F, uint8_t *TableStart,
+ uint8_t *TableEnd, uint8_t* FrameRegister) {
assert(TableEnd > TableStart);
- assert(TableStart == (unsigned char *)(CurBlock+1) &&
+ assert(TableStart == (uint8_t *)(CurBlock+1) &&
"Mismatched table start/end!");
- uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock;
+ uintptr_t BlockSize = TableEnd - (uint8_t *)CurBlock;
TableBlocks[F] = CurBlock;
// Release the memory at the end of this block that isn't needed.
FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
}
- unsigned char *getGOTBase() const {
+ uint8_t *getGOTBase() const {
return GOTBase;
}
+ void *getDlsymTable() const {
+ return DlsymTable;
+ }
+
/// deallocateMemForFunction - Deallocate all memory for the specified
/// function body.
void deallocateMemForFunction(const Function *F) {
sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20);
#endif
- unsigned char *MemBase = static_cast<unsigned char*>(MemBlock.base());
+ uint8_t *MemBase = static_cast<uint8_t*>(MemBlock.base());
// Allocate stubs backwards from the base, allocate functions forward
// from the base.
FreeMemoryList = Mem0;
GOTBase = NULL;
+ DlsymTable = NULL;
}
void DefaultJITMemoryManager::AllocateGOT() {
assert(GOTBase == 0 && "Cannot allocate the got multiple times");
- GOTBase = new unsigned char[sizeof(void*) * 8192];
+ GOTBase = new uint8_t[sizeof(void*) * 8192];
HasGOT = true;
}
+void DefaultJITMemoryManager::SetDlsymTable(void *ptr) {
+ DlsymTable = ptr;
+}
DefaultJITMemoryManager::~DefaultJITMemoryManager() {
for (unsigned i = 0, e = Blocks.size(); i != e; ++i)
Blocks.clear();
}
-unsigned char *DefaultJITMemoryManager::allocateStub(const GlobalValue* F,
+uint8_t *DefaultJITMemoryManager::allocateStub(const GlobalValue* F,
unsigned StubSize,
unsigned Alignment) {
CurStubPtr -= StubSize;
- CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) &
- ~(intptr_t)(Alignment-1));
+ CurStubPtr = (uint8_t*)(((intptr_t)CurStubPtr) &
+ ~(intptr_t)(Alignment-1));
if (CurStubPtr < StubBase) {
// FIXME: allocate a new block
fprintf(stderr, "JIT ran out of memory for function stubs!\n");