llvm.org GIT mirror llvm / 08ef6db
[ORC] Switch the object layer API from addObjectSet to addObject (singular), and move the ObjectCache from the IRCompileLayer to SimpleCompiler. This is the first in a series of patches aimed at cleaning up and improving the robustness and performance of the ORC APIs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306058 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 2 years ago
16 changed file(s) with 330 addition(s) and 376 deletion(s). Raw diff Collapse all Expand all
3939 private:
4040 std::unique_ptr TM;
4141 const DataLayout DL;
42 RTDyldObjectLinkingLayer<> ObjectLayer;
43 IRCompileLayer CompileLayer;
42 RTDyldObjectLinkingLayer ObjectLayer;
43 IRCompileLayer CompileLayer;
4444
4545 public:
4646 using ModuleHandle = decltype(CompileLayer)::ModuleSetHandleT;
4343 private:
4444 std::unique_ptr TM;
4545 const DataLayout DL;
46 RTDyldObjectLinkingLayer<> ObjectLayer;
47 IRCompileLayer CompileLayer;
46 RTDyldObjectLinkingLayer ObjectLayer;
47 IRCompileLayer CompileLayer;
4848
4949 using OptimizeFunction =
5050 std::function(std::unique_ptr)>;
4646 private:
4747 std::unique_ptr TM;
4848 const DataLayout DL;
49 RTDyldObjectLinkingLayer<> ObjectLayer;
50 IRCompileLayer CompileLayer;
49 RTDyldObjectLinkingLayer ObjectLayer;
50 IRCompileLayer CompileLayer;
5151
5252 using OptimizeFunction =
5353 std::function(std::unique_ptr)>;
7272 private:
7373 std::unique_ptr TM;
7474 const DataLayout DL;
75 RTDyldObjectLinkingLayer<> ObjectLayer;
76 IRCompileLayer CompileLayer;
75 RTDyldObjectLinkingLayer ObjectLayer;
76 IRCompileLayer CompileLayer;
7777
7878 using OptimizeFunction =
7979 std::function(std::unique_ptr)>;
7777 private:
7878 std::unique_ptr TM;
7979 const DataLayout DL;
80 RTDyldObjectLinkingLayer<> ObjectLayer;
81 IRCompileLayer CompileLayer;
80 RTDyldObjectLinkingLayer ObjectLayer;
81 IRCompileLayer CompileLayer;
8282
8383 using OptimizeFunction =
8484 std::function(std::unique_ptr)>;
3838
3939 class KaleidoscopeJIT {
4040 public:
41 using ObjLayerT = RTDyldObjectLinkingLayer<>;
42 using CompileLayerT = IRCompileLayer;
41 using ObjLayerT = RTDyldObjectLinkingLayer;
42 using CompileLayerT = IRCompileLayer;
4343 using ModuleHandleT = CompileLayerT::ModuleSetHandleT;
4444
4545 KaleidoscopeJIT()
1414 #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
1515
1616 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ExecutionEngine/ObjectCache.h"
1718 #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
1819 #include "llvm/IR/LegacyPassManager.h"
1920 #include "llvm/Object/Binary.h"
3738 /// ObjectFile.
3839 class SimpleCompiler {
3940 public:
41
42 using CompileResult = object::OwningBinary;
43
4044 /// @brief Construct a simple compile functor with the given target.
41 SimpleCompiler(TargetMachine &TM) : TM(TM) {}
45 SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr)
46 : TM(TM), ObjCache(ObjCache) {}
47
48 /// @brief Set an ObjectCache to query before compiling.
49 void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
4250
4351 /// @brief Compile a Module to an ObjectFile.
44 object::OwningBinary operator()(Module &M) const {
52 CompileResult operator()(Module &M) {
53 CompileResult CachedObject = tryToLoadFromObjectCache(M);
54 if (CachedObject.getBinary())
55 return CachedObject;
56
4557 SmallVector ObjBufferSV;
4658 raw_svector_ostream ObjStream(ObjBufferSV);
4759
5466 new ObjectMemoryBuffer(std::move(ObjBufferSV)));
5567 Expected> Obj =
5668 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
57 using OwningObj = object::OwningBinary;
58 if (Obj)
59 return OwningObj(std::move(*Obj), std::move(ObjBuffer));
69 if (Obj) {
70 notifyObjectCompiled(M, *ObjBuffer);
71 return CompileResult(std::move(*Obj), std::move(ObjBuffer));
72 }
6073 // TODO: Actually report errors helpfully.
6174 consumeError(Obj.takeError());
62 return OwningObj(nullptr, nullptr);
75 return CompileResult(nullptr, nullptr);
6376 }
6477
6578 private:
79
80 CompileResult tryToLoadFromObjectCache(const Module &M) {
81 if (!ObjCache)
82 return CompileResult();
83
84 std::unique_ptr ObjBuffer = ObjCache->getObject(&M);
85 if (!ObjBuffer)
86 return CompileResult();
87
88 Expected> Obj =
89 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
90 if (!Obj) {
91 // TODO: Actually report errors helpfully.
92 consumeError(Obj.takeError());
93 return CompileResult();
94 }
95
96 return CompileResult(std::move(*Obj), std::move(ObjBuffer));
97 }
98
99 void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) {
100 if (ObjCache)
101 ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
102 }
103
66104 TargetMachine &TM;
105 ObjectCache *ObjCache = nullptr;
67106 };
68107
69108 } // end namespace orc
1515
1616 #include "llvm/ADT/STLExtras.h"
1717 #include "llvm/ExecutionEngine/JITSymbol.h"
18 #include "llvm/ExecutionEngine/ObjectCache.h"
19 #include "llvm/Object/Binary.h"
20 #include "llvm/Object/ObjectFile.h"
2118 #include "llvm/Support/Error.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include
24 #include
2519 #include
2620 #include
27 #include
2821
2922 namespace llvm {
3023
3831 /// immediately compiles each IR module to an object file (each IR Module is
3932 /// compiled separately). The resulting set of object files is then added to
4033 /// the layer below, which must implement the object layer concept.
41 template class IRCompileLayer {
42 public:
43 using CompileFtor =
44 std::function(Module &)>;
45
46 private:
47 using ObjSetHandleT = typename BaseLayerT::ObjSetHandleT;
48
34 template
35 class IRCompileLayer {
4936 public:
5037 /// @brief Handle to a set of compiled modules.
51 using ModuleSetHandleT = ObjSetHandleT;
38 using ModuleSetHandleT = typename BaseLayerT::ObjHandleT;
5239
5340 /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
5441 /// implement the ObjectLayer concept.
5542 IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
5643 : BaseLayer(BaseLayer), Compile(std::move(Compile)) {}
5744
58 /// @brief Set an ObjectCache to query before compiling.
59 void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
45 /// @brief Get a reference to the compiler functor.
46 CompileFtor& getCompiler() { return Compile; }
6047
6148 /// @brief Compile each module in the given module set, then add the resulting
6249 /// set of objects to the base layer along with the memory manager and
6855 ModuleSetHandleT addModuleSet(ModuleSetT Ms,
6956 MemoryManagerPtrT MemMgr,
7057 SymbolResolverPtrT Resolver) {
71 std::vector>>
72 Objects;
73
74 for (const auto &M : Ms) {
75 auto Object =
76 llvm::make_unique>();
77
78 if (ObjCache)
79 *Object = tryToLoadFromObjectCache(*M);
80
81 if (!Object->getBinary()) {
82 *Object = Compile(*M);
83 if (ObjCache)
84 ObjCache->notifyObjectCompiled(&*M,
85 Object->getBinary()->getMemoryBufferRef());
86 }
87
88 Objects.push_back(std::move(Object));
89 }
90
91 ModuleSetHandleT H =
92 BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
93 std::move(Resolver));
94
95 return H;
58 assert(Ms.size() == 1);
59 using CompileResult = decltype(Compile(*Ms.front()));
60 auto Obj = std::make_shared(Compile(*Ms.front()));
61 return BaseLayer.addObject(std::move(Obj), std::move(MemMgr),
62 std::move(Resolver));
9663 }
9764
9865 /// @brief Remove the module set associated with the handle H.
99 void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
66 void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObject(H); }
10067
10168 /// @brief Search for the given named symbol.
10269 /// @param Name The name of the symbol to search for.
12794 }
12895
12996 private:
130 object::OwningBinary
131 tryToLoadFromObjectCache(const Module &M) {
132 std::unique_ptr ObjBuffer = ObjCache->getObject(&M);
133 if (!ObjBuffer)
134 return object::OwningBinary();
135
136 Expected> Obj =
137 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
138 if (!Obj) {
139 // TODO: Actually report errors helpfully.
140 consumeError(Obj.takeError());
141 return object::OwningBinary();
142 }
143
144 return object::OwningBinary(std::move(*Obj),
145 std::move(ObjBuffer));
146 }
147
14897 BaseLayerT &BaseLayer;
14998 CompileFtor Compile;
150 ObjectCache *ObjCache = nullptr;
15199 };
152100
153101 } // end namespace orc
2222
2323 /// @brief Object mutating layer.
2424 ///
25 /// This layer accepts sets of ObjectFiles (via addObjectSet). It
25 /// This layer accepts sets of ObjectFiles (via addObject). It
2626 /// immediately applies the user supplied functor to each object, then adds
2727 /// the set of transformed objects to the layer below.
2828 template
2929 class ObjectTransformLayer {
3030 public:
3131 /// @brief Handle to a set of added objects.
32 using ObjSetHandleT = typename BaseLayerT::ObjSetHandleT;
32 using ObjHandleT = typename BaseLayerT::ObjHandleT;
3333
3434 /// @brief Construct an ObjectTransformLayer with the given BaseLayer
3535 ObjectTransformLayer(BaseLayerT &BaseLayer,
4141 /// memory manager and symbol resolver.
4242 ///
4343 /// @return A handle for the added objects.
44 template SetT, typename MemoryManagerPtrT,
44 template PtrT, typename MemoryManagerPtrT,
4545 typename SymbolResolverPtrT>
46 ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
47 SymbolResolverPtrT Resolver) {
48 for (auto I = Objects.begin(), E = Objects.end(); I != E; ++I)
49 *I = Transform(std::move(*I));
50
51 return BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
52 std::move(Resolver));
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));
5350 }
5451
5552 /// @brief Remove the object set associated with the handle H.
56 void removeObjectSet(ObjSetHandleT H) { BaseLayer.removeObjectSet(H); }
53 void removeObject(ObjHandleT H) { BaseLayer.removeObject(H); }
5754
5855 /// @brief Search for the given named symbol.
5956 /// @param Name The name of the symbol to search for.
7168 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
7269 /// @return A handle for the given named symbol, if it is found in the
7370 /// given object set.
74 JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name,
71 JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
7572 bool ExportedSymbolsOnly) {
7673 return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
7774 }
7976 /// @brief Immediately emit and finalize the object set represented by the
8077 /// given handle.
8178 /// @param H Handle for object set to emit/finalize.
82 void emitAndFinalize(ObjSetHandleT H) { BaseLayer.emitAndFinalize(H); }
79 void emitAndFinalize(ObjHandleT H) { BaseLayer.emitAndFinalize(H); }
8380
8481 /// @brief Map section addresses for the objects associated with the handle H.
85 void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
82 void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
8683 JITTargetAddress TargetAddr) {
8784 BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr);
8885 }
173173 ArgV[0] = "";
174174 for (auto &Arg : Args)
175175 ArgV[Idx++] = Arg.c_str();
176 ArgV[ArgC] = 0;
177 DEBUG(
178 for (int Idx = 0; Idx < ArgC; ++Idx) {
179 llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n";
180 }
181 );
176182
177183 DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n");
178184 int Result = Fn(ArgC, ArgV.get());
3434
3535 class RTDyldObjectLinkingLayerBase {
3636 protected:
37
38 using ObjectPtr =
39 std::shared_ptr>;
40
3741 /// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
3842 ///
3943 /// An instance of this class will be created for each set of objects added
40 /// via JITObjectLayer::addObjectSet. Deleting the instance (via
41 /// removeObjectSet) frees its memory, removing all symbol definitions that
44 /// via JITObjectLayer::addObject. Deleting the instance (via
45 /// removeObject) frees its memory, removing all symbol definitions that
4246 /// had been provided by this instance. Higher level layers are responsible
4347 /// for taking any action required to handle the missing symbols.
44 class LinkedObjectSet {
48 class LinkedObject {
4549 public:
46 LinkedObjectSet() = default;
47 LinkedObjectSet(const LinkedObjectSet&) = delete;
48 void operator=(const LinkedObjectSet&) = delete;
49 virtual ~LinkedObjectSet() = default;
50 LinkedObject() = default;
51 LinkedObject(const LinkedObject&) = delete;
52 void operator=(const LinkedObject&) = delete;
53 virtual ~LinkedObject() = default;
5054
5155 virtual void finalize() = 0;
5256
7377 bool Finalized = false;
7478 };
7579
76 using LinkedObjectSetListT = std::listt>>;
80 using LinkedObjectListT = std::listt>>;
7781
7882 public:
7983 /// @brief Handle to a set of loaded objects.
80 using ObjSetHandleT = LinkedObjectSetListT::iterator;
81 };
82
83 /// @brief Default (no-op) action to perform when loading objects.
84 class DoNothingOnNotifyLoaded {
85 public:
86 template
87 void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &,
88 const LoadResult &) {}
84 using ObjHandleT = LinkedObjectListT::iterator;
8985 };
9086
9187 /// @brief Bare bones object linking layer.
9490 /// object files to be loaded into memory, linked, and the addresses of their
9591 /// symbols queried. All objects added to this layer can see each other's
9692 /// symbols.
97 template
9893 class RTDyldObjectLinkingLayer : public RTDyldObjectLinkingLayerBase {
9994 public:
95
96 using RTDyldObjectLinkingLayerBase::ObjectPtr;
97
98 /// @brief Functor for receiving object-loaded notifications.
99 using NotifyLoadedFtor = std::function
100 const LoadedObjectInfo &)>;
101
100102 /// @brief Functor for receiving finalization notifications.
101 using NotifyFinalizedFtor = std::functionSetHandleT)>;
103 using NotifyFinalizedFtor = std::functionHandleT)>;
102104
103105 private:
104 template
105 typename SymbolResolverPtrT, typename FinalizerFtor>
106 class ConcreteLinkedObjectSet : public LinkedObjectSet {
106
107
108 template
109 typename FinalizerFtor>
110 class ConcreteLinkedObject : public LinkedObject {
107111 public:
108 ConcreteLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
109 SymbolResolverPtrT Resolver,
110 FinalizerFtor Finalizer,
111 bool ProcessAllSections)
112 ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
113 SymbolResolverPtrT Resolver,
114 FinalizerFtor Finalizer,
115 bool ProcessAllSections)
112116 : MemMgr(std::move(MemMgr)),
113 PFC(llvm::make_unique(std::move(Objects),
117 PFC(llvm::make_unique(std::move(Obj),
114118 std::move(Resolver),
115119 std::move(Finalizer),
116120 ProcessAllSections)) {
117 buildInitialSymbolTable(PFC->Objects);
118 }
119
120 ~ConcreteLinkedObjectSet() override {
121 buildInitialSymbolTable(PFC->Obj);
122 }
123
124 ~ConcreteLinkedObject() override {
121125 MemMgr->deregisterEHFrames();
122126 }
123
124 void setHandle(ObjSetHandleT H) {
127
128 void setHandle(ObjHandleT H) {
125129 PFC->Handle = H;
126130 }
127131
128132 void finalize() override {
129 assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
133 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
130134
131135 RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver);
132136 RTDyld.setProcessAllSections(PFC->ProcessAllSections);
133137 PFC->RTDyld = &RTDyld;
134138
135139 this->Finalized = true;
136 PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects),
140 PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
137141 [&]() {
138142 this->updateSymbolTable(RTDyld);
139143 });
155159
156160 void mapSectionAddress(const void *LocalAddress,
157161 JITTargetAddress TargetAddr) const override {
158 assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet");
159 assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObjectSet");
162 assert(PFC && "mapSectionAddress called on finalized LinkedObject");
163 assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject");
160164 PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
161165 }
162166
163167 private:
164 void buildInitialSymbolTable(const ObjSetT &Objects) {
165 for (const auto &Obj : Objects)
166 for (auto &Symbol : getObject(*Obj).symbols()) {
167 if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
168 continue;
169 Expected SymbolName = Symbol.getName();
170 // FIXME: Raise an error for bad symbols.
171 if (!SymbolName) {
172 consumeError(SymbolName.takeError());
173 continue;
174 }
175 auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
176 SymbolTable.insert(
177 std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
168
169 void buildInitialSymbolTable(const ObjectPtr &Obj) {
170 for (auto &Symbol : Obj->getBinary()->symbols()) {
171 if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
172 continue;
173 Expected SymbolName = Symbol.getName();
174 // FIXME: Raise an error for bad symbols.
175 if (!SymbolName) {
176 consumeError(SymbolName.takeError());
177 continue;
178178 }
179 auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol);
180 SymbolTable.insert(
181 std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags)));
182 }
179183 }
180184
181185 void updateSymbolTable(const RuntimeDyld &RTDyld) {
186190 // Contains the information needed prior to finalization: the object files,
187191 // memory manager, resolver, and flags needed for RuntimeDyld.
188192 struct PreFinalizeContents {
189 PreFinalizeContents(ObjSetT Objects, SymbolResolverPtrT Resolver,
193 PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver,
190194 FinalizerFtor Finalizer, bool ProcessAllSections)
191 : Objects(std::move(Objects)), Resolver(std::move(Resolver)),
195 : Obj(std::move(Obj)), Resolver(std::move(Resolver)),
192196 Finalizer(std::move(Finalizer)),
193197 ProcessAllSections(ProcessAllSections) {}
194198
195 ObjSetT Objects;
199 ObjectPtr Obj;
196200 SymbolResolverPtrT Resolver;
197201 FinalizerFtor Finalizer;
198202 bool ProcessAllSections;
199 ObjSetHandleT Handle;
203 ObjHandleT Handle;
200204 RuntimeDyld *RTDyld;
201205 };
202206
204208 std::unique_ptr PFC;
205209 };
206210
207 template
208 typename SymbolResolverPtrT, typename FinalizerFtor>
211 template
212 typename FinalizerFtor>
209213 std::unique_ptr<
210 ConcreteLinkedObjectSet
211 SymbolResolverPtrT, FinalizerFtor>>
212 createLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
213 SymbolResolverPtrT Resolver,
214 FinalizerFtor Finalizer,
215 bool ProcessAllSections) {
216 using LOS = ConcreteLinkedObjectSet
217 SymbolResolverPtrT, FinalizerFtor>;
218 return llvm::make_unique(std::move(Objects), std::move(MemMgr),
214 ConcreteLinkedObject>
215 createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
216 SymbolResolverPtrT Resolver,
217 FinalizerFtor Finalizer,
218 bool ProcessAllSections) {
219 using LOS = ConcreteLinkedObject
220 FinalizerFtor>;
221 return llvm::make_unique(std::move(Obj), std::move(MemMgr),
219222 std::move(Resolver), std::move(Finalizer),
220223 ProcessAllSections);
221224 }
222225
223226 public:
224 /// @brief LoadedObjectInfo list. Contains a list of owning pointers to
225 /// RuntimeDyld::LoadedObjectInfo instances.
226 using LoadedObjInfoList =
227 std::vector>;
228227
229228 /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
230229 /// and NotifyFinalized functors.
249248 ///
250249 /// @return A handle that can be used to refer to the loaded objects (for
251250 /// symbol searching, finalization, freeing memory, etc.).
252 template
253 typename MemoryManagerPtrT,
251 template <typename MemoryManagerPtrT,
254252 typename SymbolResolverPtrT>
255 ObjSetHandleT addObjectSet(ObjSetT Objects,
256 MemoryManagerPtrT MemMgr,
257 SymbolResolverPtrT Resolver) {
258 auto Finalizer = [&](ObjSetHandleT H, RuntimeDyld &RTDyld,
259 const ObjSetT &Objs,
253 ObjHandleT addObject(ObjectPtr Obj,
254 MemoryManagerPtrT MemMgr,
255 SymbolResolverPtrT Resolver) {
256
257 auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
258 const ObjectPtr &ObjToLoad,
260259 std::function LOSHandleLoad) {
261 LoadedObjInfoList LoadedObjInfos;
262
263 for (auto &Obj : Objs)
264 LoadedObjInfos.push_back(RTDyld.loadObject(this->getObject(*Obj)));
260 std::unique_ptr Info =
261 RTDyld.loadObject(*ObjToLoad->getBinary());
265262
266263 LOSHandleLoad();
267264
268 this->NotifyLoaded(H, Objs, LoadedObjInfos);
265 if (this->NotifyLoaded)
266 this->NotifyLoaded(H, ObjToLoad, *Info);
269267
270268 RTDyld.finalizeWithMemoryManagerLocking();
271269
273271 this->NotifyFinalized(H);
274272 };
275273
276 auto LOS =
277 createLinkedObjectSet(std::move(Objects), std::move(MemMgr),
278 std::move(Resolver), std::move(Finalizer),
279 ProcessAllSections);
274 auto LO =
275 createLinkedObject(std::move(Obj), std::move(MemMgr), std::move(Resolver),
276 std::move(Finalizer), ProcessAllSections);
280277 // LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
281278 // below.
282 auto *LOSPtr = LOS.get();
283
284 ObjSetHandleT Handle = LinkedObjSetList.insert(LinkedObjSetList.end(),
285 std::move(LOS));
286 LOSPtr->setHandle(Handle);
279 auto *LOPtr = LO.get();
280
281 ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO));
282 LOPtr->setHandle(Handle);
287283
288284 return Handle;
289285 }
296292 /// indirectly) will result in undefined behavior. If dependence tracking is
297293 /// required to detect or resolve such issues it should be added at a higher
298294 /// layer.
299 void removeObjectSet(ObjSetHandleT H) {
295 void removeObject(ObjHandleT H) {
300296 // How do we invalidate the symbols in H?
301 LinkedObjSetList.erase(H);
297 LinkedObjList.erase(H);
302298 }
303299
304300 /// @brief Search for the given named symbol.
306302 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
307303 /// @return A handle for the given named symbol, if it exists.
308304 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
309 for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
305 for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E;
310306 ++I)
311307 if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
312308 return Symbol;
321317 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
322318 /// @return A handle for the given named symbol, if it is found in the
323319 /// given object set.
324 JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
320 JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
325321 bool ExportedSymbolsOnly) {
326322 return (*H)->getSymbol(Name, ExportedSymbolsOnly);
327323 }
328324
329325 /// @brief Map section addresses for the objects associated with the handle H.
330 void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
326 void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
331327 JITTargetAddress TargetAddr) {
332328 (*H)->mapSectionAddress(LocalAddress, TargetAddr);
333329 }
335331 /// @brief Immediately emit and finalize the object set represented by the
336332 /// given handle.
337333 /// @param H Handle for object set to emit/finalize.
338 void emitAndFinalize(ObjSetHandleT H) {
334 void emitAndFinalize(ObjHandleT H) {
339335 (*H)->finalize();
340336 }
341337
342338 private:
343 static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
344 return Obj;
345 }
346
347 template
348 static const object::ObjectFile&
349 getObject(const object::OwningBinary &Obj) {
350 return *Obj.getBinary();
351 }
352
353 LinkedObjectSetListT LinkedObjSetList;
339
340 LinkedObjectListT LinkedObjList;
354341 NotifyLoadedFtor NotifyLoaded;
355342 NotifyFinalizedFtor NotifyFinalized;
356343 bool ProcessAllSections = false;
4646
4747 class OrcCBindingsStack {
4848 public:
49
4950 using CompileCallbackMgr = orc::JITCompileCallbackManager;
50 using ObjLayerT = orc::RTDyldObjectLinkingLayer<>;
51 using CompileLayerT = orc::IRCompileLayer;
51 using ObjLayerT = orc::RTDyldObjectLinkingLayer;
52 using CompileLayerT = orc::IRCompileLayer;
5253 using CODLayerT =
53 orc::CompileOnDemandLayer;
54 orc::CompileOnDemandLayer;
5455
5556 using CallbackManagerBuilder =
5657 std::function()>;
197197 }
198198
199199 void addObjectFile(std::unique_ptr O) override {
200 std::vector> Objs;
201 Objs.push_back(std::move(O));
202 ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
200 auto Obj =
201 std::make_shared>(std::move(O),
202 nullptr);
203 ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
203204 }
204205
205206 void addObjectFile(object::OwningBinary O) override {
206 std::vector>> Objs;
207 Objs.push_back(
208 llvm::make_unique>(
209 std::move(O)));
210 ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
207 auto Obj =
208 std::make_shared>(std::move(O));
209 ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
211210 }
212211
213212 void addArchive(object::OwningBinary A) override {
259258 ArrayRef ArgValues) override;
260259
261260 void setObjectCache(ObjectCache *NewCache) override {
262 CompileLayer.setObjectCache(NewCache);
261 CompileLayer.getCompiler().setObjectCache(NewCache);
263262 }
264263
265264 void setProcessAllSections(bool ProcessAllSections) override {
297296 }
298297 std::unique_ptr &ChildBin = ChildBinOrErr.get();
299298 if (ChildBin->isObject()) {
300 std::vector> ObjSet;
301 ObjSet.push_back(std::unique_ptr(
302 static_cast(ChildBin.release())));
303 ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
299 std::unique_ptr ChildObj(
300 static_cast(ChildBinOrErr->release()));
301 auto Obj =
302 std::make_shared>(
303 std::move(ChildObj), nullptr);
304 ObjectLayer.addObject(std::move(Obj), &MemMgr, &Resolver);
304305 if (auto Sym = ObjectLayer.findSymbol(Name, true))
305306 return Sym;
306307 }
316317
317318 NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
318319
319 template
320 void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT H,
321 const ObjListT &Objects,
322 const LoadedObjInfoListT &Infos) const {
320 void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H,
321 const RTDyldObjectLinkingLayer::ObjectPtr &Obj,
322 const LoadedObjectInfo &Info) const {
323323 M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
324324 M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
325 assert(Objects.size() == Infos.size() &&
326 "Incorrect number of Infos for Objects.");
327 for (unsigned I = 0; I < Objects.size(); ++I)
328 M.MemMgr.notifyObjectLoaded(&M, getObject(*Objects[I]));
329 }
330
325 M.MemMgr.notifyObjectLoaded(&M, *Obj->getBinary());
326 }
331327 private:
332 static const object::ObjectFile& getObject(const object::ObjectFile &Obj) {
333 return Obj;
334 }
335
336 template
337 static const object::ObjectFile&
338 getObject(const object::OwningBinary &Obj) {
339 return *Obj.getBinary();
340 }
341
342328 OrcMCJITReplacement &M;
343329 };
344330
346332 public:
347333 NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
348334
349 void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT H) {
335 void operator()(RTDyldObjectLinkingLayerBase::ObjHandleT H) {
350336 M.UnfinalizedSections.erase(H);
351337 }
352338
363349 return MangledName;
364350 }
365351
366 using ObjectLayerT = RTDyldObjectLinkingLayer;
367 using CompileLayerT = IRCompileLayer;
352 using ObjectLayerT = RTDyldObjectLinkingLayer;
353 using CompileLayerT = IRCompileLayer;
368354 using LazyEmitLayerT = LazyEmittingLayer;
369355
370356 std::unique_ptr TM;
384370 // that have been emitted but not yet finalized so that we can forward the
385371 // mapSectionAddress calls appropriately.
386372 using SectionAddrSet = std::set;
387 struct ObjSetHandleCompare {
388 bool operator()(ObjectLayerT::ObjSetHandleT H1,
389 ObjectLayerT::ObjSetHandleT H2) const {
373 struct ObjHandleCompare {
374 bool operator()(ObjectLayerT::ObjHandleT H1,
375 ObjectLayerT::ObjHandleT H2) const {
390376 return &*H1 < &*H2;
391377 }
392378 };
393379 SectionAddrSet SectionsAllocatedSinceLastLoad;
394 std::mapSetHandleT, SectionAddrSet, ObjSetHandleCompare>
380 std::mapHandleT, SectionAddrSet, ObjHandleCompare>
395381 UnfinalizedSections;
396382
397383 std::vector> Archives;
4444
4545 class OrcLazyJIT {
4646 public:
47
4748 using CompileCallbackMgr = orc::JITCompileCallbackManager;
48 using ObjLayerT = orc::RTDyldObjectLinkingLayer<>;
49 using CompileLayerT = orc::IRCompileLayer;
49 using ObjLayerT = orc::RTDyldObjectLinkingLayer;
50 using CompileLayerT = orc::IRCompileLayer;
5051 using TransformFtor =
51 std::function(std::unique_ptr)>;
52 std::function(std::unique_ptr)>;
5253 using IRDumpLayerT = orc::IRTransformLayer;
5354 using CODLayerT = orc::CompileOnDemandLayer;
5455 using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
3030 typedef int MockObjectFile;
3131
3232 // stand-in for llvm::MemoryBuffer set
33 typedef int MockMemoryBufferSet;
33 typedef int MockMemoryBuffer;
3434
3535 // Mock transform that operates on unique pointers to object files, and
3636 // allocates new object files rather than mutating the given ones.
3737 struct AllocatingTransform {
38 std::unique_ptr
39 operator()(std::unique_ptr Obj) const {
40 return llvm::make_unique(*Obj + 1);
38 std::shared_ptr
39 operator()(std::shared_ptr Obj) const {
40 return std::make_shared(*Obj + 1);
4141 }
4242 };
4343
4949 // transform layer called the base layer and forwarded any return value.
5050 class MockBaseLayer {
5151 public:
52 typedef int ObjSetHandleT;
52 typedef int ObjHandleT;
5353
5454 MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
5555
56 template SetT, typename MemoryManagerPtrT,
56 template PtrT, typename MemoryManagerPtrT,
5757 typename SymbolResolverPtrT>
58 ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr,
59 SymbolResolverPtrT Resolver) {
58 ObjHandleT addObject(ObjPtrT Obj, MemoryManagerPtrT MemMgr,
59 SymbolResolverPtrT Resolver) {
6060 EXPECT_EQ(MockManager, *MemMgr) << "MM should pass through";
6161 EXPECT_EQ(MockResolver, *Resolver) << "Resolver should pass through";
62 size_t I = 0;
63 for (auto &ObjPtr : Objects) {
64 EXPECT_EQ(MockObjects[I] + 1, *ObjPtr) << "Transform should be applied";
65 I++;
66 }
67 EXPECT_EQ(MockObjects.size(), I) << "Number of objects should match";
68 LastCalled = "addObjectSet";
69 MockObjSetHandle = 111;
70 return MockObjSetHandle;
71 }
72 template
73 void expectAddObjectSet(ObjSetT &Objects, MockMemoryManager *MemMgr,
74 MockSymbolResolver *Resolver) {
62 EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
63 LastCalled = "addObject";
64 MockObjHandle = 111;
65 return MockObjHandle;
66 }
67 template
68 void expectAddObject(ObjPtrT Obj, MockMemoryManager *MemMgr,
69 MockSymbolResolver *Resolver) {
7570 MockManager = *MemMgr;
7671 MockResolver = *Resolver;
77 for (auto &ObjPtr : Objects) {
78 MockObjects.push_back(*ObjPtr);
79 }
80 }
81 void verifyAddObjectSet(ObjSetHandleT Returned) {
82 EXPECT_EQ("addObjectSet", LastCalled);
83 EXPECT_EQ(MockObjSetHandle, Returned) << "Return should pass through";
84 resetExpectations();
85 }
86
87 void removeObjectSet(ObjSetHandleT H) {
88 EXPECT_EQ(MockObjSetHandle, H);
89 LastCalled = "removeObjectSet";
90 }
91 void expectRemoveObjectSet(ObjSetHandleT H) { MockObjSetHandle = H; }
92 void verifyRemoveObjectSet() {
93 EXPECT_EQ("removeObjectSet", LastCalled);
72 MockObject = *Obj;
73 }
74 void verifyAddObject(ObjHandleT Returned) {
75 EXPECT_EQ("addObject", LastCalled);
76 EXPECT_EQ(MockObjHandle, Returned) << "Return should pass through";
77 resetExpectations();
78 }
79
80 void removeObject(ObjHandleT H) {
81 EXPECT_EQ(MockObjHandle, H);
82 LastCalled = "removeObject";
83 }
84 void expectRemoveObject(ObjHandleT H) { MockObjHandle = H; }
85 void verifyRemoveObject() {
86 EXPECT_EQ("removeObject", LastCalled);
9487 resetExpectations();
9588 }
9689
113106 resetExpectations();
114107 }
115108
116 llvm::JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name,
109 llvm::JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name,
117110 bool ExportedSymbolsOnly) {
118 EXPECT_EQ(MockObjSetHandle, H) << "Handle should pass through";
111 EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
119112 EXPECT_EQ(MockName, Name) << "Name should pass through";
120113 EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
121114 LastCalled = "findSymbolIn";
122115 MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
123116 return MockSymbol;
124117 }
125 void expectFindSymbolIn(ObjSetHandleT H, const std::string &Name,
118 void expectFindSymbolIn(ObjHandleT H, const std::string &Name,
126119 bool ExportedSymbolsOnly) {
127 MockObjSetHandle = H;
120 MockObjHandle = H;
128121 MockName = Name;
129122 MockBool = ExportedSymbolsOnly;
130123 }
135128 resetExpectations();
136129 }
137130
138 void emitAndFinalize(ObjSetHandleT H) {
139 EXPECT_EQ(MockObjSetHandle, H) << "Handle should pass through";
131 void emitAndFinalize(ObjHandleT H) {
132 EXPECT_EQ(MockObjHandle, H) << "Handle should pass through";
140133 LastCalled = "emitAndFinalize";
141134 }
142 void expectEmitAndFinalize(ObjSetHandleT H) { MockObjSetHandle = H; }
135 void expectEmitAndFinalize(ObjHandleT H) { MockObjHandle = H; }
143136 void verifyEmitAndFinalize() {
144137 EXPECT_EQ("emitAndFinalize", LastCalled);
145138 resetExpectations();
146139 }
147140
148 void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
141 void mapSectionAddress(ObjHandleT H, const void *LocalAddress,
149142 llvm::JITTargetAddress TargetAddr) {
150 EXPECT_EQ(MockObjSetHandle, H);
143 EXPECT_EQ(MockObjHandle, H);
151144 EXPECT_EQ(MockLocalAddress, LocalAddress);
152145 EXPECT_EQ(MockTargetAddress, TargetAddr);
153146 LastCalled = "mapSectionAddress";
154147 }
155 void expectMapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
148 void expectMapSectionAddress(ObjHandleT H, const void *LocalAddress,
156149 llvm::JITTargetAddress TargetAddr) {
157 MockObjSetHandle = H;
150 MockObjHandle = H;
158151 MockLocalAddress = LocalAddress;
159152 MockTargetAddress = TargetAddr;
160153 }
168161 std::string LastCalled;
169162 MockMemoryManager MockManager;
170163 MockSymbolResolver MockResolver;
171 std::vector MockObjects;
172 ObjSetHandleT MockObjSetHandle;
164 MockObjectFile MockObject;
165 ObjHandleT MockObjHandle;
173166 std::string MockName;
174167 bool MockBool;
175168 llvm::JITSymbol MockSymbol;
176169 const void *MockLocalAddress;
177170 llvm::JITTargetAddress MockTargetAddress;
178 MockMemoryBufferSet MockBufferSet;
171 MockMemoryBuffer MockBuffer;
179172
180173 // Clear remembered parameters between calls
181174 void resetExpectations() {
182175 LastCalled = "nothing";
183176 MockManager = 0;
184177 MockResolver = 0;
185 MockObjects.clear();
186 MockObjSetHandle = 0;
178 MockObject = 0;
179 MockObjHandle = 0;
187180 MockName = "bogus";
188181 MockSymbol = llvm::JITSymbol(nullptr);
189182 MockLocalAddress = nullptr;
190183 MockTargetAddress = 0;
191 MockBufferSet = 0;
184 MockBuffer = 0;
192185 }
193186 };
194187
203196 // Create a second object transform layer using a transform (as a lambda)
204197 // that mutates objects in place, and deals in naked pointers
205198 ObjectTransformLayer
206 std::function>
207 T2(M, [](MockObjectFile *Obj) {
199 std::function(
200 std::shared_ptr)>>
201 T2(M, [](std::shared_ptr Obj) {
208202 ++(*Obj);
209203 return Obj;
210204 });
211205
212206 // Instantiate some mock objects to use below
213 MockObjectFile MockObject1 = 211;
214 MockObjectFile MockObject2 = 222;
215207 MockMemoryManager MockManager = 233;
216208 MockSymbolResolver MockResolver = 244;
217209
218 // Test addObjectSet with T1 (allocating, unique pointers)
219 std::vector> Objs1;
220 Objs1.push_back(llvm::make_unique(MockObject1));
221 Objs1.push_back(llvm::make_unique(MockObject2));
210 // Test addObject with T1 (allocating)
211 auto Obj1 = std::make_shared(211);
222212 auto MM = llvm::make_unique(MockManager);
223213 auto SR = llvm::make_unique(MockResolver);
224 M.expectAddObjectSet(Objs1, MM.get(), SR.get());
225 auto H = T1.addObjectSet(std::move(Objs1), std::move(MM), std::move(SR));
226 M.verifyAddObjectSet(H);
227
228 // Test addObjectSet with T2 (mutating, naked pointers)
229 llvm::SmallVector Objs2Vec;
230 Objs2Vec.push_back(&MockObject1);
231 Objs2Vec.push_back(&MockObject2);
232 llvm::MutableArrayRef Objs2(Objs2Vec);
233 M.expectAddObjectSet(Objs2, &MockManager, &MockResolver);
234 H = T2.addObjectSet(Objs2, &MockManager, &MockResolver);
235 M.verifyAddObjectSet(H);
236 EXPECT_EQ(212, MockObject1) << "Expected mutation";
237 EXPECT_EQ(223, MockObject2) << "Expected mutation";
214 M.expectAddObject(Obj1, MM.get(), SR.get());
215 auto H = T1.addObject(std::move(Obj1), std::move(MM), std::move(SR));
216 M.verifyAddObject(H);
217
218 // Test addObjectSet with T2 (mutating)
219 auto Obj2 = std::make_shared(222);
220 M.expectAddObject(Obj2, &MockManager, &MockResolver);
221 H = T2.addObject(Obj2, &MockManager, &MockResolver);
222 M.verifyAddObject(H);
223 EXPECT_EQ(223, *Obj2) << "Expected mutation";
238224
239225 // Test removeObjectSet
240 M.expectRemoveObjectSet(H);
241 T1.removeObjectSet(H);
242 M.verifyRemoveObjectSet();
226 M.expectRemoveObject(H);
227 T1.removeObject(H);
228 M.verifyRemoveObject();
243229
244230 // Test findSymbol
245231 std::string Name = "foo";
268254 M.verifyMapSectionAddress();
269255
270256 // Verify transform getter (non-const)
271 MockObjectFile Mutatee = 277;
272 MockObjectFile *Out = T2.getTransform()(&Mutatee);
273 EXPECT_EQ(&Mutatee, Out) << "Expected in-place transform";
274 EXPECT_EQ(278, Mutatee) << "Expected incrementing transform";
257 auto Mutatee = std::make_shared(277);
258 auto Out = T2.getTransform()(Mutatee);
259 EXPECT_EQ(*Mutatee, *Out) << "Expected in-place transform";
260 EXPECT_EQ(278, *Mutatee) << "Expected incrementing transform";
275261
276262 // Verify transform getter (const)
277 auto OwnedObj = llvm::make_unique(288);
263 auto OwnedObj = std::make_shared(288);
278264 const auto &T1C = T1;
279265 OwnedObj = T1C.getTransform()(std::move(OwnedObj));
280266 EXPECT_EQ(289, *OwnedObj) << "Expected incrementing transform";
286272 // Make sure that ObjectTransformLayer implements the object layer concept
287273 // correctly by sandwitching one between an ObjectLinkingLayer and an
288274 // IRCompileLayer, verifying that it compiles if we have a call to the
289 // IRComileLayer's addModuleSet that should call the transform layer's
290 // addObjectSet, and also calling the other public transform layer methods
275 // IRComileLayer's addModule that should call the transform layer's
276 // addObject, and also calling the other public transform layer methods
291277 // directly to make sure the methods they intend to forward to exist on
292278 // the ObjectLinkingLayer.
293279
308294 };
309295
310296 // Construct the jit layers.
311 RTDyldObjectLinkingLayer<> BaseLayer;
312 auto IdentityTransform = [](
313 std::unique_ptr>
314 Obj) { return Obj; };
297 RTDyldObjectLinkingLayer BaseLayer;
298 auto IdentityTransform =
299 [](std::shared_ptr>
300 Obj) {
301 return Obj;
302 };
315303 ObjectTransformLayer
316304 TransformLayer(BaseLayer, IdentityTransform);
317305 auto NullCompiler = [](llvm::Module &) {
318 return llvm::object::OwningBinary();
306 return llvm::object::OwningBinary(nullptr,
307 nullptr);
319308 };
320 IRCompileLayer CompileLayer(TransformLayer,
321 NullCompiler);
309 IRCompileLayer
310 CompileLayer(TransformLayer, NullCompiler);
322311
323312 // Make sure that the calls from IRCompileLayer to ObjectTransformLayer
324313 // compile.
328317
329318 // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
330319 // compile.
331 decltype(TransformLayer)::ObjSetHandleT ObjSet;
332 TransformLayer.emitAndFinalize(ObjSet);
333 TransformLayer.findSymbolIn(ObjSet, Name, false);
320 decltype(TransformLayer)::ObjHandleT H2;
321 TransformLayer.emitAndFinalize(H2);
322 TransformLayer.findSymbolIn(H2, Name, false);
334323 TransformLayer.findSymbol(Name, true);
335 TransformLayer.mapSectionAddress(ObjSet, nullptr, 0);
336 TransformLayer.removeObjectSet(ObjSet);
324 TransformLayer.mapSectionAddress(H2, nullptr, 0);
325 TransformLayer.removeObject(H2);
337326 }
338327 }
6262 bool &DebugSeen;
6363 };
6464
65 RTDyldObjectLinkingLayer<> ObjLayer;
65 RTDyldObjectLinkingLayer ObjLayer;
6666
6767 LLVMContext Context;
6868 auto M = llvm::make_unique("", Context);
8484 if (!TM)
8585 return;
8686
87 auto OwningObj = SimpleCompiler(*TM)(*M);
88 std::vector Objs;
89 Objs.push_back(OwningObj.getBinary());
87 auto Obj =
88 std::make_shared>(
89 SimpleCompiler(*TM)(*M));
9090
9191 bool DebugSectionSeen = false;
9292 auto SMMW =
102102
103103 {
104104 // Test with ProcessAllSections = false (the default).
105 auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
105 auto H = ObjLayer.addObject(Obj, SMMW, &*Resolver);
106106 ObjLayer.emitAndFinalize(H);
107107 EXPECT_EQ(DebugSectionSeen, false)
108108 << "Unexpected debug info section";
109 ObjLayer.removeObjectSet(H);
109 ObjLayer.removeObject(H);
110110 }
111111
112112 {
113113 // Test with ProcessAllSections = true.
114114 ObjLayer.setProcessAllSections(true);
115 auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
115 auto H = ObjLayer.addObject(Obj, SMMW, &*Resolver);
116116 ObjLayer.emitAndFinalize(H);
117117 EXPECT_EQ(DebugSectionSeen, true)
118118 << "Expected debug info section not seen";
119 ObjLayer.removeObjectSet(H);
119 ObjLayer.removeObject(H);
120120 }
121121 }
122122
124124 if (!TM)
125125 return;
126126
127 RTDyldObjectLinkingLayer<> ObjLayer;
127 RTDyldObjectLinkingLayer ObjLayer;
128128 SimpleCompiler Compile(*TM);
129129
130130 // Create a pair of modules that will trigger recursive finalization:
150150 Builder.CreateRet(FourtyTwo);
151151 }
152152
153 auto Obj1 = Compile(*MB1.getModule());
154 std::vector Obj1Set;
155 Obj1Set.push_back(Obj1.getBinary());
153 auto Obj1 =
154 std::make_shared>(
155 Compile(*MB1.getModule()));
156156
157157 ModuleBuilder MB2(Context, "", "dummy");
158158 {
163163 IRBuilder<> Builder(FooEntry);
164164 Builder.CreateRet(Builder.CreateCall(BarDecl));
165165 }
166 auto Obj2 = Compile(*MB2.getModule());
167 std::vector Obj2Set;
168 Obj2Set.push_back(Obj2.getBinary());
166 auto Obj2 =
167 std::make_shared>(
168 Compile(*MB2.getModule()));
169169
170170 auto Resolver =
171171 createLambdaResolver(
179179 });
180180
181181 auto SMMW = std::make_shared();
182 ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &*Resolver);
183 auto H = ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &*Resolver);
182 ObjLayer.addObject(std::move(Obj1), SMMW, &*Resolver);
183 auto H = ObjLayer.addObject(std::move(Obj2), SMMW, &*Resolver);
184184 ObjLayer.emitAndFinalize(H);
185 ObjLayer.removeObjectSet(H);
185 ObjLayer.removeObject(H);
186186
187187 // Finalization of module 2 should trigger finalization of module 1.
188188 // Verify that finalize on SMMW is only called once.
194194 if (!TM)
195195 return;
196196
197 RTDyldObjectLinkingLayer<> ObjLayer;
197 RTDyldObjectLinkingLayer ObjLayer;
198198 SimpleCompiler Compile(*TM);
199199
200200 // Create a pair of unrelated modules:
221221 Builder.CreateRet(FourtyTwo);
222222 }
223223
224 auto Obj1 = Compile(*MB1.getModule());
225 std::vector Obj1Set;
226 Obj1Set.push_back(Obj1.getBinary());
224 auto Obj1 =
225 std::make_shared>(
226 Compile(*MB1.getModule()));
227227
228228 ModuleBuilder MB2(Context, "", "dummy");
229229 {
235235 Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
236236 Builder.CreateRet(Seven);
237237 }
238 auto Obj2 = Compile(*MB2.getModule());
239 std::vector Obj2Set;
240 Obj2Set.push_back(Obj2.getBinary());
238 auto Obj2 =
239 std::make_shared>(
240 Compile(*MB2.getModule()));
241241
242242 auto SMMW = std::make_shared();
243243 NullResolver NR;
244 auto H = ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &NR);
245 ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &NR);
244 auto H = ObjLayer.addObject(std::move(Obj1), SMMW, &NR);
245 ObjLayer.addObject(std::move(Obj2), SMMW, &NR);
246246 ObjLayer.emitAndFinalize(H);
247 ObjLayer.removeObjectSet(H);
247 ObjLayer.removeObject(H);
248248
249249 // Only one call to needsToReserveAllocationSpace should have been made.
250250 EXPECT_EQ(SMMW->NeedsToReserveAllocationSpaceCount, 1)