Home | History | Annotate | Download | only in lli
      1 //===- RecordingMemoryManager.cpp - Recording memory manager --------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This memory manager allocates local storage and keeps a record of each
     11 // allocation. Iterators are provided for all data and code allocations.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "RecordingMemoryManager.h"
     16 using namespace llvm;
     17 
     18 RecordingMemoryManager::~RecordingMemoryManager() {
     19   for (SmallVectorImpl<Allocation>::iterator
     20          I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();
     21        I != E; ++I)
     22     sys::Memory::releaseMappedMemory(I->first);
     23   for (SmallVectorImpl<Allocation>::iterator
     24          I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();
     25        I != E; ++I)
     26     sys::Memory::releaseMappedMemory(I->first);
     27 }
     28 
     29 uint8_t *RecordingMemoryManager::
     30 allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
     31   // The recording memory manager is just a local copy of the remote target.
     32   // The alignment requirement is just stored here for later use. Regular
     33   // heap storage is sufficient here, but we're using mapped memory to work
     34   // around a bug in MCJIT.
     35   sys::MemoryBlock Block = allocateSection(Size);
     36   AllocatedCodeMem.push_back(Allocation(Block, Alignment));
     37   return (uint8_t*)Block.base();
     38 }
     39 
     40 uint8_t *RecordingMemoryManager::
     41 allocateDataSection(uintptr_t Size, unsigned Alignment,
     42                     unsigned SectionID, bool IsReadOnly) {
     43   // The recording memory manager is just a local copy of the remote target.
     44   // The alignment requirement is just stored here for later use. Regular
     45   // heap storage is sufficient here, but we're using mapped memory to work
     46   // around a bug in MCJIT.
     47   sys::MemoryBlock Block = allocateSection(Size);
     48   AllocatedDataMem.push_back(Allocation(Block, Alignment));
     49   return (uint8_t*)Block.base();
     50 }
     51 
     52 sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) {
     53   error_code ec;
     54   sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size,
     55                                                           &Near,
     56                                                           sys::Memory::MF_READ |
     57                                                           sys::Memory::MF_WRITE,
     58                                                           ec);
     59   assert(!ec && MB.base());
     60 
     61   // FIXME: This is part of a work around to keep sections near one another
     62   // when MCJIT performs relocations after code emission but before
     63   // the generated code is moved to the remote target.
     64   // Save this address as the basis for our next request
     65   Near = MB;
     66   return MB;
     67 }
     68 
     69 void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); }
     70 void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); }
     71 void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); }
     72 void RecordingMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); }
     73 uint8_t *RecordingMemoryManager::getGOTBase() const {
     74   llvm_unreachable("Unexpected!");
     75   return 0;
     76 }
     77 uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){
     78   llvm_unreachable("Unexpected!");
     79   return 0;
     80 }
     81 uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
     82                                               unsigned Alignment) {
     83   llvm_unreachable("Unexpected!");
     84   return 0;
     85 }
     86 void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart,
     87                                              uint8_t *FunctionEnd) {
     88   llvm_unreachable("Unexpected!");
     89 }
     90 uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {
     91   llvm_unreachable("Unexpected!");
     92   return 0;
     93 }
     94 uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {
     95   llvm_unreachable("Unexpected!");
     96   return 0;
     97 }
     98 void RecordingMemoryManager::deallocateFunctionBody(void *Body) {
     99   llvm_unreachable("Unexpected!");
    100 }
    101 
    102 static int jit_noop() {
    103   return 0;
    104 }
    105 
    106 void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name,
    107                                                         bool AbortOnFailure) {
    108   // We should not invoke parent's ctors/dtors from generated main()!
    109   // On Mingw and Cygwin, the symbol __main is resolved to
    110   // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
    111   // (and register wrong callee's dtors with atexit(3)).
    112   // We expect ExecutionEngine::runStaticConstructorsDestructors()
    113   // is called before ExecutionEngine::runFunctionAsMain() is called.
    114   if (Name == "__main") return (void*)(intptr_t)&jit_noop;
    115 
    116   return NULL;
    117 }
    118