Home | History | Annotate | Line # | Download | only in Orc
      1 //===--- Core.cpp - Core ORC APIs (MaterializationUnit, JITDylib, etc.) ---===//
      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 #include "llvm/ExecutionEngine/Orc/Core.h"
     10 
     11 #include "llvm/ADT/STLExtras.h"
     12 #include "llvm/Config/llvm-config.h"
     13 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
     14 #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
     15 #include "llvm/Support/FormatVariadic.h"
     16 #include "llvm/Support/MSVCErrorWorkarounds.h"
     17 
     18 #include <condition_variable>
     19 #include <future>
     20 
     21 #define DEBUG_TYPE "orc"
     22 
     23 namespace llvm {
     24 namespace orc {
     25 
     26 char ResourceTrackerDefunct::ID = 0;
     27 char FailedToMaterialize::ID = 0;
     28 char SymbolsNotFound::ID = 0;
     29 char SymbolsCouldNotBeRemoved::ID = 0;
     30 char MissingSymbolDefinitions::ID = 0;
     31 char UnexpectedSymbolDefinitions::ID = 0;
     32 char Task::ID = 0;
     33 char MaterializationTask::ID = 0;
     34 
     35 RegisterDependenciesFunction NoDependenciesToRegister =
     36     RegisterDependenciesFunction();
     37 
     38 void MaterializationUnit::anchor() {}
     39 
     40 ResourceTracker::ResourceTracker(JITDylibSP JD) {
     41   assert((reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 &&
     42          "JITDylib must be two byte aligned");
     43   JD->Retain();
     44   JDAndFlag.store(reinterpret_cast<uintptr_t>(JD.get()));
     45 }
     46 
     47 ResourceTracker::~ResourceTracker() {
     48   getJITDylib().getExecutionSession().destroyResourceTracker(*this);
     49   getJITDylib().Release();
     50 }
     51 
     52 Error ResourceTracker::remove() {
     53   return getJITDylib().getExecutionSession().removeResourceTracker(*this);
     54 }
     55 
     56 void ResourceTracker::transferTo(ResourceTracker &DstRT) {
     57   getJITDylib().getExecutionSession().transferResourceTracker(DstRT, *this);
     58 }
     59 
     60 void ResourceTracker::makeDefunct() {
     61   uintptr_t Val = JDAndFlag.load();
     62   Val |= 0x1U;
     63   JDAndFlag.store(Val);
     64 }
     65 
     66 ResourceManager::~ResourceManager() {}
     67 
     68 ResourceTrackerDefunct::ResourceTrackerDefunct(ResourceTrackerSP RT)
     69     : RT(std::move(RT)) {}
     70 
     71 std::error_code ResourceTrackerDefunct::convertToErrorCode() const {
     72   return orcError(OrcErrorCode::UnknownORCError);
     73 }
     74 
     75 void ResourceTrackerDefunct::log(raw_ostream &OS) const {
     76   OS << "Resource tracker " << (void *)RT.get() << " became defunct";
     77 }
     78 
     79 FailedToMaterialize::FailedToMaterialize(
     80     std::shared_ptr<SymbolDependenceMap> Symbols)
     81     : Symbols(std::move(Symbols)) {
     82   assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
     83 }
     84 
     85 std::error_code FailedToMaterialize::convertToErrorCode() const {
     86   return orcError(OrcErrorCode::UnknownORCError);
     87 }
     88 
     89 void FailedToMaterialize::log(raw_ostream &OS) const {
     90   OS << "Failed to materialize symbols: " << *Symbols;
     91 }
     92 
     93 SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) {
     94   for (auto &Sym : Symbols)
     95     this->Symbols.push_back(Sym);
     96   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
     97 }
     98 
     99 SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols)
    100     : Symbols(std::move(Symbols)) {
    101   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
    102 }
    103 
    104 std::error_code SymbolsNotFound::convertToErrorCode() const {
    105   return orcError(OrcErrorCode::UnknownORCError);
    106 }
    107 
    108 void SymbolsNotFound::log(raw_ostream &OS) const {
    109   OS << "Symbols not found: " << Symbols;
    110 }
    111 
    112 SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
    113     : Symbols(std::move(Symbols)) {
    114   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
    115 }
    116 
    117 std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const {
    118   return orcError(OrcErrorCode::UnknownORCError);
    119 }
    120 
    121 void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const {
    122   OS << "Symbols could not be removed: " << Symbols;
    123 }
    124 
    125 std::error_code MissingSymbolDefinitions::convertToErrorCode() const {
    126   return orcError(OrcErrorCode::MissingSymbolDefinitions);
    127 }
    128 
    129 void MissingSymbolDefinitions::log(raw_ostream &OS) const {
    130   OS << "Missing definitions in module " << ModuleName
    131      << ": " << Symbols;
    132 }
    133 
    134 std::error_code UnexpectedSymbolDefinitions::convertToErrorCode() const {
    135   return orcError(OrcErrorCode::UnexpectedSymbolDefinitions);
    136 }
    137 
    138 void UnexpectedSymbolDefinitions::log(raw_ostream &OS) const {
    139   OS << "Unexpected definitions in module " << ModuleName
    140      << ": " << Symbols;
    141 }
    142 
    143 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
    144     const SymbolLookupSet &Symbols, SymbolState RequiredState,
    145     SymbolsResolvedCallback NotifyComplete)
    146     : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
    147   assert(RequiredState >= SymbolState::Resolved &&
    148          "Cannot query for a symbols that have not reached the resolve state "
    149          "yet");
    150 
    151   OutstandingSymbolsCount = Symbols.size();
    152 
    153   for (auto &KV : Symbols)
    154     ResolvedSymbols[KV.first] = nullptr;
    155 }
    156 
    157 void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
    158     const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) {
    159   auto I = ResolvedSymbols.find(Name);
    160   assert(I != ResolvedSymbols.end() &&
    161          "Resolving symbol outside the requested set");
    162   assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name");
    163 
    164   // If this is a materialization-side-effects-only symbol then drop it,
    165   // otherwise update its map entry with its resolved address.
    166   if (Sym.getFlags().hasMaterializationSideEffectsOnly())
    167     ResolvedSymbols.erase(I);
    168   else
    169     I->second = std::move(Sym);
    170   --OutstandingSymbolsCount;
    171 }
    172 
    173 void AsynchronousSymbolQuery::handleComplete(ExecutionSession &ES) {
    174   assert(OutstandingSymbolsCount == 0 &&
    175          "Symbols remain, handleComplete called prematurely");
    176 
    177   class RunQueryCompleteTask : public Task {
    178   public:
    179     RunQueryCompleteTask(SymbolMap ResolvedSymbols,
    180                          SymbolsResolvedCallback NotifyComplete)
    181         : ResolvedSymbols(std::move(ResolvedSymbols)),
    182           NotifyComplete(std::move(NotifyComplete)) {}
    183     void printDescription(raw_ostream &OS) override {
    184       OS << "Execute query complete callback for " << ResolvedSymbols;
    185     }
    186     void run() override { NotifyComplete(std::move(ResolvedSymbols)); }
    187 
    188   private:
    189     SymbolMap ResolvedSymbols;
    190     SymbolsResolvedCallback NotifyComplete;
    191   };
    192 
    193   auto T = std::make_unique<RunQueryCompleteTask>(std::move(ResolvedSymbols),
    194                                                   std::move(NotifyComplete));
    195   NotifyComplete = SymbolsResolvedCallback();
    196   ES.dispatchTask(std::move(T));
    197 }
    198 
    199 void AsynchronousSymbolQuery::handleFailed(Error Err) {
    200   assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
    201          OutstandingSymbolsCount == 0 &&
    202          "Query should already have been abandoned");
    203   NotifyComplete(std::move(Err));
    204   NotifyComplete = SymbolsResolvedCallback();
    205 }
    206 
    207 void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
    208                                                  SymbolStringPtr Name) {
    209   bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
    210   (void)Added;
    211   assert(Added && "Duplicate dependence notification?");
    212 }
    213 
    214 void AsynchronousSymbolQuery::removeQueryDependence(
    215     JITDylib &JD, const SymbolStringPtr &Name) {
    216   auto QRI = QueryRegistrations.find(&JD);
    217   assert(QRI != QueryRegistrations.end() &&
    218          "No dependencies registered for JD");
    219   assert(QRI->second.count(Name) && "No dependency on Name in JD");
    220   QRI->second.erase(Name);
    221   if (QRI->second.empty())
    222     QueryRegistrations.erase(QRI);
    223 }
    224 
    225 void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) {
    226   auto I = ResolvedSymbols.find(Name);
    227   assert(I != ResolvedSymbols.end() &&
    228          "Redundant removal of weakly-referenced symbol");
    229   ResolvedSymbols.erase(I);
    230   --OutstandingSymbolsCount;
    231 }
    232 
    233 void AsynchronousSymbolQuery::detach() {
    234   ResolvedSymbols.clear();
    235   OutstandingSymbolsCount = 0;
    236   for (auto &KV : QueryRegistrations)
    237     KV.first->detachQueryHelper(*this, KV.second);
    238   QueryRegistrations.clear();
    239 }
    240 
    241 AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
    242     SymbolMap Symbols)
    243     : MaterializationUnit(extractFlags(Symbols), nullptr),
    244       Symbols(std::move(Symbols)) {}
    245 
    246 StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
    247   return "<Absolute Symbols>";
    248 }
    249 
    250 void AbsoluteSymbolsMaterializationUnit::materialize(
    251     std::unique_ptr<MaterializationResponsibility> R) {
    252   // No dependencies, so these calls can't fail.
    253   cantFail(R->notifyResolved(Symbols));
    254   cantFail(R->notifyEmitted());
    255 }
    256 
    257 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
    258                                                  const SymbolStringPtr &Name) {
    259   assert(Symbols.count(Name) && "Symbol is not part of this MU");
    260   Symbols.erase(Name);
    261 }
    262 
    263 SymbolFlagsMap
    264 AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
    265   SymbolFlagsMap Flags;
    266   for (const auto &KV : Symbols)
    267     Flags[KV.first] = KV.second.getFlags();
    268   return Flags;
    269 }
    270 
    271 ReExportsMaterializationUnit::ReExportsMaterializationUnit(
    272     JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
    273     SymbolAliasMap Aliases)
    274     : MaterializationUnit(extractFlags(Aliases), nullptr), SourceJD(SourceJD),
    275       SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {}
    276 
    277 StringRef ReExportsMaterializationUnit::getName() const {
    278   return "<Reexports>";
    279 }
    280 
    281 void ReExportsMaterializationUnit::materialize(
    282     std::unique_ptr<MaterializationResponsibility> R) {
    283 
    284   auto &ES = R->getTargetJITDylib().getExecutionSession();
    285   JITDylib &TgtJD = R->getTargetJITDylib();
    286   JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
    287 
    288   // Find the set of requested aliases and aliasees. Return any unrequested
    289   // aliases back to the JITDylib so as to not prematurely materialize any
    290   // aliasees.
    291   auto RequestedSymbols = R->getRequestedSymbols();
    292   SymbolAliasMap RequestedAliases;
    293 
    294   for (auto &Name : RequestedSymbols) {
    295     auto I = Aliases.find(Name);
    296     assert(I != Aliases.end() && "Symbol not found in aliases map?");
    297     RequestedAliases[Name] = std::move(I->second);
    298     Aliases.erase(I);
    299   }
    300 
    301   LLVM_DEBUG({
    302     ES.runSessionLocked([&]() {
    303       dbgs() << "materializing reexports: target = " << TgtJD.getName()
    304              << ", source = " << SrcJD.getName() << " " << RequestedAliases
    305              << "\n";
    306     });
    307   });
    308 
    309   if (!Aliases.empty()) {
    310     auto Err = SourceJD ? R->replace(reexports(*SourceJD, std::move(Aliases),
    311                                                SourceJDLookupFlags))
    312                         : R->replace(symbolAliases(std::move(Aliases)));
    313 
    314     if (Err) {
    315       // FIXME: Should this be reported / treated as failure to materialize?
    316       // Or should this be treated as a sanctioned bailing-out?
    317       ES.reportError(std::move(Err));
    318       R->failMaterialization();
    319       return;
    320     }
    321   }
    322 
    323   // The OnResolveInfo struct will hold the aliases and responsibilty for each
    324   // query in the list.
    325   struct OnResolveInfo {
    326     OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R,
    327                   SymbolAliasMap Aliases)
    328         : R(std::move(R)), Aliases(std::move(Aliases)) {}
    329 
    330     std::unique_ptr<MaterializationResponsibility> R;
    331     SymbolAliasMap Aliases;
    332   };
    333 
    334   // Build a list of queries to issue. In each round we build a query for the
    335   // largest set of aliases that we can resolve without encountering a chain of
    336   // aliases (e.g. Foo -> Bar, Bar -> Baz). Such a chain would deadlock as the
    337   // query would be waiting on a symbol that it itself had to resolve. Creating
    338   // a new query for each link in such a chain eliminates the possibility of
    339   // deadlock. In practice chains are likely to be rare, and this algorithm will
    340   // usually result in a single query to issue.
    341 
    342   std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
    343       QueryInfos;
    344   while (!RequestedAliases.empty()) {
    345     SymbolNameSet ResponsibilitySymbols;
    346     SymbolLookupSet QuerySymbols;
    347     SymbolAliasMap QueryAliases;
    348 
    349     // Collect as many aliases as we can without including a chain.
    350     for (auto &KV : RequestedAliases) {
    351       // Chain detected. Skip this symbol for this round.
    352       if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
    353                                RequestedAliases.count(KV.second.Aliasee)))
    354         continue;
    355 
    356       ResponsibilitySymbols.insert(KV.first);
    357       QuerySymbols.add(KV.second.Aliasee,
    358                        KV.second.AliasFlags.hasMaterializationSideEffectsOnly()
    359                            ? SymbolLookupFlags::WeaklyReferencedSymbol
    360                            : SymbolLookupFlags::RequiredSymbol);
    361       QueryAliases[KV.first] = std::move(KV.second);
    362     }
    363 
    364     // Remove the aliases collected this round from the RequestedAliases map.
    365     for (auto &KV : QueryAliases)
    366       RequestedAliases.erase(KV.first);
    367 
    368     assert(!QuerySymbols.empty() && "Alias cycle detected!");
    369 
    370     auto NewR = R->delegate(ResponsibilitySymbols);
    371     if (!NewR) {
    372       ES.reportError(NewR.takeError());
    373       R->failMaterialization();
    374       return;
    375     }
    376 
    377     auto QueryInfo = std::make_shared<OnResolveInfo>(std::move(*NewR),
    378                                                      std::move(QueryAliases));
    379     QueryInfos.push_back(
    380         make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
    381   }
    382 
    383   // Issue the queries.
    384   while (!QueryInfos.empty()) {
    385     auto QuerySymbols = std::move(QueryInfos.back().first);
    386     auto QueryInfo = std::move(QueryInfos.back().second);
    387 
    388     QueryInfos.pop_back();
    389 
    390     auto RegisterDependencies = [QueryInfo,
    391                                  &SrcJD](const SymbolDependenceMap &Deps) {
    392       // If there were no materializing symbols, just bail out.
    393       if (Deps.empty())
    394         return;
    395 
    396       // Otherwise the only deps should be on SrcJD.
    397       assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
    398              "Unexpected dependencies for reexports");
    399 
    400       auto &SrcJDDeps = Deps.find(&SrcJD)->second;
    401       SymbolDependenceMap PerAliasDepsMap;
    402       auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
    403 
    404       for (auto &KV : QueryInfo->Aliases)
    405         if (SrcJDDeps.count(KV.second.Aliasee)) {
    406           PerAliasDeps = {KV.second.Aliasee};
    407           QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap);
    408         }
    409     };
    410 
    411     auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
    412       auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();
    413       if (Result) {
    414         SymbolMap ResolutionMap;
    415         for (auto &KV : QueryInfo->Aliases) {
    416           assert((KV.second.AliasFlags.hasMaterializationSideEffectsOnly() ||
    417                   Result->count(KV.second.Aliasee)) &&
    418                  "Result map missing entry?");
    419           // Don't try to resolve materialization-side-effects-only symbols.
    420           if (KV.second.AliasFlags.hasMaterializationSideEffectsOnly())
    421             continue;
    422 
    423           ResolutionMap[KV.first] = JITEvaluatedSymbol(
    424               (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
    425         }
    426         if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {
    427           ES.reportError(std::move(Err));
    428           QueryInfo->R->failMaterialization();
    429           return;
    430         }
    431         if (auto Err = QueryInfo->R->notifyEmitted()) {
    432           ES.reportError(std::move(Err));
    433           QueryInfo->R->failMaterialization();
    434           return;
    435         }
    436       } else {
    437         ES.reportError(Result.takeError());
    438         QueryInfo->R->failMaterialization();
    439       }
    440     };
    441 
    442     ES.lookup(LookupKind::Static,
    443               JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
    444               QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
    445               std::move(RegisterDependencies));
    446   }
    447 }
    448 
    449 void ReExportsMaterializationUnit::discard(const JITDylib &JD,
    450                                            const SymbolStringPtr &Name) {
    451   assert(Aliases.count(Name) &&
    452          "Symbol not covered by this MaterializationUnit");
    453   Aliases.erase(Name);
    454 }
    455 
    456 SymbolFlagsMap
    457 ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
    458   SymbolFlagsMap SymbolFlags;
    459   for (auto &KV : Aliases)
    460     SymbolFlags[KV.first] = KV.second.AliasFlags;
    461 
    462   return SymbolFlags;
    463 }
    464 
    465 Expected<SymbolAliasMap> buildSimpleReexportsAliasMap(JITDylib &SourceJD,
    466                                                       SymbolNameSet Symbols) {
    467   SymbolLookupSet LookupSet(Symbols);
    468   auto Flags = SourceJD.getExecutionSession().lookupFlags(
    469       LookupKind::Static, {{&SourceJD, JITDylibLookupFlags::MatchAllSymbols}},
    470       SymbolLookupSet(std::move(Symbols)));
    471 
    472   if (!Flags)
    473     return Flags.takeError();
    474 
    475   SymbolAliasMap Result;
    476   for (auto &Name : Symbols) {
    477     assert(Flags->count(Name) && "Missing entry in flags map");
    478     Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
    479   }
    480 
    481   return Result;
    482 }
    483 
    484 class InProgressLookupState {
    485 public:
    486   InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder,
    487                         SymbolLookupSet LookupSet, SymbolState RequiredState)
    488       : K(K), SearchOrder(std::move(SearchOrder)),
    489         LookupSet(std::move(LookupSet)), RequiredState(RequiredState) {
    490     DefGeneratorCandidates = this->LookupSet;
    491   }
    492   virtual ~InProgressLookupState() {}
    493   virtual void complete(std::unique_ptr<InProgressLookupState> IPLS) = 0;
    494   virtual void fail(Error Err) = 0;
    495 
    496   LookupKind K;
    497   JITDylibSearchOrder SearchOrder;
    498   SymbolLookupSet LookupSet;
    499   SymbolState RequiredState;
    500 
    501   std::unique_lock<std::mutex> GeneratorLock;
    502   size_t CurSearchOrderIndex = 0;
    503   bool NewJITDylib = true;
    504   SymbolLookupSet DefGeneratorCandidates;
    505   SymbolLookupSet DefGeneratorNonCandidates;
    506   std::vector<std::weak_ptr<DefinitionGenerator>> CurDefGeneratorStack;
    507 };
    508 
    509 class InProgressLookupFlagsState : public InProgressLookupState {
    510 public:
    511   InProgressLookupFlagsState(
    512       LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
    513       unique_function<void(Expected<SymbolFlagsMap>)> OnComplete)
    514       : InProgressLookupState(K, std::move(SearchOrder), std::move(LookupSet),
    515                               SymbolState::NeverSearched),
    516         OnComplete(std::move(OnComplete)) {}
    517 
    518   void complete(std::unique_ptr<InProgressLookupState> IPLS) override {
    519     GeneratorLock = {}; // Unlock and release.
    520     auto &ES = SearchOrder.front().first->getExecutionSession();
    521     ES.OL_completeLookupFlags(std::move(IPLS), std::move(OnComplete));
    522   }
    523 
    524   void fail(Error Err) override {
    525     GeneratorLock = {}; // Unlock and release.
    526     OnComplete(std::move(Err));
    527   }
    528 
    529 private:
    530   unique_function<void(Expected<SymbolFlagsMap>)> OnComplete;
    531 };
    532 
    533 class InProgressFullLookupState : public InProgressLookupState {
    534 public:
    535   InProgressFullLookupState(LookupKind K, JITDylibSearchOrder SearchOrder,
    536                             SymbolLookupSet LookupSet,
    537                             SymbolState RequiredState,
    538                             std::shared_ptr<AsynchronousSymbolQuery> Q,
    539                             RegisterDependenciesFunction RegisterDependencies)
    540       : InProgressLookupState(K, std::move(SearchOrder), std::move(LookupSet),
    541                               RequiredState),
    542         Q(std::move(Q)), RegisterDependencies(std::move(RegisterDependencies)) {
    543   }
    544 
    545   void complete(std::unique_ptr<InProgressLookupState> IPLS) override {
    546     GeneratorLock = {}; // Unlock and release.
    547     auto &ES = SearchOrder.front().first->getExecutionSession();
    548     ES.OL_completeLookup(std::move(IPLS), std::move(Q),
    549                          std::move(RegisterDependencies));
    550   }
    551 
    552   void fail(Error Err) override {
    553     GeneratorLock = {};
    554     Q->detach();
    555     Q->handleFailed(std::move(Err));
    556   }
    557 
    558 private:
    559   std::shared_ptr<AsynchronousSymbolQuery> Q;
    560   RegisterDependenciesFunction RegisterDependencies;
    561 };
    562 
    563 ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
    564                                        JITDylibLookupFlags SourceJDLookupFlags,
    565                                        SymbolPredicate Allow)
    566     : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
    567       Allow(std::move(Allow)) {}
    568 
    569 Error ReexportsGenerator::tryToGenerate(LookupState &LS, LookupKind K,
    570                                         JITDylib &JD,
    571                                         JITDylibLookupFlags JDLookupFlags,
    572                                         const SymbolLookupSet &LookupSet) {
    573   assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
    574 
    575   // Use lookupFlags to find the subset of symbols that match our lookup.
    576   auto Flags = JD.getExecutionSession().lookupFlags(
    577       K, {{&SourceJD, JDLookupFlags}}, LookupSet);
    578   if (!Flags)
    579     return Flags.takeError();
    580 
    581   // Create an alias map.
    582   orc::SymbolAliasMap AliasMap;
    583   for (auto &KV : *Flags)
    584     if (!Allow || Allow(KV.first))
    585       AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
    586 
    587   if (AliasMap.empty())
    588     return Error::success();
    589 
    590   // Define the re-exports.
    591   return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
    592 }
    593 
    594 LookupState::LookupState(std::unique_ptr<InProgressLookupState> IPLS)
    595     : IPLS(std::move(IPLS)) {}
    596 
    597 void LookupState::reset(InProgressLookupState *IPLS) { this->IPLS.reset(IPLS); }
    598 
    599 LookupState::LookupState() = default;
    600 LookupState::LookupState(LookupState &&) = default;
    601 LookupState &LookupState::operator=(LookupState &&) = default;
    602 LookupState::~LookupState() = default;
    603 
    604 void LookupState::continueLookup(Error Err) {
    605   assert(IPLS && "Cannot call continueLookup on empty LookupState");
    606   auto &ES = IPLS->SearchOrder.begin()->first->getExecutionSession();
    607   ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err));
    608 }
    609 
    610 DefinitionGenerator::~DefinitionGenerator() {}
    611 
    612 Error JITDylib::clear() {
    613   std::vector<ResourceTrackerSP> TrackersToRemove;
    614   ES.runSessionLocked([&]() {
    615     for (auto &KV : TrackerSymbols)
    616       TrackersToRemove.push_back(KV.first);
    617     TrackersToRemove.push_back(getDefaultResourceTracker());
    618   });
    619 
    620   Error Err = Error::success();
    621   for (auto &RT : TrackersToRemove)
    622     Err = joinErrors(std::move(Err), RT->remove());
    623   return Err;
    624 }
    625 
    626 ResourceTrackerSP JITDylib::getDefaultResourceTracker() {
    627   return ES.runSessionLocked([this] {
    628     if (!DefaultTracker)
    629       DefaultTracker = new ResourceTracker(this);
    630     return DefaultTracker;
    631   });
    632 }
    633 
    634 ResourceTrackerSP JITDylib::createResourceTracker() {
    635   return ES.runSessionLocked([this] {
    636     ResourceTrackerSP RT = new ResourceTracker(this);
    637     return RT;
    638   });
    639 }
    640 
    641 void JITDylib::removeGenerator(DefinitionGenerator &G) {
    642   std::lock_guard<std::mutex> Lock(GeneratorsMutex);
    643   auto I = llvm::find_if(DefGenerators,
    644                          [&](const std::shared_ptr<DefinitionGenerator> &H) {
    645                            return H.get() == &G;
    646                          });
    647   assert(I != DefGenerators.end() && "Generator not found");
    648   DefGenerators.erase(I);
    649 }
    650 
    651 Expected<SymbolFlagsMap>
    652 JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
    653 
    654   return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
    655     std::vector<SymbolTable::iterator> AddedSyms;
    656     std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
    657 
    658     for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
    659          SFItr != SFEnd; ++SFItr) {
    660 
    661       auto &Name = SFItr->first;
    662       auto &Flags = SFItr->second;
    663 
    664       auto EntryItr = Symbols.find(Name);
    665 
    666       // If the entry already exists...
    667       if (EntryItr != Symbols.end()) {
    668 
    669         // If this is a strong definition then error out.
    670         if (!Flags.isWeak()) {
    671           // Remove any symbols already added.
    672           for (auto &SI : AddedSyms)
    673             Symbols.erase(SI);
    674 
    675           // FIXME: Return all duplicates.
    676           return make_error<DuplicateDefinition>(std::string(*Name));
    677         }
    678 
    679         // Otherwise just make a note to discard this symbol after the loop.
    680         RejectedWeakDefs.push_back(SFItr);
    681         continue;
    682       } else
    683         EntryItr =
    684           Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
    685 
    686       AddedSyms.push_back(EntryItr);
    687       EntryItr->second.setState(SymbolState::Materializing);
    688     }
    689 
    690     // Remove any rejected weak definitions from the SymbolFlags map.
    691     while (!RejectedWeakDefs.empty()) {
    692       SymbolFlags.erase(RejectedWeakDefs.back());
    693       RejectedWeakDefs.pop_back();
    694     }
    695 
    696     return SymbolFlags;
    697   });
    698 }
    699 
    700 Error JITDylib::replace(MaterializationResponsibility &FromMR,
    701                         std::unique_ptr<MaterializationUnit> MU) {
    702   assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
    703   std::unique_ptr<MaterializationUnit> MustRunMU;
    704   std::unique_ptr<MaterializationResponsibility> MustRunMR;
    705 
    706   auto Err =
    707       ES.runSessionLocked([&, this]() -> Error {
    708         auto RT = getTracker(FromMR);
    709 
    710         if (RT->isDefunct())
    711           return make_error<ResourceTrackerDefunct>(std::move(RT));
    712 
    713 #ifndef NDEBUG
    714         for (auto &KV : MU->getSymbols()) {
    715           auto SymI = Symbols.find(KV.first);
    716           assert(SymI != Symbols.end() && "Replacing unknown symbol");
    717           assert(SymI->second.getState() == SymbolState::Materializing &&
    718                  "Can not replace a symbol that ha is not materializing");
    719           assert(!SymI->second.hasMaterializerAttached() &&
    720                  "Symbol should not have materializer attached already");
    721           assert(UnmaterializedInfos.count(KV.first) == 0 &&
    722                  "Symbol being replaced should have no UnmaterializedInfo");
    723         }
    724 #endif // NDEBUG
    725 
    726         // If the tracker is defunct we need to bail out immediately.
    727 
    728         // If any symbol has pending queries against it then we need to
    729         // materialize MU immediately.
    730         for (auto &KV : MU->getSymbols()) {
    731           auto MII = MaterializingInfos.find(KV.first);
    732           if (MII != MaterializingInfos.end()) {
    733             if (MII->second.hasQueriesPending()) {
    734               MustRunMR = ES.createMaterializationResponsibility(
    735                   *RT, std::move(MU->SymbolFlags), std::move(MU->InitSymbol));
    736               MustRunMU = std::move(MU);
    737               return Error::success();
    738             }
    739           }
    740         }
    741 
    742         // Otherwise, make MU responsible for all the symbols.
    743         auto RTI = MRTrackers.find(&FromMR);
    744         assert(RTI != MRTrackers.end() && "No tracker for FromMR");
    745         auto UMI =
    746             std::make_shared<UnmaterializedInfo>(std::move(MU), RTI->second);
    747         for (auto &KV : UMI->MU->getSymbols()) {
    748           auto SymI = Symbols.find(KV.first);
    749           assert(SymI->second.getState() == SymbolState::Materializing &&
    750                  "Can not replace a symbol that is not materializing");
    751           assert(!SymI->second.hasMaterializerAttached() &&
    752                  "Can not replace a symbol that has a materializer attached");
    753           assert(UnmaterializedInfos.count(KV.first) == 0 &&
    754                  "Unexpected materializer entry in map");
    755           SymI->second.setAddress(SymI->second.getAddress());
    756           SymI->second.setMaterializerAttached(true);
    757 
    758           auto &UMIEntry = UnmaterializedInfos[KV.first];
    759           assert((!UMIEntry || !UMIEntry->MU) &&
    760                  "Replacing symbol with materializer still attached");
    761           UMIEntry = UMI;
    762         }
    763 
    764         return Error::success();
    765       });
    766 
    767   if (Err)
    768     return Err;
    769 
    770   if (MustRunMU) {
    771     assert(MustRunMR && "MustRunMU set implies MustRunMR set");
    772     ES.dispatchTask(std::make_unique<MaterializationTask>(
    773         std::move(MustRunMU), std::move(MustRunMR)));
    774   } else {
    775     assert(!MustRunMR && "MustRunMU unset implies MustRunMR unset");
    776   }
    777 
    778   return Error::success();
    779 }
    780 
    781 Expected<std::unique_ptr<MaterializationResponsibility>>
    782 JITDylib::delegate(MaterializationResponsibility &FromMR,
    783                    SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol) {
    784 
    785   return ES.runSessionLocked(
    786       [&]() -> Expected<std::unique_ptr<MaterializationResponsibility>> {
    787         auto RT = getTracker(FromMR);
    788 
    789         if (RT->isDefunct())
    790           return make_error<ResourceTrackerDefunct>(std::move(RT));
    791 
    792         return ES.createMaterializationResponsibility(
    793             *RT, std::move(SymbolFlags), std::move(InitSymbol));
    794       });
    795 }
    796 
    797 SymbolNameSet
    798 JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
    799   return ES.runSessionLocked([&]() {
    800     SymbolNameSet RequestedSymbols;
    801 
    802     for (auto &KV : SymbolFlags) {
    803       assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
    804       assert(Symbols.find(KV.first)->second.getState() !=
    805                  SymbolState::NeverSearched &&
    806              Symbols.find(KV.first)->second.getState() != SymbolState::Ready &&
    807              "getRequestedSymbols can only be called for symbols that have "
    808              "started materializing");
    809       auto I = MaterializingInfos.find(KV.first);
    810       if (I == MaterializingInfos.end())
    811         continue;
    812 
    813       if (I->second.hasQueriesPending())
    814         RequestedSymbols.insert(KV.first);
    815     }
    816 
    817     return RequestedSymbols;
    818   });
    819 }
    820 
    821 void JITDylib::addDependencies(const SymbolStringPtr &Name,
    822                                const SymbolDependenceMap &Dependencies) {
    823   ES.runSessionLocked([&]() {
    824     assert(Symbols.count(Name) && "Name not in symbol table");
    825     assert(Symbols[Name].getState() < SymbolState::Emitted &&
    826            "Can not add dependencies for a symbol that is not materializing");
    827 
    828     LLVM_DEBUG({
    829       dbgs() << "In " << getName() << " adding dependencies for " << *Name
    830              << ": " << Dependencies << "\n";
    831     });
    832 
    833     // If Name is already in an error state then just bail out.
    834     if (Symbols[Name].getFlags().hasError())
    835       return;
    836 
    837     auto &MI = MaterializingInfos[Name];
    838     assert(Symbols[Name].getState() != SymbolState::Emitted &&
    839            "Can not add dependencies to an emitted symbol");
    840 
    841     bool DependsOnSymbolInErrorState = false;
    842 
    843     // Register dependencies, record whether any depenendency is in the error
    844     // state.
    845     for (auto &KV : Dependencies) {
    846       assert(KV.first && "Null JITDylib in dependency?");
    847       auto &OtherJITDylib = *KV.first;
    848       auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
    849 
    850       for (auto &OtherSymbol : KV.second) {
    851 
    852         // Check the sym entry for the dependency.
    853         auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
    854 
    855         // Assert that this symbol exists and has not reached the ready state
    856         // already.
    857         assert(OtherSymI != OtherJITDylib.Symbols.end() &&
    858                "Dependency on unknown symbol");
    859 
    860         auto &OtherSymEntry = OtherSymI->second;
    861 
    862         // If the other symbol is already in the Ready state then there's no
    863         // dependency to add.
    864         if (OtherSymEntry.getState() == SymbolState::Ready)
    865           continue;
    866 
    867         // If the dependency is in an error state then note this and continue,
    868         // we will move this symbol to the error state below.
    869         if (OtherSymEntry.getFlags().hasError()) {
    870           DependsOnSymbolInErrorState = true;
    871           continue;
    872         }
    873 
    874         // If the dependency was not in the error state then add it to
    875         // our list of dependencies.
    876         auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
    877 
    878         if (OtherSymEntry.getState() == SymbolState::Emitted)
    879           transferEmittedNodeDependencies(MI, Name, OtherMI);
    880         else if (&OtherJITDylib != this || OtherSymbol != Name) {
    881           OtherMI.Dependants[this].insert(Name);
    882           DepsOnOtherJITDylib.insert(OtherSymbol);
    883         }
    884       }
    885 
    886       if (DepsOnOtherJITDylib.empty())
    887         MI.UnemittedDependencies.erase(&OtherJITDylib);
    888     }
    889 
    890     // If this symbol dependended on any symbols in the error state then move
    891     // this symbol to the error state too.
    892     if (DependsOnSymbolInErrorState)
    893       Symbols[Name].setFlags(Symbols[Name].getFlags() |
    894                              JITSymbolFlags::HasError);
    895   });
    896 }
    897 
    898 Error JITDylib::resolve(MaterializationResponsibility &MR,
    899                         const SymbolMap &Resolved) {
    900   AsynchronousSymbolQuerySet CompletedQueries;
    901 
    902   if (auto Err = ES.runSessionLocked([&, this]() -> Error {
    903         auto RTI = MRTrackers.find(&MR);
    904         assert(RTI != MRTrackers.end() && "No resource tracker for MR?");
    905         if (RTI->second->isDefunct())
    906           return make_error<ResourceTrackerDefunct>(RTI->second);
    907 
    908         struct WorklistEntry {
    909           SymbolTable::iterator SymI;
    910           JITEvaluatedSymbol ResolvedSym;
    911         };
    912 
    913         SymbolNameSet SymbolsInErrorState;
    914         std::vector<WorklistEntry> Worklist;
    915         Worklist.reserve(Resolved.size());
    916 
    917         // Build worklist and check for any symbols in the error state.
    918         for (const auto &KV : Resolved) {
    919 
    920           assert(!KV.second.getFlags().hasError() &&
    921                  "Resolution result can not have error flag set");
    922 
    923           auto SymI = Symbols.find(KV.first);
    924 
    925           assert(SymI != Symbols.end() && "Symbol not found");
    926           assert(!SymI->second.hasMaterializerAttached() &&
    927                  "Resolving symbol with materializer attached?");
    928           assert(SymI->second.getState() == SymbolState::Materializing &&
    929                  "Symbol should be materializing");
    930           assert(SymI->second.getAddress() == 0 &&
    931                  "Symbol has already been resolved");
    932 
    933           if (SymI->second.getFlags().hasError())
    934             SymbolsInErrorState.insert(KV.first);
    935           else {
    936             auto Flags = KV.second.getFlags();
    937             Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common);
    938             assert(Flags ==
    939                        (SymI->second.getFlags() &
    940                         ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&
    941                    "Resolved flags should match the declared flags");
    942 
    943             Worklist.push_back(
    944                 {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
    945           }
    946         }
    947 
    948         // If any symbols were in the error state then bail out.
    949         if (!SymbolsInErrorState.empty()) {
    950           auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
    951           (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
    952           return make_error<FailedToMaterialize>(
    953               std::move(FailedSymbolsDepMap));
    954         }
    955 
    956         while (!Worklist.empty()) {
    957           auto SymI = Worklist.back().SymI;
    958           auto ResolvedSym = Worklist.back().ResolvedSym;
    959           Worklist.pop_back();
    960 
    961           auto &Name = SymI->first;
    962 
    963           // Resolved symbols can not be weak: discard the weak flag.
    964           JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
    965           SymI->second.setAddress(ResolvedSym.getAddress());
    966           SymI->second.setFlags(ResolvedFlags);
    967           SymI->second.setState(SymbolState::Resolved);
    968 
    969           auto MII = MaterializingInfos.find(Name);
    970           if (MII == MaterializingInfos.end())
    971             continue;
    972 
    973           auto &MI = MII->second;
    974           for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
    975             Q->notifySymbolMetRequiredState(Name, ResolvedSym);
    976             Q->removeQueryDependence(*this, Name);
    977             if (Q->isComplete())
    978               CompletedQueries.insert(std::move(Q));
    979           }
    980         }
    981 
    982         return Error::success();
    983       }))
    984     return Err;
    985 
    986   // Otherwise notify all the completed queries.
    987   for (auto &Q : CompletedQueries) {
    988     assert(Q->isComplete() && "Q not completed");
    989     Q->handleComplete(ES);
    990   }
    991 
    992   return Error::success();
    993 }
    994 
    995 Error JITDylib::emit(MaterializationResponsibility &MR,
    996                      const SymbolFlagsMap &Emitted) {
    997   AsynchronousSymbolQuerySet CompletedQueries;
    998   DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
    999 
   1000   if (auto Err = ES.runSessionLocked([&, this]() -> Error {
   1001         auto RTI = MRTrackers.find(&MR);
   1002         assert(RTI != MRTrackers.end() && "No resource tracker for MR?");
   1003         if (RTI->second->isDefunct())
   1004           return make_error<ResourceTrackerDefunct>(RTI->second);
   1005 
   1006         SymbolNameSet SymbolsInErrorState;
   1007         std::vector<SymbolTable::iterator> Worklist;
   1008 
   1009         // Scan to build worklist, record any symbols in the erorr state.
   1010         for (const auto &KV : Emitted) {
   1011           auto &Name = KV.first;
   1012 
   1013           auto SymI = Symbols.find(Name);
   1014           assert(SymI != Symbols.end() && "No symbol table entry for Name");
   1015 
   1016           if (SymI->second.getFlags().hasError())
   1017             SymbolsInErrorState.insert(Name);
   1018           else
   1019             Worklist.push_back(SymI);
   1020         }
   1021 
   1022         // If any symbols were in the error state then bail out.
   1023         if (!SymbolsInErrorState.empty()) {
   1024           auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
   1025           (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
   1026           return make_error<FailedToMaterialize>(
   1027               std::move(FailedSymbolsDepMap));
   1028         }
   1029 
   1030         // Otherwise update dependencies and move to the emitted state.
   1031         while (!Worklist.empty()) {
   1032           auto SymI = Worklist.back();
   1033           Worklist.pop_back();
   1034 
   1035           auto &Name = SymI->first;
   1036           auto &SymEntry = SymI->second;
   1037 
   1038           // Move symbol to the emitted state.
   1039           assert(((SymEntry.getFlags().hasMaterializationSideEffectsOnly() &&
   1040                    SymEntry.getState() == SymbolState::Materializing) ||
   1041                   SymEntry.getState() == SymbolState::Resolved) &&
   1042                  "Emitting from state other than Resolved");
   1043           SymEntry.setState(SymbolState::Emitted);
   1044 
   1045           auto MII = MaterializingInfos.find(Name);
   1046 
   1047           // If this symbol has no MaterializingInfo then it's trivially ready.
   1048           // Update its state and continue.
   1049           if (MII == MaterializingInfos.end()) {
   1050             SymEntry.setState(SymbolState::Ready);
   1051             continue;
   1052           }
   1053 
   1054           auto &MI = MII->second;
   1055 
   1056           // For each dependant, transfer this node's emitted dependencies to
   1057           // it. If the dependant node is ready (i.e. has no unemitted
   1058           // dependencies) then notify any pending queries.
   1059           for (auto &KV : MI.Dependants) {
   1060             auto &DependantJD = *KV.first;
   1061             auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
   1062             for (auto &DependantName : KV.second) {
   1063               auto DependantMII =
   1064                   DependantJD.MaterializingInfos.find(DependantName);
   1065               assert(DependantMII != DependantJD.MaterializingInfos.end() &&
   1066                      "Dependant should have MaterializingInfo");
   1067 
   1068               auto &DependantMI = DependantMII->second;
   1069 
   1070               // Remove the dependant's dependency on this node.
   1071               assert(DependantMI.UnemittedDependencies.count(this) &&
   1072                      "Dependant does not have an unemitted dependencies record "
   1073                      "for "
   1074                      "this JITDylib");
   1075               assert(DependantMI.UnemittedDependencies[this].count(Name) &&
   1076                      "Dependant does not count this symbol as a dependency?");
   1077 
   1078               DependantMI.UnemittedDependencies[this].erase(Name);
   1079               if (DependantMI.UnemittedDependencies[this].empty())
   1080                 DependantMI.UnemittedDependencies.erase(this);
   1081 
   1082               // Transfer unemitted dependencies from this node to the
   1083               // dependant.
   1084               DependantJD.transferEmittedNodeDependencies(DependantMI,
   1085                                                           DependantName, MI);
   1086 
   1087               auto DependantSymI = DependantJD.Symbols.find(DependantName);
   1088               assert(DependantSymI != DependantJD.Symbols.end() &&
   1089                      "Dependant has no entry in the Symbols table");
   1090               auto &DependantSymEntry = DependantSymI->second;
   1091 
   1092               // If the dependant is emitted and this node was the last of its
   1093               // unemitted dependencies then the dependant node is now ready, so
   1094               // notify any pending queries on the dependant node.
   1095               if (DependantSymEntry.getState() == SymbolState::Emitted &&
   1096                   DependantMI.UnemittedDependencies.empty()) {
   1097                 assert(DependantMI.Dependants.empty() &&
   1098                        "Dependants should be empty by now");
   1099 
   1100                 // Since this dependant is now ready, we erase its
   1101                 // MaterializingInfo and update its materializing state.
   1102                 DependantSymEntry.setState(SymbolState::Ready);
   1103                 DependantJDReadySymbols.push_back(DependantName);
   1104 
   1105                 for (auto &Q :
   1106                      DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
   1107                   Q->notifySymbolMetRequiredState(
   1108                       DependantName, DependantSymI->second.getSymbol());
   1109                   if (Q->isComplete())
   1110                     CompletedQueries.insert(Q);
   1111                   Q->removeQueryDependence(DependantJD, DependantName);
   1112                 }
   1113                 DependantJD.MaterializingInfos.erase(DependantMII);
   1114               }
   1115             }
   1116           }
   1117 
   1118           auto &ThisJDReadySymbols = ReadySymbols[this];
   1119           MI.Dependants.clear();
   1120           if (MI.UnemittedDependencies.empty()) {
   1121             SymI->second.setState(SymbolState::Ready);
   1122             ThisJDReadySymbols.push_back(Name);
   1123             for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
   1124               Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
   1125               if (Q->isComplete())
   1126                 CompletedQueries.insert(Q);
   1127               Q->removeQueryDependence(*this, Name);
   1128             }
   1129             MaterializingInfos.erase(MII);
   1130           }
   1131         }
   1132 
   1133         return Error::success();
   1134       }))
   1135     return Err;
   1136 
   1137   // Otherwise notify all the completed queries.
   1138   for (auto &Q : CompletedQueries) {
   1139     assert(Q->isComplete() && "Q is not complete");
   1140     Q->handleComplete(ES);
   1141   }
   1142 
   1143   return Error::success();
   1144 }
   1145 
   1146 void JITDylib::unlinkMaterializationResponsibility(
   1147     MaterializationResponsibility &MR) {
   1148   ES.runSessionLocked([&]() {
   1149     auto I = MRTrackers.find(&MR);
   1150     assert(I != MRTrackers.end() && "MaterializationResponsibility not linked");
   1151     MRTrackers.erase(I);
   1152   });
   1153 }
   1154 
   1155 std::pair<JITDylib::AsynchronousSymbolQuerySet,
   1156           std::shared_ptr<SymbolDependenceMap>>
   1157 JITDylib::failSymbols(FailedSymbolsWorklist Worklist) {
   1158   AsynchronousSymbolQuerySet FailedQueries;
   1159   auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
   1160 
   1161   while (!Worklist.empty()) {
   1162     assert(Worklist.back().first && "Failed JITDylib can not be null");
   1163     auto &JD = *Worklist.back().first;
   1164     auto Name = std::move(Worklist.back().second);
   1165     Worklist.pop_back();
   1166 
   1167     (*FailedSymbolsMap)[&JD].insert(Name);
   1168 
   1169     assert(JD.Symbols.count(Name) && "No symbol table entry for Name");
   1170     auto &Sym = JD.Symbols[Name];
   1171 
   1172     // Move the symbol into the error state.
   1173     // Note that this may be redundant: The symbol might already have been
   1174     // moved to this state in response to the failure of a dependence.
   1175     Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
   1176 
   1177     // FIXME: Come up with a sane mapping of state to
   1178     // presence-of-MaterializingInfo so that we can assert presence / absence
   1179     // here, rather than testing it.
   1180     auto MII = JD.MaterializingInfos.find(Name);
   1181 
   1182     if (MII == JD.MaterializingInfos.end())
   1183       continue;
   1184 
   1185     auto &MI = MII->second;
   1186 
   1187     // Move all dependants to the error state and disconnect from them.
   1188     for (auto &KV : MI.Dependants) {
   1189       auto &DependantJD = *KV.first;
   1190       for (auto &DependantName : KV.second) {
   1191         assert(DependantJD.Symbols.count(DependantName) &&
   1192                "No symbol table entry for DependantName");
   1193         auto &DependantSym = DependantJD.Symbols[DependantName];
   1194         DependantSym.setFlags(DependantSym.getFlags() |
   1195                               JITSymbolFlags::HasError);
   1196 
   1197         assert(DependantJD.MaterializingInfos.count(DependantName) &&
   1198                "No MaterializingInfo for dependant");
   1199         auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
   1200 
   1201         auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
   1202         assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
   1203                "No UnemittedDependencies entry for this JITDylib");
   1204         assert(UnemittedDepI->second.count(Name) &&
   1205                "No UnemittedDependencies entry for this symbol");
   1206         UnemittedDepI->second.erase(Name);
   1207         if (UnemittedDepI->second.empty())
   1208           DependantMI.UnemittedDependencies.erase(UnemittedDepI);
   1209 
   1210         // If this symbol is already in the emitted state then we need to
   1211         // take responsibility for failing its queries, so add it to the
   1212         // worklist.
   1213         if (DependantSym.getState() == SymbolState::Emitted) {
   1214           assert(DependantMI.Dependants.empty() &&
   1215                  "Emitted symbol should not have dependants");
   1216           Worklist.push_back(std::make_pair(&DependantJD, DependantName));
   1217         }
   1218       }
   1219     }
   1220     MI.Dependants.clear();
   1221 
   1222     // Disconnect from all unemitted depenencies.
   1223     for (auto &KV : MI.UnemittedDependencies) {
   1224       auto &UnemittedDepJD = *KV.first;
   1225       for (auto &UnemittedDepName : KV.second) {
   1226         auto UnemittedDepMII =
   1227             UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
   1228         assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
   1229                "Missing MII for unemitted dependency");
   1230         assert(UnemittedDepMII->second.Dependants.count(&JD) &&
   1231                "JD not listed as a dependant of unemitted dependency");
   1232         assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
   1233                "Name is not listed as a dependant of unemitted dependency");
   1234         UnemittedDepMII->second.Dependants[&JD].erase(Name);
   1235         if (UnemittedDepMII->second.Dependants[&JD].empty())
   1236           UnemittedDepMII->second.Dependants.erase(&JD);
   1237       }
   1238     }
   1239     MI.UnemittedDependencies.clear();
   1240 
   1241     // Collect queries to be failed for this MII.
   1242     AsynchronousSymbolQueryList ToDetach;
   1243     for (auto &Q : MII->second.pendingQueries()) {
   1244       // Add the query to the list to be failed and detach it.
   1245       FailedQueries.insert(Q);
   1246       ToDetach.push_back(Q);
   1247     }
   1248     for (auto &Q : ToDetach)
   1249       Q->detach();
   1250 
   1251     assert(MI.Dependants.empty() &&
   1252            "Can not delete MaterializingInfo with dependants still attached");
   1253     assert(MI.UnemittedDependencies.empty() &&
   1254            "Can not delete MaterializingInfo with unemitted dependencies "
   1255            "still attached");
   1256     assert(!MI.hasQueriesPending() &&
   1257            "Can not delete MaterializingInfo with queries pending");
   1258     JD.MaterializingInfos.erase(MII);
   1259   }
   1260 
   1261   return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap));
   1262 }
   1263 
   1264 void JITDylib::setLinkOrder(JITDylibSearchOrder NewLinkOrder,
   1265                             bool LinkAgainstThisJITDylibFirst) {
   1266   ES.runSessionLocked([&]() {
   1267     if (LinkAgainstThisJITDylibFirst) {
   1268       LinkOrder.clear();
   1269       if (NewLinkOrder.empty() || NewLinkOrder.front().first != this)
   1270         LinkOrder.push_back(
   1271             std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
   1272       llvm::append_range(LinkOrder, NewLinkOrder);
   1273     } else
   1274       LinkOrder = std::move(NewLinkOrder);
   1275   });
   1276 }
   1277 
   1278 void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) {
   1279   ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });
   1280 }
   1281 
   1282 void JITDylib::replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
   1283                                   JITDylibLookupFlags JDLookupFlags) {
   1284   ES.runSessionLocked([&]() {
   1285     for (auto &KV : LinkOrder)
   1286       if (KV.first == &OldJD) {
   1287         KV = {&NewJD, JDLookupFlags};
   1288         break;
   1289       }
   1290   });
   1291 }
   1292 
   1293 void JITDylib::removeFromLinkOrder(JITDylib &JD) {
   1294   ES.runSessionLocked([&]() {
   1295     auto I = llvm::find_if(LinkOrder,
   1296                            [&](const JITDylibSearchOrder::value_type &KV) {
   1297                              return KV.first == &JD;
   1298                            });
   1299     if (I != LinkOrder.end())
   1300       LinkOrder.erase(I);
   1301   });
   1302 }
   1303 
   1304 Error JITDylib::remove(const SymbolNameSet &Names) {
   1305   return ES.runSessionLocked([&]() -> Error {
   1306     using SymbolMaterializerItrPair =
   1307         std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
   1308     std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
   1309     SymbolNameSet Missing;
   1310     SymbolNameSet Materializing;
   1311 
   1312     for (auto &Name : Names) {
   1313       auto I = Symbols.find(Name);
   1314 
   1315       // Note symbol missing.
   1316       if (I == Symbols.end()) {
   1317         Missing.insert(Name);
   1318         continue;
   1319       }
   1320 
   1321       // Note symbol materializing.
   1322       if (I->second.getState() != SymbolState::NeverSearched &&
   1323           I->second.getState() != SymbolState::Ready) {
   1324         Materializing.insert(Name);
   1325         continue;
   1326       }
   1327 
   1328       auto UMII = I->second.hasMaterializerAttached()
   1329                       ? UnmaterializedInfos.find(Name)
   1330                       : UnmaterializedInfos.end();
   1331       SymbolsToRemove.push_back(std::make_pair(I, UMII));
   1332     }
   1333 
   1334     // If any of the symbols are not defined, return an error.
   1335     if (!Missing.empty())
   1336       return make_error<SymbolsNotFound>(std::move(Missing));
   1337 
   1338     // If any of the symbols are currently materializing, return an error.
   1339     if (!Materializing.empty())
   1340       return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
   1341 
   1342     // Remove the symbols.
   1343     for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
   1344       auto UMII = SymbolMaterializerItrPair.second;
   1345 
   1346       // If there is a materializer attached, call discard.
   1347       if (UMII != UnmaterializedInfos.end()) {
   1348         UMII->second->MU->doDiscard(*this, UMII->first);
   1349         UnmaterializedInfos.erase(UMII);
   1350       }
   1351 
   1352       auto SymI = SymbolMaterializerItrPair.first;
   1353       Symbols.erase(SymI);
   1354     }
   1355 
   1356     return Error::success();
   1357   });
   1358 }
   1359 
   1360 void JITDylib::dump(raw_ostream &OS) {
   1361   ES.runSessionLocked([&, this]() {
   1362     OS << "JITDylib \"" << JITDylibName << "\" (ES: "
   1363        << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
   1364        << "Link order: " << LinkOrder << "\n"
   1365        << "Symbol table:\n";
   1366 
   1367     for (auto &KV : Symbols) {
   1368       OS << "    \"" << *KV.first << "\": ";
   1369       if (auto Addr = KV.second.getAddress())
   1370         OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
   1371            << " ";
   1372       else
   1373         OS << "<not resolved> ";
   1374 
   1375       OS << KV.second.getFlags() << " " << KV.second.getState();
   1376 
   1377       if (KV.second.hasMaterializerAttached()) {
   1378         OS << " (Materializer ";
   1379         auto I = UnmaterializedInfos.find(KV.first);
   1380         assert(I != UnmaterializedInfos.end() &&
   1381                "Lazy symbol should have UnmaterializedInfo");
   1382         OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";
   1383       } else
   1384         OS << "\n";
   1385     }
   1386 
   1387     if (!MaterializingInfos.empty())
   1388       OS << "  MaterializingInfos entries:\n";
   1389     for (auto &KV : MaterializingInfos) {
   1390       OS << "    \"" << *KV.first << "\":\n"
   1391          << "      " << KV.second.pendingQueries().size()
   1392          << " pending queries: { ";
   1393       for (const auto &Q : KV.second.pendingQueries())
   1394         OS << Q.get() << " (" << Q->getRequiredState() << ") ";
   1395       OS << "}\n      Dependants:\n";
   1396       for (auto &KV2 : KV.second.Dependants)
   1397         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
   1398       OS << "      Unemitted Dependencies:\n";
   1399       for (auto &KV2 : KV.second.UnemittedDependencies)
   1400         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
   1401       assert((Symbols[KV.first].getState() != SymbolState::Ready ||
   1402               !KV.second.pendingQueries().empty() ||
   1403               !KV.second.Dependants.empty() ||
   1404               !KV.second.UnemittedDependencies.empty()) &&
   1405              "Stale materializing info entry");
   1406     }
   1407   });
   1408 }
   1409 
   1410 void JITDylib::MaterializingInfo::addQuery(
   1411     std::shared_ptr<AsynchronousSymbolQuery> Q) {
   1412 
   1413   auto I = std::lower_bound(
   1414       PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
   1415       [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
   1416         return V->getRequiredState() <= S;
   1417       });
   1418   PendingQueries.insert(I.base(), std::move(Q));
   1419 }
   1420 
   1421 void JITDylib::MaterializingInfo::removeQuery(
   1422     const AsynchronousSymbolQuery &Q) {
   1423   // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
   1424   auto I = llvm::find_if(
   1425       PendingQueries, [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
   1426         return V.get() == &Q;
   1427       });
   1428   assert(I != PendingQueries.end() &&
   1429          "Query is not attached to this MaterializingInfo");
   1430   PendingQueries.erase(I);
   1431 }
   1432 
   1433 JITDylib::AsynchronousSymbolQueryList
   1434 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
   1435   AsynchronousSymbolQueryList Result;
   1436   while (!PendingQueries.empty()) {
   1437     if (PendingQueries.back()->getRequiredState() > RequiredState)
   1438       break;
   1439 
   1440     Result.push_back(std::move(PendingQueries.back()));
   1441     PendingQueries.pop_back();
   1442   }
   1443 
   1444   return Result;
   1445 }
   1446 
   1447 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
   1448     : ES(ES), JITDylibName(std::move(Name)) {
   1449   LinkOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
   1450 }
   1451 
   1452 ResourceTrackerSP JITDylib::getTracker(MaterializationResponsibility &MR) {
   1453   auto I = MRTrackers.find(&MR);
   1454   assert(I != MRTrackers.end() && "MR is not linked");
   1455   assert(I->second && "Linked tracker is null");
   1456   return I->second;
   1457 }
   1458 
   1459 std::pair<JITDylib::AsynchronousSymbolQuerySet,
   1460           std::shared_ptr<SymbolDependenceMap>>
   1461 JITDylib::removeTracker(ResourceTracker &RT) {
   1462   // Note: Should be called under the session lock.
   1463 
   1464   SymbolNameVector SymbolsToRemove;
   1465   std::vector<std::pair<JITDylib *, SymbolStringPtr>> SymbolsToFail;
   1466 
   1467   if (&RT == DefaultTracker.get()) {
   1468     SymbolNameSet TrackedSymbols;
   1469     for (auto &KV : TrackerSymbols)
   1470       for (auto &Sym : KV.second)
   1471         TrackedSymbols.insert(Sym);
   1472 
   1473     for (auto &KV : Symbols) {
   1474       auto &Sym = KV.first;
   1475       if (!TrackedSymbols.count(Sym))
   1476         SymbolsToRemove.push_back(Sym);
   1477     }
   1478 
   1479     DefaultTracker.reset();
   1480   } else {
   1481     /// Check for a non-default tracker.
   1482     auto I = TrackerSymbols.find(&RT);
   1483     if (I != TrackerSymbols.end()) {
   1484       SymbolsToRemove = std::move(I->second);
   1485       TrackerSymbols.erase(I);
   1486     }
   1487     // ... if not found this tracker was already defunct. Nothing to do.
   1488   }
   1489 
   1490   for (auto &Sym : SymbolsToRemove) {
   1491     assert(Symbols.count(Sym) && "Symbol not in symbol table");
   1492 
   1493     // If there is a MaterializingInfo then collect any queries to fail.
   1494     auto MII = MaterializingInfos.find(Sym);
   1495     if (MII != MaterializingInfos.end())
   1496       SymbolsToFail.push_back({this, Sym});
   1497   }
   1498 
   1499   AsynchronousSymbolQuerySet QueriesToFail;
   1500   auto Result = failSymbols(std::move(SymbolsToFail));
   1501 
   1502   // Removed symbols should be taken out of the table altogether.
   1503   for (auto &Sym : SymbolsToRemove) {
   1504     auto I = Symbols.find(Sym);
   1505     assert(I != Symbols.end() && "Symbol not present in table");
   1506 
   1507     // Remove Materializer if present.
   1508     if (I->second.hasMaterializerAttached()) {
   1509       // FIXME: Should this discard the symbols?
   1510       UnmaterializedInfos.erase(Sym);
   1511     } else {
   1512       assert(!UnmaterializedInfos.count(Sym) &&
   1513              "Symbol has materializer attached");
   1514     }
   1515 
   1516     Symbols.erase(I);
   1517   }
   1518 
   1519   return Result;
   1520 }
   1521 
   1522 void JITDylib::transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT) {
   1523   assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker");
   1524   assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib");
   1525   assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib");
   1526 
   1527   // Update trackers for any not-yet materialized units.
   1528   for (auto &KV : UnmaterializedInfos) {
   1529     if (KV.second->RT == &SrcRT)
   1530       KV.second->RT = &DstRT;
   1531   }
   1532 
   1533   // Update trackers for any active materialization responsibilities.
   1534   for (auto &KV : MRTrackers) {
   1535     if (KV.second == &SrcRT)
   1536       KV.second = &DstRT;
   1537   }
   1538 
   1539   // If we're transfering to the default tracker we just need to delete the
   1540   // tracked symbols for the source tracker.
   1541   if (&DstRT == DefaultTracker.get()) {
   1542     TrackerSymbols.erase(&SrcRT);
   1543     return;
   1544   }
   1545 
   1546   // If we're transferring from the default tracker we need to find all
   1547   // currently untracked symbols.
   1548   if (&SrcRT == DefaultTracker.get()) {
   1549     assert(!TrackerSymbols.count(&SrcRT) &&
   1550            "Default tracker should not appear in TrackerSymbols");
   1551 
   1552     SymbolNameVector SymbolsToTrack;
   1553 
   1554     SymbolNameSet CurrentlyTrackedSymbols;
   1555     for (auto &KV : TrackerSymbols)
   1556       for (auto &Sym : KV.second)
   1557         CurrentlyTrackedSymbols.insert(Sym);
   1558 
   1559     for (auto &KV : Symbols) {
   1560       auto &Sym = KV.first;
   1561       if (!CurrentlyTrackedSymbols.count(Sym))
   1562         SymbolsToTrack.push_back(Sym);
   1563     }
   1564 
   1565     TrackerSymbols[&DstRT] = std::move(SymbolsToTrack);
   1566     return;
   1567   }
   1568 
   1569   auto &DstTrackedSymbols = TrackerSymbols[&DstRT];
   1570 
   1571   // Finally if neither SrtRT or DstRT are the default tracker then
   1572   // just append DstRT's tracked symbols to SrtRT's.
   1573   auto SI = TrackerSymbols.find(&SrcRT);
   1574   if (SI == TrackerSymbols.end())
   1575     return;
   1576 
   1577   DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size());
   1578   for (auto &Sym : SI->second)
   1579     DstTrackedSymbols.push_back(std::move(Sym));
   1580   TrackerSymbols.erase(SI);
   1581 }
   1582 
   1583 Error JITDylib::defineImpl(MaterializationUnit &MU) {
   1584 
   1585   LLVM_DEBUG({ dbgs() << "  " << MU.getSymbols() << "\n"; });
   1586 
   1587   SymbolNameSet Duplicates;
   1588   std::vector<SymbolStringPtr> ExistingDefsOverridden;
   1589   std::vector<SymbolStringPtr> MUDefsOverridden;
   1590 
   1591   for (const auto &KV : MU.getSymbols()) {
   1592     auto I = Symbols.find(KV.first);
   1593 
   1594     if (I != Symbols.end()) {
   1595       if (KV.second.isStrong()) {
   1596         if (I->second.getFlags().isStrong() ||
   1597             I->second.getState() > SymbolState::NeverSearched)
   1598           Duplicates.insert(KV.first);
   1599         else {
   1600           assert(I->second.getState() == SymbolState::NeverSearched &&
   1601                  "Overridden existing def should be in the never-searched "
   1602                  "state");
   1603           ExistingDefsOverridden.push_back(KV.first);
   1604         }
   1605       } else
   1606         MUDefsOverridden.push_back(KV.first);
   1607     }
   1608   }
   1609 
   1610   // If there were any duplicate definitions then bail out.
   1611   if (!Duplicates.empty()) {
   1612     LLVM_DEBUG(
   1613         { dbgs() << "  Error: Duplicate symbols " << Duplicates << "\n"; });
   1614     return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
   1615   }
   1616 
   1617   // Discard any overridden defs in this MU.
   1618   LLVM_DEBUG({
   1619     if (!MUDefsOverridden.empty())
   1620       dbgs() << "  Defs in this MU overridden: " << MUDefsOverridden << "\n";
   1621   });
   1622   for (auto &S : MUDefsOverridden)
   1623     MU.doDiscard(*this, S);
   1624 
   1625   // Discard existing overridden defs.
   1626   LLVM_DEBUG({
   1627     if (!ExistingDefsOverridden.empty())
   1628       dbgs() << "  Existing defs overridden by this MU: " << MUDefsOverridden
   1629              << "\n";
   1630   });
   1631   for (auto &S : ExistingDefsOverridden) {
   1632 
   1633     auto UMII = UnmaterializedInfos.find(S);
   1634     assert(UMII != UnmaterializedInfos.end() &&
   1635            "Overridden existing def should have an UnmaterializedInfo");
   1636     UMII->second->MU->doDiscard(*this, S);
   1637   }
   1638 
   1639   // Finally, add the defs from this MU.
   1640   for (auto &KV : MU.getSymbols()) {
   1641     auto &SymEntry = Symbols[KV.first];
   1642     SymEntry.setFlags(KV.second);
   1643     SymEntry.setState(SymbolState::NeverSearched);
   1644     SymEntry.setMaterializerAttached(true);
   1645   }
   1646 
   1647   return Error::success();
   1648 }
   1649 
   1650 void JITDylib::installMaterializationUnit(
   1651     std::unique_ptr<MaterializationUnit> MU, ResourceTracker &RT) {
   1652 
   1653   /// defineImpl succeeded.
   1654   if (&RT != DefaultTracker.get()) {
   1655     auto &TS = TrackerSymbols[&RT];
   1656     TS.reserve(TS.size() + MU->getSymbols().size());
   1657     for (auto &KV : MU->getSymbols())
   1658       TS.push_back(KV.first);
   1659   }
   1660 
   1661   auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU), &RT);
   1662   for (auto &KV : UMI->MU->getSymbols())
   1663     UnmaterializedInfos[KV.first] = UMI;
   1664 }
   1665 
   1666 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
   1667                                  const SymbolNameSet &QuerySymbols) {
   1668   for (auto &QuerySymbol : QuerySymbols) {
   1669     assert(MaterializingInfos.count(QuerySymbol) &&
   1670            "QuerySymbol does not have MaterializingInfo");
   1671     auto &MI = MaterializingInfos[QuerySymbol];
   1672     MI.removeQuery(Q);
   1673   }
   1674 }
   1675 
   1676 void JITDylib::transferEmittedNodeDependencies(
   1677     MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
   1678     MaterializingInfo &EmittedMI) {
   1679   for (auto &KV : EmittedMI.UnemittedDependencies) {
   1680     auto &DependencyJD = *KV.first;
   1681     SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
   1682 
   1683     for (auto &DependencyName : KV.second) {
   1684       auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
   1685 
   1686       // Do not add self dependencies.
   1687       if (&DependencyMI == &DependantMI)
   1688         continue;
   1689 
   1690       // If we haven't looked up the dependencies for DependencyJD yet, do it
   1691       // now and cache the result.
   1692       if (!UnemittedDependenciesOnDependencyJD)
   1693         UnemittedDependenciesOnDependencyJD =
   1694             &DependantMI.UnemittedDependencies[&DependencyJD];
   1695 
   1696       DependencyMI.Dependants[this].insert(DependantName);
   1697       UnemittedDependenciesOnDependencyJD->insert(DependencyName);
   1698     }
   1699   }
   1700 }
   1701 
   1702 Platform::~Platform() {}
   1703 
   1704 Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
   1705     ExecutionSession &ES,
   1706     const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
   1707 
   1708   DenseMap<JITDylib *, SymbolMap> CompoundResult;
   1709   Error CompoundErr = Error::success();
   1710   std::mutex LookupMutex;
   1711   std::condition_variable CV;
   1712   uint64_t Count = InitSyms.size();
   1713 
   1714   LLVM_DEBUG({
   1715     dbgs() << "Issuing init-symbol lookup:\n";
   1716     for (auto &KV : InitSyms)
   1717       dbgs() << "  " << KV.first->getName() << ": " << KV.second << "\n";
   1718   });
   1719 
   1720   for (auto &KV : InitSyms) {
   1721     auto *JD = KV.first;
   1722     auto Names = std::move(KV.second);
   1723     ES.lookup(
   1724         LookupKind::Static,
   1725         JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),
   1726         std::move(Names), SymbolState::Ready,
   1727         [&, JD](Expected<SymbolMap> Result) {
   1728           {
   1729             std::lock_guard<std::mutex> Lock(LookupMutex);
   1730             --Count;
   1731             if (Result) {
   1732               assert(!CompoundResult.count(JD) &&
   1733                      "Duplicate JITDylib in lookup?");
   1734               CompoundResult[JD] = std::move(*Result);
   1735             } else
   1736               CompoundErr =
   1737                   joinErrors(std::move(CompoundErr), Result.takeError());
   1738           }
   1739           CV.notify_one();
   1740         },
   1741         NoDependenciesToRegister);
   1742   }
   1743 
   1744   std::unique_lock<std::mutex> Lock(LookupMutex);
   1745   CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
   1746 
   1747   if (CompoundErr)
   1748     return std::move(CompoundErr);
   1749 
   1750   return std::move(CompoundResult);
   1751 }
   1752 
   1753 void Task::anchor() {}
   1754 
   1755 void MaterializationTask::printDescription(raw_ostream &OS) {
   1756   OS << "Materialization task: " << MU->getName() << " in "
   1757      << MR->getTargetJITDylib().getName();
   1758 }
   1759 
   1760 void MaterializationTask::run() { MU->materialize(std::move(MR)); }
   1761 
   1762 ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)
   1763     : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {}
   1764 
   1765 Error ExecutionSession::endSession() {
   1766   LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
   1767 
   1768   std::vector<JITDylibSP> JITDylibsToClose = runSessionLocked([&] {
   1769     SessionOpen = false;
   1770     return std::move(JDs);
   1771   });
   1772 
   1773   // TODO: notifiy platform? run static deinits?
   1774 
   1775   Error Err = Error::success();
   1776   for (auto &JD : JITDylibsToClose)
   1777     Err = joinErrors(std::move(Err), JD->clear());
   1778   return Err;
   1779 }
   1780 
   1781 void ExecutionSession::registerResourceManager(ResourceManager &RM) {
   1782   runSessionLocked([&] { ResourceManagers.push_back(&RM); });
   1783 }
   1784 
   1785 void ExecutionSession::deregisterResourceManager(ResourceManager &RM) {
   1786   runSessionLocked([&] {
   1787     assert(!ResourceManagers.empty() && "No managers registered");
   1788     if (ResourceManagers.back() == &RM)
   1789       ResourceManagers.pop_back();
   1790     else {
   1791       auto I = llvm::find(ResourceManagers, &RM);
   1792       assert(I != ResourceManagers.end() && "RM not registered");
   1793       ResourceManagers.erase(I);
   1794     }
   1795   });
   1796 }
   1797 
   1798 JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {
   1799   return runSessionLocked([&, this]() -> JITDylib * {
   1800     for (auto &JD : JDs)
   1801       if (JD->getName() == Name)
   1802         return JD.get();
   1803     return nullptr;
   1804   });
   1805 }
   1806 
   1807 JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {
   1808   assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
   1809   return runSessionLocked([&, this]() -> JITDylib & {
   1810     JDs.push_back(new JITDylib(*this, std::move(Name)));
   1811     return *JDs.back();
   1812   });
   1813 }
   1814 
   1815 Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
   1816   auto &JD = createBareJITDylib(Name);
   1817   if (P)
   1818     if (auto Err = P->setupJITDylib(JD))
   1819       return std::move(Err);
   1820   return JD;
   1821 }
   1822 
   1823 std::vector<JITDylibSP> JITDylib::getDFSLinkOrder(ArrayRef<JITDylibSP> JDs) {
   1824   if (JDs.empty())
   1825     return {};
   1826 
   1827   auto &ES = JDs.front()->getExecutionSession();
   1828   return ES.runSessionLocked([&]() {
   1829     DenseSet<JITDylib *> Visited;
   1830     std::vector<JITDylibSP> Result;
   1831 
   1832     for (auto &JD : JDs) {
   1833 
   1834       if (Visited.count(JD.get()))
   1835         continue;
   1836 
   1837       SmallVector<JITDylibSP, 64> WorkStack;
   1838       WorkStack.push_back(JD);
   1839       Visited.insert(JD.get());
   1840 
   1841       while (!WorkStack.empty()) {
   1842         Result.push_back(std::move(WorkStack.back()));
   1843         WorkStack.pop_back();
   1844 
   1845         for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) {
   1846           auto &JD = *KV.first;
   1847           if (Visited.count(&JD))
   1848             continue;
   1849           Visited.insert(&JD);
   1850           WorkStack.push_back(&JD);
   1851         }
   1852       }
   1853     }
   1854     return Result;
   1855   });
   1856 }
   1857 
   1858 std::vector<JITDylibSP>
   1859 JITDylib::getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs) {
   1860   auto Tmp = getDFSLinkOrder(JDs);
   1861   std::reverse(Tmp.begin(), Tmp.end());
   1862   return Tmp;
   1863 }
   1864 
   1865 std::vector<JITDylibSP> JITDylib::getDFSLinkOrder() {
   1866   return getDFSLinkOrder({this});
   1867 }
   1868 
   1869 std::vector<JITDylibSP> JITDylib::getReverseDFSLinkOrder() {
   1870   return getReverseDFSLinkOrder({this});
   1871 }
   1872 
   1873 void ExecutionSession::lookupFlags(
   1874     LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
   1875     unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
   1876 
   1877   OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
   1878                           K, std::move(SearchOrder), std::move(LookupSet),
   1879                           std::move(OnComplete)),
   1880                       Error::success());
   1881 }
   1882 
   1883 Expected<SymbolFlagsMap>
   1884 ExecutionSession::lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
   1885                               SymbolLookupSet LookupSet) {
   1886 
   1887   std::promise<MSVCPExpected<SymbolFlagsMap>> ResultP;
   1888   OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
   1889                           K, std::move(SearchOrder), std::move(LookupSet),
   1890                           [&ResultP](Expected<SymbolFlagsMap> Result) {
   1891                             ResultP.set_value(std::move(Result));
   1892                           }),
   1893                       Error::success());
   1894 
   1895   auto ResultF = ResultP.get_future();
   1896   return ResultF.get();
   1897 }
   1898 
   1899 void ExecutionSession::lookup(
   1900     LookupKind K, const JITDylibSearchOrder &SearchOrder,
   1901     SymbolLookupSet Symbols, SymbolState RequiredState,
   1902     SymbolsResolvedCallback NotifyComplete,
   1903     RegisterDependenciesFunction RegisterDependencies) {
   1904 
   1905   LLVM_DEBUG({
   1906     runSessionLocked([&]() {
   1907       dbgs() << "Looking up " << Symbols << " in " << SearchOrder
   1908              << " (required state: " << RequiredState << ")\n";
   1909     });
   1910   });
   1911 
   1912   // lookup can be re-entered recursively if running on a single thread. Run any
   1913   // outstanding MUs in case this query depends on them, otherwise this lookup
   1914   // will starve waiting for a result from an MU that is stuck in the queue.
   1915   dispatchOutstandingMUs();
   1916 
   1917   auto Unresolved = std::move(Symbols);
   1918   auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
   1919                                                      std::move(NotifyComplete));
   1920 
   1921   auto IPLS = std::make_unique<InProgressFullLookupState>(
   1922       K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q),
   1923       std::move(RegisterDependencies));
   1924 
   1925   OL_applyQueryPhase1(std::move(IPLS), Error::success());
   1926 }
   1927 
   1928 Expected<SymbolMap>
   1929 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
   1930                          const SymbolLookupSet &Symbols, LookupKind K,
   1931                          SymbolState RequiredState,
   1932                          RegisterDependenciesFunction RegisterDependencies) {
   1933 #if LLVM_ENABLE_THREADS
   1934   // In the threaded case we use promises to return the results.
   1935   std::promise<SymbolMap> PromisedResult;
   1936   Error ResolutionError = Error::success();
   1937 
   1938   auto NotifyComplete = [&](Expected<SymbolMap> R) {
   1939     if (R)
   1940       PromisedResult.set_value(std::move(*R));
   1941     else {
   1942       ErrorAsOutParameter _(&ResolutionError);
   1943       ResolutionError = R.takeError();
   1944       PromisedResult.set_value(SymbolMap());
   1945     }
   1946   };
   1947 
   1948 #else
   1949   SymbolMap Result;
   1950   Error ResolutionError = Error::success();
   1951 
   1952   auto NotifyComplete = [&](Expected<SymbolMap> R) {
   1953     ErrorAsOutParameter _(&ResolutionError);
   1954     if (R)
   1955       Result = std::move(*R);
   1956     else
   1957       ResolutionError = R.takeError();
   1958   };
   1959 #endif
   1960 
   1961   // Perform the asynchronous lookup.
   1962   lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
   1963          RegisterDependencies);
   1964 
   1965 #if LLVM_ENABLE_THREADS
   1966   auto ResultFuture = PromisedResult.get_future();
   1967   auto Result = ResultFuture.get();
   1968 
   1969   if (ResolutionError)
   1970     return std::move(ResolutionError);
   1971 
   1972   return std::move(Result);
   1973 
   1974 #else
   1975   if (ResolutionError)
   1976     return std::move(ResolutionError);
   1977 
   1978   return Result;
   1979 #endif
   1980 }
   1981 
   1982 Expected<JITEvaluatedSymbol>
   1983 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
   1984                          SymbolStringPtr Name, SymbolState RequiredState) {
   1985   SymbolLookupSet Names({Name});
   1986 
   1987   if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
   1988                               RequiredState, NoDependenciesToRegister)) {
   1989     assert(ResultMap->size() == 1 && "Unexpected number of results");
   1990     assert(ResultMap->count(Name) && "Missing result for symbol");
   1991     return std::move(ResultMap->begin()->second);
   1992   } else
   1993     return ResultMap.takeError();
   1994 }
   1995 
   1996 Expected<JITEvaluatedSymbol>
   1997 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
   1998                          SymbolState RequiredState) {
   1999   return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
   2000 }
   2001 
   2002 Expected<JITEvaluatedSymbol>
   2003 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
   2004                          SymbolState RequiredState) {
   2005   return lookup(SearchOrder, intern(Name), RequiredState);
   2006 }
   2007 
   2008 void ExecutionSession::dump(raw_ostream &OS) {
   2009   runSessionLocked([this, &OS]() {
   2010     for (auto &JD : JDs)
   2011       JD->dump(OS);
   2012   });
   2013 }
   2014 
   2015 void ExecutionSession::dispatchOutstandingMUs() {
   2016   LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n");
   2017   while (1) {
   2018     Optional<std::pair<std::unique_ptr<MaterializationUnit>,
   2019                        std::unique_ptr<MaterializationResponsibility>>>
   2020         JMU;
   2021 
   2022     {
   2023       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
   2024       if (!OutstandingMUs.empty()) {
   2025         JMU.emplace(std::move(OutstandingMUs.back()));
   2026         OutstandingMUs.pop_back();
   2027       }
   2028     }
   2029 
   2030     if (!JMU)
   2031       break;
   2032 
   2033     assert(JMU->first && "No MU?");
   2034     LLVM_DEBUG(dbgs() << "  Dispatching \"" << JMU->first->getName() << "\"\n");
   2035     dispatchTask(std::make_unique<MaterializationTask>(std::move(JMU->first),
   2036                                                        std::move(JMU->second)));
   2037   }
   2038   LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n");
   2039 }
   2040 
   2041 Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) {
   2042   LLVM_DEBUG({
   2043     dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "
   2044            << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
   2045   });
   2046   std::vector<ResourceManager *> CurrentResourceManagers;
   2047 
   2048   JITDylib::AsynchronousSymbolQuerySet QueriesToFail;
   2049   std::shared_ptr<SymbolDependenceMap> FailedSymbols;
   2050 
   2051   runSessionLocked([&] {
   2052     CurrentResourceManagers = ResourceManagers;
   2053     RT.makeDefunct();
   2054     std::tie(QueriesToFail, FailedSymbols) = RT.getJITDylib().removeTracker(RT);
   2055   });
   2056 
   2057   Error Err = Error::success();
   2058 
   2059   for (auto *L : reverse(CurrentResourceManagers))
   2060     Err =
   2061         joinErrors(std::move(Err), L->handleRemoveResources(RT.getKeyUnsafe()));
   2062 
   2063   for (auto &Q : QueriesToFail)
   2064     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
   2065 
   2066   return Err;
   2067 }
   2068 
   2069 void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,
   2070                                                ResourceTracker &SrcRT) {
   2071   LLVM_DEBUG({
   2072     dbgs() << "In " << SrcRT.getJITDylib().getName()
   2073            << " transfering resources from tracker "
   2074            << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "
   2075            << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";
   2076   });
   2077 
   2078   // No-op transfers are allowed and do not invalidate the source.
   2079   if (&DstRT == &SrcRT)
   2080     return;
   2081 
   2082   assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&
   2083          "Can't transfer resources between JITDylibs");
   2084   runSessionLocked([&]() {
   2085     SrcRT.makeDefunct();
   2086     auto &JD = DstRT.getJITDylib();
   2087     JD.transferTracker(DstRT, SrcRT);
   2088     for (auto *L : reverse(ResourceManagers))
   2089       L->handleTransferResources(DstRT.getKeyUnsafe(), SrcRT.getKeyUnsafe());
   2090   });
   2091 }
   2092 
   2093 void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) {
   2094   runSessionLocked([&]() {
   2095     LLVM_DEBUG({
   2096       dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "
   2097              << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
   2098     });
   2099     if (!RT.isDefunct())
   2100       transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(),
   2101                               RT);
   2102   });
   2103 }
   2104 
   2105 Error ExecutionSession::IL_updateCandidatesFor(
   2106     JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
   2107     SymbolLookupSet &Candidates, SymbolLookupSet *NonCandidates) {
   2108   return Candidates.forEachWithRemoval(
   2109       [&](const SymbolStringPtr &Name,
   2110           SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
   2111         /// Search for the symbol. If not found then continue without
   2112         /// removal.
   2113         auto SymI = JD.Symbols.find(Name);
   2114         if (SymI == JD.Symbols.end())
   2115           return false;
   2116 
   2117         // If this is a non-exported symbol and we're matching exported
   2118         // symbols only then remove this symbol from the candidates list.
   2119         //
   2120         // If we're tracking non-candidates then add this to the non-candidate
   2121         // list.
   2122         if (!SymI->second.getFlags().isExported() &&
   2123             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) {
   2124           if (NonCandidates)
   2125             NonCandidates->add(Name, SymLookupFlags);
   2126           return true;
   2127         }
   2128 
   2129         // If we match against a materialization-side-effects only symbol
   2130         // then make sure it is weakly-referenced. Otherwise bail out with
   2131         // an error.
   2132         // FIXME: Use a "materialization-side-effects-only symbols must be
   2133         // weakly referenced" specific error here to reduce confusion.
   2134         if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
   2135             SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol)
   2136           return make_error<SymbolsNotFound>(SymbolNameVector({Name}));
   2137 
   2138         // If we matched against this symbol but it is in the error state
   2139         // then bail out and treat it as a failure to materialize.
   2140         if (SymI->second.getFlags().hasError()) {
   2141           auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
   2142           (*FailedSymbolsMap)[&JD] = {Name};
   2143           return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
   2144         }
   2145 
   2146         // Otherwise this is a match. Remove it from the candidate set.
   2147         return true;
   2148       });
   2149 }
   2150 
   2151 void ExecutionSession::OL_applyQueryPhase1(
   2152     std::unique_ptr<InProgressLookupState> IPLS, Error Err) {
   2153 
   2154   LLVM_DEBUG({
   2155     dbgs() << "Entering OL_applyQueryPhase1:\n"
   2156            << "  Lookup kind: " << IPLS->K << "\n"
   2157            << "  Search order: " << IPLS->SearchOrder
   2158            << ", Current index = " << IPLS->CurSearchOrderIndex
   2159            << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
   2160            << "  Lookup set: " << IPLS->LookupSet << "\n"
   2161            << "  Definition generator candidates: "
   2162            << IPLS->DefGeneratorCandidates << "\n"
   2163            << "  Definition generator non-candidates: "
   2164            << IPLS->DefGeneratorNonCandidates << "\n";
   2165   });
   2166 
   2167   // FIXME: We should attach the query as we go: This provides a result in a
   2168   // single pass in the common case where all symbols have already reached the
   2169   // required state. The query could be detached again in the 'fail' method on
   2170   // IPLS. Phase 2 would be reduced to collecting and dispatching the MUs.
   2171 
   2172   while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) {
   2173 
   2174     // If we've been handed an error or received one back from a generator then
   2175     // fail the query. We don't need to unlink: At this stage the query hasn't
   2176     // actually been lodged.
   2177     if (Err)
   2178       return IPLS->fail(std::move(Err));
   2179 
   2180     // Get the next JITDylib and lookup flags.
   2181     auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex];
   2182     auto &JD = *KV.first;
   2183     auto JDLookupFlags = KV.second;
   2184 
   2185     LLVM_DEBUG({
   2186       dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
   2187              << ") with lookup set " << IPLS->LookupSet << ":\n";
   2188     });
   2189 
   2190     // If we've just reached a new JITDylib then perform some setup.
   2191     if (IPLS->NewJITDylib) {
   2192 
   2193       // Acquire the generator lock for this JITDylib.
   2194       IPLS->GeneratorLock = std::unique_lock<std::mutex>(JD.GeneratorsMutex);
   2195 
   2196       // Add any non-candidates from the last JITDylib (if any) back on to the
   2197       // list of definition candidates for this JITDylib, reset definition
   2198       // non-candiates to the empty set.
   2199       SymbolLookupSet Tmp;
   2200       std::swap(IPLS->DefGeneratorNonCandidates, Tmp);
   2201       IPLS->DefGeneratorCandidates.append(std::move(Tmp));
   2202 
   2203       LLVM_DEBUG({
   2204         dbgs() << "  First time visiting " << JD.getName()
   2205                << ", resetting candidate sets and building generator stack\n";
   2206       });
   2207 
   2208       // Build the definition generator stack for this JITDylib.
   2209       for (auto &DG : reverse(JD.DefGenerators))
   2210         IPLS->CurDefGeneratorStack.push_back(DG);
   2211 
   2212       // Flag that we've done our initialization.
   2213       IPLS->NewJITDylib = false;
   2214     }
   2215 
   2216     // Remove any generation candidates that are already defined (and match) in
   2217     // this JITDylib.
   2218     runSessionLocked([&] {
   2219       // Update the list of candidates (and non-candidates) for definition
   2220       // generation.
   2221       LLVM_DEBUG(dbgs() << "  Updating candidate set...\n");
   2222       Err = IL_updateCandidatesFor(
   2223           JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
   2224           JD.DefGenerators.empty() ? nullptr
   2225                                    : &IPLS->DefGeneratorNonCandidates);
   2226       LLVM_DEBUG({
   2227         dbgs() << "    Remaining candidates = " << IPLS->DefGeneratorCandidates
   2228                << "\n";
   2229       });
   2230     });
   2231 
   2232     // If we encountered an error while filtering generation candidates then
   2233     // bail out.
   2234     if (Err)
   2235       return IPLS->fail(std::move(Err));
   2236 
   2237     /// Apply any definition generators on the stack.
   2238     LLVM_DEBUG({
   2239       if (IPLS->CurDefGeneratorStack.empty())
   2240         LLVM_DEBUG(dbgs() << "  No generators to run for this JITDylib.\n");
   2241       else if (IPLS->DefGeneratorCandidates.empty())
   2242         LLVM_DEBUG(dbgs() << "  No candidates to generate.\n");
   2243       else
   2244         dbgs() << "  Running " << IPLS->CurDefGeneratorStack.size()
   2245                << " remaining generators for "
   2246                << IPLS->DefGeneratorCandidates.size() << " candidates\n";
   2247     });
   2248     while (!IPLS->CurDefGeneratorStack.empty() &&
   2249            !IPLS->DefGeneratorCandidates.empty()) {
   2250       auto DG = IPLS->CurDefGeneratorStack.back().lock();
   2251       IPLS->CurDefGeneratorStack.pop_back();
   2252 
   2253       if (!DG)
   2254         return IPLS->fail(make_error<StringError>(
   2255             "DefinitionGenerator removed while lookup in progress",
   2256             inconvertibleErrorCode()));
   2257 
   2258       auto K = IPLS->K;
   2259       auto &LookupSet = IPLS->DefGeneratorCandidates;
   2260 
   2261       // Run the generator. If the generator takes ownership of QA then this
   2262       // will break the loop.
   2263       {
   2264         LLVM_DEBUG(dbgs() << "  Attempting to generate " << LookupSet << "\n");
   2265         LookupState LS(std::move(IPLS));
   2266         Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet);
   2267         IPLS = std::move(LS.IPLS);
   2268       }
   2269 
   2270       // If there was an error then fail the query.
   2271       if (Err) {
   2272         LLVM_DEBUG({
   2273           dbgs() << "  Error attempting to generate " << LookupSet << "\n";
   2274         });
   2275         assert(IPLS && "LS cannot be retained if error is returned");
   2276         return IPLS->fail(std::move(Err));
   2277       }
   2278 
   2279       // Otherwise if QA was captured then break the loop.
   2280       if (!IPLS) {
   2281         LLVM_DEBUG(
   2282             { dbgs() << "  LookupState captured. Exiting phase1 for now.\n"; });
   2283         return;
   2284       }
   2285 
   2286       // Otherwise if we're continuing around the loop then update candidates
   2287       // for the next round.
   2288       runSessionLocked([&] {
   2289         LLVM_DEBUG(dbgs() << "  Updating candidate set post-generation\n");
   2290         Err = IL_updateCandidatesFor(
   2291             JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
   2292             JD.DefGenerators.empty() ? nullptr
   2293                                      : &IPLS->DefGeneratorNonCandidates);
   2294       });
   2295 
   2296       // If updating candidates failed then fail the query.
   2297       if (Err) {
   2298         LLVM_DEBUG(dbgs() << "  Error encountered while updating candidates\n");
   2299         return IPLS->fail(std::move(Err));
   2300       }
   2301     }
   2302 
   2303     // If we get here then we've moved on to the next JITDylib.
   2304     LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n");
   2305     ++IPLS->CurSearchOrderIndex;
   2306     IPLS->NewJITDylib = true;
   2307   }
   2308 
   2309   // Remove any weakly referenced candidates that could not be found/generated.
   2310   IPLS->DefGeneratorCandidates.remove_if(
   2311       [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
   2312         return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
   2313       });
   2314 
   2315   // If we get here then we've finished searching all JITDylibs.
   2316   // If we matched all symbols then move to phase 2, otherwise fail the query
   2317   // with a SymbolsNotFound error.
   2318   if (IPLS->DefGeneratorCandidates.empty()) {
   2319     LLVM_DEBUG(dbgs() << "Phase 1 succeeded.\n");
   2320     IPLS->complete(std::move(IPLS));
   2321   } else {
   2322     LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n");
   2323     IPLS->fail(make_error<SymbolsNotFound>(
   2324         IPLS->DefGeneratorCandidates.getSymbolNames()));
   2325   }
   2326 }
   2327 
   2328 void ExecutionSession::OL_completeLookup(
   2329     std::unique_ptr<InProgressLookupState> IPLS,
   2330     std::shared_ptr<AsynchronousSymbolQuery> Q,
   2331     RegisterDependenciesFunction RegisterDependencies) {
   2332 
   2333   LLVM_DEBUG({
   2334     dbgs() << "Entering OL_completeLookup:\n"
   2335            << "  Lookup kind: " << IPLS->K << "\n"
   2336            << "  Search order: " << IPLS->SearchOrder
   2337            << ", Current index = " << IPLS->CurSearchOrderIndex
   2338            << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
   2339            << "  Lookup set: " << IPLS->LookupSet << "\n"
   2340            << "  Definition generator candidates: "
   2341            << IPLS->DefGeneratorCandidates << "\n"
   2342            << "  Definition generator non-candidates: "
   2343            << IPLS->DefGeneratorNonCandidates << "\n";
   2344   });
   2345 
   2346   bool QueryComplete = false;
   2347   DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs;
   2348 
   2349   auto LodgingErr = runSessionLocked([&]() -> Error {
   2350     for (auto &KV : IPLS->SearchOrder) {
   2351       auto &JD = *KV.first;
   2352       auto JDLookupFlags = KV.second;
   2353       LLVM_DEBUG({
   2354         dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
   2355                << ") with lookup set " << IPLS->LookupSet << ":\n";
   2356       });
   2357 
   2358       auto Err = IPLS->LookupSet.forEachWithRemoval(
   2359           [&](const SymbolStringPtr &Name,
   2360               SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
   2361             LLVM_DEBUG({
   2362               dbgs() << "  Attempting to match \"" << Name << "\" ("
   2363                      << SymLookupFlags << ")... ";
   2364             });
   2365 
   2366             /// Search for the symbol. If not found then continue without
   2367             /// removal.
   2368             auto SymI = JD.Symbols.find(Name);
   2369             if (SymI == JD.Symbols.end()) {
   2370               LLVM_DEBUG(dbgs() << "skipping: not present\n");
   2371               return false;
   2372             }
   2373 
   2374             // If this is a non-exported symbol and we're matching exported
   2375             // symbols only then skip this symbol without removal.
   2376             if (!SymI->second.getFlags().isExported() &&
   2377                 JDLookupFlags ==
   2378                     JITDylibLookupFlags::MatchExportedSymbolsOnly) {
   2379               LLVM_DEBUG(dbgs() << "skipping: not exported\n");
   2380               return false;
   2381             }
   2382 
   2383             // If we match against a materialization-side-effects only symbol
   2384             // then make sure it is weakly-referenced. Otherwise bail out with
   2385             // an error.
   2386             // FIXME: Use a "materialization-side-effects-only symbols must be
   2387             // weakly referenced" specific error here to reduce confusion.
   2388             if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
   2389                 SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol) {
   2390               LLVM_DEBUG({
   2391                 dbgs() << "error: "
   2392                           "required, but symbol is has-side-effects-only\n";
   2393               });
   2394               return make_error<SymbolsNotFound>(SymbolNameVector({Name}));
   2395             }
   2396 
   2397             // If we matched against this symbol but it is in the error state
   2398             // then bail out and treat it as a failure to materialize.
   2399             if (SymI->second.getFlags().hasError()) {
   2400               LLVM_DEBUG(dbgs() << "error: symbol is in error state\n");
   2401               auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
   2402               (*FailedSymbolsMap)[&JD] = {Name};
   2403               return make_error<FailedToMaterialize>(
   2404                   std::move(FailedSymbolsMap));
   2405             }
   2406 
   2407             // Otherwise this is a match.
   2408 
   2409             // If this symbol is already in the requried state then notify the
   2410             // query, remove the symbol and continue.
   2411             if (SymI->second.getState() >= Q->getRequiredState()) {
   2412               LLVM_DEBUG(dbgs()
   2413                          << "matched, symbol already in required state\n");
   2414               Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
   2415               return true;
   2416             }
   2417 
   2418             // Otherwise this symbol does not yet meet the required state. Check
   2419             // whether it has a materializer attached, and if so prepare to run
   2420             // it.
   2421             if (SymI->second.hasMaterializerAttached()) {
   2422               assert(SymI->second.getAddress() == 0 &&
   2423                      "Symbol not resolved but already has address?");
   2424               auto UMII = JD.UnmaterializedInfos.find(Name);
   2425               assert(UMII != JD.UnmaterializedInfos.end() &&
   2426                      "Lazy symbol should have UnmaterializedInfo");
   2427 
   2428               auto UMI = UMII->second;
   2429               assert(UMI->MU && "Materializer should not be null");
   2430               assert(UMI->RT && "Tracker should not be null");
   2431               LLVM_DEBUG({
   2432                 dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()
   2433                        << " (" << UMI->MU->getName() << ")\n";
   2434               });
   2435 
   2436               // Move all symbols associated with this MaterializationUnit into
   2437               // materializing state.
   2438               for (auto &KV : UMI->MU->getSymbols()) {
   2439                 auto SymK = JD.Symbols.find(KV.first);
   2440                 assert(SymK != JD.Symbols.end() &&
   2441                        "No entry for symbol covered by MaterializationUnit");
   2442                 SymK->second.setMaterializerAttached(false);
   2443                 SymK->second.setState(SymbolState::Materializing);
   2444                 JD.UnmaterializedInfos.erase(KV.first);
   2445               }
   2446 
   2447               // Add MU to the list of MaterializationUnits to be materialized.
   2448               CollectedUMIs[&JD].push_back(std::move(UMI));
   2449             } else
   2450               LLVM_DEBUG(dbgs() << "matched, registering query");
   2451 
   2452             // Add the query to the PendingQueries list and continue, deleting
   2453             // the element from the lookup set.
   2454             assert(SymI->second.getState() != SymbolState::NeverSearched &&
   2455                    SymI->second.getState() != SymbolState::Ready &&
   2456                    "By this line the symbol should be materializing");
   2457             auto &MI = JD.MaterializingInfos[Name];
   2458             MI.addQuery(Q);
   2459             Q->addQueryDependence(JD, Name);
   2460 
   2461             return true;
   2462           });
   2463 
   2464       // Handle failure.
   2465       if (Err) {
   2466 
   2467         LLVM_DEBUG({
   2468           dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";
   2469         });
   2470 
   2471         // Detach the query.
   2472         Q->detach();
   2473 
   2474         // Replace the MUs.
   2475         for (auto &KV : CollectedUMIs) {
   2476           auto &JD = *KV.first;
   2477           for (auto &UMI : KV.second)
   2478             for (auto &KV2 : UMI->MU->getSymbols()) {
   2479               assert(!JD.UnmaterializedInfos.count(KV2.first) &&
   2480                      "Unexpected materializer in map");
   2481               auto SymI = JD.Symbols.find(KV2.first);
   2482               assert(SymI != JD.Symbols.end() && "Missing symbol entry");
   2483               assert(SymI->second.getState() == SymbolState::Materializing &&
   2484                      "Can not replace symbol that is not materializing");
   2485               assert(!SymI->second.hasMaterializerAttached() &&
   2486                      "MaterializerAttached flag should not be set");
   2487               SymI->second.setMaterializerAttached(true);
   2488               JD.UnmaterializedInfos[KV2.first] = UMI;
   2489             }
   2490         }
   2491 
   2492         return Err;
   2493       }
   2494     }
   2495 
   2496     LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-refererced symbols\n");
   2497     IPLS->LookupSet.forEachWithRemoval(
   2498         [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
   2499           if (SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol) {
   2500             Q->dropSymbol(Name);
   2501             return true;
   2502           } else
   2503             return false;
   2504         });
   2505 
   2506     if (!IPLS->LookupSet.empty()) {
   2507       LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
   2508       return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames());
   2509     }
   2510 
   2511     // Record whether the query completed.
   2512     QueryComplete = Q->isComplete();
   2513 
   2514     LLVM_DEBUG({
   2515       dbgs() << "Query successfully "
   2516              << (QueryComplete ? "completed" : "lodged") << "\n";
   2517     });
   2518 
   2519     // Move the collected MUs to the OutstandingMUs list.
   2520     if (!CollectedUMIs.empty()) {
   2521       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
   2522 
   2523       LLVM_DEBUG(dbgs() << "Adding MUs to dispatch:\n");
   2524       for (auto &KV : CollectedUMIs) {
   2525         auto &JD = *KV.first;
   2526         LLVM_DEBUG({
   2527           dbgs() << "  For " << JD.getName() << ": Adding " << KV.second.size()
   2528                  << " MUs.\n";
   2529         });
   2530         for (auto &UMI : KV.second) {
   2531           std::unique_ptr<MaterializationResponsibility> MR(
   2532               new MaterializationResponsibility(
   2533                   &JD, std::move(UMI->MU->SymbolFlags),
   2534                   std::move(UMI->MU->InitSymbol)));
   2535           JD.MRTrackers[MR.get()] = UMI->RT;
   2536           OutstandingMUs.push_back(
   2537               std::make_pair(std::move(UMI->MU), std::move(MR)));
   2538         }
   2539       }
   2540     } else
   2541       LLVM_DEBUG(dbgs() << "No MUs to dispatch.\n");
   2542 
   2543     if (RegisterDependencies && !Q->QueryRegistrations.empty()) {
   2544       LLVM_DEBUG(dbgs() << "Registering dependencies\n");
   2545       RegisterDependencies(Q->QueryRegistrations);
   2546     } else
   2547       LLVM_DEBUG(dbgs() << "No dependencies to register\n");
   2548 
   2549     return Error::success();
   2550   });
   2551 
   2552   if (LodgingErr) {
   2553     LLVM_DEBUG(dbgs() << "Failing query\n");
   2554     Q->detach();
   2555     Q->handleFailed(std::move(LodgingErr));
   2556     return;
   2557   }
   2558 
   2559   if (QueryComplete) {
   2560     LLVM_DEBUG(dbgs() << "Completing query\n");
   2561     Q->handleComplete(*this);
   2562   }
   2563 
   2564   dispatchOutstandingMUs();
   2565 }
   2566 
   2567 void ExecutionSession::OL_completeLookupFlags(
   2568     std::unique_ptr<InProgressLookupState> IPLS,
   2569     unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
   2570 
   2571   auto Result = runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
   2572     LLVM_DEBUG({
   2573       dbgs() << "Entering OL_completeLookupFlags:\n"
   2574              << "  Lookup kind: " << IPLS->K << "\n"
   2575              << "  Search order: " << IPLS->SearchOrder
   2576              << ", Current index = " << IPLS->CurSearchOrderIndex
   2577              << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
   2578              << "  Lookup set: " << IPLS->LookupSet << "\n"
   2579              << "  Definition generator candidates: "
   2580              << IPLS->DefGeneratorCandidates << "\n"
   2581              << "  Definition generator non-candidates: "
   2582              << IPLS->DefGeneratorNonCandidates << "\n";
   2583     });
   2584 
   2585     SymbolFlagsMap Result;
   2586 
   2587     // Attempt to find flags for each symbol.
   2588     for (auto &KV : IPLS->SearchOrder) {
   2589       auto &JD = *KV.first;
   2590       auto JDLookupFlags = KV.second;
   2591       LLVM_DEBUG({
   2592         dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
   2593                << ") with lookup set " << IPLS->LookupSet << ":\n";
   2594       });
   2595 
   2596       IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name,
   2597                                              SymbolLookupFlags SymLookupFlags) {
   2598         LLVM_DEBUG({
   2599           dbgs() << "  Attempting to match \"" << Name << "\" ("
   2600                  << SymLookupFlags << ")... ";
   2601         });
   2602 
   2603         // Search for the symbol. If not found then continue without removing
   2604         // from the lookup set.
   2605         auto SymI = JD.Symbols.find(Name);
   2606         if (SymI == JD.Symbols.end()) {
   2607           LLVM_DEBUG(dbgs() << "skipping: not present\n");
   2608           return false;
   2609         }
   2610 
   2611         // If this is a non-exported symbol then it doesn't match. Skip it.
   2612         if (!SymI->second.getFlags().isExported() &&
   2613             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) {
   2614           LLVM_DEBUG(dbgs() << "skipping: not exported\n");
   2615           return false;
   2616         }
   2617 
   2618         LLVM_DEBUG({
   2619           dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()
   2620                  << "\n";
   2621         });
   2622         Result[Name] = SymI->second.getFlags();
   2623         return true;
   2624       });
   2625     }
   2626 
   2627     // Remove any weakly referenced symbols that haven't been resolved.
   2628     IPLS->LookupSet.remove_if(
   2629         [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
   2630           return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
   2631         });
   2632 
   2633     if (!IPLS->LookupSet.empty()) {
   2634       LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
   2635       return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames());
   2636     }
   2637 
   2638     LLVM_DEBUG(dbgs() << "Succeded, result = " << Result << "\n");
   2639     return Result;
   2640   });
   2641 
   2642   // Run the callback on the result.
   2643   LLVM_DEBUG(dbgs() << "Sending result to handler.\n");
   2644   OnComplete(std::move(Result));
   2645 }
   2646 
   2647 void ExecutionSession::OL_destroyMaterializationResponsibility(
   2648     MaterializationResponsibility &MR) {
   2649 
   2650   assert(MR.SymbolFlags.empty() &&
   2651          "All symbols should have been explicitly materialized or failed");
   2652   MR.JD->unlinkMaterializationResponsibility(MR);
   2653 }
   2654 
   2655 SymbolNameSet ExecutionSession::OL_getRequestedSymbols(
   2656     const MaterializationResponsibility &MR) {
   2657   return MR.JD->getRequestedSymbols(MR.SymbolFlags);
   2658 }
   2659 
   2660 Error ExecutionSession::OL_notifyResolved(MaterializationResponsibility &MR,
   2661                                           const SymbolMap &Symbols) {
   2662   LLVM_DEBUG({
   2663     dbgs() << "In " << MR.JD->getName() << " resolving " << Symbols << "\n";
   2664   });
   2665 #ifndef NDEBUG
   2666   for (auto &KV : Symbols) {
   2667     auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
   2668     auto I = MR.SymbolFlags.find(KV.first);
   2669     assert(I != MR.SymbolFlags.end() &&
   2670            "Resolving symbol outside this responsibility set");
   2671     assert(!I->second.hasMaterializationSideEffectsOnly() &&
   2672            "Can't resolve materialization-side-effects-only symbol");
   2673     assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&
   2674            "Resolving symbol with incorrect flags");
   2675   }
   2676 #endif
   2677 
   2678   return MR.JD->resolve(MR, Symbols);
   2679 }
   2680 
   2681 Error ExecutionSession::OL_notifyEmitted(MaterializationResponsibility &MR) {
   2682   LLVM_DEBUG({
   2683     dbgs() << "In " << MR.JD->getName() << " emitting " << MR.SymbolFlags << "\n";
   2684   });
   2685 
   2686   if (auto Err = MR.JD->emit(MR, MR.SymbolFlags))
   2687     return Err;
   2688 
   2689   MR.SymbolFlags.clear();
   2690   return Error::success();
   2691 }
   2692 
   2693 Error ExecutionSession::OL_defineMaterializing(
   2694     MaterializationResponsibility &MR, SymbolFlagsMap NewSymbolFlags) {
   2695 
   2696   LLVM_DEBUG({
   2697     dbgs() << "In " << MR.JD->getName() << " defining materializing symbols "
   2698            << NewSymbolFlags << "\n";
   2699   });
   2700   if (auto AcceptedDefs = MR.JD->defineMaterializing(std::move(NewSymbolFlags))) {
   2701     // Add all newly accepted symbols to this responsibility object.
   2702     for (auto &KV : *AcceptedDefs)
   2703       MR.SymbolFlags.insert(KV);
   2704     return Error::success();
   2705   } else
   2706     return AcceptedDefs.takeError();
   2707 }
   2708 
   2709 void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) {
   2710 
   2711   LLVM_DEBUG({
   2712     dbgs() << "In " << MR.JD->getName() << " failing materialization for "
   2713            << MR.SymbolFlags << "\n";
   2714   });
   2715 
   2716   JITDylib::FailedSymbolsWorklist Worklist;
   2717 
   2718   for (auto &KV : MR.SymbolFlags)
   2719     Worklist.push_back(std::make_pair(MR.JD.get(), KV.first));
   2720   MR.SymbolFlags.clear();
   2721 
   2722   if (Worklist.empty())
   2723     return;
   2724 
   2725   JITDylib::AsynchronousSymbolQuerySet FailedQueries;
   2726   std::shared_ptr<SymbolDependenceMap> FailedSymbols;
   2727 
   2728   runSessionLocked([&]() {
   2729     auto RTI = MR.JD->MRTrackers.find(&MR);
   2730     assert(RTI != MR.JD->MRTrackers.end() && "No tracker for this");
   2731     if (RTI->second->isDefunct())
   2732       return;
   2733 
   2734     std::tie(FailedQueries, FailedSymbols) =
   2735         JITDylib::failSymbols(std::move(Worklist));
   2736   });
   2737 
   2738   for (auto &Q : FailedQueries)
   2739     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
   2740 }
   2741 
   2742 Error ExecutionSession::OL_replace(MaterializationResponsibility &MR,
   2743                                    std::unique_ptr<MaterializationUnit> MU) {
   2744   for (auto &KV : MU->getSymbols()) {
   2745     assert(MR.SymbolFlags.count(KV.first) &&
   2746            "Replacing definition outside this responsibility set");
   2747     MR.SymbolFlags.erase(KV.first);
   2748   }
   2749 
   2750   if (MU->getInitializerSymbol() == MR.InitSymbol)
   2751     MR.InitSymbol = nullptr;
   2752 
   2753   LLVM_DEBUG(MR.JD->getExecutionSession().runSessionLocked([&]() {
   2754     dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU
   2755            << "\n";
   2756   }););
   2757 
   2758   return MR.JD->replace(MR, std::move(MU));
   2759 }
   2760 
   2761 Expected<std::unique_ptr<MaterializationResponsibility>>
   2762 ExecutionSession::OL_delegate(MaterializationResponsibility &MR,
   2763                               const SymbolNameSet &Symbols) {
   2764 
   2765   SymbolStringPtr DelegatedInitSymbol;
   2766   SymbolFlagsMap DelegatedFlags;
   2767 
   2768   for (auto &Name : Symbols) {
   2769     auto I = MR.SymbolFlags.find(Name);
   2770     assert(I != MR.SymbolFlags.end() &&
   2771            "Symbol is not tracked by this MaterializationResponsibility "
   2772            "instance");
   2773 
   2774     DelegatedFlags[Name] = std::move(I->second);
   2775     if (Name == MR.InitSymbol)
   2776       std::swap(MR.InitSymbol, DelegatedInitSymbol);
   2777 
   2778     MR.SymbolFlags.erase(I);
   2779   }
   2780 
   2781   return MR.JD->delegate(MR, std::move(DelegatedFlags),
   2782                          std::move(DelegatedInitSymbol));
   2783 }
   2784 
   2785 void ExecutionSession::OL_addDependencies(
   2786     MaterializationResponsibility &MR, const SymbolStringPtr &Name,
   2787     const SymbolDependenceMap &Dependencies) {
   2788   LLVM_DEBUG({
   2789     dbgs() << "Adding dependencies for " << Name << ": " << Dependencies
   2790            << "\n";
   2791   });
   2792   assert(MR.SymbolFlags.count(Name) &&
   2793          "Symbol not covered by this MaterializationResponsibility instance");
   2794   MR.JD->addDependencies(Name, Dependencies);
   2795 }
   2796 
   2797 void ExecutionSession::OL_addDependenciesForAll(
   2798     MaterializationResponsibility &MR,
   2799     const SymbolDependenceMap &Dependencies) {
   2800   LLVM_DEBUG({
   2801     dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": "
   2802            << Dependencies << "\n";
   2803   });
   2804   for (auto &KV : MR.SymbolFlags)
   2805     MR.JD->addDependencies(KV.first, Dependencies);
   2806 }
   2807 
   2808 #ifndef NDEBUG
   2809 void ExecutionSession::dumpDispatchInfo(Task &T) {
   2810   runSessionLocked([&]() {
   2811     dbgs() << "Dispatching: ";
   2812     T.printDescription(dbgs());
   2813   });
   2814 }
   2815 #endif // NDEBUG
   2816 
   2817 } // End namespace orc.
   2818 } // End namespace llvm.
   2819