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