1193323Sed//===-- JITMemoryManager.cpp - Memory Allocator for JIT'd code ------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines the DefaultJITMemoryManager class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14198090Srdivacky#define DEBUG_TYPE "jit" 15198090Srdivacky#include "llvm/ExecutionEngine/JITMemoryManager.h" 16198090Srdivacky#include "llvm/ADT/SmallPtrSet.h" 17198090Srdivacky#include "llvm/ADT/Statistic.h" 18207618Srdivacky#include "llvm/ADT/Twine.h" 19252723Sdim#include "llvm/Config/config.h" 20252723Sdim#include "llvm/IR/GlobalValue.h" 21198090Srdivacky#include "llvm/Support/Allocator.h" 22193323Sed#include "llvm/Support/Compiler.h" 23198090Srdivacky#include "llvm/Support/Debug.h" 24252723Sdim#include "llvm/Support/DynamicLibrary.h" 25198090Srdivacky#include "llvm/Support/ErrorHandling.h" 26252723Sdim#include "llvm/Support/Memory.h" 27198090Srdivacky#include "llvm/Support/raw_ostream.h" 28193323Sed#include <cassert> 29193323Sed#include <climits> 30193323Sed#include <cstring> 31252723Sdim#include <vector> 32235633Sdim 33235633Sdim#if defined(__linux__) 34235633Sdim#if defined(HAVE_SYS_STAT_H) 35235633Sdim#include <sys/stat.h> 36235633Sdim#endif 37235633Sdim#include <fcntl.h> 38235633Sdim#include <unistd.h> 39235633Sdim#endif 40235633Sdim 41193323Sedusing namespace llvm; 42193323Sed 43198090SrdivackySTATISTIC(NumSlabs, "Number of slabs of memory allocated by the JIT"); 44193323Sed 45193323SedJITMemoryManager::~JITMemoryManager() {} 46193323Sed 47193323Sed//===----------------------------------------------------------------------===// 48193323Sed// Memory Block Implementation. 49193323Sed//===----------------------------------------------------------------------===// 50193323Sed 51193323Sednamespace { 52193323Sed /// MemoryRangeHeader - For a range of memory, this is the header that we put 53193323Sed /// on the block of memory. It is carefully crafted to be one word of memory. 54193323Sed /// Allocated blocks have just this header, free'd blocks have FreeRangeHeader 55193323Sed /// which starts with this. 56193323Sed struct FreeRangeHeader; 57193323Sed struct MemoryRangeHeader { 58193323Sed /// ThisAllocated - This is true if this block is currently allocated. If 59193323Sed /// not, this can be converted to a FreeRangeHeader. 60193323Sed unsigned ThisAllocated : 1; 61199481Srdivacky 62193323Sed /// PrevAllocated - Keep track of whether the block immediately before us is 63193323Sed /// allocated. If not, the word immediately before this header is the size 64193323Sed /// of the previous block. 65193323Sed unsigned PrevAllocated : 1; 66199481Srdivacky 67193323Sed /// BlockSize - This is the size in bytes of this memory block, 68193323Sed /// including this header. 69193323Sed uintptr_t BlockSize : (sizeof(intptr_t)*CHAR_BIT - 2); 70193323Sed 71199481Srdivacky 72193323Sed /// getBlockAfter - Return the memory block immediately after this one. 73193323Sed /// 74193323Sed MemoryRangeHeader &getBlockAfter() const { 75252723Sdim return *reinterpret_cast<MemoryRangeHeader *>( 76252723Sdim reinterpret_cast<char*>( 77252723Sdim const_cast<MemoryRangeHeader *>(this))+BlockSize); 78193323Sed } 79199481Srdivacky 80193323Sed /// getFreeBlockBefore - If the block before this one is free, return it, 81193323Sed /// otherwise return null. 82193323Sed FreeRangeHeader *getFreeBlockBefore() const { 83193323Sed if (PrevAllocated) return 0; 84252723Sdim intptr_t PrevSize = reinterpret_cast<intptr_t *>( 85252723Sdim const_cast<MemoryRangeHeader *>(this))[-1]; 86252723Sdim return reinterpret_cast<FreeRangeHeader *>( 87252723Sdim reinterpret_cast<char*>( 88252723Sdim const_cast<MemoryRangeHeader *>(this))-PrevSize); 89193323Sed } 90199481Srdivacky 91193323Sed /// FreeBlock - Turn an allocated block into a free block, adjusting 92193323Sed /// bits in the object headers, and adding an end of region memory block. 93193323Sed FreeRangeHeader *FreeBlock(FreeRangeHeader *FreeList); 94199481Srdivacky 95193323Sed /// TrimAllocationToSize - If this allocated block is significantly larger 96193323Sed /// than NewSize, split it into two pieces (where the former is NewSize 97193323Sed /// bytes, including the header), and add the new block to the free list. 98199481Srdivacky FreeRangeHeader *TrimAllocationToSize(FreeRangeHeader *FreeList, 99193323Sed uint64_t NewSize); 100193323Sed }; 101193323Sed 102193323Sed /// FreeRangeHeader - For a memory block that isn't already allocated, this 103193323Sed /// keeps track of the current block and has a pointer to the next free block. 104193323Sed /// Free blocks are kept on a circularly linked list. 105193323Sed struct FreeRangeHeader : public MemoryRangeHeader { 106193323Sed FreeRangeHeader *Prev; 107193323Sed FreeRangeHeader *Next; 108199481Srdivacky 109193323Sed /// getMinBlockSize - Get the minimum size for a memory block. Blocks 110193323Sed /// smaller than this size cannot be created. 111193323Sed static unsigned getMinBlockSize() { 112193323Sed return sizeof(FreeRangeHeader)+sizeof(intptr_t); 113193323Sed } 114199481Srdivacky 115193323Sed /// SetEndOfBlockSizeMarker - The word at the end of every free block is 116193323Sed /// known to be the size of the free block. Set it for this block. 117193323Sed void SetEndOfBlockSizeMarker() { 118193323Sed void *EndOfBlock = (char*)this + BlockSize; 119193323Sed ((intptr_t *)EndOfBlock)[-1] = BlockSize; 120193323Sed } 121193323Sed 122193323Sed FreeRangeHeader *RemoveFromFreeList() { 123193323Sed assert(Next->Prev == this && Prev->Next == this && "Freelist broken!"); 124193323Sed Next->Prev = Prev; 125193323Sed return Prev->Next = Next; 126193323Sed } 127199481Srdivacky 128193323Sed void AddToFreeList(FreeRangeHeader *FreeList) { 129193323Sed Next = FreeList; 130193323Sed Prev = FreeList->Prev; 131193323Sed Prev->Next = this; 132193323Sed Next->Prev = this; 133193323Sed } 134193323Sed 135193323Sed /// GrowBlock - The block after this block just got deallocated. Merge it 136193323Sed /// into the current block. 137193323Sed void GrowBlock(uintptr_t NewSize); 138199481Srdivacky 139193323Sed /// AllocateBlock - Mark this entire block allocated, updating freelists 140193323Sed /// etc. This returns a pointer to the circular free-list. 141193323Sed FreeRangeHeader *AllocateBlock(); 142193323Sed }; 143193323Sed} 144193323Sed 145193323Sed 146193323Sed/// AllocateBlock - Mark this entire block allocated, updating freelists 147193323Sed/// etc. This returns a pointer to the circular free-list. 148193323SedFreeRangeHeader *FreeRangeHeader::AllocateBlock() { 149193323Sed assert(!ThisAllocated && !getBlockAfter().PrevAllocated && 150193323Sed "Cannot allocate an allocated block!"); 151193323Sed // Mark this block allocated. 152193323Sed ThisAllocated = 1; 153193323Sed getBlockAfter().PrevAllocated = 1; 154199481Srdivacky 155193323Sed // Remove it from the free list. 156193323Sed return RemoveFromFreeList(); 157193323Sed} 158193323Sed 159193323Sed/// FreeBlock - Turn an allocated block into a free block, adjusting 160193323Sed/// bits in the object headers, and adding an end of region memory block. 161193323Sed/// If possible, coalesce this block with neighboring blocks. Return the 162193323Sed/// FreeRangeHeader to allocate from. 163193323SedFreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) { 164193323Sed MemoryRangeHeader *FollowingBlock = &getBlockAfter(); 165198090Srdivacky assert(ThisAllocated && "This block is already free!"); 166193323Sed assert(FollowingBlock->PrevAllocated && "Flags out of sync!"); 167199481Srdivacky 168193323Sed FreeRangeHeader *FreeListToReturn = FreeList; 169199481Srdivacky 170193323Sed // If the block after this one is free, merge it into this block. 171193323Sed if (!FollowingBlock->ThisAllocated) { 172193323Sed FreeRangeHeader &FollowingFreeBlock = *(FreeRangeHeader *)FollowingBlock; 173193323Sed // "FreeList" always needs to be a valid free block. If we're about to 174193323Sed // coalesce with it, update our notion of what the free list is. 175193323Sed if (&FollowingFreeBlock == FreeList) { 176193323Sed FreeList = FollowingFreeBlock.Next; 177193323Sed FreeListToReturn = 0; 178193323Sed assert(&FollowingFreeBlock != FreeList && "No tombstone block?"); 179193323Sed } 180193323Sed FollowingFreeBlock.RemoveFromFreeList(); 181199481Srdivacky 182193323Sed // Include the following block into this one. 183193323Sed BlockSize += FollowingFreeBlock.BlockSize; 184193323Sed FollowingBlock = &FollowingFreeBlock.getBlockAfter(); 185199481Srdivacky 186193323Sed // Tell the block after the block we are coalescing that this block is 187193323Sed // allocated. 188193323Sed FollowingBlock->PrevAllocated = 1; 189193323Sed } 190199481Srdivacky 191193323Sed assert(FollowingBlock->ThisAllocated && "Missed coalescing?"); 192199481Srdivacky 193193323Sed if (FreeRangeHeader *PrevFreeBlock = getFreeBlockBefore()) { 194193323Sed PrevFreeBlock->GrowBlock(PrevFreeBlock->BlockSize + BlockSize); 195193323Sed return FreeListToReturn ? FreeListToReturn : PrevFreeBlock; 196193323Sed } 197193323Sed 198193323Sed // Otherwise, mark this block free. 199193323Sed FreeRangeHeader &FreeBlock = *(FreeRangeHeader*)this; 200193323Sed FollowingBlock->PrevAllocated = 0; 201193323Sed FreeBlock.ThisAllocated = 0; 202193323Sed 203193323Sed // Link this into the linked list of free blocks. 204193323Sed FreeBlock.AddToFreeList(FreeList); 205193323Sed 206193323Sed // Add a marker at the end of the block, indicating the size of this free 207193323Sed // block. 208193323Sed FreeBlock.SetEndOfBlockSizeMarker(); 209193323Sed return FreeListToReturn ? FreeListToReturn : &FreeBlock; 210193323Sed} 211193323Sed 212193323Sed/// GrowBlock - The block after this block just got deallocated. Merge it 213193323Sed/// into the current block. 214193323Sedvoid FreeRangeHeader::GrowBlock(uintptr_t NewSize) { 215193323Sed assert(NewSize > BlockSize && "Not growing block?"); 216193323Sed BlockSize = NewSize; 217193323Sed SetEndOfBlockSizeMarker(); 218193323Sed getBlockAfter().PrevAllocated = 0; 219193323Sed} 220193323Sed 221193323Sed/// TrimAllocationToSize - If this allocated block is significantly larger 222193323Sed/// than NewSize, split it into two pieces (where the former is NewSize 223193323Sed/// bytes, including the header), and add the new block to the free list. 224193323SedFreeRangeHeader *MemoryRangeHeader:: 225193323SedTrimAllocationToSize(FreeRangeHeader *FreeList, uint64_t NewSize) { 226193323Sed assert(ThisAllocated && getBlockAfter().PrevAllocated && 227193323Sed "Cannot deallocate part of an allocated block!"); 228193323Sed 229193323Sed // Don't allow blocks to be trimmed below minimum required size 230193323Sed NewSize = std::max<uint64_t>(FreeRangeHeader::getMinBlockSize(), NewSize); 231193323Sed 232193323Sed // Round up size for alignment of header. 233193323Sed unsigned HeaderAlign = __alignof(FreeRangeHeader); 234193323Sed NewSize = (NewSize+ (HeaderAlign-1)) & ~(HeaderAlign-1); 235199481Srdivacky 236193323Sed // Size is now the size of the block we will remove from the start of the 237193323Sed // current block. 238193323Sed assert(NewSize <= BlockSize && 239193323Sed "Allocating more space from this block than exists!"); 240199481Srdivacky 241193323Sed // If splitting this block will cause the remainder to be too small, do not 242193323Sed // split the block. 243193323Sed if (BlockSize <= NewSize+FreeRangeHeader::getMinBlockSize()) 244193323Sed return FreeList; 245199481Srdivacky 246193323Sed // Otherwise, we splice the required number of bytes out of this block, form 247193323Sed // a new block immediately after it, then mark this block allocated. 248193323Sed MemoryRangeHeader &FormerNextBlock = getBlockAfter(); 249199481Srdivacky 250193323Sed // Change the size of this block. 251193323Sed BlockSize = NewSize; 252199481Srdivacky 253193323Sed // Get the new block we just sliced out and turn it into a free block. 254193323Sed FreeRangeHeader &NewNextBlock = (FreeRangeHeader &)getBlockAfter(); 255193323Sed NewNextBlock.BlockSize = (char*)&FormerNextBlock - (char*)&NewNextBlock; 256193323Sed NewNextBlock.ThisAllocated = 0; 257193323Sed NewNextBlock.PrevAllocated = 1; 258193323Sed NewNextBlock.SetEndOfBlockSizeMarker(); 259193323Sed FormerNextBlock.PrevAllocated = 0; 260193323Sed NewNextBlock.AddToFreeList(FreeList); 261193323Sed return &NewNextBlock; 262193323Sed} 263193323Sed 264193323Sed//===----------------------------------------------------------------------===// 265193323Sed// Memory Block Implementation. 266193323Sed//===----------------------------------------------------------------------===// 267193323Sed 268198090Srdivackynamespace { 269198090Srdivacky 270198090Srdivacky class DefaultJITMemoryManager; 271198090Srdivacky 272198090Srdivacky class JITSlabAllocator : public SlabAllocator { 273198090Srdivacky DefaultJITMemoryManager &JMM; 274198090Srdivacky public: 275198090Srdivacky JITSlabAllocator(DefaultJITMemoryManager &jmm) : JMM(jmm) { } 276198090Srdivacky virtual ~JITSlabAllocator() { } 277198090Srdivacky virtual MemSlab *Allocate(size_t Size); 278198090Srdivacky virtual void Deallocate(MemSlab *Slab); 279198090Srdivacky }; 280198090Srdivacky 281193323Sed /// DefaultJITMemoryManager - Manage memory for the JIT code generation. 282193323Sed /// This splits a large block of MAP_NORESERVE'd memory into two 283193323Sed /// sections, one for function stubs, one for the functions themselves. We 284193323Sed /// have to do this because we may need to emit a function stub while in the 285193323Sed /// middle of emitting a function, and we don't know how large the function we 286193323Sed /// are emitting is. 287198090Srdivacky class DefaultJITMemoryManager : public JITMemoryManager { 288198090Srdivacky 289198090Srdivacky // Whether to poison freed memory. 290198090Srdivacky bool PoisonMemory; 291198090Srdivacky 292198090Srdivacky /// LastSlab - This points to the last slab allocated and is used as the 293198090Srdivacky /// NearBlock parameter to AllocateRWX so that we can attempt to lay out all 294198090Srdivacky /// stubs, data, and code contiguously in memory. In general, however, this 295198090Srdivacky /// is not possible because the NearBlock parameter is ignored on Windows 296198090Srdivacky /// platforms and even on Unix it works on a best-effort pasis. 297198090Srdivacky sys::MemoryBlock LastSlab; 298198090Srdivacky 299198090Srdivacky // Memory slabs allocated by the JIT. We refer to them as slabs so we don't 300199481Srdivacky // confuse them with the blocks of memory described above. 301198090Srdivacky std::vector<sys::MemoryBlock> CodeSlabs; 302198090Srdivacky JITSlabAllocator BumpSlabAllocator; 303198090Srdivacky BumpPtrAllocator StubAllocator; 304198090Srdivacky BumpPtrAllocator DataAllocator; 305198090Srdivacky 306198090Srdivacky // Circular list of free blocks. 307198090Srdivacky FreeRangeHeader *FreeMemoryList; 308198090Srdivacky 309193323Sed // When emitting code into a memory block, this is the block. 310193323Sed MemoryRangeHeader *CurBlock; 311198090Srdivacky 312193574Sed uint8_t *GOTBase; // Target Specific reserved memory 313193323Sed public: 314193323Sed DefaultJITMemoryManager(); 315193323Sed ~DefaultJITMemoryManager(); 316193323Sed 317198090Srdivacky /// allocateNewSlab - Allocates a new MemoryBlock and remembers it as the 318198090Srdivacky /// last slab it allocated, so that subsequent allocations follow it. 319198090Srdivacky sys::MemoryBlock allocateNewSlab(size_t size); 320198090Srdivacky 321198090Srdivacky /// DefaultCodeSlabSize - When we have to go map more memory, we allocate at 322198090Srdivacky /// least this much unless more is requested. 323198090Srdivacky static const size_t DefaultCodeSlabSize; 324198090Srdivacky 325198090Srdivacky /// DefaultSlabSize - Allocate data into slabs of this size unless we get 326198090Srdivacky /// an allocation above SizeThreshold. 327198090Srdivacky static const size_t DefaultSlabSize; 328198090Srdivacky 329198090Srdivacky /// DefaultSizeThreshold - For any allocation larger than this threshold, we 330198090Srdivacky /// should allocate a separate slab. 331198090Srdivacky static const size_t DefaultSizeThreshold; 332198090Srdivacky 333235633Sdim /// getPointerToNamedFunction - This method returns the address of the 334235633Sdim /// specified function by using the dlsym function call. 335235633Sdim virtual void *getPointerToNamedFunction(const std::string &Name, 336235633Sdim bool AbortOnFailure = true); 337235633Sdim 338193323Sed void AllocateGOT(); 339198090Srdivacky 340198090Srdivacky // Testing methods. 341198090Srdivacky virtual bool CheckInvariants(std::string &ErrorStr); 342198090Srdivacky size_t GetDefaultCodeSlabSize() { return DefaultCodeSlabSize; } 343198090Srdivacky size_t GetDefaultDataSlabSize() { return DefaultSlabSize; } 344198090Srdivacky size_t GetDefaultStubSlabSize() { return DefaultSlabSize; } 345198090Srdivacky unsigned GetNumCodeSlabs() { return CodeSlabs.size(); } 346198090Srdivacky unsigned GetNumDataSlabs() { return DataAllocator.GetNumSlabs(); } 347198090Srdivacky unsigned GetNumStubSlabs() { return StubAllocator.GetNumSlabs(); } 348198090Srdivacky 349193323Sed /// startFunctionBody - When a function starts, allocate a block of free 350193323Sed /// executable memory, returning a pointer to it and its actual size. 351193574Sed uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize) { 352198090Srdivacky 353193323Sed FreeRangeHeader* candidateBlock = FreeMemoryList; 354193323Sed FreeRangeHeader* head = FreeMemoryList; 355193323Sed FreeRangeHeader* iter = head->Next; 356193323Sed 357193323Sed uintptr_t largest = candidateBlock->BlockSize; 358198090Srdivacky 359193323Sed // Search for the largest free block 360193323Sed while (iter != head) { 361198090Srdivacky if (iter->BlockSize > largest) { 362198090Srdivacky largest = iter->BlockSize; 363198090Srdivacky candidateBlock = iter; 364198090Srdivacky } 365198090Srdivacky iter = iter->Next; 366193323Sed } 367198090Srdivacky 368198090Srdivacky largest = largest - sizeof(MemoryRangeHeader); 369199481Srdivacky 370198090Srdivacky // If this block isn't big enough for the allocation desired, allocate 371198090Srdivacky // another block of memory and add it to the free list. 372198090Srdivacky if (largest < ActualSize || 373198090Srdivacky largest <= FreeRangeHeader::getMinBlockSize()) { 374202375Srdivacky DEBUG(dbgs() << "JIT: Allocating another slab of memory for function."); 375198090Srdivacky candidateBlock = allocateNewCodeSlab((size_t)ActualSize); 376198090Srdivacky } 377198090Srdivacky 378193323Sed // Select this candidate block for allocation 379193323Sed CurBlock = candidateBlock; 380193323Sed 381193323Sed // Allocate the entire memory block. 382193323Sed FreeMemoryList = candidateBlock->AllocateBlock(); 383198090Srdivacky ActualSize = CurBlock->BlockSize - sizeof(MemoryRangeHeader); 384198090Srdivacky return (uint8_t *)(CurBlock + 1); 385193323Sed } 386198090Srdivacky 387198090Srdivacky /// allocateNewCodeSlab - Helper method to allocate a new slab of code 388198090Srdivacky /// memory from the OS and add it to the free list. Returns the new 389198090Srdivacky /// FreeRangeHeader at the base of the slab. 390198090Srdivacky FreeRangeHeader *allocateNewCodeSlab(size_t MinSize) { 391198090Srdivacky // If the user needs at least MinSize free memory, then we account for 392198090Srdivacky // two MemoryRangeHeaders: the one in the user's block, and the one at the 393198090Srdivacky // end of the slab. 394198090Srdivacky size_t PaddedMin = MinSize + 2 * sizeof(MemoryRangeHeader); 395198090Srdivacky size_t SlabSize = std::max(DefaultCodeSlabSize, PaddedMin); 396198090Srdivacky sys::MemoryBlock B = allocateNewSlab(SlabSize); 397198090Srdivacky CodeSlabs.push_back(B); 398198090Srdivacky char *MemBase = (char*)(B.base()); 399198090Srdivacky 400198090Srdivacky // Put a tiny allocated block at the end of the memory chunk, so when 401198090Srdivacky // FreeBlock calls getBlockAfter it doesn't fall off the end. 402198090Srdivacky MemoryRangeHeader *EndBlock = 403198090Srdivacky (MemoryRangeHeader*)(MemBase + B.size()) - 1; 404198090Srdivacky EndBlock->ThisAllocated = 1; 405198090Srdivacky EndBlock->PrevAllocated = 0; 406198090Srdivacky EndBlock->BlockSize = sizeof(MemoryRangeHeader); 407198090Srdivacky 408198090Srdivacky // Start out with a vast new block of free memory. 409198090Srdivacky FreeRangeHeader *NewBlock = (FreeRangeHeader*)MemBase; 410198090Srdivacky NewBlock->ThisAllocated = 0; 411198090Srdivacky // Make sure getFreeBlockBefore doesn't look into unmapped memory. 412198090Srdivacky NewBlock->PrevAllocated = 1; 413198090Srdivacky NewBlock->BlockSize = (uintptr_t)EndBlock - (uintptr_t)NewBlock; 414198090Srdivacky NewBlock->SetEndOfBlockSizeMarker(); 415198090Srdivacky NewBlock->AddToFreeList(FreeMemoryList); 416198090Srdivacky 417198090Srdivacky assert(NewBlock->BlockSize - sizeof(MemoryRangeHeader) >= MinSize && 418198090Srdivacky "The block was too small!"); 419198090Srdivacky return NewBlock; 420198090Srdivacky } 421198090Srdivacky 422193323Sed /// endFunctionBody - The function F is now allocated, and takes the memory 423193323Sed /// in the range [FunctionStart,FunctionEnd). 424193574Sed void endFunctionBody(const Function *F, uint8_t *FunctionStart, 425193574Sed uint8_t *FunctionEnd) { 426193323Sed assert(FunctionEnd > FunctionStart); 427193574Sed assert(FunctionStart == (uint8_t *)(CurBlock+1) && 428193323Sed "Mismatched function start/end!"); 429193323Sed 430193574Sed uintptr_t BlockSize = FunctionEnd - (uint8_t *)CurBlock; 431193323Sed 432193323Sed // Release the memory at the end of this block that isn't needed. 433193323Sed FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 434193323Sed } 435193323Sed 436198090Srdivacky /// allocateSpace - Allocate a memory block of the given size. This method 437198090Srdivacky /// cannot be called between calls to startFunctionBody and endFunctionBody. 438193574Sed uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { 439193323Sed CurBlock = FreeMemoryList; 440193323Sed FreeMemoryList = FreeMemoryList->AllocateBlock(); 441193323Sed 442198090Srdivacky uint8_t *result = (uint8_t *)(CurBlock + 1); 443193323Sed 444193323Sed if (Alignment == 0) Alignment = 1; 445193574Sed result = (uint8_t*)(((intptr_t)result+Alignment-1) & 446193323Sed ~(intptr_t)(Alignment-1)); 447193323Sed 448193574Sed uintptr_t BlockSize = result + Size - (uint8_t *)CurBlock; 449193323Sed FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize); 450193323Sed 451193323Sed return result; 452193323Sed } 453193323Sed 454198090Srdivacky /// allocateStub - Allocate memory for a function stub. 455198090Srdivacky uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, 456198090Srdivacky unsigned Alignment) { 457198090Srdivacky return (uint8_t*)StubAllocator.Allocate(StubSize, Alignment); 458198090Srdivacky } 459198090Srdivacky 460198090Srdivacky /// allocateGlobal - Allocate memory for a global. 461198090Srdivacky uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { 462198090Srdivacky return (uint8_t*)DataAllocator.Allocate(Size, Alignment); 463198090Srdivacky } 464198090Srdivacky 465235633Sdim /// allocateCodeSection - Allocate memory for a code section. 466235633Sdim uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 467263509Sdim unsigned SectionID, StringRef SectionName) { 468245431Sdim // Grow the required block size to account for the block header 469245431Sdim Size += sizeof(*CurBlock); 470245431Sdim 471263509Sdim // Alignment handling. 472263509Sdim if (!Alignment) 473263509Sdim Alignment = 16; 474263509Sdim Size += Alignment - 1; 475263509Sdim 476235633Sdim FreeRangeHeader* candidateBlock = FreeMemoryList; 477235633Sdim FreeRangeHeader* head = FreeMemoryList; 478235633Sdim FreeRangeHeader* iter = head->Next; 479235633Sdim 480235633Sdim uintptr_t largest = candidateBlock->BlockSize; 481235633Sdim 482235633Sdim // Search for the largest free block. 483235633Sdim while (iter != head) { 484235633Sdim if (iter->BlockSize > largest) { 485235633Sdim largest = iter->BlockSize; 486235633Sdim candidateBlock = iter; 487235633Sdim } 488235633Sdim iter = iter->Next; 489235633Sdim } 490235633Sdim 491235633Sdim largest = largest - sizeof(MemoryRangeHeader); 492235633Sdim 493235633Sdim // If this block isn't big enough for the allocation desired, allocate 494235633Sdim // another block of memory and add it to the free list. 495235633Sdim if (largest < Size || largest <= FreeRangeHeader::getMinBlockSize()) { 496235633Sdim DEBUG(dbgs() << "JIT: Allocating another slab of memory for function."); 497235633Sdim candidateBlock = allocateNewCodeSlab((size_t)Size); 498235633Sdim } 499235633Sdim 500235633Sdim // Select this candidate block for allocation 501235633Sdim CurBlock = candidateBlock; 502235633Sdim 503235633Sdim // Allocate the entire memory block. 504235633Sdim FreeMemoryList = candidateBlock->AllocateBlock(); 505235633Sdim // Release the memory at the end of this block that isn't needed. 506235633Sdim FreeMemoryList = CurBlock->TrimAllocationToSize(FreeMemoryList, Size); 507263509Sdim uintptr_t unalignedAddr = (uintptr_t)CurBlock + sizeof(*CurBlock); 508263509Sdim return (uint8_t*)RoundUpToAlignment((uint64_t)unalignedAddr, Alignment); 509235633Sdim } 510235633Sdim 511235633Sdim /// allocateDataSection - Allocate memory for a data section. 512235633Sdim uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 513263509Sdim unsigned SectionID, StringRef SectionName, 514263509Sdim bool IsReadOnly) { 515235633Sdim return (uint8_t*)DataAllocator.Allocate(Size, Alignment); 516235633Sdim } 517235633Sdim 518263509Sdim bool finalizeMemory(std::string *ErrMsg) { 519252723Sdim return false; 520252723Sdim } 521252723Sdim 522193574Sed uint8_t *getGOTBase() const { 523193323Sed return GOTBase; 524193323Sed } 525199481Srdivacky 526198396Srdivacky void deallocateBlock(void *Block) { 527193323Sed // Find the block that is allocated for this function. 528198396Srdivacky MemoryRangeHeader *MemRange = static_cast<MemoryRangeHeader*>(Block) - 1; 529193323Sed assert(MemRange->ThisAllocated && "Block isn't allocated!"); 530198090Srdivacky 531193323Sed // Fill the buffer with garbage! 532198090Srdivacky if (PoisonMemory) { 533198090Srdivacky memset(MemRange+1, 0xCD, MemRange->BlockSize-sizeof(*MemRange)); 534198090Srdivacky } 535198090Srdivacky 536193323Sed // Free the memory. 537193323Sed FreeMemoryList = MemRange->FreeBlock(FreeMemoryList); 538198396Srdivacky } 539198090Srdivacky 540198396Srdivacky /// deallocateFunctionBody - Deallocate all memory for the specified 541198396Srdivacky /// function body. 542198396Srdivacky void deallocateFunctionBody(void *Body) { 543198396Srdivacky if (Body) deallocateBlock(Body); 544198396Srdivacky } 545198090Srdivacky 546193323Sed /// setMemoryWritable - When code generation is in progress, 547193323Sed /// the code pages may need permissions changed. 548198090Srdivacky void setMemoryWritable() 549193323Sed { 550198090Srdivacky for (unsigned i = 0, e = CodeSlabs.size(); i != e; ++i) 551198090Srdivacky sys::Memory::setWritable(CodeSlabs[i]); 552193323Sed } 553193323Sed /// setMemoryExecutable - When code generation is done and we're ready to 554193323Sed /// start execution, the code pages may need permissions changed. 555198090Srdivacky void setMemoryExecutable() 556193323Sed { 557198090Srdivacky for (unsigned i = 0, e = CodeSlabs.size(); i != e; ++i) 558198090Srdivacky sys::Memory::setExecutable(CodeSlabs[i]); 559193323Sed } 560198090Srdivacky 561198090Srdivacky /// setPoisonMemory - Controls whether we write garbage over freed memory. 562198090Srdivacky /// 563198090Srdivacky void setPoisonMemory(bool poison) { 564198090Srdivacky PoisonMemory = poison; 565198090Srdivacky } 566193323Sed }; 567193323Sed} 568193323Sed 569198090SrdivackyMemSlab *JITSlabAllocator::Allocate(size_t Size) { 570198090Srdivacky sys::MemoryBlock B = JMM.allocateNewSlab(Size); 571198090Srdivacky MemSlab *Slab = (MemSlab*)B.base(); 572198090Srdivacky Slab->Size = B.size(); 573198090Srdivacky Slab->NextPtr = 0; 574198090Srdivacky return Slab; 575198090Srdivacky} 576198090Srdivacky 577198090Srdivackyvoid JITSlabAllocator::Deallocate(MemSlab *Slab) { 578198090Srdivacky sys::MemoryBlock B(Slab, Slab->Size); 579198090Srdivacky sys::Memory::ReleaseRWX(B); 580198090Srdivacky} 581198090Srdivacky 582198090SrdivackyDefaultJITMemoryManager::DefaultJITMemoryManager() 583198090Srdivacky : 584198090Srdivacky#ifdef NDEBUG 585198090Srdivacky PoisonMemory(false), 586193323Sed#else 587198090Srdivacky PoisonMemory(true), 588193323Sed#endif 589198090Srdivacky LastSlab(0, 0), 590198090Srdivacky BumpSlabAllocator(*this), 591198090Srdivacky StubAllocator(DefaultSlabSize, DefaultSizeThreshold, BumpSlabAllocator), 592198090Srdivacky DataAllocator(DefaultSlabSize, DefaultSizeThreshold, BumpSlabAllocator) { 593193323Sed 594198090Srdivacky // Allocate space for code. 595198090Srdivacky sys::MemoryBlock MemBlock = allocateNewSlab(DefaultCodeSlabSize); 596198090Srdivacky CodeSlabs.push_back(MemBlock); 597198090Srdivacky uint8_t *MemBase = (uint8_t*)MemBlock.base(); 598193323Sed 599193323Sed // We set up the memory chunk with 4 mem regions, like this: 600193323Sed // [ START 601193323Sed // [ Free #0 ] -> Large space to allocate functions from. 602193323Sed // [ Allocated #1 ] -> Tiny space to separate regions. 603193323Sed // [ Free #2 ] -> Tiny space so there is always at least 1 free block. 604193323Sed // [ Allocated #3 ] -> Tiny space to prevent looking past end of block. 605193323Sed // END ] 606193323Sed // 607193323Sed // The last three blocks are never deallocated or touched. 608199481Srdivacky 609193323Sed // Add MemoryRangeHeader to the end of the memory region, indicating that 610193323Sed // the space after the block of memory is allocated. This is block #3. 611193323Sed MemoryRangeHeader *Mem3 = (MemoryRangeHeader*)(MemBase+MemBlock.size())-1; 612193323Sed Mem3->ThisAllocated = 1; 613193323Sed Mem3->PrevAllocated = 0; 614198090Srdivacky Mem3->BlockSize = sizeof(MemoryRangeHeader); 615199481Srdivacky 616193323Sed /// Add a tiny free region so that the free list always has one entry. 617199481Srdivacky FreeRangeHeader *Mem2 = 618193323Sed (FreeRangeHeader *)(((char*)Mem3)-FreeRangeHeader::getMinBlockSize()); 619193323Sed Mem2->ThisAllocated = 0; 620193323Sed Mem2->PrevAllocated = 1; 621193323Sed Mem2->BlockSize = FreeRangeHeader::getMinBlockSize(); 622193323Sed Mem2->SetEndOfBlockSizeMarker(); 623193323Sed Mem2->Prev = Mem2; // Mem2 *is* the free list for now. 624193323Sed Mem2->Next = Mem2; 625193323Sed 626193323Sed /// Add a tiny allocated region so that Mem2 is never coalesced away. 627193323Sed MemoryRangeHeader *Mem1 = (MemoryRangeHeader*)Mem2-1; 628193323Sed Mem1->ThisAllocated = 1; 629193323Sed Mem1->PrevAllocated = 0; 630198090Srdivacky Mem1->BlockSize = sizeof(MemoryRangeHeader); 631199481Srdivacky 632193323Sed // Add a FreeRangeHeader to the start of the function body region, indicating 633193323Sed // that the space is free. Mark the previous block allocated so we never look 634193323Sed // at it. 635198090Srdivacky FreeRangeHeader *Mem0 = (FreeRangeHeader*)MemBase; 636193323Sed Mem0->ThisAllocated = 0; 637193323Sed Mem0->PrevAllocated = 1; 638193323Sed Mem0->BlockSize = (char*)Mem1-(char*)Mem0; 639193323Sed Mem0->SetEndOfBlockSizeMarker(); 640193323Sed Mem0->AddToFreeList(Mem2); 641199481Srdivacky 642193323Sed // Start out with the freelist pointing to Mem0. 643193323Sed FreeMemoryList = Mem0; 644193323Sed 645193323Sed GOTBase = NULL; 646193323Sed} 647193323Sed 648193323Sedvoid DefaultJITMemoryManager::AllocateGOT() { 649193323Sed assert(GOTBase == 0 && "Cannot allocate the got multiple times"); 650193574Sed GOTBase = new uint8_t[sizeof(void*) * 8192]; 651193323Sed HasGOT = true; 652193323Sed} 653193323Sed 654193323SedDefaultJITMemoryManager::~DefaultJITMemoryManager() { 655198090Srdivacky for (unsigned i = 0, e = CodeSlabs.size(); i != e; ++i) 656198090Srdivacky sys::Memory::ReleaseRWX(CodeSlabs[i]); 657198090Srdivacky 658193323Sed delete[] GOTBase; 659193323Sed} 660193323Sed 661198090Srdivackysys::MemoryBlock DefaultJITMemoryManager::allocateNewSlab(size_t size) { 662193323Sed // Allocate a new block close to the last one. 663193323Sed std::string ErrMsg; 664198090Srdivacky sys::MemoryBlock *LastSlabPtr = LastSlab.base() ? &LastSlab : 0; 665198090Srdivacky sys::MemoryBlock B = sys::Memory::AllocateRWX(size, LastSlabPtr, &ErrMsg); 666193323Sed if (B.base() == 0) { 667207618Srdivacky report_fatal_error("Allocation failed when allocating new memory in the" 668207618Srdivacky " JIT\n" + Twine(ErrMsg)); 669193323Sed } 670198090Srdivacky LastSlab = B; 671198090Srdivacky ++NumSlabs; 672198090Srdivacky // Initialize the slab to garbage when debugging. 673198090Srdivacky if (PoisonMemory) { 674198090Srdivacky memset(B.base(), 0xCD, B.size()); 675198090Srdivacky } 676193323Sed return B; 677193323Sed} 678193323Sed 679198090Srdivacky/// CheckInvariants - For testing only. Return "" if all internal invariants 680198090Srdivacky/// are preserved, and a helpful error message otherwise. For free and 681198090Srdivacky/// allocated blocks, make sure that adding BlockSize gives a valid block. 682198090Srdivacky/// For free blocks, make sure they're in the free list and that their end of 683198090Srdivacky/// block size marker is correct. This function should return an error before 684198090Srdivacky/// accessing bad memory. This function is defined here instead of in 685198090Srdivacky/// JITMemoryManagerTest.cpp so that we don't have to expose all of the 686198090Srdivacky/// implementation details of DefaultJITMemoryManager. 687198090Srdivackybool DefaultJITMemoryManager::CheckInvariants(std::string &ErrorStr) { 688198090Srdivacky raw_string_ostream Err(ErrorStr); 689193323Sed 690198090Srdivacky // Construct a the set of FreeRangeHeader pointers so we can query it 691198090Srdivacky // efficiently. 692198090Srdivacky llvm::SmallPtrSet<MemoryRangeHeader*, 16> FreeHdrSet; 693198090Srdivacky FreeRangeHeader* FreeHead = FreeMemoryList; 694198090Srdivacky FreeRangeHeader* FreeRange = FreeHead; 695198090Srdivacky 696198090Srdivacky do { 697198090Srdivacky // Check that the free range pointer is in the blocks we've allocated. 698198090Srdivacky bool Found = false; 699198090Srdivacky for (std::vector<sys::MemoryBlock>::iterator I = CodeSlabs.begin(), 700198090Srdivacky E = CodeSlabs.end(); I != E && !Found; ++I) { 701198090Srdivacky char *Start = (char*)I->base(); 702198090Srdivacky char *End = Start + I->size(); 703198090Srdivacky Found = (Start <= (char*)FreeRange && (char*)FreeRange < End); 704198090Srdivacky } 705198090Srdivacky if (!Found) { 706198090Srdivacky Err << "Corrupt free list; points to " << FreeRange; 707198090Srdivacky return false; 708198090Srdivacky } 709198090Srdivacky 710198090Srdivacky if (FreeRange->Next->Prev != FreeRange) { 711198090Srdivacky Err << "Next and Prev pointers do not match."; 712198090Srdivacky return false; 713198090Srdivacky } 714198090Srdivacky 715198090Srdivacky // Otherwise, add it to the set. 716198090Srdivacky FreeHdrSet.insert(FreeRange); 717198090Srdivacky FreeRange = FreeRange->Next; 718198090Srdivacky } while (FreeRange != FreeHead); 719198090Srdivacky 720198090Srdivacky // Go over each block, and look at each MemoryRangeHeader. 721198090Srdivacky for (std::vector<sys::MemoryBlock>::iterator I = CodeSlabs.begin(), 722198090Srdivacky E = CodeSlabs.end(); I != E; ++I) { 723198090Srdivacky char *Start = (char*)I->base(); 724198090Srdivacky char *End = Start + I->size(); 725198090Srdivacky 726198090Srdivacky // Check each memory range. 727198090Srdivacky for (MemoryRangeHeader *Hdr = (MemoryRangeHeader*)Start, *LastHdr = NULL; 728198090Srdivacky Start <= (char*)Hdr && (char*)Hdr < End; 729198090Srdivacky Hdr = &Hdr->getBlockAfter()) { 730198090Srdivacky if (Hdr->ThisAllocated == 0) { 731198090Srdivacky // Check that this range is in the free list. 732198090Srdivacky if (!FreeHdrSet.count(Hdr)) { 733198090Srdivacky Err << "Found free header at " << Hdr << " that is not in free list."; 734198090Srdivacky return false; 735198090Srdivacky } 736198090Srdivacky 737198090Srdivacky // Now make sure the size marker at the end of the block is correct. 738198090Srdivacky uintptr_t *Marker = ((uintptr_t*)&Hdr->getBlockAfter()) - 1; 739198090Srdivacky if (!(Start <= (char*)Marker && (char*)Marker < End)) { 740198090Srdivacky Err << "Block size in header points out of current MemoryBlock."; 741198090Srdivacky return false; 742198090Srdivacky } 743198090Srdivacky if (Hdr->BlockSize != *Marker) { 744198090Srdivacky Err << "End of block size marker (" << *Marker << ") " 745198090Srdivacky << "and BlockSize (" << Hdr->BlockSize << ") don't match."; 746198090Srdivacky return false; 747198090Srdivacky } 748198090Srdivacky } 749198090Srdivacky 750198090Srdivacky if (LastHdr && LastHdr->ThisAllocated != Hdr->PrevAllocated) { 751198090Srdivacky Err << "Hdr->PrevAllocated (" << Hdr->PrevAllocated << ") != " 752198090Srdivacky << "LastHdr->ThisAllocated (" << LastHdr->ThisAllocated << ")"; 753198090Srdivacky return false; 754198090Srdivacky } else if (!LastHdr && !Hdr->PrevAllocated) { 755198090Srdivacky Err << "The first header should have PrevAllocated true."; 756198090Srdivacky return false; 757198090Srdivacky } 758198090Srdivacky 759198090Srdivacky // Remember the last header. 760198090Srdivacky LastHdr = Hdr; 761198090Srdivacky } 762198090Srdivacky } 763198090Srdivacky 764198090Srdivacky // All invariants are preserved. 765198090Srdivacky return true; 766198090Srdivacky} 767198090Srdivacky 768235633Sdim//===----------------------------------------------------------------------===// 769235633Sdim// getPointerToNamedFunction() implementation. 770235633Sdim//===----------------------------------------------------------------------===// 771235633Sdim 772235633Sdim// AtExitHandlers - List of functions to call when the program exits, 773235633Sdim// registered with the atexit() library function. 774235633Sdimstatic std::vector<void (*)()> AtExitHandlers; 775235633Sdim 776235633Sdim/// runAtExitHandlers - Run any functions registered by the program's 777235633Sdim/// calls to atexit(3), which we intercept and store in 778235633Sdim/// AtExitHandlers. 779235633Sdim/// 780235633Sdimstatic void runAtExitHandlers() { 781235633Sdim while (!AtExitHandlers.empty()) { 782235633Sdim void (*Fn)() = AtExitHandlers.back(); 783235633Sdim AtExitHandlers.pop_back(); 784235633Sdim Fn(); 785235633Sdim } 786235633Sdim} 787235633Sdim 788235633Sdim//===----------------------------------------------------------------------===// 789235633Sdim// Function stubs that are invoked instead of certain library calls 790235633Sdim// 791235633Sdim// Force the following functions to be linked in to anything that uses the 792235633Sdim// JIT. This is a hack designed to work around the all-too-clever Glibc 793235633Sdim// strategy of making these functions work differently when inlined vs. when 794235633Sdim// not inlined, and hiding their real definitions in a separate archive file 795235633Sdim// that the dynamic linker can't see. For more info, search for 796235633Sdim// 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. 797263509Sdim#if defined(__linux__) && defined(__GLIBC__) 798235633Sdim/* stat functions are redirecting to __xstat with a version number. On x86-64 799235633Sdim * linking with libc_nonshared.a and -Wl,--export-dynamic doesn't make 'stat' 800235633Sdim * available as an exported symbol, so we have to add it explicitly. 801235633Sdim */ 802235633Sdimnamespace { 803235633Sdimclass StatSymbols { 804235633Sdimpublic: 805235633Sdim StatSymbols() { 806235633Sdim sys::DynamicLibrary::AddSymbol("stat", (void*)(intptr_t)stat); 807235633Sdim sys::DynamicLibrary::AddSymbol("fstat", (void*)(intptr_t)fstat); 808235633Sdim sys::DynamicLibrary::AddSymbol("lstat", (void*)(intptr_t)lstat); 809235633Sdim sys::DynamicLibrary::AddSymbol("stat64", (void*)(intptr_t)stat64); 810235633Sdim sys::DynamicLibrary::AddSymbol("\x1stat64", (void*)(intptr_t)stat64); 811235633Sdim sys::DynamicLibrary::AddSymbol("\x1open64", (void*)(intptr_t)open64); 812235633Sdim sys::DynamicLibrary::AddSymbol("\x1lseek64", (void*)(intptr_t)lseek64); 813235633Sdim sys::DynamicLibrary::AddSymbol("fstat64", (void*)(intptr_t)fstat64); 814235633Sdim sys::DynamicLibrary::AddSymbol("lstat64", (void*)(intptr_t)lstat64); 815235633Sdim sys::DynamicLibrary::AddSymbol("atexit", (void*)(intptr_t)atexit); 816235633Sdim sys::DynamicLibrary::AddSymbol("mknod", (void*)(intptr_t)mknod); 817235633Sdim } 818235633Sdim}; 819235633Sdim} 820235633Sdimstatic StatSymbols initStatSymbols; 821235633Sdim#endif // __linux__ 822235633Sdim 823235633Sdim// jit_exit - Used to intercept the "exit" library call. 824235633Sdimstatic void jit_exit(int Status) { 825235633Sdim runAtExitHandlers(); // Run atexit handlers... 826235633Sdim exit(Status); 827235633Sdim} 828235633Sdim 829235633Sdim// jit_atexit - Used to intercept the "atexit" library call. 830235633Sdimstatic int jit_atexit(void (*Fn)()) { 831235633Sdim AtExitHandlers.push_back(Fn); // Take note of atexit handler... 832235633Sdim return 0; // Always successful 833235633Sdim} 834235633Sdim 835235633Sdimstatic int jit_noop() { 836235633Sdim return 0; 837235633Sdim} 838235633Sdim 839235633Sdim//===----------------------------------------------------------------------===// 840235633Sdim// 841235633Sdim/// getPointerToNamedFunction - This method returns the address of the specified 842235633Sdim/// function by using the dynamic loader interface. As such it is only useful 843235633Sdim/// for resolving library symbols, not code generated symbols. 844235633Sdim/// 845235633Sdimvoid *DefaultJITMemoryManager::getPointerToNamedFunction(const std::string &Name, 846245431Sdim bool AbortOnFailure) { 847235633Sdim // Check to see if this is one of the functions we want to intercept. Note, 848235633Sdim // we cast to intptr_t here to silence a -pedantic warning that complains 849235633Sdim // about casting a function pointer to a normal pointer. 850235633Sdim if (Name == "exit") return (void*)(intptr_t)&jit_exit; 851235633Sdim if (Name == "atexit") return (void*)(intptr_t)&jit_atexit; 852235633Sdim 853235633Sdim // We should not invoke parent's ctors/dtors from generated main()! 854235633Sdim // On Mingw and Cygwin, the symbol __main is resolved to 855235633Sdim // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors 856235633Sdim // (and register wrong callee's dtors with atexit(3)). 857235633Sdim // We expect ExecutionEngine::runStaticConstructorsDestructors() 858235633Sdim // is called before ExecutionEngine::runFunctionAsMain() is called. 859235633Sdim if (Name == "__main") return (void*)(intptr_t)&jit_noop; 860235633Sdim 861235633Sdim const char *NameStr = Name.c_str(); 862235633Sdim // If this is an asm specifier, skip the sentinal. 863235633Sdim if (NameStr[0] == 1) ++NameStr; 864235633Sdim 865235633Sdim // If it's an external function, look it up in the process image... 866235633Sdim void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); 867235633Sdim if (Ptr) return Ptr; 868235633Sdim 869235633Sdim // If it wasn't found and if it starts with an underscore ('_') character, 870235633Sdim // try again without the underscore. 871235633Sdim if (NameStr[0] == '_') { 872235633Sdim Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); 873235633Sdim if (Ptr) return Ptr; 874235633Sdim } 875235633Sdim 876235633Sdim // Darwin/PPC adds $LDBLStub suffixes to various symbols like printf. These 877235633Sdim // are references to hidden visibility symbols that dlsym cannot resolve. 878235633Sdim // If we have one of these, strip off $LDBLStub and try again. 879235633Sdim#if defined(__APPLE__) && defined(__ppc__) 880235633Sdim if (Name.size() > 9 && Name[Name.size()-9] == '$' && 881235633Sdim memcmp(&Name[Name.size()-8], "LDBLStub", 8) == 0) { 882235633Sdim // First try turning $LDBLStub into $LDBL128. If that fails, strip it off. 883235633Sdim // This mirrors logic in libSystemStubs.a. 884235633Sdim std::string Prefix = std::string(Name.begin(), Name.end()-9); 885235633Sdim if (void *Ptr = getPointerToNamedFunction(Prefix+"$LDBL128", false)) 886235633Sdim return Ptr; 887235633Sdim if (void *Ptr = getPointerToNamedFunction(Prefix, false)) 888235633Sdim return Ptr; 889235633Sdim } 890235633Sdim#endif 891235633Sdim 892235633Sdim if (AbortOnFailure) { 893235633Sdim report_fatal_error("Program used external function '"+Name+ 894235633Sdim "' which could not be resolved!"); 895235633Sdim } 896235633Sdim return 0; 897235633Sdim} 898235633Sdim 899235633Sdim 900235633Sdim 901193323SedJITMemoryManager *JITMemoryManager::CreateDefaultMemManager() { 902193323Sed return new DefaultJITMemoryManager(); 903193323Sed} 904198090Srdivacky 905198090Srdivacky// Allocate memory for code in 512K slabs. 906198090Srdivackyconst size_t DefaultJITMemoryManager::DefaultCodeSlabSize = 512 * 1024; 907198090Srdivacky 908198090Srdivacky// Allocate globals and stubs in slabs of 64K. (probably 16 pages) 909198090Srdivackyconst size_t DefaultJITMemoryManager::DefaultSlabSize = 64 * 1024; 910198090Srdivacky 911198090Srdivacky// Waste at most 16K at the end of each bump slab. (probably 4 pages) 912198090Srdivackyconst size_t DefaultJITMemoryManager::DefaultSizeThreshold = 16 * 1024; 913