Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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