MCJIT.h revision f14bb8f5e664cda4cd720d638ad99cc635531442
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_H 11#define LLVM_LIB_EXECUTIONENGINE_MCJIT_H 12 13#include "llvm/ADT/DenseMap.h" 14#include "llvm/ADT/SmallVector.h" 15#include "llvm/ExecutionEngine/ExecutionEngine.h" 16#include "llvm/ExecutionEngine/ObjectCache.h" 17#include "llvm/ExecutionEngine/ObjectImage.h" 18#include "llvm/ExecutionEngine/RuntimeDyld.h" 19#include "llvm/PassManager.h" 20 21namespace llvm { 22 23class MCJIT; 24 25// This is a helper class that the MCJIT execution engine uses for linking 26// functions across modules that it owns. It aggregates the memory manager 27// that is passed in to the MCJIT constructor and defers most functionality 28// to that object. 29class LinkingMemoryManager : public RTDyldMemoryManager { 30public: 31 LinkingMemoryManager(MCJIT *Parent, RTDyldMemoryManager *MM) 32 : ParentEngine(Parent), ClientMM(MM) {} 33 34 virtual uint64_t getSymbolAddress(const std::string &Name); 35 36 // Functions deferred to client memory manager 37 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 38 unsigned SectionID, StringRef SectionName) { 39 return ClientMM->allocateCodeSection(Size, Alignment, SectionID, SectionName); 40 } 41 42 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 43 unsigned SectionID, StringRef SectionName, 44 bool IsReadOnly) { 45 return ClientMM->allocateDataSection(Size, Alignment, 46 SectionID, SectionName, IsReadOnly); 47 } 48 49 virtual void notifyObjectLoaded(ExecutionEngine *EE, 50 const ObjectImage *Obj) { 51 ClientMM->notifyObjectLoaded(EE, Obj); 52 } 53 54 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { 55 ClientMM->registerEHFrames(Addr, LoadAddr, Size); 56 } 57 58 virtual void deregisterEHFrames(uint8_t *Addr, 59 uint64_t LoadAddr, 60 size_t Size) { 61 ClientMM->deregisterEHFrames(Addr, LoadAddr, Size); 62 } 63 64 virtual bool finalizeMemory(std::string *ErrMsg = 0) { 65 return ClientMM->finalizeMemory(ErrMsg); 66 } 67 68private: 69 MCJIT *ParentEngine; 70 OwningPtr<RTDyldMemoryManager> ClientMM; 71}; 72 73// FIXME: This makes all kinds of horrible assumptions for the time being, 74// like only having one module, not needing to worry about multi-threading, 75// blah blah. Purely in get-it-up-and-limping mode for now. 76 77// About Module states: 78// 79// The purpose of the "added" state is having modules in standby. (added=known 80// but not compiled). The idea is that you can add a module to provide function 81// definitions but if nothing in that module is referenced by a module in which 82// a function is executed (note the wording here because it�s not exactly the 83// ideal case) then the module never gets compiled. This is sort of lazy 84// compilation. 85// 86// The purpose of the "loaded" state (loaded=compiled and required sections 87// copied into local memory but not yet ready for execution) is to have an 88// intermediate state wherein clients can remap the addresses of sections, using 89// MCJIT::mapSectionAddress, (in preparation for later copying to a new location 90// or an external process) before relocations and page permissions are applied. 91// 92// It might not be obvious at first glance, but the "remote-mcjit" case in the 93// lli tool does this. In that case, the intermediate action is taken by the 94// RemoteMemoryManager in response to the notifyObjectLoaded function being 95// called. 96 97class MCJIT : public ExecutionEngine { 98 MCJIT(Module *M, TargetMachine *tm, RTDyldMemoryManager *MemMgr, 99 bool AllocateGVsWithCode); 100 101 enum ModuleState { 102 ModuleAdded, 103 ModuleEmitted, 104 ModuleLoading, 105 ModuleLoaded, 106 ModuleFinalizing, 107 ModuleFinalized 108 }; 109 110 class MCJITModuleState { 111 public: 112 MCJITModuleState() : State(ModuleAdded) {} 113 114 MCJITModuleState & operator=(ModuleState s) { State = s; return *this; } 115 bool hasBeenEmitted() { return State != ModuleAdded; } 116 bool hasBeenLoaded() { return State != ModuleAdded && 117 State != ModuleEmitted; } 118 bool hasBeenFinalized() { return State == ModuleFinalized; } 119 120 private: 121 ModuleState State; 122 }; 123 124 TargetMachine *TM; 125 MCContext *Ctx; 126 LinkingMemoryManager MemMgr; 127 RuntimeDyld Dyld; 128 SmallVector<JITEventListener*, 2> EventListeners; 129 130 typedef DenseMap<Module *, MCJITModuleState> ModuleStateMap; 131 ModuleStateMap ModuleStates; 132 133 typedef DenseMap<Module *, ObjectImage *> LoadedObjectMap; 134 LoadedObjectMap LoadedObjects; 135 136 // An optional ObjectCache to be notified of compiled objects and used to 137 // perform lookup of pre-compiled code to avoid re-compilation. 138 ObjectCache *ObjCache; 139 140public: 141 ~MCJIT(); 142 143 /// @name ExecutionEngine interface implementation 144 /// @{ 145 virtual void addModule(Module *M); 146 147 /// Sets the object manager that MCJIT should use to avoid compilation. 148 virtual void setObjectCache(ObjectCache *manager); 149 150 virtual void generateCodeForModule(Module *M); 151 152 /// finalizeObject - ensure the module is fully processed and is usable. 153 /// 154 /// It is the user-level function for completing the process of making the 155 /// object usable for execution. It should be called after sections within an 156 /// object have been relocated using mapSectionAddress. When this method is 157 /// called the MCJIT execution engine will reapply relocations for a loaded 158 /// object. 159 /// Is it OK to finalize a set of modules, add modules and finalize again. 160 /// FIXME: Do we really need both of these? 161 virtual void finalizeObject(); 162 virtual void finalizeModule(Module *); 163 void finalizeLoadedModules(); 164 165 virtual void *getPointerToBasicBlock(BasicBlock *BB); 166 167 virtual void *getPointerToFunction(Function *F); 168 169 virtual void *recompileAndRelinkFunction(Function *F); 170 171 virtual void freeMachineCodeForFunction(Function *F); 172 173 virtual GenericValue runFunction(Function *F, 174 const std::vector<GenericValue> &ArgValues); 175 176 /// getPointerToNamedFunction - This method returns the address of the 177 /// specified function by using the dlsym function call. As such it is only 178 /// useful for resolving library symbols, not code generated symbols. 179 /// 180 /// If AbortOnFailure is false and no function with the given name is 181 /// found, this function silently returns a null pointer. Otherwise, 182 /// it prints a message to stderr and aborts. 183 /// 184 virtual void *getPointerToNamedFunction(const std::string &Name, 185 bool AbortOnFailure = true); 186 187 /// mapSectionAddress - map a section to its target address space value. 188 /// Map the address of a JIT section as returned from the memory manager 189 /// to the address in the target process as the running code will see it. 190 /// This is the address which will be used for relocation resolution. 191 virtual void mapSectionAddress(const void *LocalAddress, 192 uint64_t TargetAddress) { 193 Dyld.mapSectionAddress(LocalAddress, TargetAddress); 194 } 195 virtual void RegisterJITEventListener(JITEventListener *L); 196 virtual void UnregisterJITEventListener(JITEventListener *L); 197 198 // If successful, these function will implicitly finalize all loaded objects. 199 // To get a function address within MCJIT without causing a finalize, use 200 // getSymbolAddress. 201 virtual uint64_t getGlobalValueAddress(const std::string &Name); 202 virtual uint64_t getFunctionAddress(const std::string &Name); 203 204 /// @} 205 /// @name (Private) Registration Interfaces 206 /// @{ 207 208 static void Register() { 209 MCJITCtor = createJIT; 210 } 211 212 static ExecutionEngine *createJIT(Module *M, 213 std::string *ErrorStr, 214 RTDyldMemoryManager *MemMgr, 215 bool GVsWithCode, 216 TargetMachine *TM); 217 218 // @} 219 220 // This is not directly exposed via the ExecutionEngine API, but it is 221 // used by the LinkingMemoryManager. 222 uint64_t getSymbolAddress(const std::string &Name, 223 bool CheckFunctionsOnly); 224 225protected: 226 /// emitObject -- Generate a JITed object in memory from the specified module 227 /// Currently, MCJIT only supports a single module and the module passed to 228 /// this function call is expected to be the contained module. The module 229 /// is passed as a parameter here to prepare for multiple module support in 230 /// the future. 231 ObjectBufferStream* emitObject(Module *M); 232 233 void NotifyObjectEmitted(const ObjectImage& Obj); 234 void NotifyFreeingObject(const ObjectImage& Obj); 235 236 uint64_t getExistingSymbolAddress(const std::string &Name); 237 Module *findModuleForSymbol(const std::string &Name, 238 bool CheckFunctionsOnly); 239}; 240 241} // End llvm namespace 242 243#endif 244