xref: /llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h (revision 212cdc9a377a1b3ac96be0da20212592ebd2c818)
1 //===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Contains core ORC APIs.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H
14 #define LLVM_EXECUTIONENGINE_ORC_CORE_H
15 
16 #include "llvm/ADT/BitmaskEnum.h"
17 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/ADT/FunctionExtras.h"
19 #include "llvm/ADT/IntrusiveRefCntPtr.h"
20 #include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
21 #include "llvm/ExecutionEngine/JITSymbol.h"
22 #include "llvm/ExecutionEngine/Orc/CoreContainers.h"
23 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
24 #include "llvm/ExecutionEngine/Orc/MaterializationUnit.h"
25 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
26 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
27 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
28 #include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/ExtensibleRTTI.h"
31 
32 #include <atomic>
33 #include <deque>
34 #include <future>
35 #include <memory>
36 #include <vector>
37 
38 namespace llvm {
39 namespace orc {
40 
41 // Forward declare some classes.
42 class AsynchronousSymbolQuery;
43 class ExecutionSession;
44 class MaterializationResponsibility;
45 class JITDylib;
46 class ResourceTracker;
47 class InProgressLookupState;
48 
49 enum class SymbolState : uint8_t;
50 
51 using ResourceTrackerSP = IntrusiveRefCntPtr<ResourceTracker>;
52 using JITDylibSP = IntrusiveRefCntPtr<JITDylib>;
53 
54 /// A definition of a Symbol within a JITDylib.
55 class SymbolInstance {
56 public:
57   using LookupAsyncOnCompleteFn =
58       unique_function<void(Expected<ExecutorSymbolDef>)>;
59 
60   SymbolInstance(JITDylibSP JD, SymbolStringPtr Name)
61       : JD(std::move(JD)), Name(std::move(Name)) {}
62 
63   const JITDylib &getJITDylib() const { return *JD; }
64   const SymbolStringPtr &getName() const { return Name; }
65 
66   Expected<ExecutorSymbolDef> lookup() const;
67   void lookupAsync(LookupAsyncOnCompleteFn OnComplete) const;
68 
69 private:
70   JITDylibSP JD;
71   SymbolStringPtr Name;
72 };
73 
74 using ResourceKey = uintptr_t;
75 
76 /// API to remove / transfer ownership of JIT resources.
77 class ResourceTracker : public ThreadSafeRefCountedBase<ResourceTracker> {
78 private:
79   friend class ExecutionSession;
80   friend class JITDylib;
81   friend class MaterializationResponsibility;
82 
83 public:
84   ResourceTracker(const ResourceTracker &) = delete;
85   ResourceTracker &operator=(const ResourceTracker &) = delete;
86   ResourceTracker(ResourceTracker &&) = delete;
87   ResourceTracker &operator=(ResourceTracker &&) = delete;
88 
89   ~ResourceTracker();
90 
91   /// Return the JITDylib targeted by this tracker.
92   JITDylib &getJITDylib() const {
93     return *reinterpret_cast<JITDylib *>(JDAndFlag.load() &
94                                          ~static_cast<uintptr_t>(1));
95   }
96 
97   /// Runs the given callback under the session lock, passing in the associated
98   /// ResourceKey. This is the safe way to associate resources with trackers.
99   template <typename Func> Error withResourceKeyDo(Func &&F);
100 
101   /// Remove all resources associated with this key.
102   Error remove();
103 
104   /// Transfer all resources associated with this key to the given
105   /// tracker, which must target the same JITDylib as this one.
106   void transferTo(ResourceTracker &DstRT);
107 
108   /// Return true if this tracker has become defunct.
109   bool isDefunct() const { return JDAndFlag.load() & 0x1; }
110 
111   /// Returns the key associated with this tracker.
112   /// This method should not be used except for debug logging: there is no
113   /// guarantee that the returned value will remain valid.
114   ResourceKey getKeyUnsafe() const { return reinterpret_cast<uintptr_t>(this); }
115 
116 private:
117   ResourceTracker(JITDylibSP JD);
118 
119   void makeDefunct();
120 
121   std::atomic_uintptr_t JDAndFlag;
122 };
123 
124 /// Listens for ResourceTracker operations.
125 class ResourceManager {
126 public:
127   virtual ~ResourceManager();
128 
129   /// This function will be called *outside* the session lock. ResourceManagers
130   /// should perform book-keeping under the session lock, and any expensive
131   /// cleanup outside the session lock.
132   virtual Error handleRemoveResources(JITDylib &JD, ResourceKey K) = 0;
133 
134   /// This function will be called *inside* the session lock. ResourceManagers
135   /// DO NOT need to re-lock the session.
136   virtual void handleTransferResources(JITDylib &JD, ResourceKey DstK,
137                                        ResourceKey SrcK) = 0;
138 };
139 
140 /// Lookup flags that apply to each dylib in the search order for a lookup.
141 ///
142 /// If MatchHiddenSymbolsOnly is used (the default) for a given dylib, then
143 /// only symbols in that Dylib's interface will be searched. If
144 /// MatchHiddenSymbols is used then symbols with hidden visibility will match
145 /// as well.
146 enum class JITDylibLookupFlags { MatchExportedSymbolsOnly, MatchAllSymbols };
147 
148 /// Lookup flags that apply to each symbol in a lookup.
149 ///
150 /// If RequiredSymbol is used (the default) for a given symbol then that symbol
151 /// must be found during the lookup or the lookup will fail returning a
152 /// SymbolNotFound error. If WeaklyReferencedSymbol is used and the given
153 /// symbol is not found then the query will continue, and no result for the
154 /// missing symbol will be present in the result (assuming the rest of the
155 /// lookup succeeds).
156 enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
157 
158 /// Describes the kind of lookup being performed. The lookup kind is passed to
159 /// symbol generators (if they're invoked) to help them determine what
160 /// definitions to generate.
161 ///
162 /// Static -- Lookup is being performed as-if at static link time (e.g.
163 ///           generators representing static archives should pull in new
164 ///           definitions).
165 ///
166 /// DLSym -- Lookup is being performed as-if at runtime (e.g. generators
167 ///          representing static archives should not pull in new definitions).
168 enum class LookupKind { Static, DLSym };
169 
170 /// A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search
171 /// order during symbol lookup.
172 using JITDylibSearchOrder =
173     std::vector<std::pair<JITDylib *, JITDylibLookupFlags>>;
174 
175 /// Convenience function for creating a search order from an ArrayRef of
176 /// JITDylib*, all with the same flags.
177 inline JITDylibSearchOrder makeJITDylibSearchOrder(
178     ArrayRef<JITDylib *> JDs,
179     JITDylibLookupFlags Flags = JITDylibLookupFlags::MatchExportedSymbolsOnly) {
180   JITDylibSearchOrder O;
181   O.reserve(JDs.size());
182   for (auto *JD : JDs)
183     O.push_back(std::make_pair(JD, Flags));
184   return O;
185 }
186 
187 /// A set of symbols to look up, each associated with a SymbolLookupFlags
188 /// value.
189 ///
190 /// This class is backed by a vector and optimized for fast insertion,
191 /// deletion and iteration. It does not guarantee a stable order between
192 /// operations, and will not automatically detect duplicate elements (they
193 /// can be manually checked by calling the validate method).
194 class SymbolLookupSet {
195 public:
196   using value_type = std::pair<SymbolStringPtr, SymbolLookupFlags>;
197   using UnderlyingVector = std::vector<value_type>;
198   using iterator = UnderlyingVector::iterator;
199   using const_iterator = UnderlyingVector::const_iterator;
200 
201   SymbolLookupSet() = default;
202 
203   SymbolLookupSet(std::initializer_list<value_type> Elems) {
204     for (auto &E : Elems)
205       Symbols.push_back(std::move(E));
206   }
207 
208   explicit SymbolLookupSet(
209       SymbolStringPtr Name,
210       SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
211     add(std::move(Name), Flags);
212   }
213 
214   /// Construct a SymbolLookupSet from an initializer list of SymbolStringPtrs.
215   explicit SymbolLookupSet(
216       std::initializer_list<SymbolStringPtr> Names,
217       SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
218     Symbols.reserve(Names.size());
219     for (const auto &Name : Names)
220       add(std::move(Name), Flags);
221   }
222 
223   /// Construct a SymbolLookupSet from a SymbolNameSet with the given
224   /// Flags used for each value.
225   explicit SymbolLookupSet(
226       const SymbolNameSet &Names,
227       SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
228     Symbols.reserve(Names.size());
229     for (const auto &Name : Names)
230       add(Name, Flags);
231   }
232 
233   /// Construct a SymbolLookupSet from a vector of symbols with the given Flags
234   /// used for each value.
235   /// If the ArrayRef contains duplicates it is up to the client to remove these
236   /// before using this instance for lookup.
237   explicit SymbolLookupSet(
238       ArrayRef<SymbolStringPtr> Names,
239       SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
240     Symbols.reserve(Names.size());
241     for (const auto &Name : Names)
242       add(Name, Flags);
243   }
244 
245   /// Construct a SymbolLookupSet from DenseMap keys.
246   template <typename ValT>
247   static SymbolLookupSet
248   fromMapKeys(const DenseMap<SymbolStringPtr, ValT> &M,
249               SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
250     SymbolLookupSet Result;
251     Result.Symbols.reserve(M.size());
252     for (const auto &[Name, Val] : M)
253       Result.add(Name, Flags);
254     return Result;
255   }
256 
257   /// Add an element to the set. The client is responsible for checking that
258   /// duplicates are not added.
259   SymbolLookupSet &
260   add(SymbolStringPtr Name,
261       SymbolLookupFlags Flags = SymbolLookupFlags::RequiredSymbol) {
262     Symbols.push_back(std::make_pair(std::move(Name), Flags));
263     return *this;
264   }
265 
266   /// Quickly append one lookup set to another.
267   SymbolLookupSet &append(SymbolLookupSet Other) {
268     Symbols.reserve(Symbols.size() + Other.size());
269     for (auto &KV : Other)
270       Symbols.push_back(std::move(KV));
271     return *this;
272   }
273 
274   bool empty() const { return Symbols.empty(); }
275   UnderlyingVector::size_type size() const { return Symbols.size(); }
276   iterator begin() { return Symbols.begin(); }
277   iterator end() { return Symbols.end(); }
278   const_iterator begin() const { return Symbols.begin(); }
279   const_iterator end() const { return Symbols.end(); }
280 
281   /// Removes the Ith element of the vector, replacing it with the last element.
282   void remove(UnderlyingVector::size_type I) {
283     std::swap(Symbols[I], Symbols.back());
284     Symbols.pop_back();
285   }
286 
287   /// Removes the element pointed to by the given iterator. This iterator and
288   /// all subsequent ones (including end()) are invalidated.
289   void remove(iterator I) { remove(I - begin()); }
290 
291   /// Removes all elements matching the given predicate, which must be callable
292   /// as bool(const SymbolStringPtr &, SymbolLookupFlags Flags).
293   template <typename PredFn> void remove_if(PredFn &&Pred) {
294     UnderlyingVector::size_type I = 0;
295     while (I != Symbols.size()) {
296       const auto &Name = Symbols[I].first;
297       auto Flags = Symbols[I].second;
298       if (Pred(Name, Flags))
299         remove(I);
300       else
301         ++I;
302     }
303   }
304 
305   /// Loop over the elements of this SymbolLookupSet, applying the Body function
306   /// to each one. Body must be callable as
307   /// bool(const SymbolStringPtr &, SymbolLookupFlags).
308   /// If Body returns true then the element just passed in is removed from the
309   /// set. If Body returns false then the element is retained.
310   template <typename BodyFn>
311   auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
312       std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
313                                  std::declval<SymbolLookupFlags>())),
314                    bool>::value> {
315     UnderlyingVector::size_type I = 0;
316     while (I != Symbols.size()) {
317       const auto &Name = Symbols[I].first;
318       auto Flags = Symbols[I].second;
319       if (Body(Name, Flags))
320         remove(I);
321       else
322         ++I;
323     }
324   }
325 
326   /// Loop over the elements of this SymbolLookupSet, applying the Body function
327   /// to each one. Body must be callable as
328   /// Expected<bool>(const SymbolStringPtr &, SymbolLookupFlags).
329   /// If Body returns a failure value, the loop exits immediately. If Body
330   /// returns true then the element just passed in is removed from the set. If
331   /// Body returns false then the element is retained.
332   template <typename BodyFn>
333   auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
334       std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
335                                  std::declval<SymbolLookupFlags>())),
336                    Expected<bool>>::value,
337       Error> {
338     UnderlyingVector::size_type I = 0;
339     while (I != Symbols.size()) {
340       const auto &Name = Symbols[I].first;
341       auto Flags = Symbols[I].second;
342       auto Remove = Body(Name, Flags);
343       if (!Remove)
344         return Remove.takeError();
345       if (*Remove)
346         remove(I);
347       else
348         ++I;
349     }
350     return Error::success();
351   }
352 
353   /// Construct a SymbolNameVector from this instance by dropping the Flags
354   /// values.
355   SymbolNameVector getSymbolNames() const {
356     SymbolNameVector Names;
357     Names.reserve(Symbols.size());
358     for (const auto &KV : Symbols)
359       Names.push_back(KV.first);
360     return Names;
361   }
362 
363   /// Sort the lookup set by pointer value. This sort is fast but sensitive to
364   /// allocation order and so should not be used where a consistent order is
365   /// required.
366   void sortByAddress() { llvm::sort(Symbols, llvm::less_first()); }
367 
368   /// Sort the lookup set lexicographically. This sort is slow but the order
369   /// is unaffected by allocation order.
370   void sortByName() {
371     llvm::sort(Symbols, [](const value_type &LHS, const value_type &RHS) {
372       return *LHS.first < *RHS.first;
373     });
374   }
375 
376   /// Remove any duplicate elements. If a SymbolLookupSet is not duplicate-free
377   /// by construction, this method can be used to turn it into a proper set.
378   void removeDuplicates() {
379     sortByAddress();
380     auto LastI = llvm::unique(Symbols);
381     Symbols.erase(LastI, Symbols.end());
382   }
383 
384 #ifndef NDEBUG
385   /// Returns true if this set contains any duplicates. This should only be used
386   /// in assertions.
387   bool containsDuplicates() {
388     if (Symbols.size() < 2)
389       return false;
390     sortByAddress();
391     for (UnderlyingVector::size_type I = 1; I != Symbols.size(); ++I)
392       if (Symbols[I].first == Symbols[I - 1].first)
393         return true;
394     return false;
395   }
396 #endif
397 
398 private:
399   UnderlyingVector Symbols;
400 };
401 
402 struct SymbolAliasMapEntry {
403   SymbolAliasMapEntry() = default;
404   SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
405       : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
406 
407   SymbolStringPtr Aliasee;
408   JITSymbolFlags AliasFlags;
409 };
410 
411 /// A map of Symbols to (Symbol, Flags) pairs.
412 using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
413 
414 /// Callback to notify client that symbols have been resolved.
415 using SymbolsResolvedCallback = unique_function<void(Expected<SymbolMap>)>;
416 
417 /// Callback to register the dependencies for a given query.
418 using RegisterDependenciesFunction =
419     std::function<void(const SymbolDependenceMap &)>;
420 
421 /// This can be used as the value for a RegisterDependenciesFunction if there
422 /// are no dependants to register with.
423 extern RegisterDependenciesFunction NoDependenciesToRegister;
424 
425 class ResourceTrackerDefunct : public ErrorInfo<ResourceTrackerDefunct> {
426 public:
427   static char ID;
428 
429   ResourceTrackerDefunct(ResourceTrackerSP RT);
430   std::error_code convertToErrorCode() const override;
431   void log(raw_ostream &OS) const override;
432 
433 private:
434   ResourceTrackerSP RT;
435 };
436 
437 /// Used to notify a JITDylib that the given set of symbols failed to
438 /// materialize.
439 class FailedToMaterialize : public ErrorInfo<FailedToMaterialize> {
440 public:
441   static char ID;
442 
443   FailedToMaterialize(std::shared_ptr<SymbolStringPool> SSP,
444                       std::shared_ptr<SymbolDependenceMap> Symbols);
445   ~FailedToMaterialize();
446   std::error_code convertToErrorCode() const override;
447   void log(raw_ostream &OS) const override;
448   const SymbolDependenceMap &getSymbols() const { return *Symbols; }
449 
450 private:
451   std::shared_ptr<SymbolStringPool> SSP;
452   std::shared_ptr<SymbolDependenceMap> Symbols;
453 };
454 
455 /// Used to report failure due to unsatisfiable symbol dependencies.
456 class UnsatisfiedSymbolDependencies
457     : public ErrorInfo<UnsatisfiedSymbolDependencies> {
458 public:
459   static char ID;
460 
461   UnsatisfiedSymbolDependencies(std::shared_ptr<SymbolStringPool> SSP,
462                                 JITDylibSP JD, SymbolNameSet FailedSymbols,
463                                 SymbolDependenceMap BadDeps,
464                                 std::string Explanation);
465   std::error_code convertToErrorCode() const override;
466   void log(raw_ostream &OS) const override;
467 
468 private:
469   std::shared_ptr<SymbolStringPool> SSP;
470   JITDylibSP JD;
471   SymbolNameSet FailedSymbols;
472   SymbolDependenceMap BadDeps;
473   std::string Explanation;
474 };
475 
476 /// Used to notify clients when symbols can not be found during a lookup.
477 class SymbolsNotFound : public ErrorInfo<SymbolsNotFound> {
478 public:
479   static char ID;
480 
481   SymbolsNotFound(std::shared_ptr<SymbolStringPool> SSP, SymbolNameSet Symbols);
482   SymbolsNotFound(std::shared_ptr<SymbolStringPool> SSP,
483                   SymbolNameVector Symbols);
484   std::error_code convertToErrorCode() const override;
485   void log(raw_ostream &OS) const override;
486   std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
487   const SymbolNameVector &getSymbols() const { return Symbols; }
488 
489 private:
490   std::shared_ptr<SymbolStringPool> SSP;
491   SymbolNameVector Symbols;
492 };
493 
494 /// Used to notify clients that a set of symbols could not be removed.
495 class SymbolsCouldNotBeRemoved : public ErrorInfo<SymbolsCouldNotBeRemoved> {
496 public:
497   static char ID;
498 
499   SymbolsCouldNotBeRemoved(std::shared_ptr<SymbolStringPool> SSP,
500                            SymbolNameSet Symbols);
501   std::error_code convertToErrorCode() const override;
502   void log(raw_ostream &OS) const override;
503   std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
504   const SymbolNameSet &getSymbols() const { return Symbols; }
505 
506 private:
507   std::shared_ptr<SymbolStringPool> SSP;
508   SymbolNameSet Symbols;
509 };
510 
511 /// Errors of this type should be returned if a module fails to include
512 /// definitions that are claimed by the module's associated
513 /// MaterializationResponsibility. If this error is returned it is indicative of
514 /// a broken transformation / compiler / object cache.
515 class MissingSymbolDefinitions : public ErrorInfo<MissingSymbolDefinitions> {
516 public:
517   static char ID;
518 
519   MissingSymbolDefinitions(std::shared_ptr<SymbolStringPool> SSP,
520                            std::string ModuleName, SymbolNameVector Symbols)
521       : SSP(std::move(SSP)), ModuleName(std::move(ModuleName)),
522         Symbols(std::move(Symbols)) {}
523   std::error_code convertToErrorCode() const override;
524   void log(raw_ostream &OS) const override;
525   std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
526   const std::string &getModuleName() const { return ModuleName; }
527   const SymbolNameVector &getSymbols() const { return Symbols; }
528 private:
529   std::shared_ptr<SymbolStringPool> SSP;
530   std::string ModuleName;
531   SymbolNameVector Symbols;
532 };
533 
534 /// Errors of this type should be returned if a module contains definitions for
535 /// symbols that are not claimed by the module's associated
536 /// MaterializationResponsibility. If this error is returned it is indicative of
537 /// a broken transformation / compiler / object cache.
538 class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions> {
539 public:
540   static char ID;
541 
542   UnexpectedSymbolDefinitions(std::shared_ptr<SymbolStringPool> SSP,
543                               std::string ModuleName, SymbolNameVector Symbols)
544       : SSP(std::move(SSP)), ModuleName(std::move(ModuleName)),
545         Symbols(std::move(Symbols)) {}
546   std::error_code convertToErrorCode() const override;
547   void log(raw_ostream &OS) const override;
548   std::shared_ptr<SymbolStringPool> getSymbolStringPool() { return SSP; }
549   const std::string &getModuleName() const { return ModuleName; }
550   const SymbolNameVector &getSymbols() const { return Symbols; }
551 private:
552   std::shared_ptr<SymbolStringPool> SSP;
553   std::string ModuleName;
554   SymbolNameVector Symbols;
555 };
556 
557 /// A set of symbols and the their dependencies. Used to describe dependencies
558 /// for the MaterializationResponsibility::notifyEmitted operation.
559 struct SymbolDependenceGroup {
560   SymbolNameSet Symbols;
561   SymbolDependenceMap Dependencies;
562 };
563 
564 /// Tracks responsibility for materialization, and mediates interactions between
565 /// MaterializationUnits and JDs.
566 ///
567 /// An instance of this class is passed to MaterializationUnits when their
568 /// materialize method is called. It allows MaterializationUnits to resolve and
569 /// emit symbols, or abandon materialization by notifying any unmaterialized
570 /// symbols of an error.
571 class MaterializationResponsibility {
572   friend class ExecutionSession;
573   friend class JITDylib;
574 
575 public:
576   MaterializationResponsibility(MaterializationResponsibility &&) = delete;
577   MaterializationResponsibility &
578   operator=(MaterializationResponsibility &&) = delete;
579 
580   /// Destruct a MaterializationResponsibility instance. In debug mode
581   ///        this asserts that all symbols being tracked have been either
582   ///        emitted or notified of an error.
583   ~MaterializationResponsibility();
584 
585   /// Return the ResourceTracker associated with this instance.
586   const ResourceTrackerSP &getResourceTracker() const { return RT; }
587 
588   /// Runs the given callback under the session lock, passing in the associated
589   /// ResourceKey. This is the safe way to associate resources with trackers.
590   template <typename Func> Error withResourceKeyDo(Func &&F) const {
591     return RT->withResourceKeyDo(std::forward<Func>(F));
592   }
593 
594   /// Returns the target JITDylib that these symbols are being materialized
595   ///        into.
596   JITDylib &getTargetJITDylib() const { return JD; }
597 
598   /// Returns the ExecutionSession for this instance.
599   ExecutionSession &getExecutionSession() const;
600 
601   /// Returns the symbol flags map for this responsibility instance.
602   /// Note: The returned flags may have transient flags (Lazy, Materializing)
603   /// set. These should be stripped with JITSymbolFlags::stripTransientFlags
604   /// before using.
605   const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
606 
607   /// Returns the initialization pseudo-symbol, if any. This symbol will also
608   /// be present in the SymbolFlagsMap for this MaterializationResponsibility
609   /// object.
610   const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }
611 
612   /// Returns the names of any symbols covered by this
613   /// MaterializationResponsibility object that have queries pending. This
614   /// information can be used to return responsibility for unrequested symbols
615   /// back to the JITDylib via the delegate method.
616   SymbolNameSet getRequestedSymbols() const;
617 
618   /// Notifies the target JITDylib that the given symbols have been resolved.
619   /// This will update the given symbols' addresses in the JITDylib, and notify
620   /// any pending queries on the given symbols of their resolution. The given
621   /// symbols must be ones covered by this MaterializationResponsibility
622   /// instance. Individual calls to this method may resolve a subset of the
623   /// symbols, but all symbols must have been resolved prior to calling emit.
624   ///
625   /// This method will return an error if any symbols being resolved have been
626   /// moved to the error state due to the failure of a dependency. If this
627   /// method returns an error then clients should log it and call
628   /// failMaterialize. If no dependencies have been registered for the
629   /// symbols covered by this MaterializationResponsibility then this method
630   /// is guaranteed to return Error::success() and can be wrapped with cantFail.
631   Error notifyResolved(const SymbolMap &Symbols);
632 
633   /// Notifies the target JITDylib (and any pending queries on that JITDylib)
634   /// that all symbols covered by this MaterializationResponsibility instance
635   /// have been emitted.
636   ///
637   /// The DepGroups array describes the dependencies of symbols being emitted on
638   /// symbols that are outside this MaterializationResponsibility object. Each
639   /// group consists of a pair of a set of symbols and a SymbolDependenceMap
640   /// that describes the dependencies for the symbols in the first set. The
641   /// elements of DepGroups must be non-overlapping (no symbol should appear in
642   /// more than one of hte symbol sets), but do not have to be exhaustive. Any
643   /// symbol in this MaterializationResponsibility object that is not covered
644   /// by an entry will be treated as having no dependencies.
645   ///
646   /// This method will return an error if any symbols being resolved have been
647   /// moved to the error state due to the failure of a dependency. If this
648   /// method returns an error then clients should log it and call
649   /// failMaterialize. If no dependencies have been registered for the
650   /// symbols covered by this MaterializationResponsibility then this method
651   /// is guaranteed to return Error::success() and can be wrapped with cantFail.
652   Error notifyEmitted(ArrayRef<SymbolDependenceGroup> DepGroups);
653 
654   /// Attempt to claim responsibility for new definitions. This method can be
655   /// used to claim responsibility for symbols that are added to a
656   /// materialization unit during the compilation process (e.g. literal pool
657   /// symbols). Symbol linkage rules are the same as for symbols that are
658   /// defined up front: duplicate strong definitions will result in errors.
659   /// Duplicate weak definitions will be discarded (in which case they will
660   /// not be added to this responsibility instance).
661   ///
662   ///   This method can be used by materialization units that want to add
663   /// additional symbols at materialization time (e.g. stubs, compile
664   /// callbacks, metadata).
665   Error defineMaterializing(SymbolFlagsMap SymbolFlags);
666 
667   /// Notify all not-yet-emitted covered by this MaterializationResponsibility
668   /// instance that an error has occurred.
669   /// This will remove all symbols covered by this MaterializationResponsibility
670   /// from the target JITDylib, and send an error to any queries waiting on
671   /// these symbols.
672   void failMaterialization();
673 
674   /// Transfers responsibility to the given MaterializationUnit for all
675   /// symbols defined by that MaterializationUnit. This allows
676   /// materializers to break up work based on run-time information (e.g.
677   /// by introspecting which symbols have actually been looked up and
678   /// materializing only those).
679   Error replace(std::unique_ptr<MaterializationUnit> MU);
680 
681   /// Delegates responsibility for the given symbols to the returned
682   /// materialization responsibility. Useful for breaking up work between
683   /// threads, or different kinds of materialization processes.
684   Expected<std::unique_ptr<MaterializationResponsibility>>
685   delegate(const SymbolNameSet &Symbols);
686 
687 private:
688   /// Create a MaterializationResponsibility for the given JITDylib and
689   ///        initial symbols.
690   MaterializationResponsibility(ResourceTrackerSP RT,
691                                 SymbolFlagsMap SymbolFlags,
692                                 SymbolStringPtr InitSymbol)
693       : JD(RT->getJITDylib()), RT(std::move(RT)),
694         SymbolFlags(std::move(SymbolFlags)), InitSymbol(std::move(InitSymbol)) {
695     assert(!this->SymbolFlags.empty() && "Materializing nothing?");
696   }
697 
698   JITDylib &JD;
699   ResourceTrackerSP RT;
700   SymbolFlagsMap SymbolFlags;
701   SymbolStringPtr InitSymbol;
702 };
703 
704 /// A materialization unit for symbol aliases. Allows existing symbols to be
705 /// aliased with alternate flags.
706 class ReExportsMaterializationUnit : public MaterializationUnit {
707 public:
708   /// SourceJD is allowed to be nullptr, in which case the source JITDylib is
709   /// taken to be whatever JITDylib these definitions are materialized in (and
710   /// MatchNonExported has no effect). This is useful for defining aliases
711   /// within a JITDylib.
712   ///
713   /// Note: Care must be taken that no sets of aliases form a cycle, as such
714   ///       a cycle will result in a deadlock when any symbol in the cycle is
715   ///       resolved.
716   ReExportsMaterializationUnit(JITDylib *SourceJD,
717                                JITDylibLookupFlags SourceJDLookupFlags,
718                                SymbolAliasMap Aliases);
719 
720   StringRef getName() const override;
721 
722 private:
723   void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
724   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
725   static MaterializationUnit::Interface
726   extractFlags(const SymbolAliasMap &Aliases);
727 
728   JITDylib *SourceJD = nullptr;
729   JITDylibLookupFlags SourceJDLookupFlags;
730   SymbolAliasMap Aliases;
731 };
732 
733 /// Create a ReExportsMaterializationUnit with the given aliases.
734 /// Useful for defining symbol aliases.: E.g., given a JITDylib JD containing
735 /// symbols "foo" and "bar", we can define aliases "baz" (for "foo") and "qux"
736 /// (for "bar") with: \code{.cpp}
737 ///   SymbolStringPtr Baz = ...;
738 ///   SymbolStringPtr Qux = ...;
739 ///   if (auto Err = JD.define(symbolAliases({
740 ///       {Baz, { Foo, JITSymbolFlags::Exported }},
741 ///       {Qux, { Bar, JITSymbolFlags::Weak }}}))
742 ///     return Err;
743 /// \endcode
744 inline std::unique_ptr<ReExportsMaterializationUnit>
745 symbolAliases(SymbolAliasMap Aliases) {
746   return std::make_unique<ReExportsMaterializationUnit>(
747       nullptr, JITDylibLookupFlags::MatchAllSymbols, std::move(Aliases));
748 }
749 
750 /// Create a materialization unit for re-exporting symbols from another JITDylib
751 /// with alternative names/flags.
752 /// SourceJD will be searched using the given JITDylibLookupFlags.
753 inline std::unique_ptr<ReExportsMaterializationUnit>
754 reexports(JITDylib &SourceJD, SymbolAliasMap Aliases,
755           JITDylibLookupFlags SourceJDLookupFlags =
756               JITDylibLookupFlags::MatchExportedSymbolsOnly) {
757   return std::make_unique<ReExportsMaterializationUnit>(
758       &SourceJD, SourceJDLookupFlags, std::move(Aliases));
759 }
760 
761 /// Build a SymbolAliasMap for the common case where you want to re-export
762 /// symbols from another JITDylib with the same linkage/flags.
763 Expected<SymbolAliasMap>
764 buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols);
765 
766 /// Represents the state that a symbol has reached during materialization.
767 enum class SymbolState : uint8_t {
768   Invalid,       /// No symbol should be in this state.
769   NeverSearched, /// Added to the symbol table, never queried.
770   Materializing, /// Queried, materialization begun.
771   Resolved,      /// Assigned address, still materializing.
772   Emitted,       /// Emitted to memory, but waiting on transitive dependencies.
773   Ready = 0x3f   /// Ready and safe for clients to access.
774 };
775 
776 /// A symbol query that returns results via a callback when results are
777 ///        ready.
778 ///
779 /// makes a callback when all symbols are available.
780 class AsynchronousSymbolQuery {
781   friend class ExecutionSession;
782   friend class InProgressFullLookupState;
783   friend class JITDylib;
784   friend class JITSymbolResolverAdapter;
785   friend class MaterializationResponsibility;
786 
787 public:
788   /// Create a query for the given symbols. The NotifyComplete
789   /// callback will be called once all queried symbols reach the given
790   /// minimum state.
791   AsynchronousSymbolQuery(const SymbolLookupSet &Symbols,
792                           SymbolState RequiredState,
793                           SymbolsResolvedCallback NotifyComplete);
794 
795   /// Notify the query that a requested symbol has reached the required state.
796   void notifySymbolMetRequiredState(const SymbolStringPtr &Name,
797                                     ExecutorSymbolDef Sym);
798 
799   /// Returns true if all symbols covered by this query have been
800   ///        resolved.
801   bool isComplete() const { return OutstandingSymbolsCount == 0; }
802 
803 
804 private:
805   void handleComplete(ExecutionSession &ES);
806 
807   SymbolState getRequiredState() { return RequiredState; }
808 
809   void addQueryDependence(JITDylib &JD, SymbolStringPtr Name);
810 
811   void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
812 
813   void dropSymbol(const SymbolStringPtr &Name);
814 
815   void handleFailed(Error Err);
816 
817   void detach();
818 
819   SymbolsResolvedCallback NotifyComplete;
820   SymbolDependenceMap QueryRegistrations;
821   SymbolMap ResolvedSymbols;
822   size_t OutstandingSymbolsCount;
823   SymbolState RequiredState;
824 };
825 
826 /// Wraps state for a lookup-in-progress.
827 /// DefinitionGenerators can optionally take ownership of a LookupState object
828 /// to suspend a lookup-in-progress while they search for definitions.
829 class LookupState {
830   friend class OrcV2CAPIHelper;
831   friend class ExecutionSession;
832 
833 public:
834   LookupState();
835   LookupState(LookupState &&);
836   LookupState &operator=(LookupState &&);
837   ~LookupState();
838 
839   /// Continue the lookup. This can be called by DefinitionGenerators
840   /// to re-start a captured query-application operation.
841   void continueLookup(Error Err);
842 
843 private:
844   LookupState(std::unique_ptr<InProgressLookupState> IPLS);
845 
846   // For C API.
847   void reset(InProgressLookupState *IPLS);
848 
849   std::unique_ptr<InProgressLookupState> IPLS;
850 };
851 
852 /// Definition generators can be attached to JITDylibs to generate new
853 /// definitions for otherwise unresolved symbols during lookup.
854 class DefinitionGenerator {
855   friend class ExecutionSession;
856 
857 public:
858   virtual ~DefinitionGenerator();
859 
860   /// DefinitionGenerators should override this method to insert new
861   /// definitions into the parent JITDylib. K specifies the kind of this
862   /// lookup. JD specifies the target JITDylib being searched, and
863   /// JDLookupFlags specifies whether the search should match against
864   /// hidden symbols. Finally, Symbols describes the set of unresolved
865   /// symbols and their associated lookup flags.
866   virtual Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
867                               JITDylibLookupFlags JDLookupFlags,
868                               const SymbolLookupSet &LookupSet) = 0;
869 
870 private:
871   std::mutex M;
872   bool InUse = false;
873   std::deque<LookupState> PendingLookups;
874 };
875 
876 /// Represents a JIT'd dynamic library.
877 ///
878 /// This class aims to mimic the behavior of a regular dylib or shared object,
879 /// but without requiring the contained program representations to be compiled
880 /// up-front. The JITDylib's content is defined by adding MaterializationUnits,
881 /// and contained MaterializationUnits will typically rely on the JITDylib's
882 /// links-against order to resolve external references (similar to a regular
883 /// dylib).
884 ///
885 /// The JITDylib object is a thin wrapper that references state held by the
886 /// ExecutionSession. JITDylibs can be removed, clearing this underlying state
887 /// and leaving the JITDylib object in a defunct state. In this state the
888 /// JITDylib's name is guaranteed to remain accessible. If the ExecutionSession
889 /// is still alive then other operations are callable but will return an Error
890 /// or null result (depending on the API). It is illegal to call any operation
891 /// other than getName on a JITDylib after the ExecutionSession has been torn
892 /// down.
893 ///
894 /// JITDylibs cannot be moved or copied. Their address is stable, and useful as
895 /// a key in some JIT data structures.
896 class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,
897                  public jitlink::JITLinkDylib {
898   friend class AsynchronousSymbolQuery;
899   friend class ExecutionSession;
900   friend class Platform;
901   friend class MaterializationResponsibility;
902 public:
903 
904   JITDylib(const JITDylib &) = delete;
905   JITDylib &operator=(const JITDylib &) = delete;
906   JITDylib(JITDylib &&) = delete;
907   JITDylib &operator=(JITDylib &&) = delete;
908   ~JITDylib();
909 
910   /// Get a reference to the ExecutionSession for this JITDylib.
911   ///
912   /// It is legal to call this method on a defunct JITDylib, however the result
913   /// will only usable if the ExecutionSession is still alive. If this JITDylib
914   /// is held by an error that may have torn down the JIT then the result
915   /// should not be used.
916   ExecutionSession &getExecutionSession() const { return ES; }
917 
918   /// Dump current JITDylib state to OS.
919   ///
920   /// It is legal to call this method on a defunct JITDylib.
921   void dump(raw_ostream &OS);
922 
923   /// Calls remove on all trackers currently associated with this JITDylib.
924   /// Does not run static deinits.
925   ///
926   /// Note that removal happens outside the session lock, so new code may be
927   /// added concurrently while the clear is underway, and the newly added
928   /// code will *not* be cleared. Adding new code concurrently with a clear
929   /// is usually a bug and should be avoided.
930   ///
931   /// It is illegal to call this method on a defunct JITDylib and the client
932   /// is responsible for ensuring that they do not do so.
933   Error clear();
934 
935   /// Get the default resource tracker for this JITDylib.
936   ///
937   /// It is illegal to call this method on a defunct JITDylib and the client
938   /// is responsible for ensuring that they do not do so.
939   ResourceTrackerSP getDefaultResourceTracker();
940 
941   /// Create a resource tracker for this JITDylib.
942   ///
943   /// It is illegal to call this method on a defunct JITDylib and the client
944   /// is responsible for ensuring that they do not do so.
945   ResourceTrackerSP createResourceTracker();
946 
947   /// Adds a definition generator to this JITDylib and returns a referenece to
948   /// it.
949   ///
950   /// When JITDylibs are searched during lookup, if no existing definition of
951   /// a symbol is found, then any generators that have been added are run (in
952   /// the order that they were added) to potentially generate a definition.
953   ///
954   /// It is illegal to call this method on a defunct JITDylib and the client
955   /// is responsible for ensuring that they do not do so.
956   template <typename GeneratorT>
957   GeneratorT &addGenerator(std::unique_ptr<GeneratorT> DefGenerator);
958 
959   /// Remove a definition generator from this JITDylib.
960   ///
961   /// The given generator must exist in this JITDylib's generators list (i.e.
962   /// have been added and not yet removed).
963   ///
964   /// It is illegal to call this method on a defunct JITDylib and the client
965   /// is responsible for ensuring that they do not do so.
966   void removeGenerator(DefinitionGenerator &G);
967 
968   /// Set the link order to be used when fixing up definitions in JITDylib.
969   /// This will replace the previous link order, and apply to any symbol
970   /// resolutions made for definitions in this JITDylib after the call to
971   /// setLinkOrder (even if the definition itself was added before the
972   /// call).
973   ///
974   /// If LinkAgainstThisJITDylibFirst is true (the default) then this JITDylib
975   /// will add itself to the beginning of the LinkOrder (Clients should not
976   /// put this JITDylib in the list in this case, to avoid redundant lookups).
977   ///
978   /// If LinkAgainstThisJITDylibFirst is false then the link order will be used
979   /// as-is. The primary motivation for this feature is to support deliberate
980   /// shadowing of symbols in this JITDylib by a facade JITDylib. For example,
981   /// the facade may resolve function names to stubs, and the stubs may compile
982   /// lazily by looking up symbols in this dylib. Adding the facade dylib
983   /// as the first in the link order (instead of this dylib) ensures that
984   /// definitions within this dylib resolve to the lazy-compiling stubs,
985   /// rather than immediately materializing the definitions in this dylib.
986   ///
987   /// It is illegal to call this method on a defunct JITDylib and the client
988   /// is responsible for ensuring that they do not do so.
989   void setLinkOrder(JITDylibSearchOrder NewSearchOrder,
990                     bool LinkAgainstThisJITDylibFirst = true);
991 
992   /// Append the given JITDylibSearchOrder to the link order for this
993   /// JITDylib (discarding any elements already present in this JITDylib's
994   /// link order).
995   void addToLinkOrder(const JITDylibSearchOrder &NewLinks);
996 
997   /// Add the given JITDylib to the link order for definitions in this
998   /// JITDylib.
999   ///
1000   /// It is illegal to call this method on a defunct JITDylib and the client
1001   /// is responsible for ensuring that they do not do so.
1002   void addToLinkOrder(JITDylib &JD,
1003                       JITDylibLookupFlags JDLookupFlags =
1004                           JITDylibLookupFlags::MatchExportedSymbolsOnly);
1005 
1006   /// Replace OldJD with NewJD in the link order if OldJD is present.
1007   /// Otherwise this operation is a no-op.
1008   ///
1009   /// It is illegal to call this method on a defunct JITDylib and the client
1010   /// is responsible for ensuring that they do not do so.
1011   void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
1012                           JITDylibLookupFlags JDLookupFlags =
1013                               JITDylibLookupFlags::MatchExportedSymbolsOnly);
1014 
1015   /// Remove the given JITDylib from the link order for this JITDylib if it is
1016   /// present. Otherwise this operation is a no-op.
1017   ///
1018   /// It is illegal to call this method on a defunct JITDylib and the client
1019   /// is responsible for ensuring that they do not do so.
1020   void removeFromLinkOrder(JITDylib &JD);
1021 
1022   /// Do something with the link order (run under the session lock).
1023   ///
1024   /// It is illegal to call this method on a defunct JITDylib and the client
1025   /// is responsible for ensuring that they do not do so.
1026   template <typename Func>
1027   auto withLinkOrderDo(Func &&F)
1028       -> decltype(F(std::declval<const JITDylibSearchOrder &>()));
1029 
1030   /// Define all symbols provided by the materialization unit to be part of this
1031   /// JITDylib.
1032   ///
1033   /// If RT is not specified then the default resource tracker will be used.
1034   ///
1035   /// This overload always takes ownership of the MaterializationUnit. If any
1036   /// errors occur, the MaterializationUnit consumed.
1037   ///
1038   /// It is illegal to call this method on a defunct JITDylib and the client
1039   /// is responsible for ensuring that they do not do so.
1040   template <typename MaterializationUnitType>
1041   Error define(std::unique_ptr<MaterializationUnitType> &&MU,
1042                ResourceTrackerSP RT = nullptr);
1043 
1044   /// Define all symbols provided by the materialization unit to be part of this
1045   /// JITDylib.
1046   ///
1047   /// This overload only takes ownership of the MaterializationUnit no error is
1048   /// generated. If an error occurs, ownership remains with the caller. This
1049   /// may allow the caller to modify the MaterializationUnit to correct the
1050   /// issue, then re-call define.
1051   ///
1052   /// It is illegal to call this method on a defunct JITDylib and the client
1053   /// is responsible for ensuring that they do not do so.
1054   template <typename MaterializationUnitType>
1055   Error define(std::unique_ptr<MaterializationUnitType> &MU,
1056                ResourceTrackerSP RT = nullptr);
1057 
1058   /// Tries to remove the given symbols.
1059   ///
1060   /// If any symbols are not defined in this JITDylib this method will return
1061   /// a SymbolsNotFound error covering the missing symbols.
1062   ///
1063   /// If all symbols are found but some symbols are in the process of being
1064   /// materialized this method will return a SymbolsCouldNotBeRemoved error.
1065   ///
1066   /// On success, all symbols are removed. On failure, the JITDylib state is
1067   /// left unmodified (no symbols are removed).
1068   ///
1069   /// It is illegal to call this method on a defunct JITDylib and the client
1070   /// is responsible for ensuring that they do not do so.
1071   Error remove(const SymbolNameSet &Names);
1072 
1073   /// Returns the given JITDylibs and all of their transitive dependencies in
1074   /// DFS order (based on linkage relationships). Each JITDylib will appear
1075   /// only once.
1076   ///
1077   /// If any JITDylib in the order is defunct then this method will return an
1078   /// error, otherwise returns the order.
1079   static Expected<std::vector<JITDylibSP>>
1080   getDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
1081 
1082   /// Returns the given JITDylibs and all of their transitive dependencies in
1083   /// reverse DFS order (based on linkage relationships). Each JITDylib will
1084   /// appear only once.
1085   ///
1086   /// If any JITDylib in the order is defunct then this method will return an
1087   /// error, otherwise returns the order.
1088   static Expected<std::vector<JITDylibSP>>
1089   getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs);
1090 
1091   /// Return this JITDylib and its transitive dependencies in DFS order
1092   /// based on linkage relationships.
1093   ///
1094   /// If any JITDylib in the order is defunct then this method will return an
1095   /// error, otherwise returns the order.
1096   Expected<std::vector<JITDylibSP>> getDFSLinkOrder();
1097 
1098   /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order
1099   /// based on linkage relationships.
1100   ///
1101   /// If any JITDylib in the order is defunct then this method will return an
1102   /// error, otherwise returns the order.
1103   Expected<std::vector<JITDylibSP>> getReverseDFSLinkOrder();
1104 
1105 private:
1106   using AsynchronousSymbolQuerySet =
1107     std::set<std::shared_ptr<AsynchronousSymbolQuery>>;
1108 
1109   using AsynchronousSymbolQueryList =
1110       std::vector<std::shared_ptr<AsynchronousSymbolQuery>>;
1111 
1112   struct UnmaterializedInfo {
1113     UnmaterializedInfo(std::unique_ptr<MaterializationUnit> MU,
1114                        ResourceTracker *RT)
1115         : MU(std::move(MU)), RT(RT) {}
1116 
1117     std::unique_ptr<MaterializationUnit> MU;
1118     ResourceTracker *RT;
1119   };
1120 
1121   using UnmaterializedInfosMap =
1122       DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
1123 
1124   using UnmaterializedInfosList =
1125       std::vector<std::shared_ptr<UnmaterializedInfo>>;
1126 
1127   struct EmissionDepUnit {
1128     EmissionDepUnit(JITDylib &JD) : JD(&JD) {}
1129 
1130     JITDylib *JD = nullptr;
1131     DenseMap<NonOwningSymbolStringPtr, JITSymbolFlags> Symbols;
1132     DenseMap<JITDylib *, DenseSet<NonOwningSymbolStringPtr>> Dependencies;
1133   };
1134 
1135   struct EmissionDepUnitInfo {
1136     std::shared_ptr<EmissionDepUnit> EDU;
1137     DenseSet<EmissionDepUnit *> IntraEmitUsers;
1138     DenseMap<JITDylib *, DenseSet<NonOwningSymbolStringPtr>> NewDeps;
1139   };
1140 
1141   // Information about not-yet-ready symbol.
1142   // * DefiningEDU will point to the EmissionDepUnit that defines the symbol.
1143   // * DependantEDUs will hold pointers to any EmissionDepUnits currently
1144   //   waiting on this symbol.
1145   // * Pending queries holds any not-yet-completed queries that include this
1146   //   symbol.
1147   struct MaterializingInfo {
1148     friend class ExecutionSession;
1149 
1150     std::shared_ptr<EmissionDepUnit> DefiningEDU;
1151     DenseSet<EmissionDepUnit *> DependantEDUs;
1152 
1153     void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
1154     void removeQuery(const AsynchronousSymbolQuery &Q);
1155     AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState);
1156     AsynchronousSymbolQueryList takeAllPendingQueries() {
1157       return std::move(PendingQueries);
1158     }
1159     bool hasQueriesPending() const { return !PendingQueries.empty(); }
1160     const AsynchronousSymbolQueryList &pendingQueries() const {
1161       return PendingQueries;
1162     }
1163   private:
1164     AsynchronousSymbolQueryList PendingQueries;
1165   };
1166 
1167   using MaterializingInfosMap = DenseMap<SymbolStringPtr, MaterializingInfo>;
1168 
1169   class SymbolTableEntry {
1170   public:
1171     SymbolTableEntry() = default;
1172     SymbolTableEntry(JITSymbolFlags Flags)
1173         : Flags(Flags), State(static_cast<uint8_t>(SymbolState::NeverSearched)),
1174           MaterializerAttached(false) {}
1175 
1176     ExecutorAddr getAddress() const { return Addr; }
1177     JITSymbolFlags getFlags() const { return Flags; }
1178     SymbolState getState() const { return static_cast<SymbolState>(State); }
1179 
1180     bool hasMaterializerAttached() const { return MaterializerAttached; }
1181 
1182     void setAddress(ExecutorAddr Addr) { this->Addr = Addr; }
1183     void setFlags(JITSymbolFlags Flags) { this->Flags = Flags; }
1184     void setState(SymbolState State) {
1185       assert(static_cast<uint8_t>(State) < (1 << 6) &&
1186              "State does not fit in bitfield");
1187       this->State = static_cast<uint8_t>(State);
1188     }
1189 
1190     void setMaterializerAttached(bool MaterializerAttached) {
1191       this->MaterializerAttached = MaterializerAttached;
1192     }
1193 
1194     ExecutorSymbolDef getSymbol() const { return {Addr, Flags}; }
1195 
1196   private:
1197     ExecutorAddr Addr;
1198     JITSymbolFlags Flags;
1199     uint8_t State : 7;
1200     uint8_t MaterializerAttached : 1;
1201   };
1202 
1203   using SymbolTable = DenseMap<SymbolStringPtr, SymbolTableEntry>;
1204 
1205   JITDylib(ExecutionSession &ES, std::string Name);
1206 
1207   std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
1208   IL_removeTracker(ResourceTracker &RT);
1209 
1210   void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
1211 
1212   Error defineImpl(MaterializationUnit &MU);
1213 
1214   void installMaterializationUnit(std::unique_ptr<MaterializationUnit> MU,
1215                                   ResourceTracker &RT);
1216 
1217   void detachQueryHelper(AsynchronousSymbolQuery &Q,
1218                          const SymbolNameSet &QuerySymbols);
1219 
1220   void transferEmittedNodeDependencies(MaterializingInfo &DependantMI,
1221                                        const SymbolStringPtr &DependantName,
1222                                        MaterializingInfo &EmittedMI);
1223 
1224   Expected<SymbolFlagsMap>
1225   defineMaterializing(MaterializationResponsibility &FromMR,
1226                       SymbolFlagsMap SymbolFlags);
1227 
1228   Error replace(MaterializationResponsibility &FromMR,
1229                 std::unique_ptr<MaterializationUnit> MU);
1230 
1231   Expected<std::unique_ptr<MaterializationResponsibility>>
1232   delegate(MaterializationResponsibility &FromMR, SymbolFlagsMap SymbolFlags,
1233            SymbolStringPtr InitSymbol);
1234 
1235   SymbolNameSet getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const;
1236 
1237   void addDependencies(const SymbolStringPtr &Name,
1238                        const SymbolDependenceMap &Dependants);
1239 
1240   Error resolve(MaterializationResponsibility &MR, const SymbolMap &Resolved);
1241 
1242   void unlinkMaterializationResponsibility(MaterializationResponsibility &MR);
1243 
1244   /// Attempt to reduce memory usage from empty \c UnmaterializedInfos and
1245   /// \c MaterializingInfos tables.
1246   void shrinkMaterializationInfoMemory();
1247 
1248   ExecutionSession &ES;
1249   enum { Open, Closing, Closed } State = Open;
1250   std::mutex GeneratorsMutex;
1251   SymbolTable Symbols;
1252   UnmaterializedInfosMap UnmaterializedInfos;
1253   MaterializingInfosMap MaterializingInfos;
1254   std::vector<std::shared_ptr<DefinitionGenerator>> DefGenerators;
1255   JITDylibSearchOrder LinkOrder;
1256   ResourceTrackerSP DefaultTracker;
1257 
1258   // Map trackers to sets of symbols tracked.
1259   DenseMap<ResourceTracker *, SymbolNameVector> TrackerSymbols;
1260   DenseMap<ResourceTracker *, DenseSet<MaterializationResponsibility *>>
1261       TrackerMRs;
1262 };
1263 
1264 /// Platforms set up standard symbols and mediate interactions between dynamic
1265 /// initializers (e.g. C++ static constructors) and ExecutionSession state.
1266 /// Note that Platforms do not automatically run initializers: clients are still
1267 /// responsible for doing this.
1268 class Platform {
1269 public:
1270   virtual ~Platform();
1271 
1272   /// This method will be called outside the session lock each time a JITDylib
1273   /// is created (unless it is created with EmptyJITDylib set) to allow the
1274   /// Platform to install any JITDylib specific standard symbols (e.g
1275   /// __dso_handle).
1276   virtual Error setupJITDylib(JITDylib &JD) = 0;
1277 
1278   /// This method will be called outside the session lock each time a JITDylib
1279   /// is removed to allow the Platform to remove any JITDylib-specific data.
1280   virtual Error teardownJITDylib(JITDylib &JD) = 0;
1281 
1282   /// This method will be called under the ExecutionSession lock each time a
1283   /// MaterializationUnit is added to a JITDylib.
1284   virtual Error notifyAdding(ResourceTracker &RT,
1285                              const MaterializationUnit &MU) = 0;
1286 
1287   /// This method will be called under the ExecutionSession lock when a
1288   /// ResourceTracker is removed.
1289   virtual Error notifyRemoving(ResourceTracker &RT) = 0;
1290 
1291   /// A utility function for looking up initializer symbols. Performs a blocking
1292   /// lookup for the given symbols in each of the given JITDylibs.
1293   ///
1294   /// Note: This function is deprecated and will be removed in the near future.
1295   static Expected<DenseMap<JITDylib *, SymbolMap>>
1296   lookupInitSymbols(ExecutionSession &ES,
1297                     const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms);
1298 
1299   /// Performs an async lookup for the given symbols in each of the given
1300   /// JITDylibs, calling the given handler once all lookups have completed.
1301   static void
1302   lookupInitSymbolsAsync(unique_function<void(Error)> OnComplete,
1303                          ExecutionSession &ES,
1304                          const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms);
1305 };
1306 
1307 /// A materialization task.
1308 class MaterializationTask : public RTTIExtends<MaterializationTask, Task> {
1309 public:
1310   static char ID;
1311 
1312   MaterializationTask(std::unique_ptr<MaterializationUnit> MU,
1313                       std::unique_ptr<MaterializationResponsibility> MR)
1314       : MU(std::move(MU)), MR(std::move(MR)) {}
1315   ~MaterializationTask() override;
1316   void printDescription(raw_ostream &OS) override;
1317   void run() override;
1318 
1319 private:
1320   std::unique_ptr<MaterializationUnit> MU;
1321   std::unique_ptr<MaterializationResponsibility> MR;
1322 };
1323 
1324 /// Lookups are usually run on the current thread, but in some cases they may
1325 /// be run as tasks, e.g. if the lookup has been continued from a suspended
1326 /// state.
1327 class LookupTask : public RTTIExtends<LookupTask, Task> {
1328 public:
1329   static char ID;
1330 
1331   LookupTask(LookupState LS) : LS(std::move(LS)) {}
1332   void printDescription(raw_ostream &OS) override;
1333   void run() override;
1334 
1335 private:
1336   LookupState LS;
1337 };
1338 
1339 /// An ExecutionSession represents a running JIT program.
1340 class ExecutionSession {
1341   friend class InProgressLookupFlagsState;
1342   friend class InProgressFullLookupState;
1343   friend class JITDylib;
1344   friend class LookupState;
1345   friend class MaterializationResponsibility;
1346   friend class ResourceTracker;
1347 
1348 public:
1349   /// For reporting errors.
1350   using ErrorReporter = unique_function<void(Error)>;
1351 
1352   /// Send a result to the remote.
1353   using SendResultFunction = unique_function<void(shared::WrapperFunctionResult)>;
1354 
1355   /// An asynchronous wrapper-function callable from the executor via
1356   /// jit-dispatch.
1357   using JITDispatchHandlerFunction = unique_function<void(
1358       SendResultFunction SendResult,
1359       const char *ArgData, size_t ArgSize)>;
1360 
1361   /// A map associating tag names with asynchronous wrapper function
1362   /// implementations in the JIT.
1363   using JITDispatchHandlerAssociationMap =
1364       DenseMap<SymbolStringPtr, JITDispatchHandlerFunction>;
1365 
1366   /// Construct an ExecutionSession with the given ExecutorProcessControl
1367   /// object.
1368   ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC);
1369 
1370   /// Destroy an ExecutionSession. Verifies that endSession was called prior to
1371   /// destruction.
1372   ~ExecutionSession();
1373 
1374   /// End the session. Closes all JITDylibs and disconnects from the
1375   /// executor. Clients must call this method before destroying the session.
1376   Error endSession();
1377 
1378   /// Get the ExecutorProcessControl object associated with this
1379   /// ExecutionSession.
1380   ExecutorProcessControl &getExecutorProcessControl() { return *EPC; }
1381 
1382   /// Return the triple for the executor.
1383   const Triple &getTargetTriple() const { return EPC->getTargetTriple(); }
1384 
1385   // Return the page size for the executor.
1386   size_t getPageSize() const { return EPC->getPageSize(); }
1387 
1388   /// Get the SymbolStringPool for this instance.
1389   std::shared_ptr<SymbolStringPool> getSymbolStringPool() {
1390     return EPC->getSymbolStringPool();
1391   }
1392 
1393   /// Add a symbol name to the SymbolStringPool and return a pointer to it.
1394   SymbolStringPtr intern(StringRef SymName) { return EPC->intern(SymName); }
1395 
1396   /// Set the Platform for this ExecutionSession.
1397   void setPlatform(std::unique_ptr<Platform> P) { this->P = std::move(P); }
1398 
1399   /// Get the Platform for this session.
1400   /// Will return null if no Platform has been set for this ExecutionSession.
1401   Platform *getPlatform() { return P.get(); }
1402 
1403   /// Run the given lambda with the session mutex locked.
1404   template <typename Func> decltype(auto) runSessionLocked(Func &&F) {
1405     std::lock_guard<std::recursive_mutex> Lock(SessionMutex);
1406     return F();
1407   }
1408 
1409   /// Register the given ResourceManager with this ExecutionSession.
1410   /// Managers will be notified of events in reverse order of registration.
1411   void registerResourceManager(ResourceManager &RM);
1412 
1413   /// Deregister the given ResourceManager with this ExecutionSession.
1414   /// Manager must have been previously registered.
1415   void deregisterResourceManager(ResourceManager &RM);
1416 
1417   /// Return a pointer to the "name" JITDylib.
1418   /// Ownership of JITDylib remains within Execution Session
1419   JITDylib *getJITDylibByName(StringRef Name);
1420 
1421   /// Add a new bare JITDylib to this ExecutionSession.
1422   ///
1423   /// The JITDylib Name is required to be unique. Clients should verify that
1424   /// names are not being re-used (E.g. by calling getJITDylibByName) if names
1425   /// are based on user input.
1426   ///
1427   /// This call does not install any library code or symbols into the newly
1428   /// created JITDylib. The client is responsible for all configuration.
1429   JITDylib &createBareJITDylib(std::string Name);
1430 
1431   /// Add a new JITDylib to this ExecutionSession.
1432   ///
1433   /// The JITDylib Name is required to be unique. Clients should verify that
1434   /// names are not being re-used (e.g. by calling getJITDylibByName) if names
1435   /// are based on user input.
1436   ///
1437   /// If a Platform is attached then Platform::setupJITDylib will be called to
1438   /// install standard platform symbols (e.g. standard library interposes).
1439   /// If no Platform is attached this call is equivalent to createBareJITDylib.
1440   Expected<JITDylib &> createJITDylib(std::string Name);
1441 
1442   /// Removes the given JITDylibs from the ExecutionSession.
1443   ///
1444   /// This method clears all resources held for the JITDylibs, puts them in the
1445   /// closed state, and clears all references to them that are held by the
1446   /// ExecutionSession or other JITDylibs. No further code can be added to the
1447   /// removed JITDylibs, and the JITDylib objects will be freed once any
1448   /// remaining JITDylibSPs pointing to them are destroyed.
1449   ///
1450   /// This method does *not* run static destructors for code contained in the
1451   /// JITDylibs, and each JITDylib can only be removed once.
1452   ///
1453   /// JITDylibs will be removed in the order given. Teardown is usually
1454   /// independent for each JITDylib, but not always. In particular, where the
1455   /// ORC runtime is used it is expected that teardown off all JITDylibs will
1456   /// depend on it, so the JITDylib containing the ORC runtime must be removed
1457   /// last. If the client has introduced any other dependencies they should be
1458   /// accounted for in the removal order too.
1459   Error removeJITDylibs(std::vector<JITDylibSP> JDsToRemove);
1460 
1461   /// Calls removeJTIDylibs on the gives JITDylib.
1462   Error removeJITDylib(JITDylib &JD) {
1463     return removeJITDylibs(std::vector<JITDylibSP>({&JD}));
1464   }
1465 
1466   /// Set the error reporter function.
1467   ExecutionSession &setErrorReporter(ErrorReporter ReportError) {
1468     this->ReportError = std::move(ReportError);
1469     return *this;
1470   }
1471 
1472   /// Report a error for this execution session.
1473   ///
1474   /// Unhandled errors can be sent here to log them.
1475   void reportError(Error Err) { ReportError(std::move(Err)); }
1476 
1477   /// Search the given JITDylibs to find the flags associated with each of the
1478   /// given symbols.
1479   void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
1480                    SymbolLookupSet Symbols,
1481                    unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
1482 
1483   /// Blocking version of lookupFlags.
1484   Expected<SymbolFlagsMap> lookupFlags(LookupKind K,
1485                                        JITDylibSearchOrder SearchOrder,
1486                                        SymbolLookupSet Symbols);
1487 
1488   /// Search the given JITDylibs for the given symbols.
1489   ///
1490   /// SearchOrder lists the JITDylibs to search. For each dylib, the associated
1491   /// boolean indicates whether the search should match against non-exported
1492   /// (hidden visibility) symbols in that dylib (true means match against
1493   /// non-exported symbols, false means do not match).
1494   ///
1495   /// The NotifyComplete callback will be called once all requested symbols
1496   /// reach the required state.
1497   ///
1498   /// If all symbols are found, the RegisterDependencies function will be called
1499   /// while the session lock is held. This gives clients a chance to register
1500   /// dependencies for on the queried symbols for any symbols they are
1501   /// materializing (if a MaterializationResponsibility instance is present,
1502   /// this can be implemented by calling
1503   /// MaterializationResponsibility::addDependencies). If there are no
1504   /// dependenant symbols for this query (e.g. it is being made by a top level
1505   /// client to get an address to call) then the value NoDependenciesToRegister
1506   /// can be used.
1507   void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder,
1508               SymbolLookupSet Symbols, SymbolState RequiredState,
1509               SymbolsResolvedCallback NotifyComplete,
1510               RegisterDependenciesFunction RegisterDependencies);
1511 
1512   /// Blocking version of lookup above. Returns the resolved symbol map.
1513   /// If WaitUntilReady is true (the default), will not return until all
1514   /// requested symbols are ready (or an error occurs). If WaitUntilReady is
1515   /// false, will return as soon as all requested symbols are resolved,
1516   /// or an error occurs. If WaitUntilReady is false and an error occurs
1517   /// after resolution, the function will return a success value, but the
1518   /// error will be reported via reportErrors.
1519   Expected<SymbolMap> lookup(const JITDylibSearchOrder &SearchOrder,
1520                              SymbolLookupSet Symbols,
1521                              LookupKind K = LookupKind::Static,
1522                              SymbolState RequiredState = SymbolState::Ready,
1523                              RegisterDependenciesFunction RegisterDependencies =
1524                                  NoDependenciesToRegister);
1525 
1526   /// Convenience version of blocking lookup.
1527   /// Searches each of the JITDylibs in the search order in turn for the given
1528   /// symbol.
1529   Expected<ExecutorSymbolDef>
1530   lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Symbol,
1531          SymbolState RequiredState = SymbolState::Ready);
1532 
1533   /// Convenience version of blocking lookup.
1534   /// Searches each of the JITDylibs in the search order in turn for the given
1535   /// symbol. The search will not find non-exported symbols.
1536   Expected<ExecutorSymbolDef>
1537   lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Symbol,
1538          SymbolState RequiredState = SymbolState::Ready);
1539 
1540   /// Convenience version of blocking lookup.
1541   /// Searches each of the JITDylibs in the search order in turn for the given
1542   /// symbol. The search will not find non-exported symbols.
1543   Expected<ExecutorSymbolDef>
1544   lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Symbol,
1545          SymbolState RequiredState = SymbolState::Ready);
1546 
1547   /// Materialize the given unit.
1548   void dispatchTask(std::unique_ptr<Task> T) {
1549     assert(T && "T must be non-null");
1550     DEBUG_WITH_TYPE("orc", dumpDispatchInfo(*T));
1551     EPC->getDispatcher().dispatch(std::move(T));
1552   }
1553 
1554   /// Run a wrapper function in the executor.
1555   ///
1556   /// The wrapper function should be callable as:
1557   ///
1558   /// \code{.cpp}
1559   ///   CWrapperFunctionResult fn(uint8_t *Data, uint64_t Size);
1560   /// \endcode{.cpp}
1561   ///
1562   /// The given OnComplete function will be called to return the result.
1563   template <typename... ArgTs>
1564   void callWrapperAsync(ArgTs &&... Args) {
1565     EPC->callWrapperAsync(std::forward<ArgTs>(Args)...);
1566   }
1567 
1568   /// Run a wrapper function in the executor. The wrapper function should be
1569   /// callable as:
1570   ///
1571   /// \code{.cpp}
1572   ///   CWrapperFunctionResult fn(uint8_t *Data, uint64_t Size);
1573   /// \endcode{.cpp}
1574   shared::WrapperFunctionResult callWrapper(ExecutorAddr WrapperFnAddr,
1575                                             ArrayRef<char> ArgBuffer) {
1576     return EPC->callWrapper(WrapperFnAddr, ArgBuffer);
1577   }
1578 
1579   /// Run a wrapper function using SPS to serialize the arguments and
1580   /// deserialize the results.
1581   template <typename SPSSignature, typename SendResultT, typename... ArgTs>
1582   void callSPSWrapperAsync(ExecutorAddr WrapperFnAddr, SendResultT &&SendResult,
1583                            const ArgTs &...Args) {
1584     EPC->callSPSWrapperAsync<SPSSignature, SendResultT, ArgTs...>(
1585         WrapperFnAddr, std::forward<SendResultT>(SendResult), Args...);
1586   }
1587 
1588   /// Run a wrapper function using SPS to serialize the arguments and
1589   /// deserialize the results.
1590   ///
1591   /// If SPSSignature is a non-void function signature then the second argument
1592   /// (the first in the Args list) should be a reference to a return value.
1593   template <typename SPSSignature, typename... WrapperCallArgTs>
1594   Error callSPSWrapper(ExecutorAddr WrapperFnAddr,
1595                        WrapperCallArgTs &&...WrapperCallArgs) {
1596     return EPC->callSPSWrapper<SPSSignature, WrapperCallArgTs...>(
1597         WrapperFnAddr, std::forward<WrapperCallArgTs>(WrapperCallArgs)...);
1598   }
1599 
1600   /// Wrap a handler that takes concrete argument types (and a sender for a
1601   /// concrete return type) to produce an AsyncHandlerWrapperFunction. Uses SPS
1602   /// to unpack the arguments and pack the result.
1603   ///
1604   /// This function is intended to support easy construction of
1605   /// AsyncHandlerWrapperFunctions that can be associated with a tag
1606   /// (using registerJITDispatchHandler) and called from the executor.
1607   template <typename SPSSignature, typename HandlerT>
1608   static JITDispatchHandlerFunction wrapAsyncWithSPS(HandlerT &&H) {
1609     return [H = std::forward<HandlerT>(H)](
1610                SendResultFunction SendResult,
1611                const char *ArgData, size_t ArgSize) mutable {
1612       shared::WrapperFunction<SPSSignature>::handleAsync(ArgData, ArgSize, H,
1613                                                          std::move(SendResult));
1614     };
1615   }
1616 
1617   /// Wrap a class method that takes concrete argument types (and a sender for
1618   /// a concrete return type) to produce an AsyncHandlerWrapperFunction. Uses
1619   /// SPS to unpack the arguments and pack the result.
1620   ///
1621   /// This function is intended to support easy construction of
1622   /// AsyncHandlerWrapperFunctions that can be associated with a tag
1623   /// (using registerJITDispatchHandler) and called from the executor.
1624   template <typename SPSSignature, typename ClassT, typename... MethodArgTs>
1625   static JITDispatchHandlerFunction
1626   wrapAsyncWithSPS(ClassT *Instance, void (ClassT::*Method)(MethodArgTs...)) {
1627     return wrapAsyncWithSPS<SPSSignature>(
1628         [Instance, Method](MethodArgTs &&...MethodArgs) {
1629           (Instance->*Method)(std::forward<MethodArgTs>(MethodArgs)...);
1630         });
1631   }
1632 
1633   /// For each tag symbol name, associate the corresponding
1634   /// AsyncHandlerWrapperFunction with the address of that symbol. The
1635   /// handler becomes callable from the executor using the ORC runtime
1636   /// __orc_rt_jit_dispatch function and the given tag.
1637   ///
1638   /// Tag symbols will be looked up in JD using LookupKind::Static,
1639   /// JITDylibLookupFlags::MatchAllSymbols (hidden tags will be found), and
1640   /// LookupFlags::WeaklyReferencedSymbol. Missing tag definitions will not
1641   /// cause an error, the handler will simply be dropped.
1642   Error registerJITDispatchHandlers(JITDylib &JD,
1643                                     JITDispatchHandlerAssociationMap WFs);
1644 
1645   /// Run a registered jit-side wrapper function.
1646   /// This should be called by the ExecutorProcessControl instance in response
1647   /// to incoming jit-dispatch requests from the executor.
1648   void runJITDispatchHandler(SendResultFunction SendResult,
1649                              ExecutorAddr HandlerFnTagAddr,
1650                              ArrayRef<char> ArgBuffer);
1651 
1652   /// Dump the state of all the JITDylibs in this session.
1653   void dump(raw_ostream &OS);
1654 
1655   /// Check the internal consistency of ExecutionSession data structures.
1656 #ifdef EXPENSIVE_CHECKS
1657   bool verifySessionState(Twine Phase);
1658 #endif
1659 
1660 private:
1661   static void logErrorsToStdErr(Error Err) {
1662     logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
1663   }
1664 
1665   void dispatchOutstandingMUs();
1666 
1667   static std::unique_ptr<MaterializationResponsibility>
1668   createMaterializationResponsibility(ResourceTracker &RT,
1669                                       SymbolFlagsMap Symbols,
1670                                       SymbolStringPtr InitSymbol) {
1671     auto &JD = RT.getJITDylib();
1672     std::unique_ptr<MaterializationResponsibility> MR(
1673         new MaterializationResponsibility(&RT, std::move(Symbols),
1674                                           std::move(InitSymbol)));
1675     JD.TrackerMRs[&RT].insert(MR.get());
1676     return MR;
1677   }
1678 
1679   Error removeResourceTracker(ResourceTracker &RT);
1680   void transferResourceTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);
1681   void destroyResourceTracker(ResourceTracker &RT);
1682 
1683   // State machine functions for query application..
1684 
1685   /// IL_updateCandidatesFor is called to remove already-defined symbols that
1686   /// match a given query from the set of candidate symbols to generate
1687   /// definitions for (no need to generate a definition if one already exists).
1688   Error IL_updateCandidatesFor(JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
1689                                SymbolLookupSet &Candidates,
1690                                SymbolLookupSet *NonCandidates);
1691 
1692   /// Handle resumption of a lookup after entering a generator.
1693   void OL_resumeLookupAfterGeneration(InProgressLookupState &IPLS);
1694 
1695   /// OL_applyQueryPhase1 is an optionally re-startable loop for triggering
1696   /// definition generation. It is called when a lookup is performed, and again
1697   /// each time that LookupState::continueLookup is called.
1698   void OL_applyQueryPhase1(std::unique_ptr<InProgressLookupState> IPLS,
1699                            Error Err);
1700 
1701   /// OL_completeLookup is run once phase 1 successfully completes for a lookup
1702   /// call. It attempts to attach the symbol to all symbol table entries and
1703   /// collect all MaterializationUnits to dispatch. If this method fails then
1704   /// all MaterializationUnits will be left un-materialized.
1705   void OL_completeLookup(std::unique_ptr<InProgressLookupState> IPLS,
1706                          std::shared_ptr<AsynchronousSymbolQuery> Q,
1707                          RegisterDependenciesFunction RegisterDependencies);
1708 
1709   /// OL_completeLookupFlags is run once phase 1 successfully completes for a
1710   /// lookupFlags call.
1711   void OL_completeLookupFlags(
1712       std::unique_ptr<InProgressLookupState> IPLS,
1713       unique_function<void(Expected<SymbolFlagsMap>)> OnComplete);
1714 
1715   // State machine functions for MaterializationResponsibility.
1716   void OL_destroyMaterializationResponsibility(
1717       MaterializationResponsibility &MR);
1718   SymbolNameSet OL_getRequestedSymbols(const MaterializationResponsibility &MR);
1719   Error OL_notifyResolved(MaterializationResponsibility &MR,
1720                           const SymbolMap &Symbols);
1721 
1722   using EDUInfosMap =
1723       DenseMap<JITDylib::EmissionDepUnit *, JITDylib::EmissionDepUnitInfo>;
1724 
1725   template <typename HandleNewDepFn>
1726   void propagateExtraEmitDeps(std::deque<JITDylib::EmissionDepUnit *> Worklist,
1727                               EDUInfosMap &EDUInfos,
1728                               HandleNewDepFn HandleNewDep);
1729   EDUInfosMap simplifyDepGroups(MaterializationResponsibility &MR,
1730                                 ArrayRef<SymbolDependenceGroup> EmittedDeps);
1731   void IL_makeEDUReady(std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
1732                        JITDylib::AsynchronousSymbolQuerySet &Queries);
1733   void IL_makeEDUEmitted(std::shared_ptr<JITDylib::EmissionDepUnit> EDU,
1734                          JITDylib::AsynchronousSymbolQuerySet &Queries);
1735   bool IL_removeEDUDependence(JITDylib::EmissionDepUnit &EDU, JITDylib &DepJD,
1736                               NonOwningSymbolStringPtr DepSym,
1737                               EDUInfosMap &EDUInfos);
1738 
1739   static Error makeJDClosedError(JITDylib::EmissionDepUnit &EDU,
1740                                  JITDylib &ClosedJD);
1741   static Error makeUnsatisfiedDepsError(JITDylib::EmissionDepUnit &EDU,
1742                                         JITDylib &BadJD, SymbolNameSet BadDeps);
1743 
1744   Expected<JITDylib::AsynchronousSymbolQuerySet>
1745   IL_emit(MaterializationResponsibility &MR, EDUInfosMap EDUInfos);
1746   Error OL_notifyEmitted(MaterializationResponsibility &MR,
1747                          ArrayRef<SymbolDependenceGroup> EmittedDeps);
1748 
1749   Error OL_defineMaterializing(MaterializationResponsibility &MR,
1750                                SymbolFlagsMap SymbolFlags);
1751 
1752   std::pair<JITDylib::AsynchronousSymbolQuerySet,
1753             std::shared_ptr<SymbolDependenceMap>>
1754   IL_failSymbols(JITDylib &JD, const SymbolNameVector &SymbolsToFail);
1755   void OL_notifyFailed(MaterializationResponsibility &MR);
1756   Error OL_replace(MaterializationResponsibility &MR,
1757                    std::unique_ptr<MaterializationUnit> MU);
1758   Expected<std::unique_ptr<MaterializationResponsibility>>
1759   OL_delegate(MaterializationResponsibility &MR, const SymbolNameSet &Symbols);
1760 
1761 #ifndef NDEBUG
1762   void dumpDispatchInfo(Task &T);
1763 #endif // NDEBUG
1764 
1765   mutable std::recursive_mutex SessionMutex;
1766   bool SessionOpen = true;
1767   std::unique_ptr<ExecutorProcessControl> EPC;
1768   std::unique_ptr<Platform> P;
1769   ErrorReporter ReportError = logErrorsToStdErr;
1770 
1771   std::vector<ResourceManager *> ResourceManagers;
1772 
1773   std::vector<JITDylibSP> JDs;
1774 
1775   // FIXME: Remove this (and runOutstandingMUs) once the linking layer works
1776   //        with callbacks from asynchronous queries.
1777   mutable std::recursive_mutex OutstandingMUsMutex;
1778   std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
1779                         std::unique_ptr<MaterializationResponsibility>>>
1780       OutstandingMUs;
1781 
1782   mutable std::mutex JITDispatchHandlersMutex;
1783   DenseMap<ExecutorAddr, std::shared_ptr<JITDispatchHandlerFunction>>
1784       JITDispatchHandlers;
1785 };
1786 
1787 inline Expected<ExecutorSymbolDef> SymbolInstance::lookup() const {
1788   return JD->getExecutionSession().lookup({JD.get()}, Name);
1789 }
1790 
1791 template <typename Func> Error ResourceTracker::withResourceKeyDo(Func &&F) {
1792   return getJITDylib().getExecutionSession().runSessionLocked([&]() -> Error {
1793     if (isDefunct())
1794       return make_error<ResourceTrackerDefunct>(this);
1795     F(getKeyUnsafe());
1796     return Error::success();
1797   });
1798 }
1799 
1800 inline ExecutionSession &
1801 MaterializationResponsibility::getExecutionSession() const {
1802   return JD.getExecutionSession();
1803 }
1804 
1805 template <typename GeneratorT>
1806 GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
1807   auto &G = *DefGenerator;
1808   ES.runSessionLocked([&] {
1809     assert(State == Open && "Cannot add generator to closed JITDylib");
1810     DefGenerators.push_back(std::move(DefGenerator));
1811   });
1812   return G;
1813 }
1814 
1815 template <typename Func>
1816 auto JITDylib::withLinkOrderDo(Func &&F)
1817     -> decltype(F(std::declval<const JITDylibSearchOrder &>())) {
1818   assert(State == Open && "Cannot use link order of closed JITDylib");
1819   return ES.runSessionLocked([&]() { return F(LinkOrder); });
1820 }
1821 
1822 template <typename MaterializationUnitType>
1823 Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
1824                        ResourceTrackerSP RT) {
1825   assert(MU && "Can not define with a null MU");
1826 
1827   if (MU->getSymbols().empty()) {
1828     // Empty MUs are allowable but pathological, so issue a warning.
1829     DEBUG_WITH_TYPE("orc", {
1830       dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for "
1831              << getName() << "\n";
1832     });
1833     return Error::success();
1834   } else
1835     DEBUG_WITH_TYPE("orc", {
1836       dbgs() << "Defining MU " << MU->getName() << " for " << getName()
1837              << " (tracker: ";
1838       if (RT == getDefaultResourceTracker())
1839         dbgs() << "default)";
1840       else if (RT)
1841         dbgs() << RT.get() << ")\n";
1842       else
1843         dbgs() << "0x0, default will be used)\n";
1844     });
1845 
1846   return ES.runSessionLocked([&, this]() -> Error {
1847     assert(State == Open && "JD is defunct");
1848 
1849     if (auto Err = defineImpl(*MU))
1850       return Err;
1851 
1852     if (!RT)
1853       RT = getDefaultResourceTracker();
1854 
1855     if (auto *P = ES.getPlatform()) {
1856       if (auto Err = P->notifyAdding(*RT, *MU))
1857         return Err;
1858     }
1859 
1860     installMaterializationUnit(std::move(MU), *RT);
1861     return Error::success();
1862   });
1863 }
1864 
1865 template <typename MaterializationUnitType>
1866 Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU,
1867                        ResourceTrackerSP RT) {
1868   assert(MU && "Can not define with a null MU");
1869 
1870   if (MU->getSymbols().empty()) {
1871     // Empty MUs are allowable but pathological, so issue a warning.
1872     DEBUG_WITH_TYPE("orc", {
1873       dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName()
1874              << "\n";
1875     });
1876     return Error::success();
1877   } else
1878     DEBUG_WITH_TYPE("orc", {
1879       dbgs() << "Defining MU " << MU->getName() << " for " << getName()
1880              << " (tracker: ";
1881       if (RT == getDefaultResourceTracker())
1882         dbgs() << "default)";
1883       else if (RT)
1884         dbgs() << RT.get() << ")\n";
1885       else
1886         dbgs() << "0x0, default will be used)\n";
1887     });
1888 
1889   return ES.runSessionLocked([&, this]() -> Error {
1890     assert(State == Open && "JD is defunct");
1891 
1892     if (auto Err = defineImpl(*MU))
1893       return Err;
1894 
1895     if (!RT)
1896       RT = getDefaultResourceTracker();
1897 
1898     if (auto *P = ES.getPlatform()) {
1899       if (auto Err = P->notifyAdding(*RT, *MU))
1900         return Err;
1901     }
1902 
1903     installMaterializationUnit(std::move(MU), *RT);
1904     return Error::success();
1905   });
1906 }
1907 
1908 /// ReexportsGenerator can be used with JITDylib::addGenerator to automatically
1909 /// re-export a subset of the source JITDylib's symbols in the target.
1910 class ReexportsGenerator : public DefinitionGenerator {
1911 public:
1912   using SymbolPredicate = std::function<bool(SymbolStringPtr)>;
1913 
1914   /// Create a reexports generator. If an Allow predicate is passed, only
1915   /// symbols for which the predicate returns true will be reexported. If no
1916   /// Allow predicate is passed, all symbols will be exported.
1917   ReexportsGenerator(JITDylib &SourceJD,
1918                      JITDylibLookupFlags SourceJDLookupFlags,
1919                      SymbolPredicate Allow = SymbolPredicate());
1920 
1921   Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
1922                       JITDylibLookupFlags JDLookupFlags,
1923                       const SymbolLookupSet &LookupSet) override;
1924 
1925 private:
1926   JITDylib &SourceJD;
1927   JITDylibLookupFlags SourceJDLookupFlags;
1928   SymbolPredicate Allow;
1929 };
1930 
1931 // --------------- IMPLEMENTATION --------------
1932 // Implementations for inline functions/methods.
1933 // ---------------------------------------------
1934 
1935 inline MaterializationResponsibility::~MaterializationResponsibility() {
1936   getExecutionSession().OL_destroyMaterializationResponsibility(*this);
1937 }
1938 
1939 inline SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
1940   return getExecutionSession().OL_getRequestedSymbols(*this);
1941 }
1942 
1943 inline Error MaterializationResponsibility::notifyResolved(
1944     const SymbolMap &Symbols) {
1945   return getExecutionSession().OL_notifyResolved(*this, Symbols);
1946 }
1947 
1948 inline Error MaterializationResponsibility::notifyEmitted(
1949     ArrayRef<SymbolDependenceGroup> EmittedDeps) {
1950   return getExecutionSession().OL_notifyEmitted(*this, EmittedDeps);
1951 }
1952 
1953 inline Error MaterializationResponsibility::defineMaterializing(
1954     SymbolFlagsMap SymbolFlags) {
1955   return getExecutionSession().OL_defineMaterializing(*this,
1956                                                       std::move(SymbolFlags));
1957 }
1958 
1959 inline void MaterializationResponsibility::failMaterialization() {
1960   getExecutionSession().OL_notifyFailed(*this);
1961 }
1962 
1963 inline Error MaterializationResponsibility::replace(
1964     std::unique_ptr<MaterializationUnit> MU) {
1965   return getExecutionSession().OL_replace(*this, std::move(MU));
1966 }
1967 
1968 inline Expected<std::unique_ptr<MaterializationResponsibility>>
1969 MaterializationResponsibility::delegate(const SymbolNameSet &Symbols) {
1970   return getExecutionSession().OL_delegate(*this, Symbols);
1971 }
1972 
1973 } // End namespace orc
1974 } // End namespace llvm
1975 
1976 #endif // LLVM_EXECUTIONENGINE_ORC_CORE_H
1977