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