OrcMCJITReplacement.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. //===---- OrcMCJITReplacement.h - Orc based MCJIT replacement ---*- 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. // Orc based MCJIT replacement.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
  14. #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
  15. #include "llvm/ExecutionEngine/ExecutionEngine.h"
  16. #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
  17. #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
  18. #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
  19. #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
  20. #include "llvm/Object/Archive.h"
  21. namespace llvm {
  22. namespace orc {
  23. class OrcMCJITReplacement : public ExecutionEngine {
  24. // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
  25. // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
  26. // expecting - see finalizeMemory.
  27. class MCJITReplacementMemMgr : public MCJITMemoryManager {
  28. public:
  29. MCJITReplacementMemMgr(OrcMCJITReplacement &M,
  30. std::shared_ptr<MCJITMemoryManager> ClientMM)
  31. : M(M), ClientMM(std::move(ClientMM)) {}
  32. uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
  33. unsigned SectionID,
  34. StringRef SectionName) override {
  35. uint8_t *Addr =
  36. ClientMM->allocateCodeSection(Size, Alignment, SectionID,
  37. SectionName);
  38. M.SectionsAllocatedSinceLastLoad.insert(Addr);
  39. return Addr;
  40. }
  41. uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
  42. unsigned SectionID, StringRef SectionName,
  43. bool IsReadOnly) override {
  44. uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
  45. SectionName, IsReadOnly);
  46. M.SectionsAllocatedSinceLastLoad.insert(Addr);
  47. return Addr;
  48. }
  49. void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
  50. uintptr_t DataSizeRW) override {
  51. return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO,
  52. DataSizeRW);
  53. }
  54. bool needsToReserveAllocationSpace() override {
  55. return ClientMM->needsToReserveAllocationSpace();
  56. }
  57. void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
  58. size_t Size) override {
  59. return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
  60. }
  61. void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
  62. size_t Size) override {
  63. return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
  64. }
  65. void notifyObjectLoaded(ExecutionEngine *EE,
  66. const object::ObjectFile &O) override {
  67. return ClientMM->notifyObjectLoaded(EE, O);
  68. }
  69. bool finalizeMemory(std::string *ErrMsg = nullptr) override {
  70. // Each set of objects loaded will be finalized exactly once, but since
  71. // symbol lookup during relocation may recursively trigger the
  72. // loading/relocation of other modules, and since we're forwarding all
  73. // finalizeMemory calls to a single underlying memory manager, we need to
  74. // defer forwarding the call on until all necessary objects have been
  75. // loaded. Otherwise, during the relocation of a leaf object, we will end
  76. // up finalizing memory, causing a crash further up the stack when we
  77. // attempt to apply relocations to finalized memory.
  78. // To avoid finalizing too early, look at how many objects have been
  79. // loaded but not yet finalized. This is a bit of a hack that relies on
  80. // the fact that we're lazily emitting object files: The only way you can
  81. // get more than one set of objects loaded but not yet finalized is if
  82. // they were loaded during relocation of another set.
  83. if (M.UnfinalizedSections.size() == 1)
  84. return ClientMM->finalizeMemory(ErrMsg);
  85. return false;
  86. }
  87. private:
  88. OrcMCJITReplacement &M;
  89. std::shared_ptr<MCJITMemoryManager> ClientMM;
  90. };
  91. class LinkingResolver : public RuntimeDyld::SymbolResolver {
  92. public:
  93. LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
  94. RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
  95. return M.findMangledSymbol(Name);
  96. }
  97. RuntimeDyld::SymbolInfo
  98. findSymbolInLogicalDylib(const std::string &Name) override {
  99. return M.ClientResolver->findSymbolInLogicalDylib(Name);
  100. }
  101. private:
  102. OrcMCJITReplacement &M;
  103. };
  104. private:
  105. static ExecutionEngine *
  106. createOrcMCJITReplacement(std::string *ErrorMsg,
  107. std::shared_ptr<MCJITMemoryManager> MemMgr,
  108. std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
  109. std::unique_ptr<TargetMachine> TM) {
  110. return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
  111. std::move(TM));
  112. }
  113. public:
  114. static void Register() {
  115. OrcMCJITReplacementCtor = createOrcMCJITReplacement;
  116. }
  117. OrcMCJITReplacement(
  118. std::shared_ptr<MCJITMemoryManager> MemMgr,
  119. std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
  120. std::unique_ptr<TargetMachine> TM)
  121. : TM(std::move(TM)), MemMgr(*this, std::move(MemMgr)),
  122. Resolver(*this), ClientResolver(std::move(ClientResolver)),
  123. NotifyObjectLoaded(*this), NotifyFinalized(*this),
  124. ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
  125. CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
  126. LazyEmitLayer(CompileLayer) {
  127. setDataLayout(this->TM->getDataLayout());
  128. }
  129. void addModule(std::unique_ptr<Module> M) override {
  130. // If this module doesn't have a DataLayout attached then attach the
  131. // default.
  132. if (M->getDataLayout().isDefault())
  133. M->setDataLayout(*getDataLayout());
  134. Modules.push_back(std::move(M));
  135. std::vector<Module *> Ms;
  136. Ms.push_back(&*Modules.back());
  137. LazyEmitLayer.addModuleSet(std::move(Ms), &MemMgr, &Resolver);
  138. }
  139. void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
  140. std::vector<std::unique_ptr<object::ObjectFile>> Objs;
  141. Objs.push_back(std::move(O));
  142. ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
  143. }
  144. void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
  145. std::unique_ptr<object::ObjectFile> Obj;
  146. std::unique_ptr<MemoryBuffer> Buf;
  147. std::tie(Obj, Buf) = O.takeBinary();
  148. std::vector<std::unique_ptr<object::ObjectFile>> Objs;
  149. Objs.push_back(std::move(Obj));
  150. auto H =
  151. ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
  152. std::vector<std::unique_ptr<MemoryBuffer>> Bufs;
  153. Bufs.push_back(std::move(Buf));
  154. ObjectLayer.takeOwnershipOfBuffers(H, std::move(Bufs));
  155. }
  156. void addArchive(object::OwningBinary<object::Archive> A) override {
  157. Archives.push_back(std::move(A));
  158. }
  159. uint64_t getSymbolAddress(StringRef Name) {
  160. return findSymbol(Name).getAddress();
  161. }
  162. RuntimeDyld::SymbolInfo findSymbol(StringRef Name) {
  163. return findMangledSymbol(Mangle(Name));
  164. }
  165. void finalizeObject() override {
  166. // This is deprecated - Aim to remove in ExecutionEngine.
  167. // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
  168. }
  169. void mapSectionAddress(const void *LocalAddress,
  170. uint64_t TargetAddress) override {
  171. for (auto &P : UnfinalizedSections)
  172. if (P.second.count(LocalAddress))
  173. ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
  174. }
  175. uint64_t getGlobalValueAddress(const std::string &Name) override {
  176. return getSymbolAddress(Name);
  177. }
  178. uint64_t getFunctionAddress(const std::string &Name) override {
  179. return getSymbolAddress(Name);
  180. }
  181. void *getPointerToFunction(Function *F) override {
  182. uint64_t FAddr = getSymbolAddress(F->getName());
  183. return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
  184. }
  185. void *getPointerToNamedFunction(StringRef Name,
  186. bool AbortOnFailure = true) override {
  187. uint64_t Addr = getSymbolAddress(Name);
  188. if (!Addr && AbortOnFailure)
  189. llvm_unreachable("Missing symbol!");
  190. return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
  191. }
  192. GenericValue runFunction(Function *F,
  193. ArrayRef<GenericValue> ArgValues) override;
  194. void setObjectCache(ObjectCache *NewCache) override {
  195. CompileLayer.setObjectCache(NewCache);
  196. }
  197. private:
  198. RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {
  199. if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
  200. return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
  201. if (auto Sym = ClientResolver->findSymbol(Name))
  202. return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
  203. if (auto Sym = scanArchives(Name))
  204. return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
  205. return nullptr;
  206. }
  207. JITSymbol scanArchives(StringRef Name) {
  208. for (object::OwningBinary<object::Archive> &OB : Archives) {
  209. object::Archive *A = OB.getBinary();
  210. // Look for our symbols in each Archive
  211. object::Archive::child_iterator ChildIt = A->findSym(Name);
  212. if (ChildIt != A->child_end()) {
  213. // FIXME: Support nested archives?
  214. ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
  215. ChildIt->getAsBinary();
  216. if (ChildBinOrErr.getError())
  217. continue;
  218. std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
  219. if (ChildBin->isObject()) {
  220. std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
  221. ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
  222. static_cast<object::ObjectFile *>(ChildBin.release())));
  223. ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
  224. if (auto Sym = ObjectLayer.findSymbol(Name, true))
  225. return Sym;
  226. }
  227. }
  228. }
  229. return nullptr;
  230. }
  231. class NotifyObjectLoadedT {
  232. public:
  233. typedef std::vector<std::unique_ptr<object::ObjectFile>> ObjListT;
  234. typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
  235. LoadedObjInfoListT;
  236. NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
  237. void operator()(ObjectLinkingLayerBase::ObjSetHandleT H,
  238. const ObjListT &Objects,
  239. const LoadedObjInfoListT &Infos) const {
  240. M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
  241. M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
  242. assert(Objects.size() == Infos.size() &&
  243. "Incorrect number of Infos for Objects.");
  244. for (unsigned I = 0; I < Objects.size(); ++I)
  245. M.MemMgr.notifyObjectLoaded(&M, *Objects[I]);
  246. };
  247. private:
  248. OrcMCJITReplacement &M;
  249. };
  250. class NotifyFinalizedT {
  251. public:
  252. NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
  253. void operator()(ObjectLinkingLayerBase::ObjSetHandleT H) {
  254. M.UnfinalizedSections.erase(H);
  255. }
  256. private:
  257. OrcMCJITReplacement &M;
  258. };
  259. std::string Mangle(StringRef Name) {
  260. std::string MangledName;
  261. {
  262. raw_string_ostream MangledNameStream(MangledName);
  263. Mang.getNameWithPrefix(MangledNameStream, Name, *TM->getDataLayout());
  264. }
  265. return MangledName;
  266. }
  267. typedef ObjectLinkingLayer<NotifyObjectLoadedT> ObjectLayerT;
  268. typedef IRCompileLayer<ObjectLayerT> CompileLayerT;
  269. typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
  270. std::unique_ptr<TargetMachine> TM;
  271. MCJITReplacementMemMgr MemMgr;
  272. LinkingResolver Resolver;
  273. std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
  274. Mangler Mang;
  275. NotifyObjectLoadedT NotifyObjectLoaded;
  276. NotifyFinalizedT NotifyFinalized;
  277. ObjectLayerT ObjectLayer;
  278. CompileLayerT CompileLayer;
  279. LazyEmitLayerT LazyEmitLayer;
  280. // We need to store ObjLayerT::ObjSetHandles for each of the object sets
  281. // that have been emitted but not yet finalized so that we can forward the
  282. // mapSectionAddress calls appropriately.
  283. typedef std::set<const void *> SectionAddrSet;
  284. struct ObjSetHandleCompare {
  285. bool operator()(ObjectLayerT::ObjSetHandleT H1,
  286. ObjectLayerT::ObjSetHandleT H2) const {
  287. return &*H1 < &*H2;
  288. }
  289. };
  290. SectionAddrSet SectionsAllocatedSinceLastLoad;
  291. std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare>
  292. UnfinalizedSections;
  293. std::vector<object::OwningBinary<object::Archive>> Archives;
  294. };
  295. } // End namespace orc.
  296. } // End namespace llvm.
  297. #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H