JITMemoryManager.cpp revision 0fdaa0b8f194f0ef7cec0610c50672b89bd7c17a
18907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===-- JITMemoryManager.cpp - Memory Allocator for JIT'd code ------------===// 28907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// 38907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// The LLVM Compiler Infrastructure 48907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 78907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// 88907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===----------------------------------------------------------------------===// 98907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// 108907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// This file defines the DefaultJITMemoryManager class. 118907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// 128907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===----------------------------------------------------------------------===// 138907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 148907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#include "llvm/ExecutionEngine/JITMemoryManager.h" 158907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#include "llvm/Support/Compiler.h" 168907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#include "llvm/System/Memory.h" 178907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#include <map> 188907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#include <vector> 193012ac63d35bc6dc450f97dbce3e2faaf8859198Chuck Rose III#include <cassert> 20ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstdlib> 21ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring> 228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnerusing namespace llvm; 238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerJITMemoryManager::~JITMemoryManager() {} 268907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===----------------------------------------------------------------------===// 288907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// Memory Block Implementation. 298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===----------------------------------------------------------------------===// 308907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 318907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnernamespace { 328907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// MemoryRangeHeader - For a range of memory, this is the header that we put 338907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// on the block of memory. It is carefully crafted to be one word of memory. 348907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// Allocated blocks have just this header, free'd blocks have FreeRangeHeader 358907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// which starts with this. 368907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner struct FreeRangeHeader; 378907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner struct MemoryRangeHeader { 388907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// ThisAllocated - This is true if this block is currently allocated. If 398907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// not, this can be converted to a FreeRangeHeader. 408907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned ThisAllocated : 1; 418907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 428907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// PrevAllocated - Keep track of whether the block immediately before us is 438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// allocated. If not, the word immediately before this header is the size 448907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// of the previous block. 458907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned PrevAllocated : 1; 468907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 478907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// BlockSize - This is the size in bytes of this memory block, 488907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// including this header. 498907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner uintptr_t BlockSize : (sizeof(intptr_t)*8 - 2); 508907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 518907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 528907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// getBlockAfter - Return the memory block immediately after this one. 538907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// 548907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader &getBlockAfter() const { 558907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return *(MemoryRangeHeader*)((char*)this+BlockSize); 568907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 578907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 588907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// getFreeBlockBefore - If the block before this one is free, return it, 598907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// otherwise return null. 608907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *getFreeBlockBefore() const { 618907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (PrevAllocated) return 0; 628907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner intptr_t PrevSize = ((intptr_t *)this)[-1]; 638907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return (FreeRangeHeader*)((char*)this-PrevSize); 648907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 658907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 668907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// FreeBlock - Turn an allocated block into a free block, adjusting 678907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// bits in the object headers, and adding an end of region memory block. 688907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *FreeBlock(FreeRangeHeader *FreeList); 698907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 708907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// TrimAllocationToSize - If this allocated block is significantly larger 718907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// than NewSize, split it into two pieces (where the former is NewSize 728907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// bytes, including the header), and add the new block to the free list. 738907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *TrimAllocationToSize(FreeRangeHeader *FreeList, 748907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner uint64_t NewSize); 758907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner }; 768907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 778907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// FreeRangeHeader - For a memory block that isn't already allocated, this 788907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// keeps track of the current block and has a pointer to the next free block. 798907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// Free blocks are kept on a circularly linked list. 808907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner struct FreeRangeHeader : public MemoryRangeHeader { 818907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *Prev; 828907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *Next; 838907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 848907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// getMinBlockSize - Get the minimum size for a memory block. Blocks 858907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// smaller than this size cannot be created. 868907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner static unsigned getMinBlockSize() { 878907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return sizeof(FreeRangeHeader)+sizeof(intptr_t); 888907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 898907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 908907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// SetEndOfBlockSizeMarker - The word at the end of every free block is 918907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// known to be the size of the free block. Set it for this block. 928907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void SetEndOfBlockSizeMarker() { 938907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void *EndOfBlock = (char*)this + BlockSize; 948907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ((intptr_t *)EndOfBlock)[-1] = BlockSize; 958907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 968907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 978907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *RemoveFromFreeList() { 988907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(Next->Prev == this && Prev->Next == this && "Freelist broken!"); 998907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Next->Prev = Prev; 1008907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return Prev->Next = Next; 1018907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 1028907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1038907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void AddToFreeList(FreeRangeHeader *FreeList) { 1048907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Next = FreeList; 1058907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Prev = FreeList->Prev; 1068907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Prev->Next = this; 1078907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Next->Prev = this; 1088907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 1098907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1108907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// GrowBlock - The block after this block just got deallocated. Merge it 1118907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// into the current block. 1128907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void GrowBlock(uintptr_t NewSize); 1138907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1148907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// AllocateBlock - Mark this entire block allocated, updating freelists 1158907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// etc. This returns a pointer to the circular free-list. 1168907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *AllocateBlock(); 1178907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner }; 1188907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 1198907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1208907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// AllocateBlock - Mark this entire block allocated, updating freelists 1228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// etc. This returns a pointer to the circular free-list. 1238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerFreeRangeHeader *FreeRangeHeader::AllocateBlock() { 1248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(!ThisAllocated && !getBlockAfter().PrevAllocated && 1258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner "Cannot allocate an allocated block!"); 1268907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Mark this block allocated. 1278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ThisAllocated = 1; 1288907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner getBlockAfter().PrevAllocated = 1; 1298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1308907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Remove it from the free list. 1318907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return RemoveFromFreeList(); 1328907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 1338907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1348907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// FreeBlock - Turn an allocated block into a free block, adjusting 1358907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// bits in the object headers, and adding an end of region memory block. 1368907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// If possible, coalesce this block with neighboring blocks. Return the 1378907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// FreeRangeHeader to allocate from. 1388907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerFreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) { 1398907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader *FollowingBlock = &getBlockAfter(); 1408907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(ThisAllocated && "This block is already allocated!"); 1418907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); 1428907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *FreeListToReturn = FreeList; 1448907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1458907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // If the block after this one is free, merge it into this block. 1468907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (!FollowingBlock->ThisAllocated) { 1478907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; 1488907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // "FreeList" always needs to be a valid free block. If we're about to 1498907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // coalesce with it, update our notion of what the free list is. 1508907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (&FollowingFreeBlock == FreeList) { 1518907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeList = FollowingFreeBlock.Next; 1528907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeListToReturn = 0; 1538907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(&FollowingFreeBlock != FreeList && "No tombstone block?"); 1548907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 1558907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FollowingFreeBlock.RemoveFromFreeList(); 1568907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1578907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Include the following block into this one. 1588907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner BlockSize += FollowingFreeBlock.BlockSize; 1598907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FollowingBlock = &FollowingFreeBlock.getBlockAfter(); 1608907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1618907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Tell the block after the block we are coalescing that this block is 1628907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // allocated. 1638907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FollowingBlock->PrevAllocated = 1; 1648907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 1658907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1668907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(FollowingBlock->ThisAllocated && "Missed coalescing?"); 1678907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1688907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { 1698907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); 1708907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return FreeListToReturn ? FreeListToReturn : PrevFreeBlock; 1718907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 1728907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1738907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Otherwise, mark this block free. 1748907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader &FreeBlock = *(FreeRangeHeader*)this; 1758907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FollowingBlock->PrevAllocated = 0; 1768907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeBlock.ThisAllocated = 0; 1778907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1788907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Link this into the linked list of free blocks. 1798907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeBlock.AddToFreeList(FreeList); 1808907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1818907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Add a marker at the end of the block, indicating the size of this free 1828907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // block. 1838907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeBlock.SetEndOfBlockSizeMarker(); 1848907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return FreeListToReturn ? FreeListToReturn : &FreeBlock; 1858907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 1868907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1878907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// GrowBlock - The block after this block just got deallocated. Merge it 1888907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// into the current block. 1898907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnervoid FreeRangeHeader::GrowBlock(uintptr_t NewSize) { 1908907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(NewSize > BlockSize && "Not growing block?"); 1918907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner BlockSize = NewSize; 1928907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner SetEndOfBlockSizeMarker(); 1938907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner getBlockAfter().PrevAllocated = 0; 1948907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 1958907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 1968907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// TrimAllocationToSize - If this allocated block is significantly larger 1978907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// than NewSize, split it into two pieces (where the former is NewSize 1988907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner/// bytes, including the header), and add the new block to the free list. 1998907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerFreeRangeHeader *MemoryRangeHeader:: 2008907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerTrimAllocationToSize(FreeRangeHeader *FreeList, uint64_t NewSize) { 2018907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(ThisAllocated && getBlockAfter().PrevAllocated && 2028907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner "Cannot deallocate part of an allocated block!"); 2038907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2048907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Round up size for alignment of header. 2058907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned HeaderAlign = __alignof(FreeRangeHeader); 2068907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner NewSize = (NewSize+ (HeaderAlign-1)) & ~(HeaderAlign-1); 2078907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2088907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Size is now the size of the block we will remove from the start of the 2098907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // current block. 2108907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(NewSize <= BlockSize && 2118907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner "Allocating more space from this block than exists!"); 2128907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2138907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // If splitting this block will cause the remainder to be too small, do not 2148907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // split the block. 2158907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (BlockSize <= NewSize+FreeRangeHeader::getMinBlockSize()) 2168907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return FreeList; 2178907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2188907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Otherwise, we splice the required number of bytes out of this block, form 2198907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // a new block immediately after it, then mark this block allocated. 2208907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader &FormerNextBlock = getBlockAfter(); 2218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Change the size of this block. 2238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner BlockSize = NewSize; 2248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Get the new block we just sliced out and turn it into a free block. 2268907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader &NewNextBlock = (FreeRangeHeader &)getBlockAfter(); 2278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner NewNextBlock.BlockSize = (char*)&FormerNextBlock - (char*)&NewNextBlock; 2288907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner NewNextBlock.ThisAllocated = 0; 2298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner NewNextBlock.PrevAllocated = 1; 2308907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner NewNextBlock.SetEndOfBlockSizeMarker(); 2318907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FormerNextBlock.PrevAllocated = 0; 2328907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner NewNextBlock.AddToFreeList(FreeList); 2338907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return &NewNextBlock; 2348907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 2358907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2368907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===----------------------------------------------------------------------===// 2378907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner// Memory Block Implementation. 2388907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner//===----------------------------------------------------------------------===// 2398907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2408907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnernamespace { 2418907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// DefaultJITMemoryManager - Manage memory for the JIT code generation. 2428907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// This splits a large block of MAP_NORESERVE'd memory into two 2438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// sections, one for function stubs, one for the functions themselves. We 2448907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// have to do this because we may need to emit a function stub while in the 2458907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// middle of emitting a function, and we don't know how large the function we 2468907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// are emitting is. 2478907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner class VISIBILITY_HIDDEN DefaultJITMemoryManager : public JITMemoryManager { 2488907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner std::vector<sys::MemoryBlock> Blocks; // Memory blocks allocated by the JIT 2498907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *FreeMemoryList; // Circular list of free blocks. 2508907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2518907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // When emitting code into a memory block, this is the block. 2528907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader *CurBlock; 2538907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2548907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *CurStubPtr, *StubBase; 2558907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *GOTBase; // Target Specific reserved memory 2568907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2578907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Centralize memory block allocation. 2588907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner sys::MemoryBlock getNewMemoryBlock(unsigned size); 2598907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2608907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner std::map<const Function*, MemoryRangeHeader*> FunctionBlocks; 261afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray std::map<const Function*, MemoryRangeHeader*> TableBlocks; 2628907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner public: 2638907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner DefaultJITMemoryManager(); 2648907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ~DefaultJITMemoryManager(); 2658907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2668907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void AllocateGOT(); 2678907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2688907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *allocateStub(unsigned StubSize, unsigned Alignment); 2698907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2708907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// startFunctionBody - When a function starts, allocate a block of free 2718907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// executable memory, returning a pointer to it and its actual size. 2728907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *startFunctionBody(const Function *F, uintptr_t &ActualSize) { 2738907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner CurBlock = FreeMemoryList; 2748907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2758907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Allocate the entire memory block. 2768907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeMemoryList = FreeMemoryList->AllocateBlock(); 2778907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader); 2788907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return (unsigned char *)(CurBlock+1); 2798907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 2808907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2818907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// endFunctionBody - The function F is now allocated, and takes the memory 2828907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// in the range [FunctionStart,FunctionEnd). 2838907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void endFunctionBody(const Function *F, unsigned char *FunctionStart, 2848907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *FunctionEnd) { 2858907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(FunctionEnd > FunctionStart); 2868907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(FunctionStart == (unsigned char *)(CurBlock+1) && 2878907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner "Mismatched function start/end!"); 2888907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2898907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock; 2908907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FunctionBlocks[F] = CurBlock; 2918907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 2928907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Release the memory at the end of this block that isn't needed. 2938907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 2948907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 2958907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 296afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// startExceptionTable - Use startFunctionBody to allocate memory for the 297afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// function's exception table. 2980fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner unsigned char* startExceptionTable(const Function* F, 2990fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner uintptr_t &ActualSize) { 300afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray return startFunctionBody(F, ActualSize); 301afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 302afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 303afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// endExceptionTable - The exception table of F is now allocated, 304afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// and takes the memory in the range [TableStart,TableEnd). 305afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray void endExceptionTable(const Function *F, unsigned char *TableStart, 306afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray unsigned char *TableEnd, 307afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray unsigned char* FrameRegister) { 308afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray assert(TableEnd > TableStart); 309afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray assert(TableStart == (unsigned char *)(CurBlock+1) && 310afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray "Mismatched table start/end!"); 311afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 312afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock; 313afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray TableBlocks[F] = CurBlock; 314afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 315afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray // Release the memory at the end of this block that isn't needed. 316afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 317afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 318afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 3198907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *getGOTBase() const { 3208907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return GOTBase; 3218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 3228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// deallocateMemForFunction - Deallocate all memory for the specified 3248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// function body. 3258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner void deallocateMemForFunction(const Function *F) { 3268907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner std::map<const Function*, MemoryRangeHeader*>::iterator 3278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner I = FunctionBlocks.find(F); 3288907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (I == FunctionBlocks.end()) return; 3298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3308907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Find the block that is allocated for this function. 3318907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader *MemRange = I->second; 3328907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(MemRange->ThisAllocated && "Block isn't allocated!"); 3338907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3348907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Fill the buffer with garbage! 3358907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#ifndef NDEBUG 3368907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange)); 3378907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#endif 3388907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3398907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Free the memory. 3408907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); 3418907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3428907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Finally, remove this entry from FunctionBlocks. 3438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FunctionBlocks.erase(I); 344afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 345afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray I = TableBlocks.find(F); 346afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray if (I == TableBlocks.end()) return; 347afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 348afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray // Find the block that is allocated for this function. 349afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray MemRange = I->second; 350afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray assert(MemRange->ThisAllocated && "Block isn't allocated!"); 351afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 352afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray // Fill the buffer with garbage! 353afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray#ifndef NDEBUG 354afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange)); 355afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray#endif 356afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 357afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray // Free the memory. 358afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); 359afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 360afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray // Finally, remove this entry from TableBlocks. 361afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray TableBlocks.erase(I); 3628907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 3638907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner }; 3648907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 3658907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3668907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerDefaultJITMemoryManager::DefaultJITMemoryManager() { 3678907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Allocate a 16M block of memory for functions. 3688907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20); 3698907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3708907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned char *MemBase = reinterpret_cast<unsigned char*>(MemBlock.base()); 3718907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3728907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Allocate stubs backwards from the base, allocate functions forward 3738907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // from the base. 3748907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner StubBase = MemBase; 3758907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner CurStubPtr = MemBase + 512*1024; // Use 512k for stubs, working backwards. 3768907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3778907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // We set up the memory chunk with 4 mem regions, like this: 3788907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // [ START 3798907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // [ Free #0 ] -> Large space to allocate functions from. 3808907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // [ Allocated #1 ] -> Tiny space to separate regions. 3818907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // [ Free #2 ] -> Tiny space so there is always at least 1 free block. 3828907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // [ Allocated #3 ] -> Tiny space to prevent looking past end of block. 3838907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // END ] 3848907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // 3858907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // The last three blocks are never deallocated or touched. 3868907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3878907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Add MemoryRangeHeader to the end of the memory region, indicating that 3888907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // the space after the block of memory is allocated. This is block #3. 3898907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader *Mem3 = (MemoryRangeHeader*)(MemBase+MemBlock.size())-1; 3908907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem3->ThisAllocated = 1; 3918907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem3->PrevAllocated = 0; 3928907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem3->BlockSize = 0; 3938907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 3948907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// Add a tiny free region so that the free list always has one entry. 3958907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *Mem2 = 3968907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner (FreeRangeHeader *)(((char*)Mem3)-FreeRangeHeader::getMinBlockSize()); 3978907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem2->ThisAllocated = 0; 3988907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem2->PrevAllocated = 1; 3998907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem2->BlockSize = FreeRangeHeader::getMinBlockSize(); 4008907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem2->SetEndOfBlockSizeMarker(); 4018907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem2->Prev = Mem2; // Mem2 *is* the free list for now. 4028907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem2->Next = Mem2; 4038907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4048907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// Add a tiny allocated region so that Mem2 is never coalesced away. 4058907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; 4068907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem1->ThisAllocated = 1; 4078907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem1->PrevAllocated = 0; 4088907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem1->BlockSize = (char*)Mem2 - (char*)Mem1; 4098907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4108907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Add a FreeRangeHeader to the start of the function body region, indicating 4118907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // that the space is free. Mark the previous block allocated so we never look 4128907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // at it. 4138907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr; 4148907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem0->ThisAllocated = 0; 4158907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem0->PrevAllocated = 1; 4168907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem0->BlockSize = (char*)Mem1-(char*)Mem0; 4178907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem0->SetEndOfBlockSizeMarker(); 4188907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Mem0->AddToFreeList(Mem2); 4198907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4208907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Start out with the freelist pointing to Mem0. 4218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner FreeMemoryList = Mem0; 4228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner GOTBase = NULL; 4248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 4258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4268907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnervoid DefaultJITMemoryManager::AllocateGOT() { 4278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner assert(GOTBase == 0 && "Cannot allocate the got multiple times"); 4288907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner GOTBase = new unsigned char[sizeof(void*) * 8192]; 4298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner HasGOT = true; 4308907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 4318907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4328907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4338907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerDefaultJITMemoryManager::~DefaultJITMemoryManager() { 4348907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner for (unsigned i = 0, e = Blocks.size(); i != e; ++i) 4358907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner sys::Memory::ReleaseRWX(Blocks[i]); 4368907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4378907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner delete[] GOTBase; 4388907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Blocks.clear(); 4398907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 4408907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4418907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnerunsigned char *DefaultJITMemoryManager::allocateStub(unsigned StubSize, 4428907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned Alignment) { 4438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner CurStubPtr -= StubSize; 4448907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) & 4458907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ~(intptr_t)(Alignment-1)); 4468907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (CurStubPtr < StubBase) { 4478907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // FIXME: allocate a new block 4488907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner fprintf(stderr, "JIT ran out of memory for function stubs!\n"); 4498907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner abort(); 4508907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 4518907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return CurStubPtr; 4528907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 4538907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4548907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattnersys::MemoryBlock DefaultJITMemoryManager::getNewMemoryBlock(unsigned size) { 4558907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner // Allocate a new block close to the last one. 4568907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front(); 4578907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner std::string ErrMsg; 4588907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld, &ErrMsg); 4598907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (B.base() == 0) { 4608907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner fprintf(stderr, 4618907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner "Allocation failed when allocating new memory in the JIT\n%s\n", 4628907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ErrMsg.c_str()); 4638907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner abort(); 4648907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 4658907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Blocks.push_back(B); 4668907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return B; 4678907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 4688907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4698907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner 4708907b4ba479bbfbe630a4c3abab32c7d49749a48Chris LattnerJITMemoryManager *JITMemoryManager::CreateDefaultMemManager() { 4718907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner return new DefaultJITMemoryManager(); 4728907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner} 473