LLVM API Documentation
00001 //===-- JITMemoryManager.cpp - Memory Allocator for JIT'd code ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the DefaultJITMemoryManager class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/GlobalValue.h" 00015 #include "llvm/ExecutionEngine/JITMemoryManager.h" 00016 #include "llvm/Support/Compiler.h" 00017 #include "llvm/System/Memory.h" 00018 #include <map> 00019 #include <vector> 00020 #include <cassert> 00021 #include <cstdio> 00022 #include <cstdlib> 00023 #include <cstring> 00024 using namespace llvm; 00025 00026 00027 JITMemoryManager::~JITMemoryManager() {} 00028 00029 //===----------------------------------------------------------------------===// 00030 // Memory Block Implementation. 00031 //===----------------------------------------------------------------------===// 00032 00033 namespace { 00034 /// MemoryRangeHeader - For a range of memory, this is the header that we put 00035 /// on the block of memory. It is carefully crafted to be one word of memory. 00036 /// Allocated blocks have just this header, free'd blocks have FreeRangeHeader 00037 /// which starts with this. 00038 struct FreeRangeHeader; 00039 struct MemoryRangeHeader { 00040 /// ThisAllocated - This is true if this block is currently allocated. If 00041 /// not, this can be converted to a FreeRangeHeader. 00042 unsigned ThisAllocated : 1; 00043 00044 /// PrevAllocated - Keep track of whether the block immediately before us is 00045 /// allocated. If not, the word immediately before this header is the size 00046 /// of the previous block. 00047 unsigned PrevAllocated : 1; 00048 00049 /// BlockSize - This is the size in bytes of this memory block, 00050 /// including this header. 00051 uintptr_t BlockSize : (sizeof(intptr_t)*8 - 2); 00052 00053 00054 /// getBlockAfter - Return the memory block immediately after this one. 00055 /// 00056 MemoryRangeHeader &getBlockAfter() const { 00057 return *(MemoryRangeHeader*)((char*)this+BlockSize); 00058 } 00059 00060 /// getFreeBlockBefore - If the block before this one is free, return it, 00061 /// otherwise return null. 00062 FreeRangeHeader *getFreeBlockBefore() const { 00063 if (PrevAllocated) return 0; 00064 intptr_t PrevSize = ((intptr_t *)this)[-1]; 00065 return (FreeRangeHeader*)((char*)this-PrevSize); 00066 } 00067 00068 /// FreeBlock - Turn an allocated block into a free block, adjusting 00069 /// bits in the object headers, and adding an end of region memory block. 00070 FreeRangeHeader *FreeBlock(FreeRangeHeader *FreeList); 00071 00072 /// TrimAllocationToSize - If this allocated block is significantly larger 00073 /// than NewSize, split it into two pieces (where the former is NewSize 00074 /// bytes, including the header), and add the new block to the free list. 00075 FreeRangeHeader *TrimAllocationToSize(FreeRangeHeader *FreeList, 00076 uint64_t NewSize); 00077 }; 00078 00079 /// FreeRangeHeader - For a memory block that isn't already allocated, this 00080 /// keeps track of the current block and has a pointer to the next free block. 00081 /// Free blocks are kept on a circularly linked list. 00082 struct FreeRangeHeader : public MemoryRangeHeader { 00083 FreeRangeHeader *Prev; 00084 FreeRangeHeader *Next; 00085 00086 /// getMinBlockSize - Get the minimum size for a memory block. Blocks 00087 /// smaller than this size cannot be created. 00088 static unsigned getMinBlockSize() { 00089 return sizeof(FreeRangeHeader)+sizeof(intptr_t); 00090 } 00091 00092 /// SetEndOfBlockSizeMarker - The word at the end of every free block is 00093 /// known to be the size of the free block. Set it for this block. 00094 void SetEndOfBlockSizeMarker() { 00095 void *EndOfBlock = (char*)this + BlockSize; 00096 ((intptr_t *)EndOfBlock)[-1] = BlockSize; 00097 } 00098 00099 FreeRangeHeader *RemoveFromFreeList() { 00100 assert(Next->Prev == this && Prev->Next == this && "Freelist broken!"); 00101 Next->Prev = Prev; 00102 return Prev->Next = Next; 00103 } 00104 00105 void AddToFreeList(FreeRangeHeader *FreeList) { 00106 Next = FreeList; 00107 Prev = FreeList->Prev; 00108 Prev->Next = this; 00109 Next->Prev = this; 00110 } 00111 00112 /// GrowBlock - The block after this block just got deallocated. Merge it 00113 /// into the current block. 00114 void GrowBlock(uintptr_t NewSize); 00115 00116 /// AllocateBlock - Mark this entire block allocated, updating freelists 00117 /// etc. This returns a pointer to the circular free-list. 00118 FreeRangeHeader *AllocateBlock(); 00119 }; 00120 } 00121 00122 00123 /// AllocateBlock - Mark this entire block allocated, updating freelists 00124 /// etc. This returns a pointer to the circular free-list. 00125 FreeRangeHeader *FreeRangeHeader::AllocateBlock() { 00126 assert(!ThisAllocated && !getBlockAfter().PrevAllocated && 00127 "Cannot allocate an allocated block!"); 00128 // Mark this block allocated. 00129 ThisAllocated = 1; 00130 getBlockAfter().PrevAllocated = 1; 00131 00132 // Remove it from the free list. 00133 return RemoveFromFreeList(); 00134 } 00135 00136 /// FreeBlock - Turn an allocated block into a free block, adjusting 00137 /// bits in the object headers, and adding an end of region memory block. 00138 /// If possible, coalesce this block with neighboring blocks. Return the 00139 /// FreeRangeHeader to allocate from. 00140 FreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) { 00141 MemoryRangeHeader *FollowingBlock = &getBlockAfter(); 00142 assert(ThisAllocated && "This block is already allocated!"); 00143 assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); 00144 00145 FreeRangeHeader *FreeListToReturn = FreeList; 00146 00147 // If the block after this one is free, merge it into this block. 00148 if (!FollowingBlock->ThisAllocated) { 00149 FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; 00150 // "FreeList" always needs to be a valid free block. If we're about to 00151 // coalesce with it, update our notion of what the free list is. 00152 if (&FollowingFreeBlock == FreeList) { 00153 FreeList = FollowingFreeBlock.Next; 00154 FreeListToReturn = 0; 00155 assert(&FollowingFreeBlock != FreeList && "No tombstone block?"); 00156 } 00157 FollowingFreeBlock.RemoveFromFreeList(); 00158 00159 // Include the following block into this one. 00160 BlockSize += FollowingFreeBlock.BlockSize; 00161 FollowingBlock = &FollowingFreeBlock.getBlockAfter(); 00162 00163 // Tell the block after the block we are coalescing that this block is 00164 // allocated. 00165 FollowingBlock->PrevAllocated = 1; 00166 } 00167 00168 assert(FollowingBlock->ThisAllocated && "Missed coalescing?"); 00169 00170 if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { 00171 PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); 00172 return FreeListToReturn ? FreeListToReturn : PrevFreeBlock; 00173 } 00174 00175 // Otherwise, mark this block free. 00176 FreeRangeHeader &FreeBlock = *(FreeRangeHeader*)this; 00177 FollowingBlock->PrevAllocated = 0; 00178 FreeBlock.ThisAllocated = 0; 00179 00180 // Link this into the linked list of free blocks. 00181 FreeBlock.AddToFreeList(FreeList); 00182 00183 // Add a marker at the end of the block, indicating the size of this free 00184 // block. 00185 FreeBlock.SetEndOfBlockSizeMarker(); 00186 return FreeListToReturn ? FreeListToReturn : &FreeBlock; 00187 } 00188 00189 /// GrowBlock - The block after this block just got deallocated. Merge it 00190 /// into the current block. 00191 void FreeRangeHeader::GrowBlock(uintptr_t NewSize) { 00192 assert(NewSize > BlockSize && "Not growing block?"); 00193 BlockSize = NewSize; 00194 SetEndOfBlockSizeMarker(); 00195 getBlockAfter().PrevAllocated = 0; 00196 } 00197 00198 /// TrimAllocationToSize - If this allocated block is significantly larger 00199 /// than NewSize, split it into two pieces (where the former is NewSize 00200 /// bytes, including the header), and add the new block to the free list. 00201 FreeRangeHeader *MemoryRangeHeader:: 00202 TrimAllocationToSize(FreeRangeHeader *FreeList, uint64_t NewSize) { 00203 assert(ThisAllocated && getBlockAfter().PrevAllocated && 00204 "Cannot deallocate part of an allocated block!"); 00205 00206 // Don't allow blocks to be trimmed below minimum required size 00207 NewSize = std::max<uint64_t>(FreeRangeHeader::getMinBlockSize(), NewSize); 00208 00209 // Round up size for alignment of header. 00210 unsigned HeaderAlign = __alignof(FreeRangeHeader); 00211 NewSize = (NewSize+ (HeaderAlign-1)) & ~(HeaderAlign-1); 00212 00213 // Size is now the size of the block we will remove from the start of the 00214 // current block. 00215 assert(NewSize <= BlockSize && 00216 "Allocating more space from this block than exists!"); 00217 00218 // If splitting this block will cause the remainder to be too small, do not 00219 // split the block. 00220 if (BlockSize <= NewSize+FreeRangeHeader::getMinBlockSize()) 00221 return FreeList; 00222 00223 // Otherwise, we splice the required number of bytes out of this block, form 00224 // a new block immediately after it, then mark this block allocated. 00225 MemoryRangeHeader &FormerNextBlock = getBlockAfter(); 00226 00227 // Change the size of this block. 00228 BlockSize = NewSize; 00229 00230 // Get the new block we just sliced out and turn it into a free block. 00231 FreeRangeHeader &NewNextBlock = (FreeRangeHeader &)getBlockAfter(); 00232 NewNextBlock.BlockSize = (char*)&FormerNextBlock - (char*)&NewNextBlock; 00233 NewNextBlock.ThisAllocated = 0; 00234 NewNextBlock.PrevAllocated = 1; 00235 NewNextBlock.SetEndOfBlockSizeMarker(); 00236 FormerNextBlock.PrevAllocated = 0; 00237 NewNextBlock.AddToFreeList(FreeList); 00238 return &NewNextBlock; 00239 } 00240 00241 //===----------------------------------------------------------------------===// 00242 // Memory Block Implementation. 00243 //===----------------------------------------------------------------------===// 00244 00245 namespace { 00246 /// DefaultJITMemoryManager - Manage memory for the JIT code generation. 00247 /// This splits a large block of MAP_NORESERVE'd memory into two 00248 /// sections, one for function stubs, one for the functions themselves. We 00249 /// have to do this because we may need to emit a function stub while in the 00250 /// middle of emitting a function, and we don't know how large the function we 00251 /// are emitting is. 00252 class VISIBILITY_HIDDEN DefaultJITMemoryManager : public JITMemoryManager { 00253 std::vector<sys::MemoryBlock> Blocks; // Memory blocks allocated by the JIT 00254 FreeRangeHeader *FreeMemoryList; // Circular list of free blocks. 00255 00256 // When emitting code into a memory block, this is the block. 00257 MemoryRangeHeader *CurBlock; 00258 00259 unsigned char *CurStubPtr, *StubBase; 00260 unsigned char *GOTBase; // Target Specific reserved memory 00261 00262 // Centralize memory block allocation. 00263 sys::MemoryBlock getNewMemoryBlock(unsigned size); 00264 00265 std::map<const Function*, MemoryRangeHeader*> FunctionBlocks; 00266 std::map<const Function*, MemoryRangeHeader*> TableBlocks; 00267 public: 00268 DefaultJITMemoryManager(); 00269 ~DefaultJITMemoryManager(); 00270 00271 void AllocateGOT(); 00272 00273 unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize, 00274 unsigned Alignment); 00275 00276 /// startFunctionBody - When a function starts, allocate a block of free 00277 /// executable memory, returning a pointer to it and its actual size. 00278 unsigned char *startFunctionBody(const Function *F, uintptr_t &ActualSize) { 00279 CurBlock = FreeMemoryList; 00280 00281 // Allocate the entire memory block. 00282 FreeMemoryList = FreeMemoryList->AllocateBlock(); 00283 ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader); 00284 return (unsigned char *)(CurBlock+1); 00285 } 00286 00287 /// endFunctionBody - The function F is now allocated, and takes the memory 00288 /// in the range [FunctionStart,FunctionEnd). 00289 void endFunctionBody(const Function *F, unsigned char *FunctionStart, 00290 unsigned char *FunctionEnd) { 00291 assert(FunctionEnd > FunctionStart); 00292 assert(FunctionStart == (unsigned char *)(CurBlock+1) && 00293 "Mismatched function start/end!"); 00294 00295 uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock; 00296 FunctionBlocks[F] = CurBlock; 00297 00298 // Release the memory at the end of this block that isn't needed. 00299 FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 00300 } 00301 00302 /// allocateSpace - Allocate a memory block of the given size. 00303 unsigned char *allocateSpace(intptr_t Size, unsigned Alignment) { 00304 CurBlock = FreeMemoryList; 00305 FreeMemoryList = FreeMemoryList->AllocateBlock(); 00306 00307 unsigned char *result = (unsigned char *)CurBlock+1; 00308 00309 if (Alignment == 0) Alignment = 1; 00310 result = (unsigned char*)(((intptr_t)result+Alignment-1) & 00311 ~(intptr_t)(Alignment-1)); 00312 00313 uintptr_t BlockSize = result + Size - (unsigned char *)CurBlock; 00314 FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 00315 00316 return result; 00317 } 00318 00319 /// startExceptionTable - Use startFunctionBody to allocate memory for the 00320 /// function's exception table. 00321 unsigned char* startExceptionTable(const Function* F, 00322 uintptr_t &ActualSize) { 00323 return startFunctionBody(F, ActualSize); 00324 } 00325 00326 /// endExceptionTable - The exception table of F is now allocated, 00327 /// and takes the memory in the range [TableStart,TableEnd). 00328 void endExceptionTable(const Function *F, unsigned char *TableStart, 00329 unsigned char *TableEnd, 00330 unsigned char* FrameRegister) { 00331 assert(TableEnd > TableStart); 00332 assert(TableStart == (unsigned char *)(CurBlock+1) && 00333 "Mismatched table start/end!"); 00334 00335 uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock; 00336 TableBlocks[F] = CurBlock; 00337 00338 // Release the memory at the end of this block that isn't needed. 00339 FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 00340 } 00341 00342 unsigned char *getGOTBase() const { 00343 return GOTBase; 00344 } 00345 00346 /// deallocateMemForFunction - Deallocate all memory for the specified 00347 /// function body. 00348 void deallocateMemForFunction(const Function *F) { 00349 std::map<const Function*, MemoryRangeHeader*>::iterator 00350 I = FunctionBlocks.find(F); 00351 if (I == FunctionBlocks.end()) return; 00352 00353 // Find the block that is allocated for this function. 00354 MemoryRangeHeader *MemRange = I->second; 00355 assert(MemRange->ThisAllocated && "Block isn't allocated!"); 00356 00357 // Fill the buffer with garbage! 00358 #ifndef NDEBUG 00359 memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange)); 00360 #endif 00361 00362 // Free the memory. 00363 FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); 00364 00365 // Finally, remove this entry from FunctionBlocks. 00366 FunctionBlocks.erase(I); 00367 00368 I = TableBlocks.find(F); 00369 if (I == TableBlocks.end()) return; 00370 00371 // Find the block that is allocated for this function. 00372 MemRange = I->second; 00373 assert(MemRange->ThisAllocated && "Block isn't allocated!"); 00374 00375 // Fill the buffer with garbage! 00376 #ifndef NDEBUG 00377 memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange)); 00378 #endif 00379 00380 // Free the memory. 00381 FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); 00382 00383 // Finally, remove this entry from TableBlocks. 00384 TableBlocks.erase(I); 00385 } 00386 00387 /// setMemoryWritable - When code generation is in progress, 00388 /// the code pages may need permissions changed. 00389 void setMemoryWritable(void) 00390 { 00391 for (unsigned i = 0, e = Blocks.size(); i != e; ++i) 00392 sys::Memory::setWritable(Blocks[i]); 00393 } 00394 /// setMemoryExecutable - When code generation is done and we're ready to 00395 /// start execution, the code pages may need permissions changed. 00396 void setMemoryExecutable(void) 00397 { 00398 for (unsigned i = 0, e = Blocks.size(); i != e; ++i) 00399 sys::Memory::setExecutable(Blocks[i]); 00400 } 00401 }; 00402 } 00403 00404 DefaultJITMemoryManager::DefaultJITMemoryManager() { 00405 // Allocate a 16M block of memory for functions. 00406 #if defined(__APPLE__) && defined(__arm__) 00407 sys::MemoryBlock MemBlock = getNewMemoryBlock(4 << 20); 00408 #else 00409 sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20); 00410 #endif 00411 00412 unsigned char *MemBase = static_cast<unsigned char*>(MemBlock.base()); 00413 00414 // Allocate stubs backwards from the base, allocate functions forward 00415 // from the base. 00416 StubBase = MemBase; 00417 CurStubPtr = MemBase + 512*1024; // Use 512k for stubs, working backwards. 00418 00419 // We set up the memory chunk with 4 mem regions, like this: 00420 // [ START 00421 // [ Free #0 ] -> Large space to allocate functions from. 00422 // [ Allocated #1 ] -> Tiny space to separate regions. 00423 // [ Free #2 ] -> Tiny space so there is always at least 1 free block. 00424 // [ Allocated #3 ] -> Tiny space to prevent looking past end of block. 00425 // END ] 00426 // 00427 // The last three blocks are never deallocated or touched. 00428 00429 // Add MemoryRangeHeader to the end of the memory region, indicating that 00430 // the space after the block of memory is allocated. This is block #3. 00431 MemoryRangeHeader *Mem3 = (MemoryRangeHeader*)(MemBase+MemBlock.size())-1; 00432 Mem3->ThisAllocated = 1; 00433 Mem3->PrevAllocated = 0; 00434 Mem3->BlockSize = 0; 00435 00436 /// Add a tiny free region so that the free list always has one entry. 00437 FreeRangeHeader *Mem2 = 00438 (FreeRangeHeader *)(((char*)Mem3)-FreeRangeHeader::getMinBlockSize()); 00439 Mem2->ThisAllocated = 0; 00440 Mem2->PrevAllocated = 1; 00441 Mem2->BlockSize = FreeRangeHeader::getMinBlockSize(); 00442 Mem2->SetEndOfBlockSizeMarker(); 00443 Mem2->Prev = Mem2; // Mem2 *is* the free list for now. 00444 Mem2->Next = Mem2; 00445 00446 /// Add a tiny allocated region so that Mem2 is never coalesced away. 00447 MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; 00448 Mem1->ThisAllocated = 1; 00449 Mem1->PrevAllocated = 0; 00450 Mem1->BlockSize = (char*)Mem2 - (char*)Mem1; 00451 00452 // Add a FreeRangeHeader to the start of the function body region, indicating 00453 // that the space is free. Mark the previous block allocated so we never look 00454 // at it. 00455 FreeRangeHeader *Mem0 = (FreeRangeHeader*)CurStubPtr; 00456 Mem0->ThisAllocated = 0; 00457 Mem0->PrevAllocated = 1; 00458 Mem0->BlockSize = (char*)Mem1-(char*)Mem0; 00459 Mem0->SetEndOfBlockSizeMarker(); 00460 Mem0->AddToFreeList(Mem2); 00461 00462 // Start out with the freelist pointing to Mem0. 00463 FreeMemoryList = Mem0; 00464 00465 GOTBase = NULL; 00466 } 00467 00468 void DefaultJITMemoryManager::AllocateGOT() { 00469 assert(GOTBase == 0 && "Cannot allocate the got multiple times"); 00470 GOTBase = new unsigned char[sizeof(void*) * 8192]; 00471 HasGOT = true; 00472 } 00473 00474 00475 DefaultJITMemoryManager::~DefaultJITMemoryManager() { 00476 for (unsigned i = 0, e = Blocks.size(); i != e; ++i) 00477 sys::Memory::ReleaseRWX(Blocks[i]); 00478 00479 delete[] GOTBase; 00480 Blocks.clear(); 00481 } 00482 00483 unsigned char *DefaultJITMemoryManager::allocateStub(const GlobalValue* F, 00484 unsigned StubSize, 00485 unsigned Alignment) { 00486 CurStubPtr -= StubSize; 00487 CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) & 00488 ~(intptr_t)(Alignment-1)); 00489 if (CurStubPtr < StubBase) { 00490 // FIXME: allocate a new block 00491 fprintf(stderr, "JIT ran out of memory for function stubs!\n"); 00492 abort(); 00493 } 00494 return CurStubPtr; 00495 } 00496 00497 sys::MemoryBlock DefaultJITMemoryManager::getNewMemoryBlock(unsigned size) { 00498 // Allocate a new block close to the last one. 00499 const sys::MemoryBlock *BOld = Blocks.empty() ? 0 : &Blocks.front(); 00500 std::string ErrMsg; 00501 sys::MemoryBlock B = sys::Memory::AllocateRWX(size, BOld, &ErrMsg); 00502 if (B.base() == 0) { 00503 fprintf(stderr, 00504 "Allocation failed when allocating new memory in the JIT\n%s\n", 00505 ErrMsg.c_str()); 00506 abort(); 00507 } 00508 Blocks.push_back(B); 00509 return B; 00510 } 00511 00512 00513 JITMemoryManager *JITMemoryManager::CreateDefaultMemManager() { 00514 return new DefaultJITMemoryManager(); 00515 }