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