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/OrcError.h"
14 #include "llvm/Support/CommandLine.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/Format.h"
17 
18 #include <condition_variable>
19 #if LLVM_ENABLE_THREADS
20 #include <future>
21 #endif
22 
23 #define DEBUG_TYPE "orc"
24 
25 using namespace llvm;
26 
27 namespace {
28 
29 #ifndef NDEBUG
30 
31 cl::opt<bool> PrintHidden("debug-orc-print-hidden", cl::init(true),
32                           cl::desc("debug print hidden symbols defined by "
33                                    "materialization units"),
34                           cl::Hidden);
35 
36 cl::opt<bool> PrintCallable("debug-orc-print-callable", cl::init(true),
37                             cl::desc("debug print callable symbols defined by "
38                                      "materialization units"),
39                             cl::Hidden);
40 
41 cl::opt<bool> PrintData("debug-orc-print-data", cl::init(true),
42                         cl::desc("debug print data symbols defined by "
43                                  "materialization units"),
44                         cl::Hidden);
45 
46 #endif // NDEBUG
47 
48 // SetPrinter predicate that prints every element.
49 template <typename T> struct PrintAll {
50   bool operator()(const T &E) { return true; }
51 };
52 
53 bool anyPrintSymbolOptionSet() {
54 #ifndef NDEBUG
55   return PrintHidden || PrintCallable || PrintData;
56 #else
57   return false;
58 #endif // NDEBUG
59 }
60 
61 bool flagsMatchCLOpts(const JITSymbolFlags &Flags) {
62 #ifndef NDEBUG
63   // Bail out early if this is a hidden symbol and we're not printing hiddens.
64   if (!PrintHidden && !Flags.isExported())
65     return false;
66 
67   // Return true if this is callable and we're printing callables.
68   if (PrintCallable && Flags.isCallable())
69     return true;
70 
71   // Return true if this is data and we're printing data.
72   if (PrintData && !Flags.isCallable())
73     return true;
74 
75   // otherwise return false.
76   return false;
77 #else
78   return false;
79 #endif // NDEBUG
80 }
81 
82 // Prints a sequence of items, filtered by an user-supplied predicate.
83 template <typename Sequence,
84           typename Pred = PrintAll<typename Sequence::value_type>>
85 class SequencePrinter {
86 public:
87   SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq,
88                   Pred ShouldPrint = Pred())
89       : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq),
90         ShouldPrint(std::move(ShouldPrint)) {}
91 
92   void printTo(llvm::raw_ostream &OS) const {
93     bool PrintComma = false;
94     OS << OpenSeq;
95     for (auto &E : S) {
96       if (ShouldPrint(E)) {
97         if (PrintComma)
98           OS << ',';
99         OS << ' ' << E;
100         PrintComma = true;
101       }
102     }
103     OS << ' ' << CloseSeq;
104   }
105 
106 private:
107   const Sequence &S;
108   char OpenSeq;
109   char CloseSeq;
110   mutable Pred ShouldPrint;
111 };
112 
113 template <typename Sequence, typename Pred>
114 SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq,
115                                               char CloseSeq, Pred P = Pred()) {
116   return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P));
117 }
118 
119 // Render a SequencePrinter by delegating to its printTo method.
120 template <typename Sequence, typename Pred>
121 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
122                               const SequencePrinter<Sequence, Pred> &Printer) {
123   Printer.printTo(OS);
124   return OS;
125 }
126 
127 struct PrintSymbolFlagsMapElemsMatchingCLOpts {
128   bool operator()(const orc::SymbolFlagsMap::value_type &KV) {
129     return flagsMatchCLOpts(KV.second);
130   }
131 };
132 
133 struct PrintSymbolMapElemsMatchingCLOpts {
134   bool operator()(const orc::SymbolMap::value_type &KV) {
135     return flagsMatchCLOpts(KV.second.getFlags());
136   }
137 };
138 
139 } // end anonymous namespace
140 
141 namespace llvm {
142 namespace orc {
143 
144 char FailedToMaterialize::ID = 0;
145 char SymbolsNotFound::ID = 0;
146 char SymbolsCouldNotBeRemoved::ID = 0;
147 char MissingSymbolDefinitions::ID = 0;
148 char UnexpectedSymbolDefinitions::ID = 0;
149 
150 RegisterDependenciesFunction NoDependenciesToRegister =
151     RegisterDependenciesFunction();
152 
153 void MaterializationUnit::anchor() {}
154 
155 raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) {
156   return OS << *Sym;
157 }
158 
159 raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) {
160   return OS << printSequence(Symbols, '{', '}', PrintAll<SymbolStringPtr>());
161 }
162 
163 raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols) {
164   return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>());
165 }
166 
167 raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
168   if (Flags.hasError())
169     OS << "[*ERROR*]";
170   if (Flags.isCallable())
171     OS << "[Callable]";
172   else
173     OS << "[Data]";
174   if (Flags.isWeak())
175     OS << "[Weak]";
176   else if (Flags.isCommon())
177     OS << "[Common]";
178 
179   if (!Flags.isExported())
180     OS << "[Hidden]";
181 
182   return OS;
183 }
184 
185 raw_ostream &operator<<(raw_ostream &OS, const JITEvaluatedSymbol &Sym) {
186   return OS << format("0x%016" PRIx64, Sym.getAddress()) << " "
187             << Sym.getFlags();
188 }
189 
190 raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV) {
191   return OS << "(\"" << KV.first << "\", " << KV.second << ")";
192 }
193 
194 raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) {
195   return OS << "(\"" << KV.first << "\": " << KV.second << ")";
196 }
197 
198 raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) {
199   return OS << printSequence(SymbolFlags, '{', '}',
200                              PrintSymbolFlagsMapElemsMatchingCLOpts());
201 }
202 
203 raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) {
204   return OS << printSequence(Symbols, '{', '}',
205                              PrintSymbolMapElemsMatchingCLOpts());
206 }
207 
208 raw_ostream &operator<<(raw_ostream &OS,
209                         const SymbolDependenceMap::value_type &KV) {
210   return OS << "(" << KV.first->getName() << ", " << KV.second << ")";
211 }
212 
213 raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
214   return OS << printSequence(Deps, '{', '}',
215                              PrintAll<SymbolDependenceMap::value_type>());
216 }
217 
218 raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
219   OS << "MU@" << &MU << " (\"" << MU.getName() << "\"";
220   if (anyPrintSymbolOptionSet())
221     OS << ", " << MU.getSymbols();
222   return OS << ")";
223 }
224 
225 raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K) {
226   switch (K) {
227   case LookupKind::Static:
228     return OS << "Static";
229   case LookupKind::DLSym:
230     return OS << "DLSym";
231   }
232   llvm_unreachable("Invalid lookup kind");
233 }
234 
235 raw_ostream &operator<<(raw_ostream &OS,
236                         const JITDylibLookupFlags &JDLookupFlags) {
237   switch (JDLookupFlags) {
238   case JITDylibLookupFlags::MatchExportedSymbolsOnly:
239     return OS << "MatchExportedSymbolsOnly";
240   case JITDylibLookupFlags::MatchAllSymbols:
241     return OS << "MatchAllSymbols";
242   }
243   llvm_unreachable("Invalid JITDylib lookup flags");
244 }
245 
246 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags) {
247   switch (LookupFlags) {
248   case SymbolLookupFlags::RequiredSymbol:
249     return OS << "RequiredSymbol";
250   case SymbolLookupFlags::WeaklyReferencedSymbol:
251     return OS << "WeaklyReferencedSymbol";
252   }
253   llvm_unreachable("Invalid symbol lookup flags");
254 }
255 
256 raw_ostream &operator<<(raw_ostream &OS,
257                         const SymbolLookupSet::value_type &KV) {
258   return OS << "(" << KV.first << ", " << KV.second << ")";
259 }
260 
261 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet) {
262   return OS << printSequence(LookupSet, '{', '}',
263                              PrintAll<SymbolLookupSet::value_type>());
264 }
265 
266 raw_ostream &operator<<(raw_ostream &OS,
267                         const JITDylibSearchOrder &SearchOrder) {
268   OS << "[";
269   if (!SearchOrder.empty()) {
270     assert(SearchOrder.front().first &&
271            "JITDylibList entries must not be null");
272     OS << " (\"" << SearchOrder.front().first->getName() << "\", "
273        << SearchOrder.begin()->second << ")";
274     for (auto &KV :
275          make_range(std::next(SearchOrder.begin(), 1), SearchOrder.end())) {
276       assert(KV.first && "JITDylibList entries must not be null");
277       OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")";
278     }
279   }
280   OS << " ]";
281   return OS;
282 }
283 
284 raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases) {
285   OS << "{";
286   for (auto &KV : Aliases)
287     OS << " " << *KV.first << ": " << KV.second.Aliasee << " "
288        << KV.second.AliasFlags;
289   OS << " }";
290   return OS;
291 }
292 
293 raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S) {
294   switch (S) {
295   case SymbolState::Invalid:
296     return OS << "Invalid";
297   case SymbolState::NeverSearched:
298     return OS << "Never-Searched";
299   case SymbolState::Materializing:
300     return OS << "Materializing";
301   case SymbolState::Resolved:
302     return OS << "Resolved";
303   case SymbolState::Emitted:
304     return OS << "Emitted";
305   case SymbolState::Ready:
306     return OS << "Ready";
307   }
308   llvm_unreachable("Invalid state");
309 }
310 
311 FailedToMaterialize::FailedToMaterialize(
312     std::shared_ptr<SymbolDependenceMap> Symbols)
313     : Symbols(std::move(Symbols)) {
314   assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
315 }
316 
317 std::error_code FailedToMaterialize::convertToErrorCode() const {
318   return orcError(OrcErrorCode::UnknownORCError);
319 }
320 
321 void FailedToMaterialize::log(raw_ostream &OS) const {
322   OS << "Failed to materialize symbols: " << *Symbols;
323 }
324 
325 SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) {
326   for (auto &Sym : Symbols)
327     this->Symbols.push_back(Sym);
328   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
329 }
330 
331 SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols)
332     : Symbols(std::move(Symbols)) {
333   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
334 }
335 
336 std::error_code SymbolsNotFound::convertToErrorCode() const {
337   return orcError(OrcErrorCode::UnknownORCError);
338 }
339 
340 void SymbolsNotFound::log(raw_ostream &OS) const {
341   OS << "Symbols not found: " << Symbols;
342 }
343 
344 SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
345     : Symbols(std::move(Symbols)) {
346   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
347 }
348 
349 std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const {
350   return orcError(OrcErrorCode::UnknownORCError);
351 }
352 
353 void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const {
354   OS << "Symbols could not be removed: " << Symbols;
355 }
356 
357 std::error_code MissingSymbolDefinitions::convertToErrorCode() const {
358   return orcError(OrcErrorCode::MissingSymbolDefinitions);
359 }
360 
361 void MissingSymbolDefinitions::log(raw_ostream &OS) const {
362   OS << "Missing definitions in module " << ModuleName
363      << ": " << Symbols;
364 }
365 
366 std::error_code UnexpectedSymbolDefinitions::convertToErrorCode() const {
367   return orcError(OrcErrorCode::UnexpectedSymbolDefinitions);
368 }
369 
370 void UnexpectedSymbolDefinitions::log(raw_ostream &OS) const {
371   OS << "Unexpected definitions in module " << ModuleName
372      << ": " << Symbols;
373 }
374 
375 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
376     const SymbolLookupSet &Symbols, SymbolState RequiredState,
377     SymbolsResolvedCallback NotifyComplete)
378     : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
379   assert(RequiredState >= SymbolState::Resolved &&
380          "Cannot query for a symbols that have not reached the resolve state "
381          "yet");
382 
383   OutstandingSymbolsCount = Symbols.size();
384 
385   for (auto &KV : Symbols)
386     ResolvedSymbols[KV.first] = nullptr;
387 }
388 
389 void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
390     const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) {
391   auto I = ResolvedSymbols.find(Name);
392   assert(I != ResolvedSymbols.end() &&
393          "Resolving symbol outside the requested set");
394   assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name");
395   I->second = std::move(Sym);
396   --OutstandingSymbolsCount;
397 }
398 
399 void AsynchronousSymbolQuery::handleComplete() {
400   assert(OutstandingSymbolsCount == 0 &&
401          "Symbols remain, handleComplete called prematurely");
402 
403   auto TmpNotifyComplete = std::move(NotifyComplete);
404   NotifyComplete = SymbolsResolvedCallback();
405   TmpNotifyComplete(std::move(ResolvedSymbols));
406 }
407 
408 bool AsynchronousSymbolQuery::canStillFail() { return !!NotifyComplete; }
409 
410 void AsynchronousSymbolQuery::handleFailed(Error Err) {
411   assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
412          OutstandingSymbolsCount == 0 &&
413          "Query should already have been abandoned");
414   NotifyComplete(std::move(Err));
415   NotifyComplete = SymbolsResolvedCallback();
416 }
417 
418 void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
419                                                  SymbolStringPtr Name) {
420   bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
421   (void)Added;
422   assert(Added && "Duplicate dependence notification?");
423 }
424 
425 void AsynchronousSymbolQuery::removeQueryDependence(
426     JITDylib &JD, const SymbolStringPtr &Name) {
427   auto QRI = QueryRegistrations.find(&JD);
428   assert(QRI != QueryRegistrations.end() &&
429          "No dependencies registered for JD");
430   assert(QRI->second.count(Name) && "No dependency on Name in JD");
431   QRI->second.erase(Name);
432   if (QRI->second.empty())
433     QueryRegistrations.erase(QRI);
434 }
435 
436 void AsynchronousSymbolQuery::detach() {
437   ResolvedSymbols.clear();
438   OutstandingSymbolsCount = 0;
439   for (auto &KV : QueryRegistrations)
440     KV.first->detachQueryHelper(*this, KV.second);
441   QueryRegistrations.clear();
442 }
443 
444 MaterializationResponsibility::~MaterializationResponsibility() {
445   assert(SymbolFlags.empty() &&
446          "All symbols should have been explicitly materialized or failed");
447 }
448 
449 SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
450   return JD.getRequestedSymbols(SymbolFlags);
451 }
452 
453 Error MaterializationResponsibility::notifyResolved(const SymbolMap &Symbols) {
454   LLVM_DEBUG({
455     dbgs() << "In " << JD.getName() << " resolving " << Symbols << "\n";
456   });
457 #ifndef NDEBUG
458   for (auto &KV : Symbols) {
459     auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
460     auto I = SymbolFlags.find(KV.first);
461     assert(I != SymbolFlags.end() &&
462            "Resolving symbol outside this responsibility set");
463     assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&
464            "Resolving symbol with incorrect flags");
465   }
466 #endif
467 
468   return JD.resolve(Symbols);
469 }
470 
471 Error MaterializationResponsibility::notifyEmitted() {
472 
473   LLVM_DEBUG({
474     dbgs() << "In " << JD.getName() << " emitting " << SymbolFlags << "\n";
475   });
476 
477   if (auto Err = JD.emit(SymbolFlags))
478     return Err;
479 
480   SymbolFlags.clear();
481   return Error::success();
482 }
483 
484 Error MaterializationResponsibility::defineMaterializing(
485     SymbolFlagsMap NewSymbolFlags) {
486 
487   LLVM_DEBUG({
488       dbgs() << "In " << JD.getName() << " defining materializing symbols "
489              << NewSymbolFlags << "\n";
490     });
491   if (auto AcceptedDefs = JD.defineMaterializing(std::move(NewSymbolFlags))) {
492     // Add all newly accepted symbols to this responsibility object.
493     for (auto &KV : *AcceptedDefs)
494       SymbolFlags.insert(KV);
495     return Error::success();
496   } else
497     return AcceptedDefs.takeError();
498 }
499 
500 void MaterializationResponsibility::failMaterialization() {
501 
502   LLVM_DEBUG({
503     dbgs() << "In " << JD.getName() << " failing materialization for "
504            << SymbolFlags << "\n";
505   });
506 
507   JITDylib::FailedSymbolsWorklist Worklist;
508 
509   for (auto &KV : SymbolFlags)
510     Worklist.push_back(std::make_pair(&JD, KV.first));
511   SymbolFlags.clear();
512 
513   JD.notifyFailed(std::move(Worklist));
514 }
515 
516 void MaterializationResponsibility::replace(
517     std::unique_ptr<MaterializationUnit> MU) {
518 
519   for (auto &KV : MU->getSymbols())
520     SymbolFlags.erase(KV.first);
521 
522   if (MU->getInitializerSymbol() == InitSymbol)
523     InitSymbol = nullptr;
524 
525   LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {
526     dbgs() << "In " << JD.getName() << " replacing symbols with " << *MU
527            << "\n";
528   }););
529 
530   JD.replace(std::move(MU));
531 }
532 
533 MaterializationResponsibility
534 MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,
535                                         VModuleKey NewKey) {
536 
537   if (NewKey == VModuleKey())
538     NewKey = K;
539 
540   SymbolStringPtr DelegatedInitSymbol;
541   SymbolFlagsMap DelegatedFlags;
542 
543   for (auto &Name : Symbols) {
544     auto I = SymbolFlags.find(Name);
545     assert(I != SymbolFlags.end() &&
546            "Symbol is not tracked by this MaterializationResponsibility "
547            "instance");
548 
549     DelegatedFlags[Name] = std::move(I->second);
550     if (Name == InitSymbol)
551       std::swap(InitSymbol, DelegatedInitSymbol);
552 
553     SymbolFlags.erase(I);
554   }
555 
556   return MaterializationResponsibility(JD, std::move(DelegatedFlags),
557                                        std::move(DelegatedInitSymbol),
558                                        std::move(NewKey));
559 }
560 
561 void MaterializationResponsibility::addDependencies(
562     const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies) {
563   LLVM_DEBUG({
564     dbgs() << "Adding dependencies for " << Name << ": " << Dependencies
565            << "\n";
566   });
567   assert(SymbolFlags.count(Name) &&
568          "Symbol not covered by this MaterializationResponsibility instance");
569   JD.addDependencies(Name, Dependencies);
570 }
571 
572 void MaterializationResponsibility::addDependenciesForAll(
573     const SymbolDependenceMap &Dependencies) {
574   LLVM_DEBUG({
575     dbgs() << "Adding dependencies for all symbols in " << SymbolFlags << ": "
576            << Dependencies << "\n";
577   });
578   for (auto &KV : SymbolFlags)
579     JD.addDependencies(KV.first, Dependencies);
580 }
581 
582 AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
583     SymbolMap Symbols, VModuleKey K)
584     : MaterializationUnit(extractFlags(Symbols), nullptr, std::move(K)),
585       Symbols(std::move(Symbols)) {}
586 
587 StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
588   return "<Absolute Symbols>";
589 }
590 
591 void AbsoluteSymbolsMaterializationUnit::materialize(
592     MaterializationResponsibility R) {
593   // No dependencies, so these calls can't fail.
594   cantFail(R.notifyResolved(Symbols));
595   cantFail(R.notifyEmitted());
596 }
597 
598 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
599                                                  const SymbolStringPtr &Name) {
600   assert(Symbols.count(Name) && "Symbol is not part of this MU");
601   Symbols.erase(Name);
602 }
603 
604 SymbolFlagsMap
605 AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
606   SymbolFlagsMap Flags;
607   for (const auto &KV : Symbols)
608     Flags[KV.first] = KV.second.getFlags();
609   return Flags;
610 }
611 
612 ReExportsMaterializationUnit::ReExportsMaterializationUnit(
613     JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
614     SymbolAliasMap Aliases, VModuleKey K)
615     : MaterializationUnit(extractFlags(Aliases), nullptr, std::move(K)),
616       SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
617       Aliases(std::move(Aliases)) {}
618 
619 StringRef ReExportsMaterializationUnit::getName() const {
620   return "<Reexports>";
621 }
622 
623 void ReExportsMaterializationUnit::materialize(
624     MaterializationResponsibility R) {
625 
626   auto &ES = R.getTargetJITDylib().getExecutionSession();
627   JITDylib &TgtJD = R.getTargetJITDylib();
628   JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
629 
630   // Find the set of requested aliases and aliasees. Return any unrequested
631   // aliases back to the JITDylib so as to not prematurely materialize any
632   // aliasees.
633   auto RequestedSymbols = R.getRequestedSymbols();
634   SymbolAliasMap RequestedAliases;
635 
636   for (auto &Name : RequestedSymbols) {
637     auto I = Aliases.find(Name);
638     assert(I != Aliases.end() && "Symbol not found in aliases map?");
639     RequestedAliases[Name] = std::move(I->second);
640     Aliases.erase(I);
641   }
642 
643   LLVM_DEBUG({
644     ES.runSessionLocked([&]() {
645       dbgs() << "materializing reexports: target = " << TgtJD.getName()
646              << ", source = " << SrcJD.getName() << " " << RequestedAliases
647              << "\n";
648     });
649   });
650 
651   if (!Aliases.empty()) {
652     if (SourceJD)
653       R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
654     else
655       R.replace(symbolAliases(std::move(Aliases)));
656   }
657 
658   // The OnResolveInfo struct will hold the aliases and responsibilty for each
659   // query in the list.
660   struct OnResolveInfo {
661     OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases)
662         : R(std::move(R)), Aliases(std::move(Aliases)) {}
663 
664     MaterializationResponsibility R;
665     SymbolAliasMap Aliases;
666   };
667 
668   // Build a list of queries to issue. In each round we build the largest set of
669   // aliases that we can resolve without encountering a chain definition of the
670   // form Foo -> Bar, Bar -> Baz. Such a form would deadlock as the query would
671   // be waitin on a symbol that it itself had to resolve. Usually this will just
672   // involve one round and a single query.
673 
674   std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
675       QueryInfos;
676   while (!RequestedAliases.empty()) {
677     SymbolNameSet ResponsibilitySymbols;
678     SymbolLookupSet QuerySymbols;
679     SymbolAliasMap QueryAliases;
680 
681     // Collect as many aliases as we can without including a chain.
682     for (auto &KV : RequestedAliases) {
683       // Chain detected. Skip this symbol for this round.
684       if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
685                                RequestedAliases.count(KV.second.Aliasee)))
686         continue;
687 
688       ResponsibilitySymbols.insert(KV.first);
689       QuerySymbols.add(KV.second.Aliasee);
690       QueryAliases[KV.first] = std::move(KV.second);
691     }
692 
693     // Remove the aliases collected this round from the RequestedAliases map.
694     for (auto &KV : QueryAliases)
695       RequestedAliases.erase(KV.first);
696 
697     assert(!QuerySymbols.empty() && "Alias cycle detected!");
698 
699     auto QueryInfo = std::make_shared<OnResolveInfo>(
700         R.delegate(ResponsibilitySymbols), std::move(QueryAliases));
701     QueryInfos.push_back(
702         make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
703   }
704 
705   // Issue the queries.
706   while (!QueryInfos.empty()) {
707     auto QuerySymbols = std::move(QueryInfos.back().first);
708     auto QueryInfo = std::move(QueryInfos.back().second);
709 
710     QueryInfos.pop_back();
711 
712     auto RegisterDependencies = [QueryInfo,
713                                  &SrcJD](const SymbolDependenceMap &Deps) {
714       // If there were no materializing symbols, just bail out.
715       if (Deps.empty())
716         return;
717 
718       // Otherwise the only deps should be on SrcJD.
719       assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
720              "Unexpected dependencies for reexports");
721 
722       auto &SrcJDDeps = Deps.find(&SrcJD)->second;
723       SymbolDependenceMap PerAliasDepsMap;
724       auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
725 
726       for (auto &KV : QueryInfo->Aliases)
727         if (SrcJDDeps.count(KV.second.Aliasee)) {
728           PerAliasDeps = {KV.second.Aliasee};
729           QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
730         }
731     };
732 
733     auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
734       auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
735       if (Result) {
736         SymbolMap ResolutionMap;
737         for (auto &KV : QueryInfo->Aliases) {
738           assert(Result->count(KV.second.Aliasee) &&
739                  "Result map missing entry?");
740           ResolutionMap[KV.first] = JITEvaluatedSymbol(
741               (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
742         }
743         if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) {
744           ES.reportError(std::move(Err));
745           QueryInfo->R.failMaterialization();
746           return;
747         }
748         if (auto Err = QueryInfo->R.notifyEmitted()) {
749           ES.reportError(std::move(Err));
750           QueryInfo->R.failMaterialization();
751           return;
752         }
753       } else {
754         ES.reportError(Result.takeError());
755         QueryInfo->R.failMaterialization();
756       }
757     };
758 
759     ES.lookup(LookupKind::Static,
760               JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
761               QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
762               std::move(RegisterDependencies));
763   }
764 }
765 
766 void ReExportsMaterializationUnit::discard(const JITDylib &JD,
767                                            const SymbolStringPtr &Name) {
768   assert(Aliases.count(Name) &&
769          "Symbol not covered by this MaterializationUnit");
770   Aliases.erase(Name);
771 }
772 
773 SymbolFlagsMap
774 ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
775   SymbolFlagsMap SymbolFlags;
776   for (auto &KV : Aliases)
777     SymbolFlags[KV.first] = KV.second.AliasFlags;
778 
779   return SymbolFlags;
780 }
781 
782 Expected<SymbolAliasMap>
783 buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
784   SymbolLookupSet LookupSet(Symbols);
785   auto Flags = SourceJD.lookupFlags(
786       LookupKind::Static, JITDylibLookupFlags::MatchAllSymbols, LookupSet);
787 
788   if (!Flags)
789     return Flags.takeError();
790 
791   if (!LookupSet.empty()) {
792     LookupSet.sortByName();
793     return make_error<SymbolsNotFound>(LookupSet.getSymbolNames());
794   }
795 
796   SymbolAliasMap Result;
797   for (auto &Name : Symbols) {
798     assert(Flags->count(Name) && "Missing entry in flags map");
799     Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
800   }
801 
802   return Result;
803 }
804 
805 ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
806                                        JITDylibLookupFlags SourceJDLookupFlags,
807                                        SymbolPredicate Allow)
808     : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
809       Allow(std::move(Allow)) {}
810 
811 Error ReexportsGenerator::tryToGenerate(LookupKind K, JITDylib &JD,
812                                         JITDylibLookupFlags JDLookupFlags,
813                                         const SymbolLookupSet &LookupSet) {
814   assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
815 
816   // Use lookupFlags to find the subset of symbols that match our lookup.
817   auto Flags = SourceJD.lookupFlags(K, JDLookupFlags, LookupSet);
818   if (!Flags)
819     return Flags.takeError();
820 
821   // Create an alias map.
822   orc::SymbolAliasMap AliasMap;
823   for (auto &KV : *Flags)
824     if (!Allow || Allow(KV.first))
825       AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
826 
827   if (AliasMap.empty())
828     return Error::success();
829 
830   // Define the re-exports.
831   return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
832 }
833 
834 JITDylib::DefinitionGenerator::~DefinitionGenerator() {}
835 
836 void JITDylib::removeGenerator(DefinitionGenerator &G) {
837   ES.runSessionLocked([&]() {
838     auto I = std::find_if(DefGenerators.begin(), DefGenerators.end(),
839                           [&](const std::unique_ptr<DefinitionGenerator> &H) {
840                             return H.get() == &G;
841                           });
842     assert(I != DefGenerators.end() && "Generator not found");
843     DefGenerators.erase(I);
844   });
845 }
846 
847 Expected<SymbolFlagsMap>
848 JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
849 
850   return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
851     std::vector<SymbolTable::iterator> AddedSyms;
852     std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
853 
854     for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
855          SFItr != SFEnd; ++SFItr) {
856 
857       auto &Name = SFItr->first;
858       auto &Flags = SFItr->second;
859 
860       auto EntryItr = Symbols.find(Name);
861 
862       // If the entry already exists...
863       if (EntryItr != Symbols.end()) {
864 
865         // If this is a strong definition then error out.
866         if (!Flags.isWeak()) {
867           // Remove any symbols already added.
868           for (auto &SI : AddedSyms)
869             Symbols.erase(SI);
870 
871           // FIXME: Return all duplicates.
872           return make_error<DuplicateDefinition>(std::string(*Name));
873         }
874 
875         // Otherwise just make a note to discard this symbol after the loop.
876         RejectedWeakDefs.push_back(SFItr);
877         continue;
878       } else
879         EntryItr =
880           Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
881 
882       AddedSyms.push_back(EntryItr);
883       EntryItr->second.setState(SymbolState::Materializing);
884     }
885 
886     // Remove any rejected weak definitions from the SymbolFlags map.
887     while (!RejectedWeakDefs.empty()) {
888       SymbolFlags.erase(RejectedWeakDefs.back());
889       RejectedWeakDefs.pop_back();
890     }
891 
892     return SymbolFlags;
893   });
894 }
895 
896 void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) {
897   assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
898 
899   auto MustRunMU =
900       ES.runSessionLocked([&, this]() -> std::unique_ptr<MaterializationUnit> {
901 
902 #ifndef NDEBUG
903         for (auto &KV : MU->getSymbols()) {
904           auto SymI = Symbols.find(KV.first);
905           assert(SymI != Symbols.end() && "Replacing unknown symbol");
906           assert(SymI->second.getState() == SymbolState::Materializing &&
907                  "Can not replace a symbol that ha is not materializing");
908           assert(!SymI->second.hasMaterializerAttached() &&
909                  "Symbol should not have materializer attached already");
910           assert(UnmaterializedInfos.count(KV.first) == 0 &&
911                  "Symbol being replaced should have no UnmaterializedInfo");
912         }
913 #endif // NDEBUG
914 
915         // If any symbol has pending queries against it then we need to
916         // materialize MU immediately.
917         for (auto &KV : MU->getSymbols()) {
918           auto MII = MaterializingInfos.find(KV.first);
919           if (MII != MaterializingInfos.end()) {
920             if (MII->second.hasQueriesPending())
921               return std::move(MU);
922           }
923         }
924 
925         // Otherwise, make MU responsible for all the symbols.
926         auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
927         for (auto &KV : UMI->MU->getSymbols()) {
928           auto SymI = Symbols.find(KV.first);
929           assert(SymI->second.getState() == SymbolState::Materializing &&
930                  "Can not replace a symbol that is not materializing");
931           assert(!SymI->second.hasMaterializerAttached() &&
932                  "Can not replace a symbol that has a materializer attached");
933           assert(UnmaterializedInfos.count(KV.first) == 0 &&
934                  "Unexpected materializer entry in map");
935           SymI->second.setAddress(SymI->second.getAddress());
936           SymI->second.setMaterializerAttached(true);
937           UnmaterializedInfos[KV.first] = UMI;
938         }
939 
940         return nullptr;
941       });
942 
943   if (MustRunMU)
944     ES.dispatchMaterialization(*this, std::move(MustRunMU));
945 }
946 
947 SymbolNameSet
948 JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
949   return ES.runSessionLocked([&]() {
950     SymbolNameSet RequestedSymbols;
951 
952     for (auto &KV : SymbolFlags) {
953       assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
954       assert(Symbols.find(KV.first)->second.getState() !=
955                  SymbolState::NeverSearched &&
956              Symbols.find(KV.first)->second.getState() != SymbolState::Ready &&
957              "getRequestedSymbols can only be called for symbols that have "
958              "started materializing");
959       auto I = MaterializingInfos.find(KV.first);
960       if (I == MaterializingInfos.end())
961         continue;
962 
963       if (I->second.hasQueriesPending())
964         RequestedSymbols.insert(KV.first);
965     }
966 
967     return RequestedSymbols;
968   });
969 }
970 
971 void JITDylib::addDependencies(const SymbolStringPtr &Name,
972                                const SymbolDependenceMap &Dependencies) {
973   assert(Symbols.count(Name) && "Name not in symbol table");
974   assert(Symbols[Name].getState() < SymbolState::Emitted &&
975          "Can not add dependencies for a symbol that is not materializing");
976 
977   LLVM_DEBUG({
978       dbgs() << "In " << getName() << " adding dependencies for "
979              << *Name << ": " << Dependencies << "\n";
980     });
981 
982   // If Name is already in an error state then just bail out.
983   if (Symbols[Name].getFlags().hasError())
984     return;
985 
986   auto &MI = MaterializingInfos[Name];
987   assert(Symbols[Name].getState() != SymbolState::Emitted &&
988          "Can not add dependencies to an emitted symbol");
989 
990   bool DependsOnSymbolInErrorState = false;
991 
992   // Register dependencies, record whether any depenendency is in the error
993   // state.
994   for (auto &KV : Dependencies) {
995     assert(KV.first && "Null JITDylib in dependency?");
996     auto &OtherJITDylib = *KV.first;
997     auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
998 
999     for (auto &OtherSymbol : KV.second) {
1000 
1001       // Check the sym entry for the dependency.
1002       auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
1003 
1004       // Assert that this symbol exists and has not reached the ready state
1005       // already.
1006       assert(OtherSymI != OtherJITDylib.Symbols.end() &&
1007              "Dependency on unknown symbol");
1008 
1009       auto &OtherSymEntry = OtherSymI->second;
1010 
1011       // If the other symbol is already in the Ready state then there's no
1012       // dependency to add.
1013       if (OtherSymEntry.getState() == SymbolState::Ready)
1014         continue;
1015 
1016       // If the dependency is in an error state then note this and continue,
1017       // we will move this symbol to the error state below.
1018       if (OtherSymEntry.getFlags().hasError()) {
1019         DependsOnSymbolInErrorState = true;
1020         continue;
1021       }
1022 
1023       // If the dependency was not in the error state then add it to
1024       // our list of dependencies.
1025       assert(OtherJITDylib.MaterializingInfos.count(OtherSymbol) &&
1026              "No MaterializingInfo for dependency");
1027       auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
1028 
1029       if (OtherSymEntry.getState() == SymbolState::Emitted)
1030         transferEmittedNodeDependencies(MI, Name, OtherMI);
1031       else if (&OtherJITDylib != this || OtherSymbol != Name) {
1032         OtherMI.Dependants[this].insert(Name);
1033         DepsOnOtherJITDylib.insert(OtherSymbol);
1034       }
1035     }
1036 
1037     if (DepsOnOtherJITDylib.empty())
1038       MI.UnemittedDependencies.erase(&OtherJITDylib);
1039   }
1040 
1041   // If this symbol dependended on any symbols in the error state then move
1042   // this symbol to the error state too.
1043   if (DependsOnSymbolInErrorState)
1044     Symbols[Name].setFlags(Symbols[Name].getFlags() | JITSymbolFlags::HasError);
1045 }
1046 
1047 Error JITDylib::resolve(const SymbolMap &Resolved) {
1048   SymbolNameSet SymbolsInErrorState;
1049   AsynchronousSymbolQuerySet CompletedQueries;
1050 
1051   ES.runSessionLocked([&, this]() {
1052     struct WorklistEntry {
1053       SymbolTable::iterator SymI;
1054       JITEvaluatedSymbol ResolvedSym;
1055     };
1056 
1057     std::vector<WorklistEntry> Worklist;
1058     Worklist.reserve(Resolved.size());
1059 
1060     // Build worklist and check for any symbols in the error state.
1061     for (const auto &KV : Resolved) {
1062 
1063       assert(!KV.second.getFlags().hasError() &&
1064              "Resolution result can not have error flag set");
1065 
1066       auto SymI = Symbols.find(KV.first);
1067 
1068       assert(SymI != Symbols.end() && "Symbol not found");
1069       assert(!SymI->second.hasMaterializerAttached() &&
1070              "Resolving symbol with materializer attached?");
1071       assert(SymI->second.getState() == SymbolState::Materializing &&
1072              "Symbol should be materializing");
1073       assert(SymI->second.getAddress() == 0 &&
1074              "Symbol has already been resolved");
1075 
1076       if (SymI->second.getFlags().hasError())
1077         SymbolsInErrorState.insert(KV.first);
1078       else {
1079         auto Flags = KV.second.getFlags();
1080         Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common);
1081         assert(Flags == (SymI->second.getFlags() &
1082                          ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&
1083                "Resolved flags should match the declared flags");
1084 
1085         Worklist.push_back(
1086             {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
1087       }
1088     }
1089 
1090     // If any symbols were in the error state then bail out.
1091     if (!SymbolsInErrorState.empty())
1092       return;
1093 
1094     while (!Worklist.empty()) {
1095       auto SymI = Worklist.back().SymI;
1096       auto ResolvedSym = Worklist.back().ResolvedSym;
1097       Worklist.pop_back();
1098 
1099       auto &Name = SymI->first;
1100 
1101       // Resolved symbols can not be weak: discard the weak flag.
1102       JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
1103       SymI->second.setAddress(ResolvedSym.getAddress());
1104       SymI->second.setFlags(ResolvedFlags);
1105       SymI->second.setState(SymbolState::Resolved);
1106 
1107       auto &MI = MaterializingInfos[Name];
1108       for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
1109         Q->notifySymbolMetRequiredState(Name, ResolvedSym);
1110         Q->removeQueryDependence(*this, Name);
1111         if (Q->isComplete())
1112           CompletedQueries.insert(std::move(Q));
1113       }
1114     }
1115   });
1116 
1117   assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
1118          "Can't fail symbols and completed queries at the same time");
1119 
1120   // If we failed any symbols then return an error.
1121   if (!SymbolsInErrorState.empty()) {
1122     auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1123     (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1124     return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1125   }
1126 
1127   // Otherwise notify all the completed queries.
1128   for (auto &Q : CompletedQueries) {
1129     assert(Q->isComplete() && "Q not completed");
1130     Q->handleComplete();
1131   }
1132 
1133   return Error::success();
1134 }
1135 
1136 Error JITDylib::emit(const SymbolFlagsMap &Emitted) {
1137   AsynchronousSymbolQuerySet CompletedQueries;
1138   SymbolNameSet SymbolsInErrorState;
1139   DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
1140 
1141   ES.runSessionLocked([&, this]() {
1142     std::vector<SymbolTable::iterator> Worklist;
1143 
1144     // Scan to build worklist, record any symbols in the erorr state.
1145     for (const auto &KV : Emitted) {
1146       auto &Name = KV.first;
1147 
1148       auto SymI = Symbols.find(Name);
1149       assert(SymI != Symbols.end() && "No symbol table entry for Name");
1150 
1151       if (SymI->second.getFlags().hasError())
1152         SymbolsInErrorState.insert(Name);
1153       else
1154         Worklist.push_back(SymI);
1155     }
1156 
1157     // If any symbols were in the error state then bail out.
1158     if (!SymbolsInErrorState.empty())
1159       return;
1160 
1161     // Otherwise update dependencies and move to the emitted state.
1162     while (!Worklist.empty()) {
1163       auto SymI = Worklist.back();
1164       Worklist.pop_back();
1165 
1166       auto &Name = SymI->first;
1167       auto &SymEntry = SymI->second;
1168 
1169       // Move symbol to the emitted state.
1170       assert(SymEntry.getState() == SymbolState::Resolved &&
1171              "Emitting from state other than Resolved");
1172       SymEntry.setState(SymbolState::Emitted);
1173 
1174       auto MII = MaterializingInfos.find(Name);
1175       assert(MII != MaterializingInfos.end() &&
1176              "Missing MaterializingInfo entry");
1177       auto &MI = MII->second;
1178 
1179       // For each dependant, transfer this node's emitted dependencies to
1180       // it. If the dependant node is ready (i.e. has no unemitted
1181       // dependencies) then notify any pending queries.
1182       for (auto &KV : MI.Dependants) {
1183         auto &DependantJD = *KV.first;
1184         auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1185         for (auto &DependantName : KV.second) {
1186           auto DependantMII =
1187               DependantJD.MaterializingInfos.find(DependantName);
1188           assert(DependantMII != DependantJD.MaterializingInfos.end() &&
1189                  "Dependant should have MaterializingInfo");
1190 
1191           auto &DependantMI = DependantMII->second;
1192 
1193           // Remove the dependant's dependency on this node.
1194           assert(DependantMI.UnemittedDependencies.count(this) &&
1195                  "Dependant does not have an unemitted dependencies record for "
1196                  "this JITDylib");
1197           assert(DependantMI.UnemittedDependencies[this].count(Name) &&
1198                  "Dependant does not count this symbol as a dependency?");
1199 
1200           DependantMI.UnemittedDependencies[this].erase(Name);
1201           if (DependantMI.UnemittedDependencies[this].empty())
1202             DependantMI.UnemittedDependencies.erase(this);
1203 
1204           // Transfer unemitted dependencies from this node to the dependant.
1205           DependantJD.transferEmittedNodeDependencies(DependantMI,
1206                                                       DependantName, MI);
1207 
1208           auto DependantSymI = DependantJD.Symbols.find(DependantName);
1209           assert(DependantSymI != DependantJD.Symbols.end() &&
1210                  "Dependant has no entry in the Symbols table");
1211           auto &DependantSymEntry = DependantSymI->second;
1212 
1213           // If the dependant is emitted and this node was the last of its
1214           // unemitted dependencies then the dependant node is now ready, so
1215           // notify any pending queries on the dependant node.
1216           if (DependantSymEntry.getState() == SymbolState::Emitted &&
1217               DependantMI.UnemittedDependencies.empty()) {
1218             assert(DependantMI.Dependants.empty() &&
1219                    "Dependants should be empty by now");
1220 
1221             // Since this dependant is now ready, we erase its MaterializingInfo
1222             // and update its materializing state.
1223             DependantSymEntry.setState(SymbolState::Ready);
1224             DependantJDReadySymbols.push_back(DependantName);
1225 
1226             for (auto &Q : DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1227               Q->notifySymbolMetRequiredState(
1228                   DependantName, DependantSymI->second.getSymbol());
1229               if (Q->isComplete())
1230                 CompletedQueries.insert(Q);
1231               Q->removeQueryDependence(DependantJD, DependantName);
1232             }
1233           }
1234         }
1235       }
1236 
1237       auto &ThisJDReadySymbols = ReadySymbols[this];
1238       MI.Dependants.clear();
1239       if (MI.UnemittedDependencies.empty()) {
1240         SymI->second.setState(SymbolState::Ready);
1241         ThisJDReadySymbols.push_back(Name);
1242         for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1243           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1244           if (Q->isComplete())
1245             CompletedQueries.insert(Q);
1246           Q->removeQueryDependence(*this, Name);
1247         }
1248       }
1249     }
1250   });
1251 
1252   assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
1253          "Can't fail symbols and completed queries at the same time");
1254 
1255   // If we failed any symbols then return an error.
1256   if (!SymbolsInErrorState.empty()) {
1257     auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1258     (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1259     return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1260   }
1261 
1262   // Otherwise notify all the completed queries.
1263   for (auto &Q : CompletedQueries) {
1264     assert(Q->isComplete() && "Q is not complete");
1265     Q->handleComplete();
1266   }
1267 
1268   return Error::success();
1269 }
1270 
1271 void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) {
1272   AsynchronousSymbolQuerySet FailedQueries;
1273   auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1274 
1275   // Failing no symbols is a no-op.
1276   if (Worklist.empty())
1277     return;
1278 
1279   auto &ES = Worklist.front().first->getExecutionSession();
1280 
1281   ES.runSessionLocked([&]() {
1282     while (!Worklist.empty()) {
1283       assert(Worklist.back().first && "Failed JITDylib can not be null");
1284       auto &JD = *Worklist.back().first;
1285       auto Name = std::move(Worklist.back().second);
1286       Worklist.pop_back();
1287 
1288       (*FailedSymbolsMap)[&JD].insert(Name);
1289 
1290       assert(JD.Symbols.count(Name) && "No symbol table entry for Name");
1291       auto &Sym = JD.Symbols[Name];
1292 
1293       // Move the symbol into the error state.
1294       // Note that this may be redundant: The symbol might already have been
1295       // moved to this state in response to the failure of a dependence.
1296       Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1297 
1298       // FIXME: Come up with a sane mapping of state to
1299       // presence-of-MaterializingInfo so that we can assert presence / absence
1300       // here, rather than testing it.
1301       auto MII = JD.MaterializingInfos.find(Name);
1302 
1303       if (MII == JD.MaterializingInfos.end())
1304         continue;
1305 
1306       auto &MI = MII->second;
1307 
1308       // Move all dependants to the error state and disconnect from them.
1309       for (auto &KV : MI.Dependants) {
1310         auto &DependantJD = *KV.first;
1311         for (auto &DependantName : KV.second) {
1312           assert(DependantJD.Symbols.count(DependantName) &&
1313                  "No symbol table entry for DependantName");
1314           auto &DependantSym = DependantJD.Symbols[DependantName];
1315           DependantSym.setFlags(DependantSym.getFlags() |
1316                                 JITSymbolFlags::HasError);
1317 
1318           assert(DependantJD.MaterializingInfos.count(DependantName) &&
1319                  "No MaterializingInfo for dependant");
1320           auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1321 
1322           auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1323           assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
1324                  "No UnemittedDependencies entry for this JITDylib");
1325           assert(UnemittedDepI->second.count(Name) &&
1326                  "No UnemittedDependencies entry for this symbol");
1327           UnemittedDepI->second.erase(Name);
1328           if (UnemittedDepI->second.empty())
1329             DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1330 
1331           // If this symbol is already in the emitted state then we need to
1332           // take responsibility for failing its queries, so add it to the
1333           // worklist.
1334           if (DependantSym.getState() == SymbolState::Emitted) {
1335             assert(DependantMI.Dependants.empty() &&
1336                    "Emitted symbol should not have dependants");
1337             Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1338           }
1339         }
1340       }
1341       MI.Dependants.clear();
1342 
1343       // Disconnect from all unemitted depenencies.
1344       for (auto &KV : MI.UnemittedDependencies) {
1345         auto &UnemittedDepJD = *KV.first;
1346         for (auto &UnemittedDepName : KV.second) {
1347           auto UnemittedDepMII =
1348               UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1349           assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
1350                  "Missing MII for unemitted dependency");
1351           assert(UnemittedDepMII->second.Dependants.count(&JD) &&
1352                  "JD not listed as a dependant of unemitted dependency");
1353           assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
1354                  "Name is not listed as a dependant of unemitted dependency");
1355           UnemittedDepMII->second.Dependants[&JD].erase(Name);
1356           if (UnemittedDepMII->second.Dependants[&JD].empty())
1357             UnemittedDepMII->second.Dependants.erase(&JD);
1358         }
1359       }
1360       MI.UnemittedDependencies.clear();
1361 
1362       // Collect queries to be failed for this MII.
1363       AsynchronousSymbolQueryList ToDetach;
1364       for (auto &Q : MII->second.pendingQueries()) {
1365         // Add the query to the list to be failed and detach it.
1366         FailedQueries.insert(Q);
1367         ToDetach.push_back(Q);
1368       }
1369       for (auto &Q : ToDetach)
1370         Q->detach();
1371 
1372       assert(MI.Dependants.empty() &&
1373              "Can not delete MaterializingInfo with dependants still attached");
1374       assert(MI.UnemittedDependencies.empty() &&
1375              "Can not delete MaterializingInfo with unemitted dependencies "
1376              "still attached");
1377       assert(!MI.hasQueriesPending() &&
1378              "Can not delete MaterializingInfo with queries pending");
1379       JD.MaterializingInfos.erase(MII);
1380     }
1381   });
1382 
1383   for (auto &Q : FailedQueries)
1384     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbolsMap));
1385 }
1386 
1387 void JITDylib::setSearchOrder(JITDylibSearchOrder NewSearchOrder,
1388                               bool SearchThisJITDylibFirst) {
1389   ES.runSessionLocked([&]() {
1390     if (SearchThisJITDylibFirst) {
1391       SearchOrder.clear();
1392       if (NewSearchOrder.empty() || NewSearchOrder.front().first != this)
1393         SearchOrder.push_back(
1394             std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1395       SearchOrder.insert(SearchOrder.end(), NewSearchOrder.begin(),
1396                          NewSearchOrder.end());
1397     } else
1398       SearchOrder = std::move(NewSearchOrder);
1399   });
1400 }
1401 
1402 void JITDylib::addToSearchOrder(JITDylib &JD,
1403                                 JITDylibLookupFlags JDLookupFlags) {
1404   ES.runSessionLocked([&]() { SearchOrder.push_back({&JD, JDLookupFlags}); });
1405 }
1406 
1407 void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
1408                                     JITDylibLookupFlags JDLookupFlags) {
1409   ES.runSessionLocked([&]() {
1410     for (auto &KV : SearchOrder)
1411       if (KV.first == &OldJD) {
1412         KV = {&NewJD, JDLookupFlags};
1413         break;
1414       }
1415   });
1416 }
1417 
1418 void JITDylib::removeFromSearchOrder(JITDylib &JD) {
1419   ES.runSessionLocked([&]() {
1420     auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
1421                           [&](const JITDylibSearchOrder::value_type &KV) {
1422                             return KV.first == &JD;
1423                           });
1424     if (I != SearchOrder.end())
1425       SearchOrder.erase(I);
1426   });
1427 }
1428 
1429 Error JITDylib::remove(const SymbolNameSet &Names) {
1430   return ES.runSessionLocked([&]() -> Error {
1431     using SymbolMaterializerItrPair =
1432         std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1433     std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1434     SymbolNameSet Missing;
1435     SymbolNameSet Materializing;
1436 
1437     for (auto &Name : Names) {
1438       auto I = Symbols.find(Name);
1439 
1440       // Note symbol missing.
1441       if (I == Symbols.end()) {
1442         Missing.insert(Name);
1443         continue;
1444       }
1445 
1446       // Note symbol materializing.
1447       if (I->second.getState() != SymbolState::NeverSearched &&
1448           I->second.getState() != SymbolState::Ready) {
1449         Materializing.insert(Name);
1450         continue;
1451       }
1452 
1453       auto UMII = I->second.hasMaterializerAttached()
1454                       ? UnmaterializedInfos.find(Name)
1455                       : UnmaterializedInfos.end();
1456       SymbolsToRemove.push_back(std::make_pair(I, UMII));
1457     }
1458 
1459     // If any of the symbols are not defined, return an error.
1460     if (!Missing.empty())
1461       return make_error<SymbolsNotFound>(std::move(Missing));
1462 
1463     // If any of the symbols are currently materializing, return an error.
1464     if (!Materializing.empty())
1465       return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1466 
1467     // Remove the symbols.
1468     for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1469       auto UMII = SymbolMaterializerItrPair.second;
1470 
1471       // If there is a materializer attached, call discard.
1472       if (UMII != UnmaterializedInfos.end()) {
1473         UMII->second->MU->doDiscard(*this, UMII->first);
1474         UnmaterializedInfos.erase(UMII);
1475       }
1476 
1477       auto SymI = SymbolMaterializerItrPair.first;
1478       Symbols.erase(SymI);
1479     }
1480 
1481     return Error::success();
1482   });
1483 }
1484 
1485 Expected<SymbolFlagsMap>
1486 JITDylib::lookupFlags(LookupKind K, JITDylibLookupFlags JDLookupFlags,
1487                       SymbolLookupSet LookupSet) {
1488   return ES.runSessionLocked([&, this]() -> Expected<SymbolFlagsMap> {
1489     SymbolFlagsMap Result;
1490     lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1491 
1492     // Run any definition generators.
1493     for (auto &DG : DefGenerators) {
1494 
1495       // Bail out early if we found everything.
1496       if (LookupSet.empty())
1497         break;
1498 
1499       // Run this generator.
1500       if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, LookupSet))
1501         return std::move(Err);
1502 
1503       // Re-try the search.
1504       lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1505     }
1506 
1507     return Result;
1508   });
1509 }
1510 
1511 void JITDylib::lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
1512                                JITDylibLookupFlags JDLookupFlags,
1513                                SymbolLookupSet &LookupSet) {
1514 
1515   LookupSet.forEachWithRemoval(
1516       [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1517         auto I = Symbols.find(Name);
1518         if (I == Symbols.end())
1519           return false;
1520         assert(!Result.count(Name) && "Symbol already present in Flags map");
1521         Result[Name] = I->second.getFlags();
1522         return true;
1523       });
1524 }
1525 
1526 Error JITDylib::lodgeQuery(MaterializationUnitList &MUs,
1527                            std::shared_ptr<AsynchronousSymbolQuery> &Q,
1528                            LookupKind K, JITDylibLookupFlags JDLookupFlags,
1529                            SymbolLookupSet &Unresolved) {
1530   assert(Q && "Query can not be null");
1531 
1532   if (auto Err = lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved))
1533     return Err;
1534 
1535   // Run any definition generators.
1536   for (auto &DG : DefGenerators) {
1537 
1538     // Bail out early if we have resolved everything.
1539     if (Unresolved.empty())
1540       break;
1541 
1542     // Run the generator.
1543     if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, Unresolved))
1544       return Err;
1545 
1546     // Lodge query. This can not fail as any new definitions were added
1547     // by the generator under the session locked. Since they can't have
1548     // started materializing yet they can not have failed.
1549     cantFail(lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved));
1550   }
1551 
1552   return Error::success();
1553 }
1554 
1555 Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs,
1556                                std::shared_ptr<AsynchronousSymbolQuery> &Q,
1557                                LookupKind K, JITDylibLookupFlags JDLookupFlags,
1558                                SymbolLookupSet &Unresolved) {
1559 
1560   return Unresolved.forEachWithRemoval(
1561       [&](const SymbolStringPtr &Name,
1562           SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
1563         // Search for name in symbols. If not found then continue without
1564         // removal.
1565         auto SymI = Symbols.find(Name);
1566         if (SymI == Symbols.end())
1567           return false;
1568 
1569         // If this is a non exported symbol and we're matching exported symbols
1570         // only then skip this symbol without removal.
1571         if (!SymI->second.getFlags().isExported() &&
1572             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly)
1573           return false;
1574 
1575         // If we matched against this symbol but it is in the error state then
1576         // bail out and treat it as a failure to materialize.
1577         if (SymI->second.getFlags().hasError()) {
1578           auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1579           (*FailedSymbolsMap)[this] = {Name};
1580           return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
1581         }
1582 
1583         // If this symbol already meets the required state for then notify the
1584         // query, then remove the symbol and continue.
1585         if (SymI->second.getState() >= Q->getRequiredState()) {
1586           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1587           return true;
1588         }
1589 
1590         // Otherwise this symbol does not yet meet the required state. Check
1591         // whether it has a materializer attached, and if so prepare to run it.
1592         if (SymI->second.hasMaterializerAttached()) {
1593           assert(SymI->second.getAddress() == 0 &&
1594                  "Symbol not resolved but already has address?");
1595           auto UMII = UnmaterializedInfos.find(Name);
1596           assert(UMII != UnmaterializedInfos.end() &&
1597                  "Lazy symbol should have UnmaterializedInfo");
1598           auto MU = std::move(UMII->second->MU);
1599           assert(MU != nullptr && "Materializer should not be null");
1600 
1601           // Move all symbols associated with this MaterializationUnit into
1602           // materializing state.
1603           for (auto &KV : MU->getSymbols()) {
1604             auto SymK = Symbols.find(KV.first);
1605             SymK->second.setMaterializerAttached(false);
1606             SymK->second.setState(SymbolState::Materializing);
1607             UnmaterializedInfos.erase(KV.first);
1608           }
1609 
1610           // Add MU to the list of MaterializationUnits to be materialized.
1611           MUs.push_back(std::move(MU));
1612         }
1613 
1614         // Add the query to the PendingQueries list and continue, deleting the
1615         // element.
1616         assert(SymI->second.getState() != SymbolState::NeverSearched &&
1617                SymI->second.getState() != SymbolState::Ready &&
1618                "By this line the symbol should be materializing");
1619         auto &MI = MaterializingInfos[Name];
1620         MI.addQuery(Q);
1621         Q->addQueryDependence(*this, Name);
1622         return true;
1623       });
1624 }
1625 
1626 Expected<SymbolNameSet>
1627 JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
1628                        SymbolNameSet Names) {
1629   assert(Q && "Query can not be null");
1630 
1631   ES.runOutstandingMUs();
1632 
1633   bool QueryComplete = false;
1634   std::vector<std::unique_ptr<MaterializationUnit>> MUs;
1635 
1636   SymbolLookupSet Unresolved(Names);
1637   auto Err = ES.runSessionLocked([&, this]() -> Error {
1638     QueryComplete = lookupImpl(Q, MUs, Unresolved);
1639 
1640     // Run any definition generators.
1641     for (auto &DG : DefGenerators) {
1642 
1643       // Bail out early if we have resolved everything.
1644       if (Unresolved.empty())
1645         break;
1646 
1647       assert(!QueryComplete && "query complete but unresolved symbols remain?");
1648       if (auto Err = DG->tryToGenerate(LookupKind::Static, *this,
1649                                        JITDylibLookupFlags::MatchAllSymbols,
1650                                        Unresolved))
1651         return Err;
1652 
1653       if (!Unresolved.empty())
1654         QueryComplete = lookupImpl(Q, MUs, Unresolved);
1655     }
1656     return Error::success();
1657   });
1658 
1659   if (Err)
1660     return std::move(Err);
1661 
1662   assert((MUs.empty() || !QueryComplete) &&
1663          "If action flags are set, there should be no work to do (so no MUs)");
1664 
1665   if (QueryComplete)
1666     Q->handleComplete();
1667 
1668   // FIXME: Swap back to the old code below once RuntimeDyld works with
1669   //        callbacks from asynchronous queries.
1670   // Add MUs to the OutstandingMUs list.
1671   {
1672     std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
1673     for (auto &MU : MUs)
1674       ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
1675   }
1676   ES.runOutstandingMUs();
1677 
1678   // Dispatch any required MaterializationUnits for materialization.
1679   // for (auto &MU : MUs)
1680   //  ES.dispatchMaterialization(*this, std::move(MU));
1681 
1682   SymbolNameSet RemainingSymbols;
1683   for (auto &KV : Unresolved)
1684     RemainingSymbols.insert(KV.first);
1685 
1686   return RemainingSymbols;
1687 }
1688 
1689 bool JITDylib::lookupImpl(
1690     std::shared_ptr<AsynchronousSymbolQuery> &Q,
1691     std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
1692     SymbolLookupSet &Unresolved) {
1693   bool QueryComplete = false;
1694 
1695   std::vector<SymbolStringPtr> ToRemove;
1696   Unresolved.forEachWithRemoval(
1697       [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1698         // Search for the name in Symbols. Skip without removing if not found.
1699         auto SymI = Symbols.find(Name);
1700         if (SymI == Symbols.end())
1701           return false;
1702 
1703         // If the symbol is already in the required state then notify the query
1704         // and remove.
1705         if (SymI->second.getState() >= Q->getRequiredState()) {
1706           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1707           if (Q->isComplete())
1708             QueryComplete = true;
1709           return true;
1710         }
1711 
1712         // If the symbol is lazy, get the MaterialiaztionUnit for it.
1713         if (SymI->second.hasMaterializerAttached()) {
1714           assert(SymI->second.getAddress() == 0 &&
1715                  "Lazy symbol should not have a resolved address");
1716           auto UMII = UnmaterializedInfos.find(Name);
1717           assert(UMII != UnmaterializedInfos.end() &&
1718                  "Lazy symbol should have UnmaterializedInfo");
1719           auto MU = std::move(UMII->second->MU);
1720           assert(MU != nullptr && "Materializer should not be null");
1721 
1722           // Kick all symbols associated with this MaterializationUnit into
1723           // materializing state.
1724           for (auto &KV : MU->getSymbols()) {
1725             auto SymK = Symbols.find(KV.first);
1726             assert(SymK != Symbols.end() && "Missing symbol table entry");
1727             SymK->second.setState(SymbolState::Materializing);
1728             SymK->second.setMaterializerAttached(false);
1729             UnmaterializedInfos.erase(KV.first);
1730           }
1731 
1732           // Add MU to the list of MaterializationUnits to be materialized.
1733           MUs.push_back(std::move(MU));
1734         }
1735 
1736         // Add the query to the PendingQueries list.
1737         assert(SymI->second.getState() != SymbolState::NeverSearched &&
1738                SymI->second.getState() != SymbolState::Ready &&
1739                "By this line the symbol should be materializing");
1740         auto &MI = MaterializingInfos[Name];
1741         MI.addQuery(Q);
1742         Q->addQueryDependence(*this, Name);
1743         return true;
1744       });
1745 
1746   return QueryComplete;
1747 }
1748 
1749 void JITDylib::dump(raw_ostream &OS) {
1750   ES.runSessionLocked([&, this]() {
1751     OS << "JITDylib \"" << JITDylibName << "\" (ES: "
1752        << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
1753        << "Search order: " << SearchOrder << "\n"
1754        << "Symbol table:\n";
1755 
1756     for (auto &KV : Symbols) {
1757       OS << "    \"" << *KV.first << "\": ";
1758       if (auto Addr = KV.second.getAddress())
1759         OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
1760            << " ";
1761       else
1762         OS << "<not resolved> ";
1763 
1764       OS << KV.second.getFlags() << " " << KV.second.getState();
1765 
1766       if (KV.second.hasMaterializerAttached()) {
1767         OS << " (Materializer ";
1768         auto I = UnmaterializedInfos.find(KV.first);
1769         assert(I != UnmaterializedInfos.end() &&
1770                "Lazy symbol should have UnmaterializedInfo");
1771         OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";
1772       } else
1773         OS << "\n";
1774     }
1775 
1776     if (!MaterializingInfos.empty())
1777       OS << "  MaterializingInfos entries:\n";
1778     for (auto &KV : MaterializingInfos) {
1779       OS << "    \"" << *KV.first << "\":\n"
1780          << "      " << KV.second.pendingQueries().size()
1781          << " pending queries: { ";
1782       for (const auto &Q : KV.second.pendingQueries())
1783         OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1784       OS << "}\n      Dependants:\n";
1785       for (auto &KV2 : KV.second.Dependants)
1786         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1787       OS << "      Unemitted Dependencies:\n";
1788       for (auto &KV2 : KV.second.UnemittedDependencies)
1789         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1790     }
1791   });
1792 }
1793 
1794 void JITDylib::MaterializingInfo::addQuery(
1795     std::shared_ptr<AsynchronousSymbolQuery> Q) {
1796 
1797   auto I = std::lower_bound(
1798       PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1799       [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1800         return V->getRequiredState() <= S;
1801       });
1802   PendingQueries.insert(I.base(), std::move(Q));
1803 }
1804 
1805 void JITDylib::MaterializingInfo::removeQuery(
1806     const AsynchronousSymbolQuery &Q) {
1807   // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1808   auto I =
1809       std::find_if(PendingQueries.begin(), PendingQueries.end(),
1810                    [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1811                      return V.get() == &Q;
1812                    });
1813   assert(I != PendingQueries.end() &&
1814          "Query is not attached to this MaterializingInfo");
1815   PendingQueries.erase(I);
1816 }
1817 
1818 JITDylib::AsynchronousSymbolQueryList
1819 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1820   AsynchronousSymbolQueryList Result;
1821   while (!PendingQueries.empty()) {
1822     if (PendingQueries.back()->getRequiredState() > RequiredState)
1823       break;
1824 
1825     Result.push_back(std::move(PendingQueries.back()));
1826     PendingQueries.pop_back();
1827   }
1828 
1829   return Result;
1830 }
1831 
1832 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1833     : ES(ES), JITDylibName(std::move(Name)) {
1834   SearchOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1835 }
1836 
1837 Error JITDylib::defineImpl(MaterializationUnit &MU) {
1838   SymbolNameSet Duplicates;
1839   std::vector<SymbolStringPtr> ExistingDefsOverridden;
1840   std::vector<SymbolStringPtr> MUDefsOverridden;
1841 
1842   for (const auto &KV : MU.getSymbols()) {
1843     auto I = Symbols.find(KV.first);
1844 
1845     if (I != Symbols.end()) {
1846       if (KV.second.isStrong()) {
1847         if (I->second.getFlags().isStrong() ||
1848             I->second.getState() > SymbolState::NeverSearched)
1849           Duplicates.insert(KV.first);
1850         else {
1851           assert(I->second.getState() == SymbolState::NeverSearched &&
1852                  "Overridden existing def should be in the never-searched "
1853                  "state");
1854           ExistingDefsOverridden.push_back(KV.first);
1855         }
1856       } else
1857         MUDefsOverridden.push_back(KV.first);
1858     }
1859   }
1860 
1861   // If there were any duplicate definitions then bail out.
1862   if (!Duplicates.empty())
1863     return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1864 
1865   // Discard any overridden defs in this MU.
1866   for (auto &S : MUDefsOverridden)
1867     MU.doDiscard(*this, S);
1868 
1869   // Discard existing overridden defs.
1870   for (auto &S : ExistingDefsOverridden) {
1871 
1872     auto UMII = UnmaterializedInfos.find(S);
1873     assert(UMII != UnmaterializedInfos.end() &&
1874            "Overridden existing def should have an UnmaterializedInfo");
1875     UMII->second->MU->doDiscard(*this, S);
1876   }
1877 
1878   // Finally, add the defs from this MU.
1879   for (auto &KV : MU.getSymbols()) {
1880     auto &SymEntry = Symbols[KV.first];
1881     SymEntry.setFlags(KV.second);
1882     SymEntry.setState(SymbolState::NeverSearched);
1883     SymEntry.setMaterializerAttached(true);
1884   }
1885 
1886   return Error::success();
1887 }
1888 
1889 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1890                                  const SymbolNameSet &QuerySymbols) {
1891   for (auto &QuerySymbol : QuerySymbols) {
1892     assert(MaterializingInfos.count(QuerySymbol) &&
1893            "QuerySymbol does not have MaterializingInfo");
1894     auto &MI = MaterializingInfos[QuerySymbol];
1895     MI.removeQuery(Q);
1896   }
1897 }
1898 
1899 void JITDylib::transferEmittedNodeDependencies(
1900     MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1901     MaterializingInfo &EmittedMI) {
1902   for (auto &KV : EmittedMI.UnemittedDependencies) {
1903     auto &DependencyJD = *KV.first;
1904     SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1905 
1906     for (auto &DependencyName : KV.second) {
1907       auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1908 
1909       // Do not add self dependencies.
1910       if (&DependencyMI == &DependantMI)
1911         continue;
1912 
1913       // If we haven't looked up the dependencies for DependencyJD yet, do it
1914       // now and cache the result.
1915       if (!UnemittedDependenciesOnDependencyJD)
1916         UnemittedDependenciesOnDependencyJD =
1917             &DependantMI.UnemittedDependencies[&DependencyJD];
1918 
1919       DependencyMI.Dependants[this].insert(DependantName);
1920       UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1921     }
1922   }
1923 }
1924 
1925 Platform::~Platform() {}
1926 
1927 Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
1928     ExecutionSession &ES,
1929     const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1930 
1931   DenseMap<JITDylib *, SymbolMap> CompoundResult;
1932   Error CompoundErr = Error::success();
1933   std::mutex LookupMutex;
1934   std::condition_variable CV;
1935   uint64_t Count = InitSyms.size();
1936 
1937   LLVM_DEBUG({
1938     dbgs() << "Issuing init-symbol lookup:\n";
1939     for (auto &KV : InitSyms)
1940       dbgs() << "  " << KV.first->getName() << ": " << KV.second << "\n";
1941   });
1942 
1943   for (auto &KV : InitSyms) {
1944     auto *JD = KV.first;
1945     auto Names = std::move(KV.second);
1946     ES.lookup(
1947         LookupKind::Static,
1948         JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),
1949         std::move(Names), SymbolState::Ready,
1950         [&, JD](Expected<SymbolMap> Result) {
1951           {
1952             std::lock_guard<std::mutex> Lock(LookupMutex);
1953             --Count;
1954             if (Result) {
1955               assert(!CompoundResult.count(JD) &&
1956                      "Duplicate JITDylib in lookup?");
1957               CompoundResult[JD] = std::move(*Result);
1958             } else
1959               CompoundErr =
1960                   joinErrors(std::move(CompoundErr), Result.takeError());
1961           }
1962           CV.notify_one();
1963         },
1964         NoDependenciesToRegister);
1965   }
1966 
1967   std::unique_lock<std::mutex> Lock(LookupMutex);
1968   CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1969 
1970   if (CompoundErr)
1971     return std::move(CompoundErr);
1972 
1973   return std::move(CompoundResult);
1974 }
1975 
1976 ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)
1977     : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {
1978 }
1979 
1980 JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {
1981   return runSessionLocked([&, this]() -> JITDylib * {
1982     for (auto &JD : JDs)
1983       if (JD->getName() == Name)
1984         return JD.get();
1985     return nullptr;
1986   });
1987 }
1988 
1989 JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {
1990   assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
1991   return runSessionLocked([&, this]() -> JITDylib & {
1992     JDs.push_back(
1993         std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name))));
1994     return *JDs.back();
1995   });
1996 }
1997 
1998 Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
1999   auto &JD = createBareJITDylib(Name);
2000   if (P)
2001     if (auto Err = P->setupJITDylib(JD))
2002       return std::move(Err);
2003   return JD;
2004 }
2005 
2006 void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) {
2007   assert(!!Err && "Error should be in failure state");
2008 
2009   bool SendErrorToQuery;
2010   runSessionLocked([&]() {
2011     Q.detach();
2012     SendErrorToQuery = Q.canStillFail();
2013   });
2014 
2015   if (SendErrorToQuery)
2016     Q.handleFailed(std::move(Err));
2017   else
2018     reportError(std::move(Err));
2019 }
2020 
2021 Expected<SymbolMap> ExecutionSession::legacyLookup(
2022     LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
2023     SymbolState RequiredState,
2024     RegisterDependenciesFunction RegisterDependencies) {
2025 #if LLVM_ENABLE_THREADS
2026   // In the threaded case we use promises to return the results.
2027   std::promise<SymbolMap> PromisedResult;
2028   Error ResolutionError = Error::success();
2029   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2030     if (R)
2031       PromisedResult.set_value(std::move(*R));
2032     else {
2033       ErrorAsOutParameter _(&ResolutionError);
2034       ResolutionError = R.takeError();
2035       PromisedResult.set_value(SymbolMap());
2036     }
2037   };
2038 #else
2039   SymbolMap Result;
2040   Error ResolutionError = Error::success();
2041 
2042   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2043     ErrorAsOutParameter _(&ResolutionError);
2044     if (R)
2045       Result = std::move(*R);
2046     else
2047       ResolutionError = R.takeError();
2048   };
2049 #endif
2050 
2051   auto Query = std::make_shared<AsynchronousSymbolQuery>(
2052       SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete));
2053   // FIXME: This should be run session locked along with the registration code
2054   // and error reporting below.
2055   SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
2056 
2057   // If the query was lodged successfully then register the dependencies,
2058   // otherwise fail it with an error.
2059   if (UnresolvedSymbols.empty())
2060     RegisterDependencies(Query->QueryRegistrations);
2061   else {
2062     bool DeliverError = runSessionLocked([&]() {
2063       Query->detach();
2064       return Query->canStillFail();
2065     });
2066     auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
2067     if (DeliverError)
2068       Query->handleFailed(std::move(Err));
2069     else
2070       reportError(std::move(Err));
2071   }
2072 
2073 #if LLVM_ENABLE_THREADS
2074   auto ResultFuture = PromisedResult.get_future();
2075   auto Result = ResultFuture.get();
2076   if (ResolutionError)
2077     return std::move(ResolutionError);
2078   return std::move(Result);
2079 
2080 #else
2081   if (ResolutionError)
2082     return std::move(ResolutionError);
2083 
2084   return Result;
2085 #endif
2086 }
2087 
2088 void ExecutionSession::lookup(
2089     LookupKind K, const JITDylibSearchOrder &SearchOrder,
2090     SymbolLookupSet Symbols, SymbolState RequiredState,
2091     SymbolsResolvedCallback NotifyComplete,
2092     RegisterDependenciesFunction RegisterDependencies) {
2093 
2094   LLVM_DEBUG({
2095     runSessionLocked([&]() {
2096       dbgs() << "Looking up " << Symbols << " in " << SearchOrder
2097              << " (required state: " << RequiredState << ")\n";
2098     });
2099   });
2100 
2101   // lookup can be re-entered recursively if running on a single thread. Run any
2102   // outstanding MUs in case this query depends on them, otherwise this lookup
2103   // will starve waiting for a result from an MU that is stuck in the queue.
2104   runOutstandingMUs();
2105 
2106   auto Unresolved = std::move(Symbols);
2107   std::map<JITDylib *, MaterializationUnitList> CollectedMUsMap;
2108   auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
2109                                                      std::move(NotifyComplete));
2110   bool QueryComplete = false;
2111 
2112   auto LodgingErr = runSessionLocked([&]() -> Error {
2113     auto LodgeQuery = [&]() -> Error {
2114       for (auto &KV : SearchOrder) {
2115         assert(KV.first && "JITDylibList entries must not be null");
2116         assert(!CollectedMUsMap.count(KV.first) &&
2117                "JITDylibList should not contain duplicate entries");
2118 
2119         auto &JD = *KV.first;
2120         auto JDLookupFlags = KV.second;
2121         if (auto Err = JD.lodgeQuery(CollectedMUsMap[&JD], Q, K, JDLookupFlags,
2122                                      Unresolved))
2123           return Err;
2124       }
2125 
2126       // Strip any weakly referenced symbols that were not found.
2127       Unresolved.forEachWithRemoval(
2128           [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) {
2129             if (Flags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2130               Q->dropSymbol(Name);
2131               return true;
2132             }
2133             return false;
2134           });
2135 
2136       if (!Unresolved.empty())
2137         return make_error<SymbolsNotFound>(Unresolved.getSymbolNames());
2138 
2139       return Error::success();
2140     };
2141 
2142     if (auto Err = LodgeQuery()) {
2143       // Query failed.
2144 
2145       // Disconnect the query from its dependencies.
2146       Q->detach();
2147 
2148       // Replace the MUs.
2149       for (auto &KV : CollectedMUsMap)
2150         for (auto &MU : KV.second)
2151           KV.first->replace(std::move(MU));
2152 
2153       return Err;
2154     }
2155 
2156     // Query lodged successfully.
2157 
2158     // Record whether this query is fully ready / resolved. We will use
2159     // this to call handleFullyResolved/handleFullyReady outside the session
2160     // lock.
2161     QueryComplete = Q->isComplete();
2162 
2163     // Call the register dependencies function.
2164     if (RegisterDependencies && !Q->QueryRegistrations.empty())
2165       RegisterDependencies(Q->QueryRegistrations);
2166 
2167     return Error::success();
2168   });
2169 
2170   if (LodgingErr) {
2171     Q->handleFailed(std::move(LodgingErr));
2172     return;
2173   }
2174 
2175   if (QueryComplete)
2176     Q->handleComplete();
2177 
2178   // Move the MUs to the OutstandingMUs list, then materialize.
2179   {
2180     std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2181 
2182     for (auto &KV : CollectedMUsMap)
2183       for (auto &MU : KV.second)
2184         OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
2185   }
2186 
2187   runOutstandingMUs();
2188 }
2189 
2190 Expected<SymbolMap>
2191 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2192                          const SymbolLookupSet &Symbols, LookupKind K,
2193                          SymbolState RequiredState,
2194                          RegisterDependenciesFunction RegisterDependencies) {
2195 #if LLVM_ENABLE_THREADS
2196   // In the threaded case we use promises to return the results.
2197   std::promise<SymbolMap> PromisedResult;
2198   Error ResolutionError = Error::success();
2199 
2200   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2201     if (R)
2202       PromisedResult.set_value(std::move(*R));
2203     else {
2204       ErrorAsOutParameter _(&ResolutionError);
2205       ResolutionError = R.takeError();
2206       PromisedResult.set_value(SymbolMap());
2207     }
2208   };
2209 
2210 #else
2211   SymbolMap Result;
2212   Error ResolutionError = Error::success();
2213 
2214   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2215     ErrorAsOutParameter _(&ResolutionError);
2216     if (R)
2217       Result = std::move(*R);
2218     else
2219       ResolutionError = R.takeError();
2220   };
2221 #endif
2222 
2223   // Perform the asynchronous lookup.
2224   lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
2225          RegisterDependencies);
2226 
2227 #if LLVM_ENABLE_THREADS
2228   auto ResultFuture = PromisedResult.get_future();
2229   auto Result = ResultFuture.get();
2230 
2231   if (ResolutionError)
2232     return std::move(ResolutionError);
2233 
2234   return std::move(Result);
2235 
2236 #else
2237   if (ResolutionError)
2238     return std::move(ResolutionError);
2239 
2240   return Result;
2241 #endif
2242 }
2243 
2244 Expected<JITEvaluatedSymbol>
2245 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2246                          SymbolStringPtr Name, SymbolState RequiredState) {
2247   SymbolLookupSet Names({Name});
2248 
2249   if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
2250                               RequiredState, NoDependenciesToRegister)) {
2251     assert(ResultMap->size() == 1 && "Unexpected number of results");
2252     assert(ResultMap->count(Name) && "Missing result for symbol");
2253     return std::move(ResultMap->begin()->second);
2254   } else
2255     return ResultMap.takeError();
2256 }
2257 
2258 Expected<JITEvaluatedSymbol>
2259 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
2260                          SymbolState RequiredState) {
2261   return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
2262 }
2263 
2264 Expected<JITEvaluatedSymbol>
2265 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
2266                          SymbolState RequiredState) {
2267   return lookup(SearchOrder, intern(Name), RequiredState);
2268 }
2269 
2270 void ExecutionSession::dump(raw_ostream &OS) {
2271   runSessionLocked([this, &OS]() {
2272     for (auto &JD : JDs)
2273       JD->dump(OS);
2274   });
2275 }
2276 
2277 void ExecutionSession::runOutstandingMUs() {
2278   while (1) {
2279     std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU;
2280 
2281     {
2282       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2283       if (!OutstandingMUs.empty()) {
2284         JITDylibAndMU = std::move(OutstandingMUs.back());
2285         OutstandingMUs.pop_back();
2286       }
2287     }
2288 
2289     if (JITDylibAndMU.first) {
2290       assert(JITDylibAndMU.second && "JITDylib, but no MU?");
2291       dispatchMaterialization(*JITDylibAndMU.first,
2292                               std::move(JITDylibAndMU.second));
2293     } else
2294       break;
2295   }
2296 }
2297 
2298 } // End namespace orc.
2299 } // End namespace llvm.
2300