Home | History | Annotate | Download | only in MCJIT
      1 //===-- MCJIT.h - Class definition for the MCJIT ----------------*- C++ -*-===//
      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 #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
     11 #define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/ADT/SmallPtrSet.h"
     15 #include "llvm/ADT/SmallVector.h"
     16 #include "llvm/ExecutionEngine/ExecutionEngine.h"
     17 #include "llvm/ExecutionEngine/ObjectCache.h"
     18 #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
     19 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
     20 #include "llvm/ExecutionEngine/RuntimeDyld.h"
     21 #include "llvm/IR/Module.h"
     22 
     23 namespace llvm {
     24 class MCJIT;
     25 
     26 // This is a helper class that the MCJIT execution engine uses for linking
     27 // functions across modules that it owns.  It aggregates the memory manager
     28 // that is passed in to the MCJIT constructor and defers most functionality
     29 // to that object.
     30 class LinkingSymbolResolver : public RuntimeDyld::SymbolResolver {
     31 public:
     32   LinkingSymbolResolver(MCJIT &Parent,
     33                         std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver)
     34     : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
     35 
     36   RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override;
     37 
     38   // MCJIT doesn't support logical dylibs.
     39   RuntimeDyld::SymbolInfo
     40   findSymbolInLogicalDylib(const std::string &Name) override {
     41     return nullptr;
     42   }
     43 
     44 private:
     45   MCJIT &ParentEngine;
     46   std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
     47 };
     48 
     49 // About Module states: added->loaded->finalized.
     50 //
     51 // The purpose of the "added" state is having modules in standby. (added=known
     52 // but not compiled). The idea is that you can add a module to provide function
     53 // definitions but if nothing in that module is referenced by a module in which
     54 // a function is executed (note the wording here because it's not exactly the
     55 // ideal case) then the module never gets compiled. This is sort of lazy
     56 // compilation.
     57 //
     58 // The purpose of the "loaded" state (loaded=compiled and required sections
     59 // copied into local memory but not yet ready for execution) is to have an
     60 // intermediate state wherein clients can remap the addresses of sections, using
     61 // MCJIT::mapSectionAddress, (in preparation for later copying to a new location
     62 // or an external process) before relocations and page permissions are applied.
     63 //
     64 // It might not be obvious at first glance, but the "remote-mcjit" case in the
     65 // lli tool does this.  In that case, the intermediate action is taken by the
     66 // RemoteMemoryManager in response to the notifyObjectLoaded function being
     67 // called.
     68 
     69 class MCJIT : public ExecutionEngine {
     70   MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
     71         std::shared_ptr<MCJITMemoryManager> MemMgr,
     72         std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver);
     73 
     74   typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
     75 
     76   class OwningModuleContainer {
     77   public:
     78     OwningModuleContainer() {
     79     }
     80     ~OwningModuleContainer() {
     81       freeModulePtrSet(AddedModules);
     82       freeModulePtrSet(LoadedModules);
     83       freeModulePtrSet(FinalizedModules);
     84     }
     85 
     86     ModulePtrSet::iterator begin_added() { return AddedModules.begin(); }
     87     ModulePtrSet::iterator end_added() { return AddedModules.end(); }
     88     iterator_range<ModulePtrSet::iterator> added() {
     89       return iterator_range<ModulePtrSet::iterator>(begin_added(), end_added());
     90     }
     91 
     92     ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); }
     93     ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); }
     94 
     95     ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
     96     ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
     97 
     98     void addModule(std::unique_ptr<Module> M) {
     99       AddedModules.insert(M.release());
    100     }
    101 
    102     bool removeModule(Module *M) {
    103       return AddedModules.erase(M) || LoadedModules.erase(M) ||
    104              FinalizedModules.erase(M);
    105     }
    106 
    107     bool hasModuleBeenAddedButNotLoaded(Module *M) {
    108       return AddedModules.count(M) != 0;
    109     }
    110 
    111     bool hasModuleBeenLoaded(Module *M) {
    112       // If the module is in either the "loaded" or "finalized" sections it
    113       // has been loaded.
    114       return (LoadedModules.count(M) != 0 ) || (FinalizedModules.count(M) != 0);
    115     }
    116 
    117     bool hasModuleBeenFinalized(Module *M) {
    118       return FinalizedModules.count(M) != 0;
    119     }
    120 
    121     bool ownsModule(Module* M) {
    122       return (AddedModules.count(M) != 0) || (LoadedModules.count(M) != 0) ||
    123              (FinalizedModules.count(M) != 0);
    124     }
    125 
    126     void markModuleAsLoaded(Module *M) {
    127       // This checks against logic errors in the MCJIT implementation.
    128       // This function should never be called with either a Module that MCJIT
    129       // does not own or a Module that has already been loaded and/or finalized.
    130       assert(AddedModules.count(M) &&
    131              "markModuleAsLoaded: Module not found in AddedModules");
    132 
    133       // Remove the module from the "Added" set.
    134       AddedModules.erase(M);
    135 
    136       // Add the Module to the "Loaded" set.
    137       LoadedModules.insert(M);
    138     }
    139 
    140     void markModuleAsFinalized(Module *M) {
    141       // This checks against logic errors in the MCJIT implementation.
    142       // This function should never be called with either a Module that MCJIT
    143       // does not own, a Module that has not been loaded or a Module that has
    144       // already been finalized.
    145       assert(LoadedModules.count(M) &&
    146              "markModuleAsFinalized: Module not found in LoadedModules");
    147 
    148       // Remove the module from the "Loaded" section of the list.
    149       LoadedModules.erase(M);
    150 
    151       // Add the Module to the "Finalized" section of the list by inserting it
    152       // before the 'end' iterator.
    153       FinalizedModules.insert(M);
    154     }
    155 
    156     void markAllLoadedModulesAsFinalized() {
    157       for (ModulePtrSet::iterator I = LoadedModules.begin(),
    158                                   E = LoadedModules.end();
    159            I != E; ++I) {
    160         Module *M = *I;
    161         FinalizedModules.insert(M);
    162       }
    163       LoadedModules.clear();
    164     }
    165 
    166   private:
    167     ModulePtrSet AddedModules;
    168     ModulePtrSet LoadedModules;
    169     ModulePtrSet FinalizedModules;
    170 
    171     void freeModulePtrSet(ModulePtrSet& MPS) {
    172       // Go through the module set and delete everything.
    173       for (ModulePtrSet::iterator I = MPS.begin(), E = MPS.end(); I != E; ++I) {
    174         Module *M = *I;
    175         delete M;
    176       }
    177       MPS.clear();
    178     }
    179   };
    180 
    181   std::unique_ptr<TargetMachine> TM;
    182   MCContext *Ctx;
    183   std::shared_ptr<MCJITMemoryManager> MemMgr;
    184   LinkingSymbolResolver Resolver;
    185   RuntimeDyld Dyld;
    186   std::vector<JITEventListener*> EventListeners;
    187 
    188   OwningModuleContainer OwnedModules;
    189 
    190   SmallVector<object::OwningBinary<object::Archive>, 2> Archives;
    191   SmallVector<std::unique_ptr<MemoryBuffer>, 2> Buffers;
    192 
    193   SmallVector<std::unique_ptr<object::ObjectFile>, 2> LoadedObjects;
    194 
    195   // An optional ObjectCache to be notified of compiled objects and used to
    196   // perform lookup of pre-compiled code to avoid re-compilation.
    197   ObjectCache *ObjCache;
    198 
    199   Function *FindFunctionNamedInModulePtrSet(const char *FnName,
    200                                             ModulePtrSet::iterator I,
    201                                             ModulePtrSet::iterator E);
    202 
    203   void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
    204                                                       ModulePtrSet::iterator I,
    205                                                       ModulePtrSet::iterator E);
    206 
    207 public:
    208   ~MCJIT() override;
    209 
    210   /// @name ExecutionEngine interface implementation
    211   /// @{
    212   void addModule(std::unique_ptr<Module> M) override;
    213   void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
    214   void addObjectFile(object::OwningBinary<object::ObjectFile> O) override;
    215   void addArchive(object::OwningBinary<object::Archive> O) override;
    216   bool removeModule(Module *M) override;
    217 
    218   /// FindFunctionNamed - Search all of the active modules to find the one that
    219   /// defines FnName.  This is very slow operation and shouldn't be used for
    220   /// general code.
    221   Function *FindFunctionNamed(const char *FnName) override;
    222 
    223   /// Sets the object manager that MCJIT should use to avoid compilation.
    224   void setObjectCache(ObjectCache *manager) override;
    225 
    226   void setProcessAllSections(bool ProcessAllSections) override {
    227     Dyld.setProcessAllSections(ProcessAllSections);
    228   }
    229 
    230   void generateCodeForModule(Module *M) override;
    231 
    232   /// finalizeObject - ensure the module is fully processed and is usable.
    233   ///
    234   /// It is the user-level function for completing the process of making the
    235   /// object usable for execution. It should be called after sections within an
    236   /// object have been relocated using mapSectionAddress.  When this method is
    237   /// called the MCJIT execution engine will reapply relocations for a loaded
    238   /// object.
    239   /// Is it OK to finalize a set of modules, add modules and finalize again.
    240   // FIXME: Do we really need both of these?
    241   void finalizeObject() override;
    242   virtual void finalizeModule(Module *);
    243   void finalizeLoadedModules();
    244 
    245   /// runStaticConstructorsDestructors - This method is used to execute all of
    246   /// the static constructors or destructors for a program.
    247   ///
    248   /// \param isDtors - Run the destructors instead of constructors.
    249   void runStaticConstructorsDestructors(bool isDtors) override;
    250 
    251   void *getPointerToFunction(Function *F) override;
    252 
    253   GenericValue runFunction(Function *F,
    254                            const std::vector<GenericValue> &ArgValues) override;
    255 
    256   /// getPointerToNamedFunction - This method returns the address of the
    257   /// specified function by using the dlsym function call.  As such it is only
    258   /// useful for resolving library symbols, not code generated symbols.
    259   ///
    260   /// If AbortOnFailure is false and no function with the given name is
    261   /// found, this function silently returns a null pointer. Otherwise,
    262   /// it prints a message to stderr and aborts.
    263   ///
    264   void *getPointerToNamedFunction(StringRef Name,
    265                                   bool AbortOnFailure = true) override;
    266 
    267   /// mapSectionAddress - map a section to its target address space value.
    268   /// Map the address of a JIT section as returned from the memory manager
    269   /// to the address in the target process as the running code will see it.
    270   /// This is the address which will be used for relocation resolution.
    271   void mapSectionAddress(const void *LocalAddress,
    272                          uint64_t TargetAddress) override {
    273     Dyld.mapSectionAddress(LocalAddress, TargetAddress);
    274   }
    275   void RegisterJITEventListener(JITEventListener *L) override;
    276   void UnregisterJITEventListener(JITEventListener *L) override;
    277 
    278   // If successful, these function will implicitly finalize all loaded objects.
    279   // To get a function address within MCJIT without causing a finalize, use
    280   // getSymbolAddress.
    281   uint64_t getGlobalValueAddress(const std::string &Name) override;
    282   uint64_t getFunctionAddress(const std::string &Name) override;
    283 
    284   TargetMachine *getTargetMachine() override { return TM.get(); }
    285 
    286   /// @}
    287   /// @name (Private) Registration Interfaces
    288   /// @{
    289 
    290   static void Register() {
    291     MCJITCtor = createJIT;
    292   }
    293 
    294   static ExecutionEngine*
    295   createJIT(std::unique_ptr<Module> M,
    296             std::string *ErrorStr,
    297             std::shared_ptr<MCJITMemoryManager> MemMgr,
    298             std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
    299             std::unique_ptr<TargetMachine> TM);
    300 
    301   // @}
    302 
    303   RuntimeDyld::SymbolInfo findSymbol(const std::string &Name,
    304                                      bool CheckFunctionsOnly);
    305   // DEPRECATED - Please use findSymbol instead.
    306   // This is not directly exposed via the ExecutionEngine API, but it is
    307   // used by the LinkingMemoryManager.
    308   uint64_t getSymbolAddress(const std::string &Name,
    309                             bool CheckFunctionsOnly);
    310 
    311 protected:
    312   /// emitObject -- Generate a JITed object in memory from the specified module
    313   /// Currently, MCJIT only supports a single module and the module passed to
    314   /// this function call is expected to be the contained module.  The module
    315   /// is passed as a parameter here to prepare for multiple module support in
    316   /// the future.
    317   std::unique_ptr<MemoryBuffer> emitObject(Module *M);
    318 
    319   void NotifyObjectEmitted(const object::ObjectFile& Obj,
    320                            const RuntimeDyld::LoadedObjectInfo &L);
    321   void NotifyFreeingObject(const object::ObjectFile& Obj);
    322 
    323   RuntimeDyld::SymbolInfo findExistingSymbol(const std::string &Name);
    324   Module *findModuleForSymbol(const std::string &Name,
    325                               bool CheckFunctionsOnly);
    326 };
    327 
    328 } // End llvm namespace
    329 
    330 #endif
    331