1218885Sdim//===-- MCJIT.h - Class definition for the MCJIT ----------------*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim 10218885Sdim#ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_H 11218885Sdim#define LLVM_LIB_EXECUTIONENGINE_MCJIT_H 12218885Sdim 13263509Sdim#include "llvm/ADT/DenseMap.h" 14263509Sdim#include "llvm/ADT/SmallPtrSet.h" 15245431Sdim#include "llvm/ADT/SmallVector.h" 16218885Sdim#include "llvm/ExecutionEngine/ExecutionEngine.h" 17252723Sdim#include "llvm/ExecutionEngine/ObjectCache.h" 18263509Sdim#include "llvm/ExecutionEngine/ObjectImage.h" 19221345Sdim#include "llvm/ExecutionEngine/RuntimeDyld.h" 20263509Sdim#include "llvm/IR/Module.h" 21218885Sdim 22218885Sdimnamespace llvm { 23263509Sdimclass MCJIT; 24218885Sdim 25263509Sdim// This is a helper class that the MCJIT execution engine uses for linking 26263509Sdim// functions across modules that it owns. It aggregates the memory manager 27263509Sdim// that is passed in to the MCJIT constructor and defers most functionality 28263509Sdim// to that object. 29263509Sdimclass LinkingMemoryManager : public RTDyldMemoryManager { 30263509Sdimpublic: 31263509Sdim LinkingMemoryManager(MCJIT *Parent, RTDyldMemoryManager *MM) 32263509Sdim : ParentEngine(Parent), ClientMM(MM) {} 33245431Sdim 34263509Sdim virtual uint64_t getSymbolAddress(const std::string &Name); 35221345Sdim 36263509Sdim // Functions deferred to client memory manager 37263509Sdim virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 38263509Sdim unsigned SectionID, StringRef SectionName) { 39263509Sdim return ClientMM->allocateCodeSection(Size, Alignment, SectionID, SectionName); 40263509Sdim } 41263509Sdim 42263509Sdim virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 43263509Sdim unsigned SectionID, StringRef SectionName, 44263509Sdim bool IsReadOnly) { 45263509Sdim return ClientMM->allocateDataSection(Size, Alignment, 46263509Sdim SectionID, SectionName, IsReadOnly); 47263509Sdim } 48263509Sdim 49263509Sdim virtual void notifyObjectLoaded(ExecutionEngine *EE, 50263509Sdim const ObjectImage *Obj) { 51263509Sdim ClientMM->notifyObjectLoaded(EE, Obj); 52263509Sdim } 53263509Sdim 54263509Sdim virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { 55263509Sdim ClientMM->registerEHFrames(Addr, LoadAddr, Size); 56263509Sdim } 57263509Sdim 58263509Sdim virtual void deregisterEHFrames(uint8_t *Addr, 59263509Sdim uint64_t LoadAddr, 60263509Sdim size_t Size) { 61263509Sdim ClientMM->deregisterEHFrames(Addr, LoadAddr, Size); 62263509Sdim } 63263509Sdim 64263509Sdim virtual bool finalizeMemory(std::string *ErrMsg = 0) { 65263509Sdim return ClientMM->finalizeMemory(ErrMsg); 66263509Sdim } 67263509Sdim 68263509Sdimprivate: 69263509Sdim MCJIT *ParentEngine; 70263509Sdim OwningPtr<RTDyldMemoryManager> ClientMM; 71263509Sdim}; 72263509Sdim 73263509Sdim// About Module states: added->loaded->finalized. 74263509Sdim// 75263509Sdim// The purpose of the "added" state is having modules in standby. (added=known 76263509Sdim// but not compiled). The idea is that you can add a module to provide function 77263509Sdim// definitions but if nothing in that module is referenced by a module in which 78263509Sdim// a function is executed (note the wording here because it's not exactly the 79263509Sdim// ideal case) then the module never gets compiled. This is sort of lazy 80263509Sdim// compilation. 81263509Sdim// 82263509Sdim// The purpose of the "loaded" state (loaded=compiled and required sections 83263509Sdim// copied into local memory but not yet ready for execution) is to have an 84263509Sdim// intermediate state wherein clients can remap the addresses of sections, using 85263509Sdim// MCJIT::mapSectionAddress, (in preparation for later copying to a new location 86263509Sdim// or an external process) before relocations and page permissions are applied. 87263509Sdim// 88263509Sdim// It might not be obvious at first glance, but the "remote-mcjit" case in the 89263509Sdim// lli tool does this. In that case, the intermediate action is taken by the 90263509Sdim// RemoteMemoryManager in response to the notifyObjectLoaded function being 91263509Sdim// called. 92263509Sdim 93218885Sdimclass MCJIT : public ExecutionEngine { 94245431Sdim MCJIT(Module *M, TargetMachine *tm, RTDyldMemoryManager *MemMgr, 95245431Sdim bool AllocateGVsWithCode); 96221345Sdim 97263509Sdim typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet; 98263509Sdim 99263509Sdim class OwningModuleContainer { 100263509Sdim public: 101263509Sdim OwningModuleContainer() { 102263509Sdim } 103263509Sdim ~OwningModuleContainer() { 104263509Sdim freeModulePtrSet(AddedModules); 105263509Sdim freeModulePtrSet(LoadedModules); 106263509Sdim freeModulePtrSet(FinalizedModules); 107263509Sdim } 108263509Sdim 109263509Sdim ModulePtrSet::iterator begin_added() { return AddedModules.begin(); } 110263509Sdim ModulePtrSet::iterator end_added() { return AddedModules.end(); } 111263509Sdim 112263509Sdim ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); } 113263509Sdim ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); } 114263509Sdim 115263509Sdim ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); } 116263509Sdim ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); } 117263509Sdim 118263509Sdim void addModule(Module *M) { 119263509Sdim AddedModules.insert(M); 120263509Sdim } 121263509Sdim 122263509Sdim bool removeModule(Module *M) { 123263509Sdim return AddedModules.erase(M) || LoadedModules.erase(M) || 124263509Sdim FinalizedModules.erase(M); 125263509Sdim } 126263509Sdim 127263509Sdim bool hasModuleBeenAddedButNotLoaded(Module *M) { 128263509Sdim return AddedModules.count(M) != 0; 129263509Sdim } 130263509Sdim 131263509Sdim bool hasModuleBeenLoaded(Module *M) { 132263509Sdim // If the module is in either the "loaded" or "finalized" sections it 133263509Sdim // has been loaded. 134263509Sdim return (LoadedModules.count(M) != 0 ) || (FinalizedModules.count(M) != 0); 135263509Sdim } 136263509Sdim 137263509Sdim bool hasModuleBeenFinalized(Module *M) { 138263509Sdim return FinalizedModules.count(M) != 0; 139263509Sdim } 140263509Sdim 141263509Sdim bool ownsModule(Module* M) { 142263509Sdim return (AddedModules.count(M) != 0) || (LoadedModules.count(M) != 0) || 143263509Sdim (FinalizedModules.count(M) != 0); 144263509Sdim } 145263509Sdim 146263509Sdim void markModuleAsLoaded(Module *M) { 147263509Sdim // This checks against logic errors in the MCJIT implementation. 148263509Sdim // This function should never be called with either a Module that MCJIT 149263509Sdim // does not own or a Module that has already been loaded and/or finalized. 150263509Sdim assert(AddedModules.count(M) && 151263509Sdim "markModuleAsLoaded: Module not found in AddedModules"); 152263509Sdim 153263509Sdim // Remove the module from the "Added" set. 154263509Sdim AddedModules.erase(M); 155263509Sdim 156263509Sdim // Add the Module to the "Loaded" set. 157263509Sdim LoadedModules.insert(M); 158263509Sdim } 159263509Sdim 160263509Sdim void markModuleAsFinalized(Module *M) { 161263509Sdim // This checks against logic errors in the MCJIT implementation. 162263509Sdim // This function should never be called with either a Module that MCJIT 163263509Sdim // does not own, a Module that has not been loaded or a Module that has 164263509Sdim // already been finalized. 165263509Sdim assert(LoadedModules.count(M) && 166263509Sdim "markModuleAsFinalized: Module not found in LoadedModules"); 167263509Sdim 168263509Sdim // Remove the module from the "Loaded" section of the list. 169263509Sdim LoadedModules.erase(M); 170263509Sdim 171263509Sdim // Add the Module to the "Finalized" section of the list by inserting it 172263509Sdim // before the 'end' iterator. 173263509Sdim FinalizedModules.insert(M); 174263509Sdim } 175263509Sdim 176263509Sdim void markAllLoadedModulesAsFinalized() { 177263509Sdim for (ModulePtrSet::iterator I = LoadedModules.begin(), 178263509Sdim E = LoadedModules.end(); 179263509Sdim I != E; ++I) { 180263509Sdim Module *M = *I; 181263509Sdim FinalizedModules.insert(M); 182263509Sdim } 183263509Sdim LoadedModules.clear(); 184263509Sdim } 185263509Sdim 186263509Sdim private: 187263509Sdim ModulePtrSet AddedModules; 188263509Sdim ModulePtrSet LoadedModules; 189263509Sdim ModulePtrSet FinalizedModules; 190263509Sdim 191263509Sdim void freeModulePtrSet(ModulePtrSet& MPS) { 192263509Sdim // Go through the module set and delete everything. 193263509Sdim for (ModulePtrSet::iterator I = MPS.begin(), E = MPS.end(); I != E; ++I) { 194263509Sdim Module *M = *I; 195263509Sdim delete M; 196263509Sdim } 197263509Sdim MPS.clear(); 198263509Sdim } 199263509Sdim }; 200263509Sdim 201221345Sdim TargetMachine *TM; 202221345Sdim MCContext *Ctx; 203263509Sdim LinkingMemoryManager MemMgr; 204245431Sdim RuntimeDyld Dyld; 205245431Sdim SmallVector<JITEventListener*, 2> EventListeners; 206221345Sdim 207263509Sdim OwningModuleContainer OwnedModules; 208221345Sdim 209263509Sdim typedef DenseMap<Module *, ObjectImage *> LoadedObjectMap; 210263509Sdim LoadedObjectMap LoadedObjects; 211263509Sdim 212252723Sdim // An optional ObjectCache to be notified of compiled objects and used to 213252723Sdim // perform lookup of pre-compiled code to avoid re-compilation. 214252723Sdim ObjectCache *ObjCache; 215252723Sdim 216263509Sdim Function *FindFunctionNamedInModulePtrSet(const char *FnName, 217263509Sdim ModulePtrSet::iterator I, 218263509Sdim ModulePtrSet::iterator E); 219263509Sdim 220263509Sdim void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors, 221263509Sdim ModulePtrSet::iterator I, 222263509Sdim ModulePtrSet::iterator E); 223263509Sdim 224218885Sdimpublic: 225218885Sdim ~MCJIT(); 226218885Sdim 227218885Sdim /// @name ExecutionEngine interface implementation 228218885Sdim /// @{ 229263509Sdim virtual void addModule(Module *M); 230263509Sdim virtual bool removeModule(Module *M); 231218885Sdim 232263509Sdim /// FindFunctionNamed - Search all of the active modules to find the one that 233263509Sdim /// defines FnName. This is very slow operation and shouldn't be used for 234263509Sdim /// general code. 235263509Sdim virtual Function *FindFunctionNamed(const char *FnName); 236263509Sdim 237252723Sdim /// Sets the object manager that MCJIT should use to avoid compilation. 238252723Sdim virtual void setObjectCache(ObjectCache *manager); 239252723Sdim 240263509Sdim virtual void generateCodeForModule(Module *M); 241263509Sdim 242263509Sdim /// finalizeObject - ensure the module is fully processed and is usable. 243263509Sdim /// 244263509Sdim /// It is the user-level function for completing the process of making the 245263509Sdim /// object usable for execution. It should be called after sections within an 246263509Sdim /// object have been relocated using mapSectionAddress. When this method is 247263509Sdim /// called the MCJIT execution engine will reapply relocations for a loaded 248263509Sdim /// object. 249263509Sdim /// Is it OK to finalize a set of modules, add modules and finalize again. 250263509Sdim // FIXME: Do we really need both of these? 251245431Sdim virtual void finalizeObject(); 252263509Sdim virtual void finalizeModule(Module *); 253263509Sdim void finalizeLoadedModules(); 254245431Sdim 255263509Sdim /// runStaticConstructorsDestructors - This method is used to execute all of 256263509Sdim /// the static constructors or destructors for a program. 257263509Sdim /// 258263509Sdim /// \param isDtors - Run the destructors instead of constructors. 259263509Sdim void runStaticConstructorsDestructors(bool isDtors); 260263509Sdim 261218885Sdim virtual void *getPointerToBasicBlock(BasicBlock *BB); 262218885Sdim 263218885Sdim virtual void *getPointerToFunction(Function *F); 264218885Sdim 265218885Sdim virtual void *recompileAndRelinkFunction(Function *F); 266218885Sdim 267218885Sdim virtual void freeMachineCodeForFunction(Function *F); 268218885Sdim 269218885Sdim virtual GenericValue runFunction(Function *F, 270218885Sdim const std::vector<GenericValue> &ArgValues); 271218885Sdim 272221345Sdim /// getPointerToNamedFunction - This method returns the address of the 273221345Sdim /// specified function by using the dlsym function call. As such it is only 274221345Sdim /// useful for resolving library symbols, not code generated symbols. 275221345Sdim /// 276221345Sdim /// If AbortOnFailure is false and no function with the given name is 277221345Sdim /// found, this function silently returns a null pointer. Otherwise, 278221345Sdim /// it prints a message to stderr and aborts. 279221345Sdim /// 280235633Sdim virtual void *getPointerToNamedFunction(const std::string &Name, 281235633Sdim bool AbortOnFailure = true); 282235633Sdim 283235633Sdim /// mapSectionAddress - map a section to its target address space value. 284235633Sdim /// Map the address of a JIT section as returned from the memory manager 285235633Sdim /// to the address in the target process as the running code will see it. 286235633Sdim /// This is the address which will be used for relocation resolution. 287245431Sdim virtual void mapSectionAddress(const void *LocalAddress, 288245431Sdim uint64_t TargetAddress) { 289235633Sdim Dyld.mapSectionAddress(LocalAddress, TargetAddress); 290235633Sdim } 291245431Sdim virtual void RegisterJITEventListener(JITEventListener *L); 292245431Sdim virtual void UnregisterJITEventListener(JITEventListener *L); 293245431Sdim 294263509Sdim // If successful, these function will implicitly finalize all loaded objects. 295263509Sdim // To get a function address within MCJIT without causing a finalize, use 296263509Sdim // getSymbolAddress. 297263509Sdim virtual uint64_t getGlobalValueAddress(const std::string &Name); 298263509Sdim virtual uint64_t getFunctionAddress(const std::string &Name); 299263509Sdim 300218885Sdim /// @} 301218885Sdim /// @name (Private) Registration Interfaces 302218885Sdim /// @{ 303218885Sdim 304218885Sdim static void Register() { 305218885Sdim MCJITCtor = createJIT; 306218885Sdim } 307218885Sdim 308218885Sdim static ExecutionEngine *createJIT(Module *M, 309218885Sdim std::string *ErrorStr, 310263509Sdim RTDyldMemoryManager *MemMgr, 311218885Sdim bool GVsWithCode, 312223017Sdim TargetMachine *TM); 313218885Sdim 314218885Sdim // @} 315245431Sdim 316263509Sdim // This is not directly exposed via the ExecutionEngine API, but it is 317263509Sdim // used by the LinkingMemoryManager. 318263509Sdim uint64_t getSymbolAddress(const std::string &Name, 319263509Sdim bool CheckFunctionsOnly); 320263509Sdim 321245431Sdimprotected: 322245431Sdim /// emitObject -- Generate a JITed object in memory from the specified module 323245431Sdim /// Currently, MCJIT only supports a single module and the module passed to 324245431Sdim /// this function call is expected to be the contained module. The module 325245431Sdim /// is passed as a parameter here to prepare for multiple module support in 326245431Sdim /// the future. 327252723Sdim ObjectBufferStream* emitObject(Module *M); 328245431Sdim 329245431Sdim void NotifyObjectEmitted(const ObjectImage& Obj); 330245431Sdim void NotifyFreeingObject(const ObjectImage& Obj); 331263509Sdim 332263509Sdim uint64_t getExistingSymbolAddress(const std::string &Name); 333263509Sdim Module *findModuleForSymbol(const std::string &Name, 334263509Sdim bool CheckFunctionsOnly); 335218885Sdim}; 336218885Sdim 337218885Sdim} // End llvm namespace 338218885Sdim 339218885Sdim#endif 340