llvm.org GIT mirror llvm / 8c824db
[ORC] Remove Layer handles from the layer concept. Handles were returned by addModule and used as keys for removeModule, findSymbolIn, and emitAndFinalize. Their job is now subsumed by VModuleKeys, which simplify resource management by providing a consistent handle across all layers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324700 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 1 year, 8 months ago
19 changed file(s) with 337 addition(s) and 434 deletion(s). Raw diff Collapse all Expand all
4646 IRCompileLayer CompileLayer;
4747
4848 public:
49 using ModuleHandle = decltype(CompileLayer)::ModuleHandleT;
5049
5150 KaleidoscopeJIT()
5251 : ES(SSP),
7372
7473 TargetMachine &getTargetMachine() { return *TM; }
7574
76 ModuleHandle addModule(std::unique_ptr M) {
75 VModuleKey addModule(std::unique_ptr M) {
7776 // Add the module to the JIT with a new VModuleKey.
78 return cantFail(CompileLayer.addModule(ES.allocateVModule(), std::move(M)));
77 auto K = ES.allocateVModule();
78 cantFail(CompileLayer.addModule(K, std::move(M)));
79 return K;
7980 }
8081
8182 JITSymbol findSymbol(const std::string Name) {
8990 return cantFail(findSymbol(Name).getAddress());
9091 }
9192
92 void removeModule(ModuleHandle H) {
93 cantFail(CompileLayer.removeModule(H));
93 void removeModule(VModuleKey K) {
94 cantFail(CompileLayer.removeModule(K));
9495 }
9596 };
9697
5555 IRTransformLayer OptimizeLayer;
5656
5757 public:
58 using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
5958
6059 KaleidoscopeJIT()
6160 : ES(SSP),
8584
8685 TargetMachine &getTargetMachine() { return *TM; }
8786
88 ModuleHandle addModule(std::unique_ptr M) {
87 VModuleKey addModule(std::unique_ptr M) {
8988 // Add the module to the JIT with a new VModuleKey.
90 return cantFail(
91 OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
89 auto K = ES.allocateVModule();
90 cantFail(OptimizeLayer.addModule(K, std::move(M)));
91 return K;
9292 }
9393
9494 JITSymbol findSymbol(const std::string Name) {
9898 return OptimizeLayer.findSymbol(MangledNameStream.str(), true);
9999 }
100100
101 void removeModule(ModuleHandle H) {
102 cantFail(OptimizeLayer.removeModule(H));
101 void removeModule(VModuleKey K) {
102 cantFail(OptimizeLayer.removeModule(K));
103103 }
104104
105105 private:
6262 CompileOnDemandLayer CODLayer;
6363
6464 public:
65 using ModuleHandle = decltype(CODLayer)::ModuleHandleT;
6665
6766 KaleidoscopeJIT()
6867 : ES(SSP), TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
9190
9291 TargetMachine &getTargetMachine() { return *TM; }
9392
94 ModuleHandle addModule(std::unique_ptr M) {
93 VModuleKey addModule(std::unique_ptr M) {
9594 // Create a new VModuleKey.
9695 VModuleKey K = ES.allocateVModule();
9796
110109 [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); });
111110
112111 // Add the module to the JIT with the new key.
113 return cantFail(CODLayer.addModule(K, std::move(M)));
112 cantFail(CODLayer.addModule(K, std::move(M)));
113 return K;
114114 }
115115
116116 JITSymbol findSymbol(const std::string Name) {
120120 return CODLayer.findSymbol(MangledNameStream.str(), true);
121121 }
122122
123 void removeModule(ModuleHandle H) {
124 cantFail(CODLayer.removeModule(H));
123 void removeModule(VModuleKey K) {
124 cantFail(CODLayer.removeModule(K));
125125 }
126126
127127 private:
8888 std::unique_ptr IndirectStubsMgr;
8989
9090 public:
91 using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
9291
9392 KaleidoscopeJIT()
9493 : ES(SSP),
126125
127126 TargetMachine &getTargetMachine() { return *TM; }
128127
129 ModuleHandle addModule(std::unique_ptr M) {
128 VModuleKey addModule(std::unique_ptr M) {
130129 // Add the module to the JIT with a new VModuleKey.
131 return cantFail(
132 OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
130 auto K = ES.allocateVModule();
131 cantFail(OptimizeLayer.addModule(K, std::move(M)));
132 return K;
133133 }
134134
135135 Error addFunctionAST(std::unique_ptr FnAST) {
194194 return OptimizeLayer.findSymbol(mangle(Name), true);
195195 }
196196
197 void removeModule(ModuleHandle H) {
198 cantFail(OptimizeLayer.removeModule(H));
197 void removeModule(VModuleKey K) {
198 cantFail(OptimizeLayer.removeModule(K));
199199 }
200200
201201 private:
9494 MyRemote &Remote;
9595
9696 public:
97 using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
9897
9998 KaleidoscopeJIT(MyRemote &Remote)
10099 : ES(SSP),
138137
139138 TargetMachine &getTargetMachine() { return *TM; }
140139
141 ModuleHandle addModule(std::unique_ptr M) {
140 VModuleKey addModule(std::unique_ptr M) {
142141 // Add the module with a new VModuleKey.
143 return cantFail(
144 OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
142 auto K = ES.allocateVModule();
143 cantFail(OptimizeLayer.addModule(K, std::move(M)));
144 return K;
145145 }
146146
147147 Error addFunctionAST(std::unique_ptr FnAST) {
210210 return OptimizeLayer.findSymbol(mangle(Name), true);
211211 }
212212
213 void removeModule(ModuleHandle H) {
214 cantFail(OptimizeLayer.removeModule(H));
213 void removeModule(VModuleKey K) {
214 cantFail(OptimizeLayer.removeModule(K));
215215 }
216216
217217 private:
4141 public:
4242 using ObjLayerT = RTDyldObjectLinkingLayer;
4343 using CompileLayerT = IRCompileLayer;
44 using ModuleHandleT = CompileLayerT::ModuleHandleT;
4544
4645 KaleidoscopeJIT()
4746 : ES(SSP),
6160
6261 TargetMachine &getTargetMachine() { return *TM; }
6362
64 ModuleHandleT addModule(std::unique_ptr M) {
65 auto H =
66 cantFail(CompileLayer.addModule(ES.allocateVModule(), std::move(M)));
67 ModuleHandles.push_back(H);
68 return H;
63 VModuleKey addModule(std::unique_ptr M) {
64 auto K = ES.allocateVModule();
65 cantFail(CompileLayer.addModule(K, std::move(M)));
66 ModuleKeys.push_back(K);
67 return K;
6968 }
7069
71 void removeModule(ModuleHandleT H) {
72 ModuleHandles.erase(find(ModuleHandles, H));
73 cantFail(CompileLayer.removeModule(H));
70 void removeModule(VModuleKey K) {
71 ModuleKeys.erase(find(ModuleKeys, K));
72 cantFail(CompileLayer.removeModule(K));
7473 }
7574
7675 JITSymbol findSymbol(const std::string Name) {
104103 // Search modules in reverse order: from last added to first added.
105104 // This is the opposite of the usual search order for dlsym, but makes more
106105 // sense in a REPL where we want to bind to the newest available definition.
107 for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend()))
106 for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend()))
108107 if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))
109108 return Sym;
110109
132131 const DataLayout DL;
133132 ObjLayerT ObjectLayer;
134133 CompileLayerT CompileLayer;
135 std::vector<ModuleHandleT> ModuleHandles;
134 std::vector<VModuleKey> ModuleKeys;
136135 };
137136
138137 } // end namespace orc
8585 return LambdaMaterializer(std::move(M));
8686 }
8787
88 using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT;
89
9088 // Provide type-erasure for the Modules and MemoryManagers.
9189 template
9290 class ResourceOwner {
146144 using SourceModulesList = std::vector;
147145 using SourceModuleHandle = typename SourceModulesList::size_type;
148146
147 LogicalDylib() = default;
148
149 LogicalDylib(VModuleKey K, std::shared_ptr BackingResolver,
150 std::unique_ptr StubsMgr)
151 : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
152 StubsMgr(std::move(StubsMgr)) {}
153
149154 SourceModuleHandle
150155 addSourceModule(std::shared_ptr M) {
151156 SourceModuleHandle H = SourceModules.size();
166171 bool ExportedSymbolsOnly) {
167172 if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
168173 return Sym;
169 for (auto BLH : BaseLayerHandles)
170 if (auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
174 for (auto BLK : BaseLayerVModuleKeys)
175 if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
171176 return Sym;
172177 else if (auto Err = Sym.takeError())
173178 return std::move(Err);
175180 }
176181
177182 Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
178 for (auto &BLH : BaseLayerHandles)
179 if (auto Err = BaseLayer.removeModule(BLH))
183 for (auto &BLK : BaseLayerVModuleKeys)
184 if (auto Err = BaseLayer.removeModule(BLK))
180185 return Err;
181186 return Error::success();
182187 }
186191 std::unique_ptr StubsMgr;
187192 StaticGlobalRenamer StaticRenamer;
188193 SourceModulesList SourceModules;
189 std::vector<BaseLayerModuleHandleT> BaseLayerHandles;
194 std::vector<VModuleKey> BaseLayerVModuleKeys;
190195 };
191196
192 using LogicalDylibList = std::list;
193
194197 public:
195
196 /// @brief Handle to loaded module.
197 using ModuleHandleT = typename LogicalDylibList::iterator;
198198
199199 /// @brief Module partitioning functor.
200200 using PartitioningFtor = std::function(Function&)>;
227227 ~CompileOnDemandLayer() {
228228 // FIXME: Report error on log.
229229 while (!LogicalDylibs.empty())
230 consumeError(removeModule(LogicalDylibs.begin()));
230 consumeError(removeModule(LogicalDylibs.begin()->first));
231231 }
232232
233233 /// @brief Add a module to the compile-on-demand layer.
234 Expected addModule(VModuleKey K, std::shared_ptr M) {
235
236 LogicalDylibs.push_back(LogicalDylib());
237 auto &LD = LogicalDylibs.back();
238 LD.K = std::move(K);
239 LD.StubsMgr = CreateIndirectStubsManager();
240 LD.BackingResolver = GetSymbolResolver(LD.K);
241
242 if (auto Err = addLogicalModule(LD, std::move(M)))
243 return std::move(Err);
244
245 return std::prev(LogicalDylibs.end());
234 Error addModule(VModuleKey K, std::shared_ptr M) {
235
236 assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
237 auto I = LogicalDylibs.insert(
238 LogicalDylibs.end(),
239 std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
240 CreateIndirectStubsManager())));
241
242 return addLogicalModule(I->second, std::move(M));
246243 }
247244
248245 /// @brief Add extra modules to an existing logical module.
249 Error addExtraModule(ModuleHandleT H, std::shared_ptr M) {
250 return addLogicalModule(*H, std::move(M));
251 }
252
253 /// @brief Remove the module represented by the given handle.
246 Error addExtraModule(VModuleKey K, std::shared_ptr M) {
247 return addLogicalModule(LogicalDylibs[K], std::move(M));
248 }
249
250 /// @brief Remove the module represented by the given key.
254251 ///
255252 /// This will remove all modules in the layers below that were derived from
256 /// the module represented by H.
257 Error removeModule(ModuleHandleT H) {
258 auto Err = H->removeModulesFromBaseLayer(BaseLayer);
259 LogicalDylibs.erase(H);
253 /// the module represented by K.
254 Error removeModule(VModuleKey K) {
255 auto I = LogicalDylibs.find(K);
256 assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
257 auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
258 LogicalDylibs.erase(I);
260259 return Err;
261260 }
262261
265264 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
266265 /// @return A handle for the given named symbol, if it exists.
267266 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
268 for (auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
269 LDI != LDE; ++LDI) {
270 if (auto Sym = LDI->StubsMgr->findStub(Name, ExportedSymbolsOnly))
267 for (auto &KV : LogicalDylibs) {
268 if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
271269 return Sym;
272 if (auto Sym = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
270 if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
273271 return Sym;
274272 else if (auto Err = Sym.takeError())
275273 return std::move(Err);
279277
280278 /// @brief Get the address of a symbol provided by this layer, or some layer
281279 /// below this one.
282 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
280 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
283281 bool ExportedSymbolsOnly) {
284 return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
282 assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
283 return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
285284 }
286285
287286 /// @brief Update the stub for the given function to point at FnBodyAddr.
501500
502501 SetSymbolResolver(LD.K, std::move(GVsResolver));
503502
504 if (auto GVsHOrErr = BaseLayer.addModule(LD.K, std::move(GVsM)))
505 LD.BaseLayerHandles.push_back(*GVsHOrErr);
506 else
507 return GVsHOrErr.takeError();
503 if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
504 return Err;
505
506 LD.BaseLayerVModuleKeys.push_back(LD.K);
508507
509508 return Error::success();
510509 }
533532
534533 JITTargetAddress CalledAddr = 0;
535534 auto Part = Partition(F);
536 if (auto PartHOrErr = emitPartition(LD, LMId, Part)) {
537 auto &PartH = *PartHOrErr;
535 if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
536 auto &PartKey = *PartKeyOrErr;
538537 for (auto *SubF : Part) {
539538 std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
540 if (auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false)) {
539 if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
541540 if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
542541 JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
543542
558557 llvm_unreachable("Function not emitted for partition");
559558 }
560559
561 LD.BaseLayerHandles.push_back(PartH);
560 LD.BaseLayerVModuleKeys.push_back(PartKey);
562561 } else
563 return PartHOrErr.takeError();
562 return PartKeyOrErr.takeError();
564563
565564 return CalledAddr;
566565 }
567566
568567 template
569 Expected<BaseLayerModuleHandleT>
568 Expected<VModuleKey>
570569 emitPartition(LogicalDylib &LD,
571570 typename LogicalDylib::SourceModuleHandle LMId,
572571 const PartitionT &Part) {
657656 });
658657 SetSymbolResolver(K, std::move(Resolver));
659658
660 return BaseLayer.addModule(std::move(K), std::move(M));
659 if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
660 return std::move(Err);
661
662 return K;
661663 }
662664
663665 ExecutionSession &ES;
668670 CompileCallbackMgrT &CompileCallbackMgr;
669671 IndirectStubsManagerBuilderT CreateIndirectStubsManager;
670672
671 LogicalDylibList LogicalDylibs;
673 std::map LogicalDylibs;
672674 bool CloneStubsIntoPartitions;
673675 };
674676
1616 #include "llvm/ADT/StringMap.h"
1717 #include "llvm/ADT/iterator_range.h"
1818 #include "llvm/ExecutionEngine/JITSymbol.h"
19 #include "llvm/ExecutionEngine/Orc/Core.h"
20 #include "llvm/ExecutionEngine/Orc/OrcError.h"
1921 #include "llvm/ExecutionEngine/RuntimeDyld.h"
20 #include "llvm/ExecutionEngine/Orc/OrcError.h"
2122 #include
2223 #include
2324 #include
25 #include
2426 #include
25 #include
2627
2728 namespace llvm {
2829
9495 public:
9596 /// @brief Construct a CtorDtorRunner for the given range using the given
9697 /// name mangling function.
97 CtorDtorRunner(std::vector CtorDtorNames,
98 typename JITLayerT::ModuleHandleT H)
99 : CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
98 CtorDtorRunner(std::vector CtorDtorNames, VModuleKey K)
99 : CtorDtorNames(std::move(CtorDtorNames)), K(K) {}
100100
101101 /// @brief Run the recorded constructors/destructors through the given JIT
102102 /// layer.
105105
106106 for (const auto &CtorDtorName : CtorDtorNames) {
107107 dbgs() << "Searching for ctor/dtor: " << CtorDtorName << "...";
108 if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
108 if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) {
109109 dbgs() << " found symbol...";
110110 if (auto AddrOrErr = CtorDtorSym.getAddress()) {
111111 dbgs() << " at addr " << format("0x%016x", *AddrOrErr) << "\n";
129129
130130 private:
131131 std::vector CtorDtorNames;
132 typename JITLayerT::ModuleHandleT H;
132 orc::VModuleKey K;
133133 };
134134
135135 /// @brief Support class for static dtor execution. For hosted (in-process) JITs
3535 class IRCompileLayer {
3636 public:
3737
38 /// @brief Handle to a compiled module.
39 using ModuleHandleT = typename BaseLayerT::ObjHandleT;
40
4138 /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
4239 /// implement the ObjectLayer concept.
4340 IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
4845
4946 /// @brief Compile the module, and add the resulting object to the base layer
5047 /// along with the given memory manager and symbol resolver.
51 ///
52 /// @return A handle for the added module.
53 Expected addModule(VModuleKey K, std::shared_ptr M) {
48 Error addModule(VModuleKey K, std::shared_ptr M) {
5449 using CompileResult = decltype(Compile(*M));
5550 auto Obj = std::make_shared(Compile(*M));
5651 return BaseLayer.addObject(std::move(K), std::move(Obj));
5752 }
5853
59 /// @brief Remove the module associated with the handle H.
60 Error removeModule(ModuleHandleT H) {
61 return BaseLayer.removeObject(H);
62 }
54 /// @brief Remove the module associated with the VModuleKey K.
55 Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
6356
6457 /// @brief Search for the given named symbol.
6558 /// @param Name The name of the symbol to search for.
7265 /// @brief Get the address of the given symbol in compiled module represented
7366 /// by the handle H. This call is forwarded to the base layer's
7467 /// implementation.
75 /// @param H The handle for the module to search in.
68 /// @param K The VModuleKey for the module to search in.
7669 /// @param Name The name of the symbol to search for.
7770 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
7871 /// @return A handle for the given named symbol, if it is found in the
7972 /// given module.
80 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
73 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
8174 bool ExportedSymbolsOnly) {
82 return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
75 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
8376 }
8477
8578 /// @brief Immediately emit and finalize the module represented by the given
8679 /// handle.
8780 /// @param H Handle for module to emit/finalize.
88 Error emitAndFinalize(ModuleHandleT H) {
89 return BaseLayer.emitAndFinalize(H);
90 }
81 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
9182
9283 private:
9384 BaseLayerT &BaseLayer;
3030 class IRTransformLayer {
3131 public:
3232
33 /// @brief Handle to a set of added modules.
34 using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
35
3633 /// @brief Construct an IRTransformLayer with the given BaseLayer
3734 IRTransformLayer(BaseLayerT &BaseLayer,
3835 TransformFtor Transform = TransformFtor())
4239 /// the layer below, along with the memory manager and symbol resolver.
4340 ///
4441 /// @return A handle for the added modules.
45 Expected addModule(VModuleKey K, std::shared_ptr M) {
42 Error addModule(VModuleKey K, std::shared_ptr M) {
4643 return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
4744 }
4845
49 /// @brief Remove the module associated with the handle H.
50 Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
46 /// @brief Remove the module associated with the VModuleKey K.
47 Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); }
5148
5249 /// @brief Search for the given named symbol.
5350 /// @param Name The name of the symbol to search for.
5855 }
5956
6057 /// @brief Get the address of the given symbol in the context of the module
61 /// represented by the handle H. This call is forwarded to the base
58 /// represented by the VModuleKey K. This call is forwarded to the base
6259 /// layer's implementation.
6360 /// @param H The handle for the module to search in.
6461 /// @param Name The name of the symbol to search for.
6562 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
6663 /// @return A handle for the given named symbol, if it is found in the
6764 /// given module.
68 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
65 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
6966 bool ExportedSymbolsOnly) {
70 return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
67 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
7168 }
7269
7370 /// @brief Immediately emit and finalize the module represented by the given
74 /// handle.
71 /// VModuleKey.
7572 /// @param H Handle for module to emit/finalize.
76 Error emitAndFinalize(ModuleHandleT H) {
77 return BaseLayer.emitAndFinalize(H);
78 }
73 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
7974
8075 /// @brief Access the transform functor directly.
8176 TransformFtor& getTransform() { return Transform; }
3939 /// is deferred until the first time the client requests the address (via
4040 /// JITSymbol::getAddress) for a symbol contained in this layer.
4141 template class LazyEmittingLayer {
42 public:
43
44 using BaseLayerHandleT = typename BaseLayerT::ModuleHandleT;
45
4642 private:
4743 class EmissionDeferredModule {
4844 public:
6460 return 0;
6561 else if (this->EmitState == NotEmitted) {
6662 this->EmitState = Emitting;
67 if (auto HandleOrErr = this->emitToBaseLayer(B))
68 Handle = std::move(*HandleOrErr);
69 else
70 return HandleOrErr.takeError();
63 if (auto Err = this->emitToBaseLayer(B))
64 return std::move(Err);
7165 this->EmitState = Emitted;
7266 }
73 if (auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly))
67 if (auto Sym = B.findSymbolIn(K, PName, ExportedSymbolsOnly))
7468 return Sym.getAddress();
7569 else if (auto Err = Sym.takeError())
7670 return std::move(Err);
8882 // RuntimeDyld that did the lookup), so just return a nullptr here.
8983 return nullptr;
9084 case Emitted:
91 return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
85 return B.findSymbolIn(K, Name, ExportedSymbolsOnly);
9286 }
9387 llvm_unreachable("Invalid emit-state.");
9488 }
9589
9690 Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
97 return EmitState != NotEmitted ? BaseLayer.removeModule(Handle)
91 return EmitState != NotEmitted ? BaseLayer.removeModule(K)
9892 : Error::success();
9993 }
10094
10397 "Cannot emitAndFinalize while already emitting");
10498 if (EmitState == NotEmitted) {
10599 EmitState = Emitting;
106 Handle = emitToBaseLayer(BaseLayer);
100 emitToBaseLayer(BaseLayer);
107101 EmitState = Emitted;
108102 }
109 BaseLayer.emitAndFinalize(Handle);
103 BaseLayer.emitAndFinalize(K);
110104 }
111105
112106 private:
134128 return buildMangledSymbols(Name, ExportedSymbolsOnly);
135129 }
136130
137 Expected emitToBaseLayer(BaseLayerT &BaseLayer) {
131 Error emitToBaseLayer(BaseLayerT &BaseLayer) {
138132 // We don't need the mangled names set any more: Once we've emitted this
139133 // to the base layer we'll just look for symbols there.
140134 MangledSymbols.reset();
191185 }
192186
193187 enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
194 BaseLayerHandleT Handle;
195188 VModuleKey K;
196189 std::shared_ptr M;
197190 mutable std::unique_ptr> MangledSymbols;
198191 };
199192
200 using ModuleListT = std::list>;
201
202193 BaseLayerT &BaseLayer;
203 ModuleListT ModuleList;
194 std::map> ModuleMap;
204195
205196 public:
206
207 /// @brief Handle to a loaded module.
208 using ModuleHandleT = typename ModuleListT::iterator;
209197
210198 /// @brief Construct a lazy emitting layer.
211199 LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
212200
213201 /// @brief Add the given module to the lazy emitting layer.
214 Expected addModule(VModuleKey K, std::shared_ptr M) {
215 return ModuleList.insert(
216 ModuleList.end(),
217 llvm::make_unique(std::move(K), std::move(M)));
202 Error addModule(VModuleKey K, std::shared_ptr M) {
203 assert(!ModuleMap.count(K) && "VModuleKey K already in use");
204 ModuleMap[K] =
205 llvm::make_unique(std::move(K), std::move(M));
206 return Error::success();
218207 }
219208
220209 /// @brief Remove the module represented by the given handle.
221210 ///
222211 /// This method will free the memory associated with the given module, both
223212 /// in this layer, and the base layer.
224 Error removeModule(ModuleHandleT H) {
225 Error Err = (*H)->removeModuleFromBaseLayer(BaseLayer);
226 ModuleList.erase(H);
227 return Err;
213 Error removeModule(VModuleKey K) {
214 auto I = ModuleMap.find(K);
215 assert(I != ModuleMap.end() && "VModuleKey K not valid here");
216 auto EDM = std::move(I.second);
217 ModuleMap.erase(I);
218 return EDM->removeModuleFromBaseLayer(BaseLayer);
228219 }
229220
230221 /// @brief Search for the given named symbol.
239230 // If not found then search the deferred modules. If any of these contain a
240231 // definition of 'Name' then they will return a JITSymbol that will emit
241232 // the corresponding module when the symbol address is requested.
242 for (auto &DeferredMod : ModuleList)
243 if (auto Symbol = DeferredMod->find(Name, ExportedSymbolsOnly, BaseLayer))
233 for (auto &KV : ModuleMap)
234 if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer))
244235 return Symbol;
245236
246237 // If no definition found anywhere return a null symbol.
248239 }
249240
250241 /// @brief Get the address of the given symbol in the context of the of
251 /// compiled modules represented by the handle H.
252 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
242 /// compiled modules represented by the key K.
243 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
253244 bool ExportedSymbolsOnly) {
254 return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
245 assert(ModuleMap.count(K) && "VModuleKey K not valid here");
246 return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
255247 }
256248
257249 /// @brief Immediately emit and finalize the module represented by the given
258 /// handle.
259 /// @param H Handle for module to emit/finalize.
260 Error emitAndFinalize(ModuleHandleT H) {
261 return (*H)->emitAndFinalize(BaseLayer);
250 /// key.
251 Error emitAndFinalize(VModuleKey K) {
252 assert(ModuleMap.count(K) && "VModuleKey K not valid here");
253 return ModuleMap[K]->emitAndFinalize(BaseLayer);
262254 }
263255 };
264256
3030 template
3131 class ObjectTransformLayer {
3232 public:
33 /// @brief Handle to a set of added objects.
34 using ObjHandleT = typename BaseLayerT::ObjHandleT;
35
3633 /// @brief Construct an ObjectTransformLayer with the given BaseLayer
3734 ObjectTransformLayer(BaseLayerT &BaseLayer,
3835 TransformFtor Transform = TransformFtor())
4340 /// memory manager and symbol resolver.
4441 ///
4542 /// @return A handle for the added objects.
46 template
47 Expected addObject(VModuleKey K, ObjectPtr Obj) {
43 template Error addObject(VModuleKey K, ObjectPtr Obj) {
4844 return BaseLayer.addObject(std::move(K), Transform(std::move(Obj)));
4945 }
5046
51 /// @brief Remove the object set associated with the handle H.
52 Error removeObject(ObjHandleT H) { return BaseLayer.removeObject(H); }
47 /// @brief Remove the object set associated with the VModuleKey K.
48 Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); }
5349
5450 /// @brief Search for the given named symbol.
5551 /// @param Name The name of the symbol to search for.
6056 }
6157
6258 /// @brief Get the address of the given symbol in the context of the set of
63 /// objects represented by the handle H. This call is forwarded to the
64 /// base layer's implementation.
59 /// objects represented by the VModuleKey K. This call is forwarded to
60 /// the base layer's implementation.
6561 /// @param H The handle for the object set to search in.
6662 /// @param Name The name of the symbol to search for.
6763 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
6864 /// @return A handle for the given named symbol, if it is found in the
6965 /// given object set.
70 JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
66 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
7167 bool ExportedSymbolsOnly) {
72 return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
68 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
7369 }
7470
7571 /// @brief Immediately emit and finalize the object set represented by the
76 /// given handle.
77 /// @param H Handle for object set to emit/finalize.
78 Error emitAndFinalize(ObjHandleT H) {
79 return BaseLayer.emitAndFinalize(H);
80 }
72 /// given VModuleKey K.
73 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
8174
82 /// @brief Map section addresses for the objects associated with the handle H.
83 void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
75 /// @brief Map section addresses for the objects associated with the
76 /// VModuleKey K.
77 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
8478 JITTargetAddress TargetAddr) {
85 BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr);
79 BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr);
8680 }
8781
8882 /// @brief Access the transform functor directly.
8080 StringMap SymbolTable;
8181 bool Finalized = false;
8282 };
83
84 using LinkedObjectListT = std::list>;
85
86 public:
87 /// @brief Handle to a loaded object.
88 using ObjHandleT = LinkedObjectListT::iterator;
8983 };
9084
9185 /// @brief Bare bones object linking layer.
10094 using RTDyldObjectLinkingLayerBase::ObjectPtr;
10195
10296 /// @brief Functor for receiving object-loaded notifications.
103 using NotifyLoadedFtor =
104 std::function
105 const RuntimeDyld::LoadedObjectInfo &)>;
97 using NotifyLoadedFtor = std::function
98 VModuleKey, const ObjectPtr &Obj, const RuntimeDyld::LoadedObjectInfo &)>;
10699
107100 /// @brief Functor for receiving finalization notifications.
108 using NotifyFinalizedFtor = std::functionObjHandleT)>;
101 using NotifyFinalizedFtor = std::functionVModuleKey)>;
109102
110103 private:
111104 template
126119 MemMgr->deregisterEHFrames();
127120 }
128121
129 void setHandle(ObjHandleT H) {
130 PFC->Handle = H;
131 }
132
133122 Error finalize() override {
134123 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
135124
139128 PFC->RTDyld = &RTDyld;
140129
141130 this->Finalized = true;
142 auto Err = PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
131 auto Err = PFC->Finalizer(RTDyld, std::move(PFC->Obj),
143132 [&]() { this->updateSymbolTable(RTDyld); });
144133
145134 // Release resources.
203192 std::shared_ptr Resolver;
204193 FinalizerFtor Finalizer;
205194 bool ProcessAllSections;
206 ObjHandleT Handle;
207195 RuntimeDyld *RTDyld;
208196 };
209197
256244 }
257245
258246 /// @brief Add an object to the JIT.
259 ///
260 /// @return A handle that can be used to refer to the loaded object (for
261 /// symbol searching, finalization, freeing memory, etc.).
262 Expected addObject(VModuleKey K, ObjectPtr Obj) {
263 auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
264 const ObjectPtr &ObjToLoad,
265 std::function LOSHandleLoad) -> Error {
247 Error addObject(VModuleKey K, ObjectPtr Obj) {
248 auto Finalizer = [&, K](RuntimeDyld &RTDyld, const ObjectPtr &ObjToLoad,
249 std::function LOSHandleLoad) -> Error {
266250 std::unique_ptr Info =
267251 RTDyld.loadObject(*ObjToLoad->getBinary());
268252
269253 LOSHandleLoad();
270254
271255 if (this->NotifyLoaded)
272 this->NotifyLoaded(H, ObjToLoad, *Info);
256 this->NotifyLoaded(K, ObjToLoad, *Info);
273257
274258 RTDyld.finalizeWithMemoryManagerLocking();
275259
278262 inconvertibleErrorCode());
279263
280264 if (this->NotifyFinalized)
281 this->NotifyFinalized(H);
265 this->NotifyFinalized(K);
282266
283267 return Error::success();
284268 };
285269
286 auto LO =
270 assert(!LinkedObjects.count(K) && "VModuleKey already in use");
271
272 LinkedObjects[K] =
287273 createLinkedObject(ES, std::move(Obj), GetMemMgr(K), GetResolver(K),
288274 std::move(Finalizer), ProcessAllSections);
289 // LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
290 // below.
291 auto *LOPtr = LO.get();
292
293 ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO));
294 LOPtr->setHandle(Handle);
295
296 return Handle;
297 }
298
299 /// @brief Remove the object associated with handle H.
275
276 return Error::success();
277 }
278
279 /// @brief Remove the object associated with VModuleKey K.
300280 ///
301281 /// All memory allocated for the object will be freed, and the sections and
302282 /// symbols it provided will no longer be available. No attempt is made to
304284 /// indirectly) will result in undefined behavior. If dependence tracking is
305285 /// required to detect or resolve such issues it should be added at a higher
306286 /// layer.
307 Error removeObject(ObjHandleT H) {
287 Error removeObject(VModuleKey K) {
288 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
308289 // How do we invalidate the symbols in H?
309 LinkedObjList.erase(H);
290 LinkedObjects.erase(K);
310291 return Error::success();
311292 }
312293
315296 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
316297 /// @return A handle for the given named symbol, if it exists.
317298 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
318 for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E;
319 ++I)
320 if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
321 return Symbol;
299 for (auto &KV : LinkedObjects)
300 if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly))
301 return Sym;
302 else if (auto Err = Sym.takeError())
303 return std::move(Err);
322304
323305 return nullptr;
324306 }
325307
326308 /// @brief Search for the given named symbol in the context of the loaded
327 /// object represented by the handle H.
328 /// @param H The handle for the object to search in.
309 /// object represented by the VModuleKey K.
310 /// @param K The VModuleKey for the object to search in.
329311 /// @param Name The name of the symbol to search for.
330312 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
331313 /// @return A handle for the given named symbol, if it is found in the
332314 /// given object.
333 JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
315 JITSymbol findSymbolIn(VModuleKey K, StringRef Name,
334316 bool ExportedSymbolsOnly) {
335 return (*H)->getSymbol(Name, ExportedSymbolsOnly);
336 }
337
338 /// @brief Map section addresses for the object associated with the handle H.
339 void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
317 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
318 return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly);
319 }
320
321 /// @brief Map section addresses for the object associated with the
322 /// VModuleKey K.
323 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
340324 JITTargetAddress TargetAddr) {
341 (*H)->mapSectionAddress(LocalAddress, TargetAddr);
325 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
326 LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr);
342327 }
343328
344329 /// @brief Immediately emit and finalize the object represented by the given
345 /// handle.
346 /// @param H Handle for object to emit/finalize.
347 Error emitAndFinalize(ObjHandleT H) { return (*H)->finalize(); }
330 /// VModuleKey.
331 /// @param K VModuleKey for object to emit/finalize.
332 Error emitAndFinalize(VModuleKey K) {
333 assert(LinkedObjects.count(K) && "VModuleKey not associated with object");
334 return LinkedObjects[K]->finalize();
335 }
348336
349337 private:
350338 ExecutionSession &ES;
351 LinkedObjectListT LinkedObjList;
339
340 std::map> LinkedObjects;
352341 MemoryManagerGetter GetMemMgr;
353342 ResolverGetter GetResolver;
354343 NotifyLoadedFtor NotifyLoaded;
3030
3131 typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
3232 typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
33 typedef uint32_t LLVMOrcModuleHandle;
33 typedef uint64_t LLVMOrcModuleHandle;
3434 typedef uint64_t LLVMOrcTargetAddress;
3535 typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name, void *LookupCtx);
3636 typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
3232 #include
3333 #include
3434 #include
35 #include
3536 #include
3637 #include
3738 #include
4849
4950 namespace detail {
5051
51
52 class GenericHandle {
52 // FIXME: Kill this off once the Layer concept becomes an interface.
53 class GenericLayer {
54 public:
55 virtual ~GenericLayer() = default;
56
57 virtual JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
58 bool ExportedSymbolsOnly) = 0;
59 virtual Error removeModule(orc::VModuleKey K) = 0;
60 };
61
62 template class GenericLayerImpl : public GenericLayer {
5363 public:
54 GenericHandle(orc::VModuleKey K) : K(K) {}
55
56 virtual ~GenericHandle() = default;
57
58 virtual JITSymbol findSymbolIn(const std::string &Name,
59 bool ExportedSymbolsOnly) = 0;
60 virtual Error removeModule(orc::ExecutionSession &ES) = 0;
61
62 orc::VModuleKey K;
63 };
64
65 template class GenericHandleImpl : public GenericHandle {
66 public:
67 GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle,
68 orc::VModuleKey K)
69 : GenericHandle(std::move(K)), Layer(Layer), Handle(std::move(Handle)) {
70 }
71
72 JITSymbol findSymbolIn(const std::string &Name,
64 GenericLayerImpl(LayerT &Layer) : Layer(Layer) {}
65
66 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
7367 bool ExportedSymbolsOnly) override {
74 return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
75 }
76
77 Error removeModule(orc::ExecutionSession &ES) override {
78 auto Err = Layer.removeModule(Handle);
79 ES.releaseVModule(K);
80 return Err;
68 return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly);
69 }
70
71 Error removeModule(orc::VModuleKey K) override {
72 return Layer.removeModule(K);
8173 }
8274
8375 private:
8476 LayerT &Layer;
85 typename LayerT::ModuleHandleT Handle;
8677 };
8778
8879 template <>
89 class GenericHandleImpl
90 : public GenericHandle {
80 class GenericLayerImpl : public GenericLayer {
9181 private:
9282 using LayerT = orc::RTDyldObjectLinkingLayer;
9383 public:
94 GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle,
95 orc::VModuleKey K)
96 : GenericHandle(std::move(K)), Layer(Layer), Handle(std::move(Handle)) {
97 }
98
99 JITSymbol findSymbolIn(const std::string &Name,
84 GenericLayerImpl(LayerT &Layer) : Layer(Layer) {}
85
86 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
10087 bool ExportedSymbolsOnly) override {
101 return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
102 }
103
104 Error removeModule(orc::ExecutionSession &ES) override {
105 auto Err = Layer.removeObject(Handle);
106 ES.releaseVModule(K);
107 return Err;
88 return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly);
89 }
90
91 Error removeModule(orc::VModuleKey K) override {
92 return Layer.removeObject(K);
10893 }
10994
11095 private:
11196 LayerT &Layer;
112 typename LayerT::ObjHandleT Handle;
11397 };
11498
115 template
116 std::unique_ptr>
117 createGenericHandle(LayerT &Layer, HandleT Handle, orc::VModuleKey K) {
118 return llvm::make_unique>(
119 Layer, std::move(Handle), std::move(K));
99 template
100 std::unique_ptr> createGenericLayer(LayerT &Layer) {
101 return llvm::make_unique>(Layer);
120102 }
121103
122104 } // end namespace detail
214196 };
215197
216198 public:
217 using ModuleHandleT = unsigned;
218199
219200 OrcCBindingsStack(TargetMachine &TM,
220201 std::unique_ptr CCMgr,
303284 }
304285 template
305286 LLVMOrcErrorCode
306 addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
307 std::shared_ptr M,
287 addIRModule(orc::VModuleKey &RetKey, LayerT &Layer, std::shared_ptr M,
308288 std::unique_ptr MemMgr,
309289 LLVMOrcSymbolResolverFn ExternalResolver,
310290 void *ExternalResolverCtx) {
322302 DtorNames.push_back(mangle(Dtor.Func->getName()));
323303
324304 // Add the module to the JIT.
325 ModuleHandleT H;
326 orc::VModuleKey K = ES.allocateVModule();
327 Resolvers[K] = std::make_shared(*this, ExternalResolver,
328 ExternalResolverCtx);
329 if (auto LHOrErr = Layer.addModule(K, std::move(M)))
330 H = createHandle(Layer, *LHOrErr, K);
331 else
332 return mapError(LHOrErr.takeError());
305 RetKey = ES.allocateVModule();
306 Resolvers[RetKey] = std::make_shared(
307 *this, ExternalResolver, ExternalResolverCtx);
308 if (auto Err = Layer.addModule(RetKey, std::move(M)))
309 return mapError(std::move(Err));
310
311 KeyLayers[RetKey] = detail::createGenericLayer(Layer);
333312
334313 // Run the static constructors, and save the static destructor runner for
335314 // execution when the JIT is torn down.
336 orc::CtorDtorRunner CtorRunner(std::move(CtorNames), H);
315 orc::CtorDtorRunner CtorRunner(std::move(CtorNames),
316 RetKey);
337317 if (auto Err = CtorRunner.runViaLayer(*this))
338318 return mapError(std::move(Err));
339319
340 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
341
342 RetHandle = H;
320 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), RetKey);
321
343322 return LLVMOrcErrSuccess;
344323 }
345324
346 LLVMOrcErrorCode addIRModuleEager(ModuleHandleT &RetHandle,
325 LLVMOrcErrorCode addIRModuleEager(orc::VModuleKey &RetKey,
347326 std::shared_ptr M,
348327 LLVMOrcSymbolResolverFn ExternalResolver,
349328 void *ExternalResolverCtx) {
350 return addIRModule(RetHandle, CompileLayer, std::move(M),
329 return addIRModule(RetKey, CompileLayer, std::move(M),
351330 llvm::make_unique(),
352331 std::move(ExternalResolver), ExternalResolverCtx);
353332 }
354333
355 LLVMOrcErrorCode addIRModuleLazy(ModuleHandleT &RetHandle,
334 LLVMOrcErrorCode addIRModuleLazy(orc::VModuleKey &RetKey,
356335 std::shared_ptr M,
357336 LLVMOrcSymbolResolverFn ExternalResolver,
358337 void *ExternalResolverCtx) {
359 return addIRModule(RetHandle, CODLayer, std::move(M),
338 return addIRModule(RetKey, CODLayer, std::move(M),
360339 llvm::make_unique(),
361340 std::move(ExternalResolver), ExternalResolverCtx);
362341 }
363342
364 LLVMOrcErrorCode removeModule(ModuleHandleT H) {
365 if (auto Err = GenericHandles[H]->removeModule(ES))
343 LLVMOrcErrorCode removeModule(orc::VModuleKey K) {
344 // FIXME: Should error release the module key?
345 if (auto Err = KeyLayers[K]->removeModule(K))
366346 return mapError(std::move(Err));
367 GenericHandles[H] = nullptr;
368 FreeHandleIndexes.push_back(H);
347 ES.releaseVModule(K);
348 KeyLayers.erase(K);
369349 return LLVMOrcErrSuccess;
370350 }
371351
372 LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
352 LLVMOrcErrorCode addObject(orc::VModuleKey &RetKey,
373353 std::unique_ptr ObjBuffer,
374354 LLVMOrcSymbolResolverFn ExternalResolver,
375355 void *ExternalResolverCtx) {
379359 auto OwningObj =
380360 std::make_shared(std::move(Obj), std::move(ObjBuffer));
381361
382 orc::VModuleKey K = ES.allocateVModule();
383 Resolvers[K] = std::make_shared(
362 RetKey = ES.allocateVModule();
363 Resolvers[RetKey] = std::make_shared(
384364 *this, ExternalResolver, ExternalResolverCtx);
385365
386 ModuleHandleT H;
387 if (auto HOrErr = ObjectLayer.addObject(K, std::move(OwningObj)))
388 H = createHandle(ObjectLayer, *HOrErr, K);
389 else
390 return mapError(HOrErr.takeError());
391
392 RetHandle = H;
366 if (auto Err = ObjectLayer.addObject(RetKey, std::move(OwningObj)))
367 return mapError(std::move(Err));
368
369 KeyLayers[RetKey] = detail::createGenericLayer(ObjectLayer);
393370
394371 return LLVMOrcErrSuccess;
395372 } else
403380 return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
404381 }
405382
406 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
383 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
407384 bool ExportedSymbolsOnly) {
408 return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
385 return KeyLayers[K]->findSymbolIn(K, Name, ExportedSymbolsOnly);
409386 }
410387
411388 LLVMOrcErrorCode findSymbolAddress(JITTargetAddress &RetAddr,
431408 const std::string &getErrorMessage() const { return ErrMsg; }
432409
433410 private:
434 template
435 unsigned createHandle(LayerT &Layer, HandleT Handle, orc::VModuleKey K) {
436 unsigned NewHandle;
437 if (!FreeHandleIndexes.empty()) {
438 NewHandle = FreeHandleIndexes.back();
439 FreeHandleIndexes.pop_back();
440 GenericHandles[NewHandle] =
441 detail::createGenericHandle(Layer, std::move(Handle), std::move(K));
442 return NewHandle;
443 } else {
444 NewHandle = GenericHandles.size();
445 GenericHandles.push_back(
446 detail::createGenericHandle(Layer, std::move(Handle), std::move(K)));
447 }
448 return NewHandle;
449 }
450411
451412 LLVMOrcErrorCode mapError(Error Err) {
452413 LLVMOrcErrorCode Result = LLVMOrcErrSuccess;
478439 CompileLayerT CompileLayer;
479440 CODLayerT CODLayer;
480441
481 std::vector> GenericHandles;
482 std::vector FreeHandleIndexes;
442 std::map> KeyLayers;
483443
484444 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
485445 std::vector> IRStaticDestructorRunners;
392392
393393 NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
394394
395 void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H,
395 void operator()(VModuleKey K,
396396 const RTDyldObjectLinkingLayer::ObjectPtr &Obj,
397397 const RuntimeDyld::LoadedObjectInfo &Info) const {
398 M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
398 M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad);
399399 M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
400400 M.MemMgr->notifyObjectLoaded(&M, *Obj->getBinary());
401401 }
407407 public:
408408 NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
409409
410 void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H) {
411 M.UnfinalizedSections.erase(H);
412 }
410 void operator()(VModuleKey K) { M.UnfinalizedSections.erase(K); }
413411
414412 private:
415413 OrcMCJITReplacement &M;
454452 // that have been emitted but not yet finalized so that we can forward the
455453 // mapSectionAddress calls appropriately.
456454 using SectionAddrSet = std::set;
457 struct ObjHandleCompare {
458 bool operator()(ObjectLayerT::ObjHandleT H1,
459 ObjectLayerT::ObjHandleT H2) const {
460 return &*H1 < &*H2;
461 }
462 };
463455 SectionAddrSet SectionsAllocatedSinceLastLoad;
464 std::map
465 UnfinalizedSections;
456 std::map UnfinalizedSections;
466457
467458 std::vector> Archives;
468459 };
5454 using IRDumpLayerT = orc::IRTransformLayer;
5555 using CODLayerT = orc::CompileOnDemandLayer;
5656 using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
57 using ModuleHandleT = CODLayerT::ModuleHandleT;
5857
5958 OrcLazyJIT(std::unique_ptr TM,
6059 std::unique_ptr CCMgr,
137136 // 1) Search the JIT symbols.
138137 // 2) Check for C++ runtime overrides.
139138 // 3) Search the host process (LLI)'s symbol table.
140 if (!ModulesHandle) {
139 if (!ModulesKey) {
141140 auto LegacyLookupInDylib = [this](const std::string &Name) -> JITSymbol {
142141 if (auto Sym = CODLayer.findSymbol(Name, true))
143142 return Sym;
159158 return nullptr;
160159 };
161160
162 auto K = ES.allocateVModule();
163 assert(!Resolvers.count(K) && "Resolver already present");
164 Resolvers[K] = orc::createSymbolResolver(
161 ModulesKey = ES.allocateVModule();
162 assert(!Resolvers.count(*ModulesKey) && "Resolver already present");
163 Resolvers[*ModulesKey] = orc::createSymbolResolver(
165164 [LegacyLookupInDylib](orc::SymbolFlagsMap &SymbolFlags,
166165 const orc::SymbolNameSet &Symbols) {
167166 auto NotFoundViaLegacyLookup = lookupFlagsWithLegacyFn(
180179 });
181180
182181 // Add the module to the JIT.
183 if (auto ModulesHandleOrErr =
184 CODLayer.addModule(std::move(K), std::move(M)))
185 ModulesHandle = std::move(*ModulesHandleOrErr);
186 else
187 return ModulesHandleOrErr.takeError();
188
189 } else if (auto Err = CODLayer.addExtraModule(*ModulesHandle, std::move(M)))
182 if (auto Err = CODLayer.addModule(*ModulesKey, std::move(M)))
183 return Err;
184
185 } else if (auto Err = CODLayer.addExtraModule(*ModulesKey, std::move(M)))
190186 return Err;
191187
192188 // Run the static constructors, and save the static destructor runner for
193189 // execution when the JIT is torn down.
194190 orc::CtorDtorRunner CtorRunner(std::move(CtorNames),
195 *ModulesHandle);
191 *ModulesKey);
196192 if (auto Err = CtorRunner.runViaLayer(CODLayer))
197193 return Err;
198194
199 IRStaticDestructorRunners.emplace_back(std::move(DtorNames),
200 *ModulesHandle);
195 IRStaticDestructorRunners.emplace_back(std::move(DtorNames), *ModulesKey);
201196
202197 return Error::success();
203198 }
206201 return CODLayer.findSymbol(mangle(Name), true);
207202 }
208203
209 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
210 return CODLayer.findSymbolIn(H, mangle(Name), true);
204 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name) {
205 return CODLayer.findSymbolIn(K, mangle(Name), true);
211206 }
212207
213208 private:
245240
246241 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
247242 std::vector> IRStaticDestructorRunners;
248 llvm::Optional<CODLayerT::ModuleHandleT> ModulesHandle;
243 llvm::Optional<orc::VModuleKey> ModulesKey;
249244 };
250245
251246 int runOrcLazyJIT(std::vector> Ms,
4242 // transform layer called the base layer and forwarded any return value.
4343 class MockBaseLayer {
4444 public:
45 typedef int ObjHandleT;
46
4745 MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
4846
49 template
50 llvm::Expected addObject(VModuleKey K, ObjPtrT Obj) {
47 template llvm::Error addObject(VModuleKey K, ObjPtrT Obj) {
5148 EXPECT_EQ(MockKey, K) << "Key should pass through";
5249 EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
5350 LastCalled = "addObject";
54 MockObjHandle = 111;
55 return MockObjHandle;
51 return llvm::Error::success();
5652 }
5753
5854 template void expectAddObject(VModuleKey K, ObjPtrT Obj) {
6056 MockObject = *Obj;
6157 }
6258
63
64 void verifyAddObject(ObjHandleT Returned) {
59 void verifyAddObject() {
6560 EXPECT_EQ("addObject", LastCalled);
66 EXPECT_EQ(MockObjHandle, Returned) << "Return should pass through";
67 resetExpectations();
68 }
69
70 llvm::Error removeObject(ObjHandleT H) {
71 EXPECT_EQ(MockObjHandle, H);
61 resetExpectations();
62 }
63
64 llvm::Error removeObject(VModuleKey K) {
65 EXPECT_EQ(MockKey, K);
7266 LastCalled = "removeObject";
7367 return llvm::Error::success();
7468 }
7569
76 void expectRemoveObject(ObjHandleT H) { MockObjHandle = H; }
70 void expectRemoveObject(VModuleKey K) { MockKey = K; }
7771 void verifyRemoveObject() {
7872 EXPECT_EQ("removeObject", LastCalled);
7973 resetExpectations();
9993 resetExpectations();
10094 }
10195
102 llvm::JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
96 llvm::JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
10397 bool ExportedSymbolsOnly) {
104 EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
98 EXPECT_EQ(MockKey, K) << "VModuleKey should pass through";
10599 EXPECT_EQ(MockName, Name) << "Name should pass through";
106100 EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
107101 LastCalled = "findSymbolIn";
108102 MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
109103 return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
110104 }
111 void expectFindSymbolIn(ObjHandleT H, const std::string &Name,
105 void expectFindSymbolIn(VModuleKey K, const std::string &Name,
112106 bool ExportedSymbolsOnly) {
113 MockObjHandle = H;
107 MockKey = K;
114108 MockName = Name;
115109 MockBool = ExportedSymbolsOnly;
116110 }
122116 resetExpectations();
123117 }
124118
125 llvm::Error emitAndFinalize(ObjHandleT H) {
126 EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
119 llvm::Error emitAndFinalize(VModuleKey K) {
120 EXPECT_EQ(MockKey, K) << "VModuleKey should pass through";
127121 LastCalled = "emitAndFinalize";
128122 return llvm::Error::success();
129123 }
130124
131 void expectEmitAndFinalize(ObjHandleT H) { MockObjHandle = H; }
125 void expectEmitAndFinalize(VModuleKey K) { MockKey = K; }
132126
133127 void verifyEmitAndFinalize() {
134128 EXPECT_EQ("emitAndFinalize", LastCalled);
135129 resetExpectations();
136130 }
137131
138 void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
132 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
139133 llvm::JITTargetAddress TargetAddr) {
140 EXPECT_EQ(MockObjHandle, H);
134 EXPECT_EQ(MockKey, K);
141135 EXPECT_EQ(MockLocalAddress, LocalAddress);
142136 EXPECT_EQ(MockTargetAddress, TargetAddr);
143137 LastCalled = "mapSectionAddress";
144138 }
145 void expectMapSectionAddress(ObjHandleT H, const void *LocalAddress,
139 void expectMapSectionAddress(VModuleKey K, const void *LocalAddress,
146140 llvm::JITTargetAddress TargetAddr) {
147 MockObjHandle = H;
141 MockKey = K;
148142 MockLocalAddress = LocalAddress;
149143 MockTargetAddress = TargetAddr;
150144 }
158152 std::string LastCalled;
159153 VModuleKey MockKey;
160154 MockObjectFile MockObject;
161 ObjHandleT MockObjHandle;
162155 std::string MockName;
163156 bool MockBool;
164157 llvm::JITSymbol MockSymbol;
171164 LastCalled = "nothing";
172165 MockKey = 0;
173166 MockObject = 0;
174 MockObjHandle = 0;
175167 MockName = "bogus";
176168 MockSymbol = llvm::JITSymbol(nullptr);
177169 MockLocalAddress = nullptr;
205197 auto K1 = ES.allocateVModule();
206198 auto Obj1 = std::make_shared(211);
207199 M.expectAddObject(K1, Obj1);
208 auto H = cantFail(T1.addObject(K1, std::move(Obj1)));
209 M.verifyAddObject(H);
200 cantFail(T1.addObject(K1, std::move(Obj1)));
201 M.verifyAddObject();
210202
211203 // Test addObjectSet with T2 (mutating)
212204 auto K2 = ES.allocateVModule();
213205 auto Obj2 = std::make_shared(222);
214206 M.expectAddObject(K2, Obj2);
215 H = cantFail(T2.addObject(K2, Obj2));
216 M.verifyAddObject(H);
207 cantFail(T2.addObject(K2, Obj2));
208 M.verifyAddObject();
217209 EXPECT_EQ(223, *Obj2) << "Expected mutation";
218210
219211 // Test removeObjectSet
220 M.expectRemoveObject(H);
221 cantFail(T1.removeObject(H));
212 M.expectRemoveObject(K2);
213 cantFail(T1.removeObject(K2));
222214 M.verifyRemoveObject();
223215
224216 // Test findSymbol
231223 // Test findSymbolIn
232224 Name = "bar";
233225 ExportedOnly = false;
234 M.expectFindSymbolIn(H, Name, ExportedOnly);
235 llvm::JITSymbol Sym2 = T1.findSymbolIn(H, Name, ExportedOnly);
226 M.expectFindSymbolIn(K1, Name, ExportedOnly);
227 llvm::JITSymbol Sym2 = T1.findSymbolIn(K1, Name, ExportedOnly);
236228 M.verifyFindSymbolIn(std::move(Sym2));
237229
238230 // Test emitAndFinalize
239 M.expectEmitAndFinalize(H);
240 cantFail(T2.emitAndFinalize(H));
231 M.expectEmitAndFinalize(K1);
232 cantFail(T2.emitAndFinalize(K1));
241233 M.verifyEmitAndFinalize();
242234
243235 // Test mapSectionAddress
244236 char Buffer[24];
245237 llvm::JITTargetAddress MockAddress = 255;
246 M.expectMapSectionAddress(H, Buffer, MockAddress);
247 T1.mapSectionAddress(H, Buffer, MockAddress);
238 M.expectMapSectionAddress(K1, Buffer, MockAddress);
239 T1.mapSectionAddress(K1, Buffer, MockAddress);
248240 M.verifyMapSectionAddress();
249241
250242 // Verify transform getter (non-const)
316308
317309 // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
318310 // compile.
319 decltype(TransformLayer)::ObjHandleT H2;
320 cantFail(TransformLayer.emitAndFinalize(H2));
321 TransformLayer.findSymbolIn(H2, Name, false);
311 VModuleKey DummyKey = ES.allocateVModule();
312 cantFail(TransformLayer.emitAndFinalize(DummyKey));
313 TransformLayer.findSymbolIn(DummyKey, Name, false);
322314 TransformLayer.findSymbol(Name, true);
323 TransformLayer.mapSectionAddress(H2, nullptr, 0);
324 cantFail(TransformLayer.removeObject(H2));
315 TransformLayer.mapSectionAddress(DummyKey, nullptr, 0);
316 cantFail(TransformLayer.removeObject(DummyKey));
325317 }
326318 }
9999
100100 {
101101 // Test with ProcessAllSections = false (the default).
102 auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), Obj));
103 cantFail(ObjLayer.emitAndFinalize(H));
102 auto K = ES.allocateVModule();
103 cantFail(ObjLayer.addObject(K, Obj));
104 cantFail(ObjLayer.emitAndFinalize(K));
104105 EXPECT_EQ(DebugSectionSeen, false)
105106 << "Unexpected debug info section";
106 cantFail(ObjLayer.removeObject(H));
107 cantFail(ObjLayer.removeObject(K));
107108 }
108109
109110 {
110111 // Test with ProcessAllSections = true.
111112 ObjLayer.setProcessAllSections(true);
112 auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), Obj));
113 cantFail(ObjLayer.emitAndFinalize(H));
113 auto K = ES.allocateVModule();
114 cantFail(ObjLayer.addObject(K, Obj));
115 cantFail(ObjLayer.emitAndFinalize(K));
114116 EXPECT_EQ(DebugSectionSeen, true)
115117 << "Expected debug info section not seen";
116 cantFail(ObjLayer.removeObject(H));
118 cantFail(ObjLayer.removeObject(K));
117119 }
118120 }
119121
197199 return lookupWithLegacyFn(Query, Symbols, LegacyLookup);
198200 });
199201
200 auto H = cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
201 cantFail(ObjLayer.emitAndFinalize(H));
202 cantFail(ObjLayer.removeObject(H));
202 cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
203 cantFail(ObjLayer.emitAndFinalize(K2));
204 cantFail(ObjLayer.removeObject(K2));
203205
204206 // Finalization of module 2 should trigger finalization of module 1.
205207 // Verify that finalize on SMMW is only called once.
263265 std::make_shared>(
264266 Compile(*MB2.getModule()));
265267
266 auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj1)));
268 auto K = ES.allocateVModule();
269 cantFail(ObjLayer.addObject(K, std::move(Obj1)));
267270 cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj2)));
268 cantFail(ObjLayer.emitAndFinalize(H));
269 cantFail(ObjLayer.removeObject(H));
271 cantFail(ObjLayer.emitAndFinalize(K));
272 cantFail(ObjLayer.removeObject(K));
270273
271274 // Only one call to needsToReserveAllocationSpace should have been made.
272275 EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)
280283 RTDyldObjectLinkingLayer ObjLayer(
281284 ES, [](VModuleKey) { return nullptr; },
282285 [](VModuleKey) { return std::make_shared(); },
283 [](RTDyldObjectLinkingLayer::ObjHandleT,
284 const RTDyldObjectLinkingLayer::ObjectPtr &obj,
286 [](VModuleKey, const RTDyldObjectLinkingLayer::ObjectPtr &obj,
285287 const RuntimeDyld::LoadedObjectInfo &info) {});
286288 }
287289