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