llvm.org GIT mirror llvm / 966d9eb
[Orc] Remove the memory manager argument to addModule, and de-templatize the symbol resolver argument. De-templatizing the symbol resolver is part of the ongoing simplification of ORC layer API. Removing the memory management argument (and delegating construction of memory managers for RTDyldObjectLinkingLayer to a functor passed in to the constructor) allows us to build JITs whose base object layers need not be compatible with RTDyldObjectLinkingLayer's memory mangement scheme. For example, a 'remote object layer' that sends fully relocatable objects directly to the remote does not need a memory management scheme at all (that will be handled by the remote). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307058 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 3 years ago
20 changed file(s) with 136 addition(s) and 188 deletion(s). Raw diff Collapse all Expand all
4747
4848 KaleidoscopeJIT()
4949 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
50 ObjectLayer([]() { return std::make_shared(); }),
5051 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
5152 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
5253 }
7475 // Add the set to the JIT with the resolver we created above and a newly
7576 // created SectionMemoryManager.
7677 return CompileLayer.addModule(std::move(M),
77 make_unique(),
7878 std::move(Resolver));
7979 }
8080
5656
5757 KaleidoscopeJIT()
5858 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
59 ObjectLayer([]() { return std::make_shared(); }),
5960 CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
6061 OptimizeLayer(CompileLayer,
6162 [this](std::shared_ptr M) {
8788 // Add the set to the JIT with the resolver we created above and a newly
8889 // created SectionMemoryManager.
8990 return OptimizeLayer.addModule(std::move(M),
90 make_unique(),
9191 std::move(Resolver));
9292 }
9393
6262
6363 KaleidoscopeJIT()
6464 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
65 ObjectLayer([]() { return std::make_shared(); }),
6566 CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
6667 OptimizeLayer(CompileLayer,
6768 [this](std::shared_ptr M) {
100101 // Add the set to the JIT with the resolver we created above and a newly
101102 // created SectionMemoryManager.
102103 return CODLayer.addModule(std::move(M),
103 make_unique(),
104104 std::move(Resolver));
105105 }
106106
8989 KaleidoscopeJIT()
9090 : TM(EngineBuilder().selectTarget()),
9191 DL(TM->createDataLayout()),
92 ObjectLayer([]() { return std::make_shared(); }),
9293 CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
9394 OptimizeLayer(CompileLayer,
9495 [this](std::shared_ptr M) {
127128 // Add the set to the JIT with the resolver we created above and a newly
128129 // created SectionMemoryManager.
129130 return OptimizeLayer.addModule(std::move(M),
130 make_unique(),
131131 std::move(Resolver));
132132 }
133133
9696 : TM(EngineBuilder().selectTarget(Triple(Remote.getTargetTriple()), "",
9797 "", SmallVector())),
9898 DL(TM->createDataLayout()),
99 ObjectLayer([&Remote]() {
100 std::unique_ptr MemMgr;
101 if (auto Err = Remote.createRemoteMemoryManager(MemMgr)) {
102 logAllUnhandledErrors(std::move(Err), errs(),
103 "Error creating remote memory manager:");
104 exit(1);
105 }
106 return MemMgr;
107 }),
99108 CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
100109 OptimizeLayer(CompileLayer,
101110 [this](std::shared_ptr M) {
145154 return JITSymbol(nullptr);
146155 });
147156
148 std::unique_ptr MemMgr;
149 if (auto Err = Remote.createRemoteMemoryManager(MemMgr)) {
150 logAllUnhandledErrors(std::move(Err), errs(),
151 "Error creating remote memory manager:");
152 exit(1);
153 }
154
155157 // Add the set to the JIT with the resolver we created above and a newly
156158 // created SectionMemoryManager.
157159 return OptimizeLayer.addModule(std::move(M),
158 std::move(MemMgr),
159160 std::move(Resolver));
160161 }
161162
4444
4545 KaleidoscopeJIT()
4646 : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
47 ObjectLayer([]() { return std::make_shared(); }),
4748 CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
4849 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
4950 }
6263 },
6364 [](const std::string &S) { return nullptr; });
6465 auto H = CompileLayer.addModule(std::move(M),
65 make_unique(),
6666 std::move(Resolver));
6767
6868 ModuleHandles.push_back(H);
145145 std::unique_ptr)>;
146146
147147 struct SourceModuleEntry {
148 std::unique_ptr> SourceMod;
148 std::shared_ptr> SourceMod;
149149 std::set StubsToClone;
150150 };
151151
153153 using SourceModuleHandle = typename SourceModulesList::size_type;
154154
155155 SourceModuleHandle
156 addSourceModule(std::unique_ptr> M) {
156 addSourceModule(std::shared_ptr> M) {
157157 SourceModuleHandle H = SourceModules.size();
158158 SourceModules.push_back(SourceModuleEntry());
159159 SourceModules.back().SourceMod = std::move(M);
161161 }
162162
163163 Module& getSourceModule(SourceModuleHandle H) {
164 return SourceModules[H].SourceMod->getResource();
164 return *SourceModules[H].SourceMod;
165165 }
166166
167167 std::set& getStubsToClone(SourceModuleHandle H) {
183183 BaseLayer.removeModule(BLH);
184184 }
185185
186 std::unique_ptr ExternalSymbolResolver;
187 std::unique_ptr> MemMgr;
186 std::shared_ptr ExternalSymbolResolver;
188187 std::unique_ptr StubsMgr;
189188 StaticGlobalRenamer StaticRenamer;
190 ModuleAdderFtor ModuleAdder;
191189 SourceModulesList SourceModules;
192190 std::vector BaseLayerHandles;
193191 };
195193 using LogicalDylibList = std::list;
196194
197195 public:
196
198197 /// @brief Handle to loaded module.
199198 using ModuleHandleT = typename LogicalDylibList::iterator;
200199
221220 }
222221
223222 /// @brief Add a module to the compile-on-demand layer.
224 template
225223 ModuleHandleT addModule(std::shared_ptr M,
226 MemoryManagerPtrT MemMgr,
227 SymbolResolverPtrT Resolver) {
224 std::shared_ptr Resolver) {
228225
229226 LogicalDylibs.push_back(LogicalDylib());
230227 auto &LD = LogicalDylibs.back();
231228 LD.ExternalSymbolResolver = std::move(Resolver);
232229 LD.StubsMgr = CreateIndirectStubsManager();
233230
234 auto &MemMgrRef = *MemMgr;
235 LD.MemMgr = wrapOwnership(std::move(MemMgr));
236
237 LD.ModuleAdder =
238 [&MemMgrRef](BaseLayerT &B, std::unique_ptr M,
239 std::unique_ptr R) {
240 return B.addModule(std::move(M), &MemMgrRef, std::move(R));
241 };
242
243231 // Process each of the modules in this module set.
244 addLogicalModule(LogicalDylibs.back(), std::move(M));
232 addLogicalModule(LD, std::move(M));
245233
246234 return std::prev(LogicalDylibs.end());
247235 }
308296 }
309297
310298 private:
311 template
312 void addLogicalModule(LogicalDylib &LD, ModulePtrT SrcMPtr) {
299
300 void addLogicalModule(LogicalDylib &LD, std::shared_ptr SrcMPtr) {
301
313302 // Rename all static functions / globals to $static.X :
314303 // This will unique the names across all modules in the logical dylib,
315304 // simplifying symbol lookup.
321310
322311 // Create a logical module handle for SrcM within the logical dylib.
323312 Module &SrcM = *SrcMPtr;
324 auto LMId = LD.addSourceModule(wrapOwnership(std::move(SrcMPtr)));
313 auto LMId = LD.addSourceModule(std::move(SrcMPtr));
325314
326315 // Create stub functions.
327316 const DataLayout &DL = SrcM.getDataLayout();
447436 return LD.ExternalSymbolResolver->findSymbol(Name);
448437 });
449438
450 auto GVsH = LD.ModuleAdder(BaseLayer, std::move(GVsM),
451 std::move(GVsResolver));
439 auto GVsH = BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver));
452440 LD.BaseLayerHandles.push_back(GVsH);
453441 }
454442
574562 return LD.ExternalSymbolResolver->findSymbol(Name);
575563 });
576564
577 return LD.ModuleAdder(BaseLayer, std::move(M), std::move(Resolver));
565 return BaseLayer.addModule(std::move(M), std::move(Resolver));
578566 }
579567
580568 BaseLayerT &BaseLayer;
4949 /// along with the given memory manager and symbol resolver.
5050 ///
5151 /// @return A handle for the added module.
52 template
5352 ModuleHandleT addModule(std::shared_ptr M,
54 MemoryManagerPtrT MemMgr,
55 SymbolResolverPtrT Resolver) {
53 std::shared_ptr Resolver) {
5654 using CompileResult = decltype(Compile(*M));
5755 auto Obj = std::make_shared(Compile(*M));
58 return BaseLayer.addObject(std::move(Obj), std::move(MemMgr),
59 std::move(Resolver));
56 return BaseLayer.addObject(std::move(Obj), std::move(Resolver));
6057 }
6158
6259 /// @brief Remove the module associated with the handle H.
4141 /// the layer below, along with the memory manager and symbol resolver.
4242 ///
4343 /// @return A handle for the added modules.
44 template
4544 ModuleHandleT addModule(std::shared_ptr M,
46 MemoryManagerPtrT MemMgr,
47 SymbolResolverPtrT Resolver) {
48 return BaseLayer.addModule(Transform(std::move(M)), std::move(MemMgr),
49 std::move(Resolver));
45 std::shared_ptr Resolver) {
46 return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver));
5047 }
5148
5249 /// @brief Remove the module associated with the handle H.
4444
4545 template
4646 typename ExternalLookupFtorT>
47 std::unique_ptr>
47 std::shared_ptr>
4848 createLambdaResolver(DylibLookupFtorT DylibLookupFtor,
4949 ExternalLookupFtorT ExternalLookupFtor) {
5050 using LR = LambdaResolver;
4545 private:
4646 class EmissionDeferredModule {
4747 public:
48 EmissionDeferredModule() = default;
49 virtual ~EmissionDeferredModule() = default;
48 EmissionDeferredModule(std::shared_ptr M,
49 std::shared_ptr Resolver)
50 : M(std::move(M)), Resolver(std::move(Resolver)) {}
5051
5152 JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
5253 switch (EmitState) {
100101 BaseLayer.emitAndFinalize(Handle);
101102 }
102103
103 template
104 static std::unique_ptr
105 create(BaseLayerT &B, std::shared_ptr M, MemoryManagerPtrT MemMgr,
106 SymbolResolverPtrT Resolver);
107
108 protected:
109 virtual const GlobalValue* searchGVs(StringRef Name,
110 bool ExportedSymbolsOnly) const = 0;
111 virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
112
113104 private:
114 enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
115 BaseLayerHandleT Handle;
116 };
117
118 template
119 class EmissionDeferredModuleImpl : public EmissionDeferredModule {
120 public:
121 EmissionDeferredModuleImpl(std::shared_ptr M,
122 MemoryManagerPtrT MemMgr,
123 SymbolResolverPtrT Resolver)
124 : M(std::move(M)), MemMgr(std::move(MemMgr)),
125 Resolver(std::move(Resolver)) {}
126
127 protected:
105
128106 const GlobalValue* searchGVs(StringRef Name,
129 bool ExportedSymbolsOnly) const override {
107 bool ExportedSymbolsOnly) const {
130108 // FIXME: We could clean all this up if we had a way to reliably demangle
131109 // names: We could just demangle name and search, rather than
132110 // mangling everything else.
148126 return buildMangledSymbols(Name, ExportedSymbolsOnly);
149127 }
150128
151 BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
129 BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) {
152130 // We don't need the mangled names set any more: Once we've emitted this
153131 // to the base layer we'll just look for symbols there.
154132 MangledSymbols.reset();
155 return BaseLayer.addModule(std::move(M), std::move(MemMgr),
156 std::move(Resolver));
157 }
158
159 private:
133 return BaseLayer.addModule(std::move(M), std::move(Resolver));
134 }
135
160136 // If the mangled name of the given GlobalValue matches the given search
161137 // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
162138 // return the symbol. Otherwise, add the mangled name to the Names map and
206182 return nullptr;
207183 }
208184
185 enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
186 BaseLayerHandleT Handle;
209187 std::shared_ptr M;
210 MemoryManagerPtrT MemMgr;
211 SymbolResolverPtrT Resolver;
188 std::shared_ptr Resolver;
212189 mutable std::unique_ptr> MangledSymbols;
213190 };
214191
218195 ModuleListT ModuleList;
219196
220197 public:
198
221199 /// @brief Handle to a loaded module.
222200 using ModuleHandleT = typename ModuleListT::iterator;
223201
225203 LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
226204
227205 /// @brief Add the given module to the lazy emitting layer.
228 template
229206 ModuleHandleT addModule(std::shared_ptr M,
230 MemoryManagerPtrT MemMgr,
231 SymbolResolverPtrT Resolver) {
207 std::shared_ptr Resolver) {
232208 return ModuleList.insert(
233209 ModuleList.end(),
234 EmissionDeferredModule::create(BaseLayer, std::move(M),
235 std::move(MemMgr),
236 std::move(Resolver)));
210 llvm::make_unique(std::move(M),
211 std::move(Resolver)));
237212 }
238213
239214 /// @brief Remove the module represented by the given handle.
280255 }
281256 };
282257
283 template
284 template
285 std::unique_ptr::EmissionDeferredModule>
286 LazyEmittingLayer::EmissionDeferredModule::create(
287 BaseLayerT &B, std::shared_ptr M, MemoryManagerPtrT MemMgr,
288 SymbolResolverPtrT Resolver) {
289 using EDS = EmissionDeferredModuleImpl;
290 return llvm::make_unique(std::move(M), std::move(MemMgr),
291 std::move(Resolver));
292 }
293
294258 } // end namespace orc
295259 } // end namespace llvm
296260
4141 /// memory manager and symbol resolver.
4242 ///
4343 /// @return A handle for the added objects.
44 template
45 typename SymbolResolverPtrT>
46 ObjHandleT addObject(ObjPtrT Obj, MemoryManagerPtrT MemMgr,
47 SymbolResolverPtrT Resolver) {
48 return BaseLayer.addObject(Transform(std::move(Obj)), std::move(MemMgr),
49 std::move(Resolver));
44 template
45 ObjHandleT addObject(ObjectPtr Obj,
46 std::shared_ptr Resolver) {
47 return BaseLayer.addObject(Transform(std::move(Obj)), std::move(Resolver));
5048 }
5149
5250 /// @brief Remove the object set associated with the handle H.
227227
228228 public:
229229
230 /// @brief Functor for creating memory managers.
231 using MemoryManagerGetter =
232 std::function()>;
233
230234 /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
231235 /// and NotifyFinalized functors.
232236 RTDyldObjectLinkingLayer(
237 MemoryManagerGetter GetMemMgr,
233238 NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
234239 NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
235 : NotifyLoaded(std::move(NotifyLoaded)),
236 NotifyFinalized(std::move(NotifyFinalized)) {}
240 : GetMemMgr(GetMemMgr),
241 NotifyLoaded(std::move(NotifyLoaded)),
242 NotifyFinalized(std::move(NotifyFinalized)),
243 ProcessAllSections(false) {}
237244
238245 /// @brief Set the 'ProcessAllSections' flag.
239246 ///
250257 ///
251258 /// @return A handle that can be used to refer to the loaded objects (for
252259 /// symbol searching, finalization, freeing memory, etc.).
253 template
254 typename SymbolResolverPtrT>
255260 ObjHandleT addObject(ObjectPtr Obj,
256 MemoryManagerPtrT MemMgr,
257 SymbolResolverPtrT Resolver) {
258
261 std::shared_ptr Resolver) {
259262 auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
260263 const ObjectPtr &ObjToLoad,
261264 std::function LOSHandleLoad) {
274277 };
275278
276279 auto LO =
277 createLinkedObject(std::move(Obj), std::move(MemMgr), std::move(Resolver),
278 std::move(Finalizer), ProcessAllSections);
280 createLinkedObject(std::move(Obj), GetMemMgr(),
281 std::move(Resolver), std::move(Finalizer),
282 ProcessAllSections);
279283 // LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
280284 // below.
281285 auto *LOPtr = LO.get();
340344 private:
341345
342346 LinkedObjectListT LinkedObjList;
347 MemoryManagerGetter GetMemMgr;
343348 NotifyLoadedFtor NotifyLoaded;
344349 NotifyFinalizedFtor NotifyFinalized;
345350 bool ProcessAllSections = false;
104104 IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
105105 : DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
106106 CCMgr(std::move(CCMgr)),
107 ObjectLayer(
108 []() {
109 return std::make_shared();
110 }),
107111 CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
108112 CODLayer(CompileLayer,
109113 [](Function &F) { return std::set({&F}); },
154158 return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
155159 }
156160
157 std::unique_ptr
161 std::shared_ptr
158162 createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
159163 void *ExternalResolverCtx) {
160164 return orc::createLambdaResolver(
203207 auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
204208
205209 // Add the module to the JIT.
206 auto LH = Layer.addModule(std::move(M), std::move(MemMgr),
207 std::move(Resolver));
210 auto LH = Layer.addModule(std::move(M), std::move(Resolver));
208211 ModuleHandleT H = createHandle(Layer, LH);
209212
210213 // Run the static constructors, and save the static destructor runner for
171171 std::shared_ptr ClientResolver,
172172 std::unique_ptr TM)
173173 : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
174 MemMgr(*this, std::move(MemMgr)), Resolver(*this),
174 MemMgr(std::make_shared(*this,
175 std::move(MemMgr))),
176 Resolver(std::make_shared(*this)),
175177 ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
176178 NotifyFinalized(*this),
177 ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
179 ObjectLayer([this]() { return this->MemMgr; }, NotifyObjectLoaded,
180 NotifyFinalized),
178181 CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
179182 LazyEmitLayer(CompileLayer) {}
180183
198201 delete Mod;
199202 };
200203 LocalModules.push_back(std::shared_ptr(MPtr, std::move(Deleter)));
201 LazyEmitLayer.addModule(LocalModules.back(), &MemMgr, &Resolver);
204 LazyEmitLayer.addModule(LocalModules.back(), Resolver);
202205 }
203206
204207 void addObjectFile(std::unique_ptr O) override {
205208 auto Obj =
206209 std::make_shared>(std::move(O),
207210 nullptr);
208 ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
211 ObjectLayer.addObject(std::move(Obj), Resolver);
209212 }
210213
211214 void addObjectFile(object::OwningBinary O) override {
212215 auto Obj =
213216 std::make_shared>(std::move(O));
214 ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
217 ObjectLayer.addObject(std::move(Obj), Resolver);
215218 }
216219
217220 void addArchive(object::OwningBinary A) override {
319322 auto Obj =
320323 std::make_shared>(
321324 std::move(ChildObj), nullptr);
322 ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
325 ObjectLayer.addObject(std::move(Obj), Resolver);
323326 if (auto Sym = ObjectLayer.findSymbol(Name, true))
324327 return Sym;
325328 }
340343 const LoadedObjectInfo &Info) const {
341344 M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
342345 M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
343 M.MemMgr.notifyObjectLoaded(&M, *Obj->getBinary());
346 M.MemMgr->notifyObjectLoaded(&M, *Obj->getBinary());
344347 }
345348 private:
346349 OrcMCJITReplacement &M;
372375 using LazyEmitLayerT = LazyEmittingLayer;
373376
374377 std::unique_ptr TM;
375 MCJITReplacementMemMgr MemMgr;
376 LinkingResolver Resolver;
378 std::shared_ptr MemMgr;
379 std::shared_ptr Resolver;
377380 std::shared_ptr ClientResolver;
378381 Mangler Mang;
379382
6060 IndirectStubsManagerBuilder IndirectStubsMgrBuilder,
6161 bool InlineStubs)
6262 : TM(std::move(TM)), DL(this->TM->createDataLayout()),
63 CCMgr(std::move(CCMgr)),
63 CCMgr(std::move(CCMgr)),
64 ObjectLayer([]() { return std::make_shared(); }),
6465 CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
6566 IRDumpLayer(CompileLayer, createDebugDumper()),
6667 CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr,
124125
125126 // Add the module to the JIT.
126127 ModulesHandle =
127 CODLayer.addModule(std::move(M),
128 llvm::make_unique(),
129 std::move(Resolver));
128 CODLayer.addModule(std::move(M), std::move(Resolver));
130129 } else
131130 CODLayer.addExtraModule(ModulesHandle, std::move(M));
132131
8383 this->MemMgr = std::move(MemMgr);
8484 }
8585
86 void setResolver(std::unique_ptr Resolver) {
86 void setResolver(std::shared_ptr Resolver) {
8787 this->Resolver = std::move(Resolver);
8888 }
8989
144144
145145 private:
146146 std::unique_ptr MemMgr;
147 std::unique_ptr Resolver;
147 std::shared_ptr Resolver;
148148 };
149149 }
150150
2626 TEST(LazyEmittingLayerTest, Empty) {
2727 MockBaseLayer M;
2828 llvm::orc::LazyEmittingLayer L(M);
29 L.addModule(std::unique_ptr(), nullptr, nullptr);
29 L.addModule(std::unique_ptr(), nullptr);
3030 }
3131
3232 }
1313 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
1414 #include "llvm/ExecutionEngine/Orc/NullResolver.h"
1515 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
16 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
1617 #include "llvm/Object/ObjectFile.h"
1718 #include "gtest/gtest.h"
1819
1920 using namespace llvm::orc;
2021
2122 namespace {
22
23 // Stand-in for RuntimeDyld::MemoryManager
24 typedef int MockMemoryManager;
25
26 // Stand-in for RuntimeDyld::SymbolResolver
27 typedef int MockSymbolResolver;
2823
2924 // stand-in for object::ObjectFile
3025 typedef int MockObjectFile;
5348
5449 MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
5550
56 template
57 typename SymbolResolverPtrT>
58 ObjHandleT addObject(ObjPtrT Obj, MemoryManagerPtrT MemMgr,
59 SymbolResolverPtrT Resolver) {
60 EXPECT_EQ(MockManager, *MemMgr) << "MM should pass through";
61 EXPECT_EQ(MockResolver, *Resolver) << "Resolver should pass through";
51 template
52 ObjHandleT addObject(ObjPtrT Obj,
53 std::shared_ptr Resolver) {
54 EXPECT_EQ(MockResolver, Resolver) << "Resolver should pass through";
6255 EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
6356 LastCalled = "addObject";
6457 MockObjHandle = 111;
6558 return MockObjHandle;
6659 }
60
6761 template
68 void expectAddObject(ObjPtrT Obj, MockMemoryManager *MemMgr,
69 MockSymbolResolver *Resolver) {
70 MockManager = *MemMgr;
71 MockResolver = *Resolver;
62 void expectAddObject(ObjPtrT Obj,
63 std::shared_ptr Resolver) {
64 MockResolver = Resolver;
7265 MockObject = *Obj;
7366 }
67
68
7469 void verifyAddObject(ObjHandleT Returned) {
7570 EXPECT_EQ("addObject", LastCalled);
7671 EXPECT_EQ(MockObjHandle, Returned) << "Return should pass through";
159154 private:
160155 // Backing fields for remembering parameter/return values
161156 std::string LastCalled;
162 MockMemoryManager MockManager;
163 MockSymbolResolver MockResolver;
157 std::shared_ptr MockResolver;
164158 MockObjectFile MockObject;
165159 ObjHandleT MockObjHandle;
166160 std::string MockName;
173167 // Clear remembered parameters between calls
174168 void resetExpectations() {
175169 LastCalled = "nothing";
176 MockManager = 0;
177 MockResolver = 0;
170 MockResolver = nullptr;
178171 MockObject = 0;
179172 MockObjHandle = 0;
180173 MockName = "bogus";
203196 return Obj;
204197 });
205198
206 // Instantiate some mock objects to use below
207 MockMemoryManager MockManager = 233;
208 MockSymbolResolver MockResolver = 244;
209
210199 // Test addObject with T1 (allocating)
211200 auto Obj1 = std::make_shared(211);
212 auto MM = llvm::make_unique(MockManager);
213 auto SR = llvm::make_unique(MockResolver);
214 M.expectAddObject(Obj1, MM.get(), SR.get());
215 auto H = T1.addObject(std::move(Obj1), std::move(MM), std::move(SR));
201 auto SR = std::make_shared();
202 M.expectAddObject(Obj1, SR);
203 auto H = T1.addObject(std::move(Obj1), SR);
216204 M.verifyAddObject(H);
217205
218206 // Test addObjectSet with T2 (mutating)
219207 auto Obj2 = std::make_shared(222);
220 M.expectAddObject(Obj2, &MockManager, &MockResolver);
221 H = T2.addObject(Obj2, &MockManager, &MockResolver);
208 M.expectAddObject(Obj2, SR);
209 H = T2.addObject(Obj2, SR);
222210 M.verifyAddObject(H);
223211 EXPECT_EQ(223, *Obj2) << "Expected mutation";
224212
294282 };
295283
296284 // Construct the jit layers.
297 RTDyldObjectLinkingLayer BaseLayer;
285 RTDyldObjectLinkingLayer BaseLayer(
286 []() {
287 return std::make_shared();
288 });
289
298290 auto IdentityTransform =
299291 [](std::shared_ptr>
300292 Obj) {
311303
312304 // Make sure that the calls from IRCompileLayer to ObjectTransformLayer
313305 // compile.
314 NullResolver Resolver;
315 NullManager Manager;
316 CompileLayer.addModule(std::shared_ptr(), &Manager, &Resolver);
306 auto Resolver = std::make_shared();
307 CompileLayer.addModule(std::shared_ptr(), Resolver);
317308
318309 // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
319310 // compile.
4444 };
4545
4646 TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
47 class SectionMemoryManagerWrapper : public SectionMemoryManager {
47 class MemoryManagerWrapper : public SectionMemoryManager {
4848 public:
49 SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
49 MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
5050 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
5151 unsigned SectionID,
5252 StringRef SectionName,
6262 bool &DebugSeen;
6363 };
6464
65 RTDyldObjectLinkingLayer ObjLayer;
65 bool DebugSectionSeen = false;
66 auto MM = std::make_shared(DebugSectionSeen);
67
68 RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
6669
6770 LLVMContext Context;
6871 auto M = llvm::make_unique("", Context);
8891 std::make_shared>(
8992 SimpleCompiler(*TM)(*M));
9093
91 bool DebugSectionSeen = false;
92 auto SMMW =
93 std::make_shared(DebugSectionSeen);
9494 auto Resolver =
9595 createLambdaResolver(
9696 [](const std::string &Name) {
102102
103103 {
104104 // Test with ProcessAllSections = false (the default).
105 auto H = ObjLayer.addObject(Obj, SMMW, &*Resolver);
105 auto H = ObjLayer.addObject(Obj, Resolver);
106106 ObjLayer.emitAndFinalize(H);
107107 EXPECT_EQ(DebugSectionSeen, false)
108108 << "Unexpected debug info section";
112112 {
113113 // Test with ProcessAllSections = true.
114114 ObjLayer.setProcessAllSections(true);
115 auto H = ObjLayer.addObject(Obj, SMMW, &*Resolver);
115 auto H = ObjLayer.addObject(Obj, Resolver);
116116 ObjLayer.emitAndFinalize(H);
117117 EXPECT_EQ(DebugSectionSeen, true)
118118 << "Expected debug info section not seen";
124124 if (!TM)
125125 return;
126126
127 RTDyldObjectLinkingLayer ObjLayer;
127 auto MM = std::make_shared();
128
129 RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
128130 SimpleCompiler Compile(*TM);
129131
130132 // Create a pair of modules that will trigger recursive finalization:
178180 return JITSymbol(nullptr);
179181 });
180182
181 auto SMMW = std::make_shared();
182 ObjLayer.addObject(std::move(Obj1), SMMW, &*Resolver);
183 auto H = ObjLayer.addObject(std::move(Obj2), SMMW, &*Resolver);
183 ObjLayer.addObject(std::move(Obj1), Resolver);
184 auto H = ObjLayer.addObject(std::move(Obj2), Resolver);
184185 ObjLayer.emitAndFinalize(H);
185186 ObjLayer.removeObject(H);
186187
187188 // Finalization of module 2 should trigger finalization of module 1.
188189 // Verify that finalize on SMMW is only called once.
189 EXPECT_EQ(SMMW->FinalizationCount, 1)
190 EXPECT_EQ(MM->FinalizationCount, 1)
190191 << "Extra call to finalize";
191192 }
192193
194195 if (!TM)
195196 return;
196197
197 RTDyldObjectLinkingLayer ObjLayer;
198 auto MM = std::make_shared();
199
200 RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
198201 SimpleCompiler Compile(*TM);
199202
200203 // Create a pair of unrelated modules:
239242 std::make_shared>(
240243 Compile(*MB2.getModule()));
241244
242 auto SMMW = std::make_shared();
243 NullResolver NR;
244 auto H = ObjLayer.addObject(std::move(Obj1), SMMW, &NR);
245 ObjLayer.addObject(std::move(Obj2), SMMW, &NR);
245 auto NR = std::make_shared();
246 auto H = ObjLayer.addObject(std::move(Obj1), NR);
247 ObjLayer.addObject(std::move(Obj2), NR);
246248 ObjLayer.emitAndFinalize(H);
247249 ObjLayer.removeObject(H);
248250
249251 // Only one call to needsToReserveAllocationSpace should have been made.
250 EXPECT_EQ(SMMW->NeedsToReserveAllocationSpaceCount, 1)
252 EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)
251253 << "More than one call to needsToReserveAllocationSpace "
252254 "(multiple unrelated objects loaded prior to finalization)";
253255 }