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