mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-13 08:25:27 +00:00
Add an option to allocate JITed global data separately from code. By
default, this option is not enabled to support clients who rely on this behavior. Fixes http://llvm.org/PR4483 A patch to allocate additional memory for globals after we run out is forthcoming. Patch by Reid Kleckner! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -251,6 +251,8 @@ namespace {
|
||||
/// middle of emitting a function, and we don't know how large the function we
|
||||
/// are emitting is.
|
||||
class VISIBILITY_HIDDEN DefaultJITMemoryManager : public JITMemoryManager {
|
||||
bool PoisonMemory; // Whether to poison freed memory.
|
||||
|
||||
std::vector<sys::MemoryBlock> Blocks; // Memory blocks allocated by the JIT
|
||||
FreeRangeHeader *FreeMemoryList; // Circular list of free blocks.
|
||||
|
||||
@@ -258,6 +260,7 @@ namespace {
|
||||
MemoryRangeHeader *CurBlock;
|
||||
|
||||
uint8_t *CurStubPtr, *StubBase;
|
||||
uint8_t *CurGlobalPtr, *GlobalEnd;
|
||||
uint8_t *GOTBase; // Target Specific reserved memory
|
||||
void *DlsymTable; // Stub external symbol information
|
||||
|
||||
@@ -324,7 +327,7 @@ namespace {
|
||||
CurBlock = FreeMemoryList;
|
||||
FreeMemoryList = FreeMemoryList->AllocateBlock();
|
||||
|
||||
uint8_t *result = (uint8_t *)CurBlock+1;
|
||||
uint8_t *result = (uint8_t *)(CurBlock + 1);
|
||||
|
||||
if (Alignment == 0) Alignment = 1;
|
||||
result = (uint8_t*)(((intptr_t)result+Alignment-1) &
|
||||
@@ -336,6 +339,30 @@ namespace {
|
||||
return result;
|
||||
}
|
||||
|
||||
/// allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
|
||||
/// this method does not touch the current block and can be called at any
|
||||
/// time.
|
||||
uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
|
||||
uint8_t *Result = CurGlobalPtr;
|
||||
|
||||
// Align the pointer.
|
||||
if (Alignment == 0) Alignment = 1;
|
||||
Result = (uint8_t*)(((uintptr_t)Result + Alignment-1) &
|
||||
~(uintptr_t)(Alignment-1));
|
||||
|
||||
// Move the current global pointer forward.
|
||||
CurGlobalPtr += Result - CurGlobalPtr + Size;
|
||||
|
||||
// Check for overflow.
|
||||
if (CurGlobalPtr > GlobalEnd) {
|
||||
// FIXME: Allocate more memory.
|
||||
fprintf(stderr, "JIT ran out of memory for globals!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// startExceptionTable - Use startFunctionBody to allocate memory for the
|
||||
/// function's exception table.
|
||||
uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
|
||||
@@ -375,12 +402,12 @@ namespace {
|
||||
// Find the block that is allocated for this function.
|
||||
MemoryRangeHeader *MemRange = I->second;
|
||||
assert(MemRange->ThisAllocated && "Block isn't allocated!");
|
||||
|
||||
|
||||
// Fill the buffer with garbage!
|
||||
#ifndef NDEBUG
|
||||
memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange));
|
||||
#endif
|
||||
|
||||
if (PoisonMemory) {
|
||||
memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange));
|
||||
}
|
||||
|
||||
// Free the memory.
|
||||
FreeMemoryList = MemRange->FreeBlock(FreeMemoryList);
|
||||
|
||||
@@ -393,12 +420,12 @@ namespace {
|
||||
// Find the block that is allocated for this function.
|
||||
MemRange = I->second;
|
||||
assert(MemRange->ThisAllocated && "Block isn't allocated!");
|
||||
|
||||
|
||||
// Fill the buffer with garbage!
|
||||
#ifndef NDEBUG
|
||||
memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange));
|
||||
#endif
|
||||
|
||||
if (PoisonMemory) {
|
||||
memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange));
|
||||
}
|
||||
|
||||
// Free the memory.
|
||||
FreeMemoryList = MemRange->FreeBlock(FreeMemoryList);
|
||||
|
||||
@@ -420,10 +447,22 @@ namespace {
|
||||
for (unsigned i = 0, e = Blocks.size(); i != e; ++i)
|
||||
sys::Memory::setExecutable(Blocks[i]);
|
||||
}
|
||||
|
||||
/// setPoisonMemory - Controls whether we write garbage over freed memory.
|
||||
///
|
||||
void setPoisonMemory(bool poison) {
|
||||
PoisonMemory = poison;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
DefaultJITMemoryManager::DefaultJITMemoryManager() {
|
||||
#ifdef NDEBUG
|
||||
PoisonMemory = true;
|
||||
#else
|
||||
PoisonMemory = false;
|
||||
#endif
|
||||
|
||||
// Allocate a 16M block of memory for functions.
|
||||
#if defined(__APPLE__) && defined(__arm__)
|
||||
sys::MemoryBlock MemBlock = getNewMemoryBlock(4 << 20);
|
||||
@@ -433,11 +472,13 @@ DefaultJITMemoryManager::DefaultJITMemoryManager() {
|
||||
|
||||
uint8_t *MemBase = static_cast<uint8_t*>(MemBlock.base());
|
||||
|
||||
// Allocate stubs backwards from the base, allocate functions forward
|
||||
// from the base.
|
||||
// Allocate stubs backwards to the base, globals forward from the stubs, and
|
||||
// functions forward after globals.
|
||||
StubBase = MemBase;
|
||||
CurStubPtr = MemBase + 512*1024; // Use 512k for stubs, working backwards.
|
||||
|
||||
CurGlobalPtr = CurStubPtr; // Use 2M for globals, working forwards.
|
||||
GlobalEnd = CurGlobalPtr + 2*1024*1024;
|
||||
|
||||
// We set up the memory chunk with 4 mem regions, like this:
|
||||
// [ START
|
||||
// [ Free #0 ] -> Large space to allocate functions from.
|
||||
@@ -474,7 +515,7 @@ DefaultJITMemoryManager::DefaultJITMemoryManager() {
|
||||
// Add a FreeRangeHeader to the start of the function body region, indicating
|
||||
// that the space is free. Mark the previous block allocated so we never look
|
||||
// at it.
|
||||
FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr;
|
||||
FreeRangeHeader *Mem0 = (FreeRangeHeader*)GlobalEnd;
|
||||
Mem0->ThisAllocated = 0;
|
||||
Mem0->PrevAllocated = 1;
|
||||
Mem0->BlockSize = (char*)Mem1-(char*)Mem0;
|
||||
@@ -522,7 +563,7 @@ uint8_t *DefaultJITMemoryManager::allocateStub(const GlobalValue* F,
|
||||
|
||||
sys::MemoryBlock DefaultJITMemoryManager::getNewMemoryBlock(unsigned size) {
|
||||
// Allocate a new block close to the last one.
|
||||
const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front();
|
||||
const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.back();
|
||||
std::string ErrMsg;
|
||||
sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld, &ErrMsg);
|
||||
if (B.base() == 0) {
|
||||
|
Reference in New Issue
Block a user