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