LLVM API Documentation

JITMemoryManager.cpp

Go to the documentation of this file.
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 }