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   assert(SymbolFlags.count(Name) &&
564          "Symbol not covered by this MaterializationResponsibility instance");
565   JD.addDependencies(Name, Dependencies);
566 }
567 
568 void MaterializationResponsibility::addDependenciesForAll(
569     const SymbolDependenceMap &Dependencies) {
570   for (auto &KV : SymbolFlags)
571     JD.addDependencies(KV.first, Dependencies);
572 }
573 
574 AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
575     SymbolMap Symbols, VModuleKey K)
576     : MaterializationUnit(extractFlags(Symbols), nullptr, std::move(K)),
577       Symbols(std::move(Symbols)) {}
578 
579 StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
580   return "<Absolute Symbols>";
581 }
582 
583 void AbsoluteSymbolsMaterializationUnit::materialize(
584     MaterializationResponsibility R) {
585   // No dependencies, so these calls can't fail.
586   cantFail(R.notifyResolved(Symbols));
587   cantFail(R.notifyEmitted());
588 }
589 
590 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
591                                                  const SymbolStringPtr &Name) {
592   assert(Symbols.count(Name) && "Symbol is not part of this MU");
593   Symbols.erase(Name);
594 }
595 
596 SymbolFlagsMap
597 AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
598   SymbolFlagsMap Flags;
599   for (const auto &KV : Symbols)
600     Flags[KV.first] = KV.second.getFlags();
601   return Flags;
602 }
603 
604 ReExportsMaterializationUnit::ReExportsMaterializationUnit(
605     JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
606     SymbolAliasMap Aliases, VModuleKey K)
607     : MaterializationUnit(extractFlags(Aliases), nullptr, std::move(K)),
608       SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
609       Aliases(std::move(Aliases)) {}
610 
611 StringRef ReExportsMaterializationUnit::getName() const {
612   return "<Reexports>";
613 }
614 
615 void ReExportsMaterializationUnit::materialize(
616     MaterializationResponsibility R) {
617 
618   auto &ES = R.getTargetJITDylib().getExecutionSession();
619   JITDylib &TgtJD = R.getTargetJITDylib();
620   JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
621 
622   // Find the set of requested aliases and aliasees. Return any unrequested
623   // aliases back to the JITDylib so as to not prematurely materialize any
624   // aliasees.
625   auto RequestedSymbols = R.getRequestedSymbols();
626   SymbolAliasMap RequestedAliases;
627 
628   for (auto &Name : RequestedSymbols) {
629     auto I = Aliases.find(Name);
630     assert(I != Aliases.end() && "Symbol not found in aliases map?");
631     RequestedAliases[Name] = std::move(I->second);
632     Aliases.erase(I);
633   }
634 
635   LLVM_DEBUG({
636     ES.runSessionLocked([&]() {
637       dbgs() << "materializing reexports: target = " << TgtJD.getName()
638              << ", source = " << SrcJD.getName() << " " << RequestedAliases
639              << "\n";
640     });
641   });
642 
643   if (!Aliases.empty()) {
644     if (SourceJD)
645       R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags));
646     else
647       R.replace(symbolAliases(std::move(Aliases)));
648   }
649 
650   // The OnResolveInfo struct will hold the aliases and responsibilty for each
651   // query in the list.
652   struct OnResolveInfo {
653     OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases)
654         : R(std::move(R)), Aliases(std::move(Aliases)) {}
655 
656     MaterializationResponsibility R;
657     SymbolAliasMap Aliases;
658   };
659 
660   // Build a list of queries to issue. In each round we build the largest set of
661   // aliases that we can resolve without encountering a chain definition of the
662   // form Foo -> Bar, Bar -> Baz. Such a form would deadlock as the query would
663   // be waitin on a symbol that it itself had to resolve. Usually this will just
664   // involve one round and a single query.
665 
666   std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
667       QueryInfos;
668   while (!RequestedAliases.empty()) {
669     SymbolNameSet ResponsibilitySymbols;
670     SymbolLookupSet QuerySymbols;
671     SymbolAliasMap QueryAliases;
672 
673     // Collect as many aliases as we can without including a chain.
674     for (auto &KV : RequestedAliases) {
675       // Chain detected. Skip this symbol for this round.
676       if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
677                                RequestedAliases.count(KV.second.Aliasee)))
678         continue;
679 
680       ResponsibilitySymbols.insert(KV.first);
681       QuerySymbols.add(KV.second.Aliasee);
682       QueryAliases[KV.first] = std::move(KV.second);
683     }
684 
685     // Remove the aliases collected this round from the RequestedAliases map.
686     for (auto &KV : QueryAliases)
687       RequestedAliases.erase(KV.first);
688 
689     assert(!QuerySymbols.empty() && "Alias cycle detected!");
690 
691     auto QueryInfo = std::make_shared<OnResolveInfo>(
692         R.delegate(ResponsibilitySymbols), std::move(QueryAliases));
693     QueryInfos.push_back(
694         make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
695   }
696 
697   // Issue the queries.
698   while (!QueryInfos.empty()) {
699     auto QuerySymbols = std::move(QueryInfos.back().first);
700     auto QueryInfo = std::move(QueryInfos.back().second);
701 
702     QueryInfos.pop_back();
703 
704     auto RegisterDependencies = [QueryInfo,
705                                  &SrcJD](const SymbolDependenceMap &Deps) {
706       // If there were no materializing symbols, just bail out.
707       if (Deps.empty())
708         return;
709 
710       // Otherwise the only deps should be on SrcJD.
711       assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
712              "Unexpected dependencies for reexports");
713 
714       auto &SrcJDDeps = Deps.find(&SrcJD)->second;
715       SymbolDependenceMap PerAliasDepsMap;
716       auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
717 
718       for (auto &KV : QueryInfo->Aliases)
719         if (SrcJDDeps.count(KV.second.Aliasee)) {
720           PerAliasDeps = {KV.second.Aliasee};
721           QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
722         }
723     };
724 
725     auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
726       auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
727       if (Result) {
728         SymbolMap ResolutionMap;
729         for (auto &KV : QueryInfo->Aliases) {
730           assert(Result->count(KV.second.Aliasee) &&
731                  "Result map missing entry?");
732           ResolutionMap[KV.first] = JITEvaluatedSymbol(
733               (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
734         }
735         if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) {
736           ES.reportError(std::move(Err));
737           QueryInfo->R.failMaterialization();
738           return;
739         }
740         if (auto Err = QueryInfo->R.notifyEmitted()) {
741           ES.reportError(std::move(Err));
742           QueryInfo->R.failMaterialization();
743           return;
744         }
745       } else {
746         ES.reportError(Result.takeError());
747         QueryInfo->R.failMaterialization();
748       }
749     };
750 
751     ES.lookup(LookupKind::Static,
752               JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
753               QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
754               std::move(RegisterDependencies));
755   }
756 }
757 
758 void ReExportsMaterializationUnit::discard(const JITDylib &JD,
759                                            const SymbolStringPtr &Name) {
760   assert(Aliases.count(Name) &&
761          "Symbol not covered by this MaterializationUnit");
762   Aliases.erase(Name);
763 }
764 
765 SymbolFlagsMap
766 ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
767   SymbolFlagsMap SymbolFlags;
768   for (auto &KV : Aliases)
769     SymbolFlags[KV.first] = KV.second.AliasFlags;
770 
771   return SymbolFlags;
772 }
773 
774 Expected<SymbolAliasMap>
775 buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols) {
776   SymbolLookupSet LookupSet(Symbols);
777   auto Flags = SourceJD.lookupFlags(
778       LookupKind::Static, JITDylibLookupFlags::MatchAllSymbols, LookupSet);
779 
780   if (!Flags)
781     return Flags.takeError();
782 
783   if (!LookupSet.empty()) {
784     LookupSet.sortByName();
785     return make_error<SymbolsNotFound>(LookupSet.getSymbolNames());
786   }
787 
788   SymbolAliasMap Result;
789   for (auto &Name : Symbols) {
790     assert(Flags->count(Name) && "Missing entry in flags map");
791     Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
792   }
793 
794   return Result;
795 }
796 
797 ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
798                                        JITDylibLookupFlags SourceJDLookupFlags,
799                                        SymbolPredicate Allow)
800     : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
801       Allow(std::move(Allow)) {}
802 
803 Error ReexportsGenerator::tryToGenerate(LookupKind K, JITDylib &JD,
804                                         JITDylibLookupFlags JDLookupFlags,
805                                         const SymbolLookupSet &LookupSet) {
806   assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
807 
808   // Use lookupFlags to find the subset of symbols that match our lookup.
809   auto Flags = SourceJD.lookupFlags(K, JDLookupFlags, LookupSet);
810   if (!Flags)
811     return Flags.takeError();
812 
813   // Create an alias map.
814   orc::SymbolAliasMap AliasMap;
815   for (auto &KV : *Flags)
816     if (!Allow || Allow(KV.first))
817       AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
818 
819   if (AliasMap.empty())
820     return Error::success();
821 
822   // Define the re-exports.
823   return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
824 }
825 
826 JITDylib::DefinitionGenerator::~DefinitionGenerator() {}
827 
828 void JITDylib::removeGenerator(DefinitionGenerator &G) {
829   ES.runSessionLocked([&]() {
830     auto I = std::find_if(DefGenerators.begin(), DefGenerators.end(),
831                           [&](const std::unique_ptr<DefinitionGenerator> &H) {
832                             return H.get() == &G;
833                           });
834     assert(I != DefGenerators.end() && "Generator not found");
835     DefGenerators.erase(I);
836   });
837 }
838 
839 Expected<SymbolFlagsMap>
840 JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
841 
842   return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
843     std::vector<SymbolTable::iterator> AddedSyms;
844     std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
845 
846     for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
847          SFItr != SFEnd; ++SFItr) {
848 
849       auto &Name = SFItr->first;
850       auto &Flags = SFItr->second;
851 
852       auto EntryItr = Symbols.find(Name);
853 
854       // If the entry already exists...
855       if (EntryItr != Symbols.end()) {
856 
857         // If this is a strong definition then error out.
858         if (!Flags.isWeak()) {
859           // Remove any symbols already added.
860           for (auto &SI : AddedSyms)
861             Symbols.erase(SI);
862 
863           // FIXME: Return all duplicates.
864           return make_error<DuplicateDefinition>(std::string(*Name));
865         }
866 
867         // Otherwise just make a note to discard this symbol after the loop.
868         RejectedWeakDefs.push_back(SFItr);
869         continue;
870       } else
871         EntryItr =
872           Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
873 
874       AddedSyms.push_back(EntryItr);
875       EntryItr->second.setState(SymbolState::Materializing);
876     }
877 
878     // Remove any rejected weak definitions from the SymbolFlags map.
879     while (!RejectedWeakDefs.empty()) {
880       SymbolFlags.erase(RejectedWeakDefs.back());
881       RejectedWeakDefs.pop_back();
882     }
883 
884     return SymbolFlags;
885   });
886 }
887 
888 void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) {
889   assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
890 
891   auto MustRunMU =
892       ES.runSessionLocked([&, this]() -> std::unique_ptr<MaterializationUnit> {
893 
894 #ifndef NDEBUG
895         for (auto &KV : MU->getSymbols()) {
896           auto SymI = Symbols.find(KV.first);
897           assert(SymI != Symbols.end() && "Replacing unknown symbol");
898           assert(SymI->second.isInMaterializationPhase() &&
899                  "Can not call replace on a symbol that is not materializing");
900           assert(!SymI->second.hasMaterializerAttached() &&
901                  "Symbol should not have materializer attached already");
902           assert(UnmaterializedInfos.count(KV.first) == 0 &&
903                  "Symbol being replaced should have no UnmaterializedInfo");
904         }
905 #endif // NDEBUG
906 
907         // If any symbol has pending queries against it then we need to
908         // materialize MU immediately.
909         for (auto &KV : MU->getSymbols()) {
910           auto MII = MaterializingInfos.find(KV.first);
911           if (MII != MaterializingInfos.end()) {
912             if (MII->second.hasQueriesPending())
913               return std::move(MU);
914           }
915         }
916 
917         // Otherwise, make MU responsible for all the symbols.
918         auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
919         for (auto &KV : UMI->MU->getSymbols()) {
920           auto SymI = Symbols.find(KV.first);
921           assert(SymI->second.getState() == SymbolState::Materializing &&
922                  "Can not replace a symbol that is not materializing");
923           assert(!SymI->second.hasMaterializerAttached() &&
924                  "Can not replace a symbol that has a materializer attached");
925           assert(UnmaterializedInfos.count(KV.first) == 0 &&
926                  "Unexpected materializer entry in map");
927           SymI->second.setAddress(SymI->second.getAddress());
928           SymI->second.setMaterializerAttached(true);
929           UnmaterializedInfos[KV.first] = UMI;
930         }
931 
932         return nullptr;
933       });
934 
935   if (MustRunMU)
936     ES.dispatchMaterialization(*this, std::move(MustRunMU));
937 }
938 
939 SymbolNameSet
940 JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
941   return ES.runSessionLocked([&]() {
942     SymbolNameSet RequestedSymbols;
943 
944     for (auto &KV : SymbolFlags) {
945       assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
946       assert(Symbols.find(KV.first)->second.isInMaterializationPhase() &&
947              "getRequestedSymbols can only be called for symbols that have "
948              "started materializing");
949       auto I = MaterializingInfos.find(KV.first);
950       if (I == MaterializingInfos.end())
951         continue;
952 
953       if (I->second.hasQueriesPending())
954         RequestedSymbols.insert(KV.first);
955     }
956 
957     return RequestedSymbols;
958   });
959 }
960 
961 void JITDylib::addDependencies(const SymbolStringPtr &Name,
962                                const SymbolDependenceMap &Dependencies) {
963   assert(Symbols.count(Name) && "Name not in symbol table");
964   assert(Symbols[Name].isInMaterializationPhase() &&
965          "Can not add dependencies for a symbol that is not materializing");
966 
967   LLVM_DEBUG({
968       dbgs() << "In " << getName() << " adding dependencies for "
969              << *Name << ": " << Dependencies << "\n";
970     });
971 
972   // If Name is already in an error state then just bail out.
973   if (Symbols[Name].getFlags().hasError())
974     return;
975 
976   auto &MI = MaterializingInfos[Name];
977   assert(Symbols[Name].getState() != SymbolState::Emitted &&
978          "Can not add dependencies to an emitted symbol");
979 
980   bool DependsOnSymbolInErrorState = false;
981 
982   // Register dependencies, record whether any depenendency is in the error
983   // state.
984   for (auto &KV : Dependencies) {
985     assert(KV.first && "Null JITDylib in dependency?");
986     auto &OtherJITDylib = *KV.first;
987     auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
988 
989     for (auto &OtherSymbol : KV.second) {
990 
991       // Check the sym entry for the dependency.
992       auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
993 
994 #ifndef NDEBUG
995       // Assert that this symbol exists and has not reached the ready state
996       // already.
997       assert(OtherSymI != OtherJITDylib.Symbols.end() &&
998              (OtherSymI->second.getState() < SymbolState::Ready &&
999               "Dependency on emitted/ready symbol"));
1000 #endif
1001 
1002       auto &OtherSymEntry = OtherSymI->second;
1003 
1004       // If the dependency is in an error state then note this and continue,
1005       // we will move this symbol to the error state below.
1006       if (OtherSymEntry.getFlags().hasError()) {
1007         DependsOnSymbolInErrorState = true;
1008         continue;
1009       }
1010 
1011       // If the dependency was not in the error state then add it to
1012       // our list of dependencies.
1013       assert(OtherJITDylib.MaterializingInfos.count(OtherSymbol) &&
1014              "No MaterializingInfo for dependency");
1015       auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
1016 
1017       if (OtherSymEntry.getState() == SymbolState::Emitted)
1018         transferEmittedNodeDependencies(MI, Name, OtherMI);
1019       else if (&OtherJITDylib != this || OtherSymbol != Name) {
1020         OtherMI.Dependants[this].insert(Name);
1021         DepsOnOtherJITDylib.insert(OtherSymbol);
1022       }
1023     }
1024 
1025     if (DepsOnOtherJITDylib.empty())
1026       MI.UnemittedDependencies.erase(&OtherJITDylib);
1027   }
1028 
1029   // If this symbol dependended on any symbols in the error state then move
1030   // this symbol to the error state too.
1031   if (DependsOnSymbolInErrorState)
1032     Symbols[Name].setFlags(Symbols[Name].getFlags() | JITSymbolFlags::HasError);
1033 }
1034 
1035 Error JITDylib::resolve(const SymbolMap &Resolved) {
1036   SymbolNameSet SymbolsInErrorState;
1037   AsynchronousSymbolQuerySet CompletedQueries;
1038 
1039   ES.runSessionLocked([&, this]() {
1040     struct WorklistEntry {
1041       SymbolTable::iterator SymI;
1042       JITEvaluatedSymbol ResolvedSym;
1043     };
1044 
1045     std::vector<WorklistEntry> Worklist;
1046     Worklist.reserve(Resolved.size());
1047 
1048     // Build worklist and check for any symbols in the error state.
1049     for (const auto &KV : Resolved) {
1050 
1051       assert(!KV.second.getFlags().hasError() &&
1052              "Resolution result can not have error flag set");
1053 
1054       auto SymI = Symbols.find(KV.first);
1055 
1056       assert(SymI != Symbols.end() && "Symbol not found");
1057       assert(!SymI->second.hasMaterializerAttached() &&
1058              "Resolving symbol with materializer attached?");
1059       assert(SymI->second.getState() == SymbolState::Materializing &&
1060              "Symbol should be materializing");
1061       assert(SymI->second.getAddress() == 0 &&
1062              "Symbol has already been resolved");
1063 
1064       if (SymI->second.getFlags().hasError())
1065         SymbolsInErrorState.insert(KV.first);
1066       else {
1067         auto Flags = KV.second.getFlags();
1068         Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common);
1069         assert(Flags == (SymI->second.getFlags() &
1070                          ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&
1071                "Resolved flags should match the declared flags");
1072 
1073         Worklist.push_back(
1074             {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
1075       }
1076     }
1077 
1078     // If any symbols were in the error state then bail out.
1079     if (!SymbolsInErrorState.empty())
1080       return;
1081 
1082     while (!Worklist.empty()) {
1083       auto SymI = Worklist.back().SymI;
1084       auto ResolvedSym = Worklist.back().ResolvedSym;
1085       Worklist.pop_back();
1086 
1087       auto &Name = SymI->first;
1088 
1089       // Resolved symbols can not be weak: discard the weak flag.
1090       JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
1091       SymI->second.setAddress(ResolvedSym.getAddress());
1092       SymI->second.setFlags(ResolvedFlags);
1093       SymI->second.setState(SymbolState::Resolved);
1094 
1095       auto &MI = MaterializingInfos[Name];
1096       for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
1097         Q->notifySymbolMetRequiredState(Name, ResolvedSym);
1098         Q->removeQueryDependence(*this, Name);
1099         if (Q->isComplete())
1100           CompletedQueries.insert(std::move(Q));
1101       }
1102     }
1103   });
1104 
1105   assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
1106          "Can't fail symbols and completed queries at the same time");
1107 
1108   // If we failed any symbols then return an error.
1109   if (!SymbolsInErrorState.empty()) {
1110     auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1111     (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1112     return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1113   }
1114 
1115   // Otherwise notify all the completed queries.
1116   for (auto &Q : CompletedQueries) {
1117     assert(Q->isComplete() && "Q not completed");
1118     Q->handleComplete();
1119   }
1120 
1121   return Error::success();
1122 }
1123 
1124 Error JITDylib::emit(const SymbolFlagsMap &Emitted) {
1125   AsynchronousSymbolQuerySet CompletedQueries;
1126   SymbolNameSet SymbolsInErrorState;
1127   DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
1128 
1129   ES.runSessionLocked([&, this]() {
1130     std::vector<SymbolTable::iterator> Worklist;
1131 
1132     // Scan to build worklist, record any symbols in the erorr state.
1133     for (const auto &KV : Emitted) {
1134       auto &Name = KV.first;
1135 
1136       auto SymI = Symbols.find(Name);
1137       assert(SymI != Symbols.end() && "No symbol table entry for Name");
1138 
1139       if (SymI->second.getFlags().hasError())
1140         SymbolsInErrorState.insert(Name);
1141       else
1142         Worklist.push_back(SymI);
1143     }
1144 
1145     // If any symbols were in the error state then bail out.
1146     if (!SymbolsInErrorState.empty())
1147       return;
1148 
1149     // Otherwise update dependencies and move to the emitted state.
1150     while (!Worklist.empty()) {
1151       auto SymI = Worklist.back();
1152       Worklist.pop_back();
1153 
1154       auto &Name = SymI->first;
1155       auto &SymEntry = SymI->second;
1156 
1157       // Move symbol to the emitted state.
1158       assert(SymEntry.getState() == SymbolState::Resolved &&
1159              "Emitting from state other than Resolved");
1160       SymEntry.setState(SymbolState::Emitted);
1161 
1162       auto MII = MaterializingInfos.find(Name);
1163       assert(MII != MaterializingInfos.end() &&
1164              "Missing MaterializingInfo entry");
1165       auto &MI = MII->second;
1166 
1167       // For each dependant, transfer this node's emitted dependencies to
1168       // it. If the dependant node is ready (i.e. has no unemitted
1169       // dependencies) then notify any pending queries.
1170       for (auto &KV : MI.Dependants) {
1171         auto &DependantJD = *KV.first;
1172         auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1173         for (auto &DependantName : KV.second) {
1174           auto DependantMII =
1175               DependantJD.MaterializingInfos.find(DependantName);
1176           assert(DependantMII != DependantJD.MaterializingInfos.end() &&
1177                  "Dependant should have MaterializingInfo");
1178 
1179           auto &DependantMI = DependantMII->second;
1180 
1181           // Remove the dependant's dependency on this node.
1182           assert(DependantMI.UnemittedDependencies.count(this) &&
1183                  "Dependant does not have an unemitted dependencies record for "
1184                  "this JITDylib");
1185           assert(DependantMI.UnemittedDependencies[this].count(Name) &&
1186                  "Dependant does not count this symbol as a dependency?");
1187 
1188           DependantMI.UnemittedDependencies[this].erase(Name);
1189           if (DependantMI.UnemittedDependencies[this].empty())
1190             DependantMI.UnemittedDependencies.erase(this);
1191 
1192           // Transfer unemitted dependencies from this node to the dependant.
1193           DependantJD.transferEmittedNodeDependencies(DependantMI,
1194                                                       DependantName, MI);
1195 
1196           auto DependantSymI = DependantJD.Symbols.find(DependantName);
1197           assert(DependantSymI != DependantJD.Symbols.end() &&
1198                  "Dependant has no entry in the Symbols table");
1199           auto &DependantSymEntry = DependantSymI->second;
1200 
1201           // If the dependant is emitted and this node was the last of its
1202           // unemitted dependencies then the dependant node is now ready, so
1203           // notify any pending queries on the dependant node.
1204           if (DependantSymEntry.getState() == SymbolState::Emitted &&
1205               DependantMI.UnemittedDependencies.empty()) {
1206             assert(DependantMI.Dependants.empty() &&
1207                    "Dependants should be empty by now");
1208 
1209             // Since this dependant is now ready, we erase its MaterializingInfo
1210             // and update its materializing state.
1211             DependantSymEntry.setState(SymbolState::Ready);
1212             DependantJDReadySymbols.push_back(DependantName);
1213 
1214             for (auto &Q : DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1215               Q->notifySymbolMetRequiredState(
1216                   DependantName, DependantSymI->second.getSymbol());
1217               if (Q->isComplete())
1218                 CompletedQueries.insert(Q);
1219               Q->removeQueryDependence(DependantJD, DependantName);
1220             }
1221           }
1222         }
1223       }
1224 
1225       auto &ThisJDReadySymbols = ReadySymbols[this];
1226       MI.Dependants.clear();
1227       if (MI.UnemittedDependencies.empty()) {
1228         SymI->second.setState(SymbolState::Ready);
1229         ThisJDReadySymbols.push_back(Name);
1230         for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1231           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1232           if (Q->isComplete())
1233             CompletedQueries.insert(Q);
1234           Q->removeQueryDependence(*this, Name);
1235         }
1236       }
1237     }
1238   });
1239 
1240   assert((SymbolsInErrorState.empty() || CompletedQueries.empty()) &&
1241          "Can't fail symbols and completed queries at the same time");
1242 
1243   // If we failed any symbols then return an error.
1244   if (!SymbolsInErrorState.empty()) {
1245     auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1246     (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1247     return make_error<FailedToMaterialize>(std::move(FailedSymbolsDepMap));
1248   }
1249 
1250   // Otherwise notify all the completed queries.
1251   for (auto &Q : CompletedQueries) {
1252     assert(Q->isComplete() && "Q is not complete");
1253     Q->handleComplete();
1254   }
1255 
1256   return Error::success();
1257 }
1258 
1259 void JITDylib::notifyFailed(FailedSymbolsWorklist Worklist) {
1260   AsynchronousSymbolQuerySet FailedQueries;
1261   auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1262 
1263   // Failing no symbols is a no-op.
1264   if (Worklist.empty())
1265     return;
1266 
1267   auto &ES = Worklist.front().first->getExecutionSession();
1268 
1269   ES.runSessionLocked([&]() {
1270     while (!Worklist.empty()) {
1271       assert(Worklist.back().first && "Failed JITDylib can not be null");
1272       auto &JD = *Worklist.back().first;
1273       auto Name = std::move(Worklist.back().second);
1274       Worklist.pop_back();
1275 
1276       (*FailedSymbolsMap)[&JD].insert(Name);
1277 
1278       assert(JD.Symbols.count(Name) && "No symbol table entry for Name");
1279       auto &Sym = JD.Symbols[Name];
1280 
1281       // Move the symbol into the error state.
1282       // Note that this may be redundant: The symbol might already have been
1283       // moved to this state in response to the failure of a dependence.
1284       Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1285 
1286       // FIXME: Come up with a sane mapping of state to
1287       // presence-of-MaterializingInfo so that we can assert presence / absence
1288       // here, rather than testing it.
1289       auto MII = JD.MaterializingInfos.find(Name);
1290 
1291       if (MII == JD.MaterializingInfos.end())
1292         continue;
1293 
1294       auto &MI = MII->second;
1295 
1296       // Move all dependants to the error state and disconnect from them.
1297       for (auto &KV : MI.Dependants) {
1298         auto &DependantJD = *KV.first;
1299         for (auto &DependantName : KV.second) {
1300           assert(DependantJD.Symbols.count(DependantName) &&
1301                  "No symbol table entry for DependantName");
1302           auto &DependantSym = DependantJD.Symbols[DependantName];
1303           DependantSym.setFlags(DependantSym.getFlags() |
1304                                 JITSymbolFlags::HasError);
1305 
1306           assert(DependantJD.MaterializingInfos.count(DependantName) &&
1307                  "No MaterializingInfo for dependant");
1308           auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1309 
1310           auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1311           assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
1312                  "No UnemittedDependencies entry for this JITDylib");
1313           assert(UnemittedDepI->second.count(Name) &&
1314                  "No UnemittedDependencies entry for this symbol");
1315           UnemittedDepI->second.erase(Name);
1316           if (UnemittedDepI->second.empty())
1317             DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1318 
1319           // If this symbol is already in the emitted state then we need to
1320           // take responsibility for failing its queries, so add it to the
1321           // worklist.
1322           if (DependantSym.getState() == SymbolState::Emitted) {
1323             assert(DependantMI.Dependants.empty() &&
1324                    "Emitted symbol should not have dependants");
1325             Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1326           }
1327         }
1328       }
1329       MI.Dependants.clear();
1330 
1331       // Disconnect from all unemitted depenencies.
1332       for (auto &KV : MI.UnemittedDependencies) {
1333         auto &UnemittedDepJD = *KV.first;
1334         for (auto &UnemittedDepName : KV.second) {
1335           auto UnemittedDepMII =
1336               UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1337           assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
1338                  "Missing MII for unemitted dependency");
1339           assert(UnemittedDepMII->second.Dependants.count(&JD) &&
1340                  "JD not listed as a dependant of unemitted dependency");
1341           assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
1342                  "Name is not listed as a dependant of unemitted dependency");
1343           UnemittedDepMII->second.Dependants[&JD].erase(Name);
1344           if (UnemittedDepMII->second.Dependants[&JD].empty())
1345             UnemittedDepMII->second.Dependants.erase(&JD);
1346         }
1347       }
1348       MI.UnemittedDependencies.clear();
1349 
1350       // Collect queries to be failed for this MII.
1351       AsynchronousSymbolQueryList ToDetach;
1352       for (auto &Q : MII->second.pendingQueries()) {
1353         // Add the query to the list to be failed and detach it.
1354         FailedQueries.insert(Q);
1355         ToDetach.push_back(Q);
1356       }
1357       for (auto &Q : ToDetach)
1358         Q->detach();
1359 
1360       assert(MI.Dependants.empty() &&
1361              "Can not delete MaterializingInfo with dependants still attached");
1362       assert(MI.UnemittedDependencies.empty() &&
1363              "Can not delete MaterializingInfo with unemitted dependencies "
1364              "still attached");
1365       assert(!MI.hasQueriesPending() &&
1366              "Can not delete MaterializingInfo with queries pending");
1367       JD.MaterializingInfos.erase(MII);
1368     }
1369   });
1370 
1371   for (auto &Q : FailedQueries)
1372     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbolsMap));
1373 }
1374 
1375 void JITDylib::setSearchOrder(JITDylibSearchOrder NewSearchOrder,
1376                               bool SearchThisJITDylibFirst) {
1377   ES.runSessionLocked([&]() {
1378     if (SearchThisJITDylibFirst) {
1379       SearchOrder.clear();
1380       if (NewSearchOrder.empty() || NewSearchOrder.front().first != this)
1381         SearchOrder.push_back(
1382             std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1383       SearchOrder.insert(SearchOrder.end(), NewSearchOrder.begin(),
1384                          NewSearchOrder.end());
1385     } else
1386       SearchOrder = std::move(NewSearchOrder);
1387   });
1388 }
1389 
1390 void JITDylib::addToSearchOrder(JITDylib &JD,
1391                                 JITDylibLookupFlags JDLookupFlags) {
1392   ES.runSessionLocked([&]() { SearchOrder.push_back({&JD, JDLookupFlags}); });
1393 }
1394 
1395 void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
1396                                     JITDylibLookupFlags JDLookupFlags) {
1397   ES.runSessionLocked([&]() {
1398     for (auto &KV : SearchOrder)
1399       if (KV.first == &OldJD) {
1400         KV = {&NewJD, JDLookupFlags};
1401         break;
1402       }
1403   });
1404 }
1405 
1406 void JITDylib::removeFromSearchOrder(JITDylib &JD) {
1407   ES.runSessionLocked([&]() {
1408     auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
1409                           [&](const JITDylibSearchOrder::value_type &KV) {
1410                             return KV.first == &JD;
1411                           });
1412     if (I != SearchOrder.end())
1413       SearchOrder.erase(I);
1414   });
1415 }
1416 
1417 Error JITDylib::remove(const SymbolNameSet &Names) {
1418   return ES.runSessionLocked([&]() -> Error {
1419     using SymbolMaterializerItrPair =
1420         std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1421     std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1422     SymbolNameSet Missing;
1423     SymbolNameSet Materializing;
1424 
1425     for (auto &Name : Names) {
1426       auto I = Symbols.find(Name);
1427 
1428       // Note symbol missing.
1429       if (I == Symbols.end()) {
1430         Missing.insert(Name);
1431         continue;
1432       }
1433 
1434       // Note symbol materializing.
1435       if (I->second.isInMaterializationPhase()) {
1436         Materializing.insert(Name);
1437         continue;
1438       }
1439 
1440       auto UMII = I->second.hasMaterializerAttached()
1441                       ? UnmaterializedInfos.find(Name)
1442                       : UnmaterializedInfos.end();
1443       SymbolsToRemove.push_back(std::make_pair(I, UMII));
1444     }
1445 
1446     // If any of the symbols are not defined, return an error.
1447     if (!Missing.empty())
1448       return make_error<SymbolsNotFound>(std::move(Missing));
1449 
1450     // If any of the symbols are currently materializing, return an error.
1451     if (!Materializing.empty())
1452       return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1453 
1454     // Remove the symbols.
1455     for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1456       auto UMII = SymbolMaterializerItrPair.second;
1457 
1458       // If there is a materializer attached, call discard.
1459       if (UMII != UnmaterializedInfos.end()) {
1460         UMII->second->MU->doDiscard(*this, UMII->first);
1461         UnmaterializedInfos.erase(UMII);
1462       }
1463 
1464       auto SymI = SymbolMaterializerItrPair.first;
1465       Symbols.erase(SymI);
1466     }
1467 
1468     return Error::success();
1469   });
1470 }
1471 
1472 Expected<SymbolFlagsMap>
1473 JITDylib::lookupFlags(LookupKind K, JITDylibLookupFlags JDLookupFlags,
1474                       SymbolLookupSet LookupSet) {
1475   return ES.runSessionLocked([&, this]() -> Expected<SymbolFlagsMap> {
1476     SymbolFlagsMap Result;
1477     lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1478 
1479     // Run any definition generators.
1480     for (auto &DG : DefGenerators) {
1481 
1482       // Bail out early if we found everything.
1483       if (LookupSet.empty())
1484         break;
1485 
1486       // Run this generator.
1487       if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, LookupSet))
1488         return std::move(Err);
1489 
1490       // Re-try the search.
1491       lookupFlagsImpl(Result, K, JDLookupFlags, LookupSet);
1492     }
1493 
1494     return Result;
1495   });
1496 }
1497 
1498 void JITDylib::lookupFlagsImpl(SymbolFlagsMap &Result, LookupKind K,
1499                                JITDylibLookupFlags JDLookupFlags,
1500                                SymbolLookupSet &LookupSet) {
1501 
1502   LookupSet.forEachWithRemoval(
1503       [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1504         auto I = Symbols.find(Name);
1505         if (I == Symbols.end())
1506           return false;
1507         assert(!Result.count(Name) && "Symbol already present in Flags map");
1508         Result[Name] = I->second.getFlags();
1509         return true;
1510       });
1511 }
1512 
1513 Error JITDylib::lodgeQuery(MaterializationUnitList &MUs,
1514                            std::shared_ptr<AsynchronousSymbolQuery> &Q,
1515                            LookupKind K, JITDylibLookupFlags JDLookupFlags,
1516                            SymbolLookupSet &Unresolved) {
1517   assert(Q && "Query can not be null");
1518 
1519   if (auto Err = lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved))
1520     return Err;
1521 
1522   // Run any definition generators.
1523   for (auto &DG : DefGenerators) {
1524 
1525     // Bail out early if we have resolved everything.
1526     if (Unresolved.empty())
1527       break;
1528 
1529     // Run the generator.
1530     if (auto Err = DG->tryToGenerate(K, *this, JDLookupFlags, Unresolved))
1531       return Err;
1532 
1533     // Lodge query. This can not fail as any new definitions were added
1534     // by the generator under the session locked. Since they can't have
1535     // started materializing yet they can not have failed.
1536     cantFail(lodgeQueryImpl(MUs, Q, K, JDLookupFlags, Unresolved));
1537   }
1538 
1539   return Error::success();
1540 }
1541 
1542 Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs,
1543                                std::shared_ptr<AsynchronousSymbolQuery> &Q,
1544                                LookupKind K, JITDylibLookupFlags JDLookupFlags,
1545                                SymbolLookupSet &Unresolved) {
1546 
1547   return Unresolved.forEachWithRemoval(
1548       [&](const SymbolStringPtr &Name,
1549           SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
1550         // Search for name in symbols. If not found then continue without
1551         // removal.
1552         auto SymI = Symbols.find(Name);
1553         if (SymI == Symbols.end())
1554           return false;
1555 
1556         // If this is a non exported symbol and we're matching exported symbols
1557         // only then skip this symbol without removal.
1558         if (!SymI->second.getFlags().isExported() &&
1559             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly)
1560           return false;
1561 
1562         // If we matched against this symbol but it is in the error state then
1563         // bail out and treat it as a failure to materialize.
1564         if (SymI->second.getFlags().hasError()) {
1565           auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1566           (*FailedSymbolsMap)[this] = {Name};
1567           return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
1568         }
1569 
1570         // If this symbol already meets the required state for then notify the
1571         // query, then remove the symbol and continue.
1572         if (SymI->second.getState() >= Q->getRequiredState()) {
1573           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1574           return true;
1575         }
1576 
1577         // Otherwise this symbol does not yet meet the required state. Check
1578         // whether it has a materializer attached, and if so prepare to run it.
1579         if (SymI->second.hasMaterializerAttached()) {
1580           assert(SymI->second.getAddress() == 0 &&
1581                  "Symbol not resolved but already has address?");
1582           auto UMII = UnmaterializedInfos.find(Name);
1583           assert(UMII != UnmaterializedInfos.end() &&
1584                  "Lazy symbol should have UnmaterializedInfo");
1585           auto MU = std::move(UMII->second->MU);
1586           assert(MU != nullptr && "Materializer should not be null");
1587 
1588           // Move all symbols associated with this MaterializationUnit into
1589           // materializing state.
1590           for (auto &KV : MU->getSymbols()) {
1591             auto SymK = Symbols.find(KV.first);
1592             SymK->second.setMaterializerAttached(false);
1593             SymK->second.setState(SymbolState::Materializing);
1594             UnmaterializedInfos.erase(KV.first);
1595           }
1596 
1597           // Add MU to the list of MaterializationUnits to be materialized.
1598           MUs.push_back(std::move(MU));
1599         }
1600 
1601         // Add the query to the PendingQueries list and continue, deleting the
1602         // element.
1603         assert(SymI->second.isInMaterializationPhase() &&
1604                "By this line the symbol should be materializing");
1605         auto &MI = MaterializingInfos[Name];
1606         MI.addQuery(Q);
1607         Q->addQueryDependence(*this, Name);
1608         return true;
1609       });
1610 }
1611 
1612 Expected<SymbolNameSet>
1613 JITDylib::legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
1614                        SymbolNameSet Names) {
1615   assert(Q && "Query can not be null");
1616 
1617   ES.runOutstandingMUs();
1618 
1619   bool QueryComplete = false;
1620   std::vector<std::unique_ptr<MaterializationUnit>> MUs;
1621 
1622   SymbolLookupSet Unresolved(Names);
1623   auto Err = ES.runSessionLocked([&, this]() -> Error {
1624     QueryComplete = lookupImpl(Q, MUs, Unresolved);
1625 
1626     // Run any definition generators.
1627     for (auto &DG : DefGenerators) {
1628 
1629       // Bail out early if we have resolved everything.
1630       if (Unresolved.empty())
1631         break;
1632 
1633       assert(!QueryComplete && "query complete but unresolved symbols remain?");
1634       if (auto Err = DG->tryToGenerate(LookupKind::Static, *this,
1635                                        JITDylibLookupFlags::MatchAllSymbols,
1636                                        Unresolved))
1637         return Err;
1638 
1639       if (!Unresolved.empty())
1640         QueryComplete = lookupImpl(Q, MUs, Unresolved);
1641     }
1642     return Error::success();
1643   });
1644 
1645   if (Err)
1646     return std::move(Err);
1647 
1648   assert((MUs.empty() || !QueryComplete) &&
1649          "If action flags are set, there should be no work to do (so no MUs)");
1650 
1651   if (QueryComplete)
1652     Q->handleComplete();
1653 
1654   // FIXME: Swap back to the old code below once RuntimeDyld works with
1655   //        callbacks from asynchronous queries.
1656   // Add MUs to the OutstandingMUs list.
1657   {
1658     std::lock_guard<std::recursive_mutex> Lock(ES.OutstandingMUsMutex);
1659     for (auto &MU : MUs)
1660       ES.OutstandingMUs.push_back(make_pair(this, std::move(MU)));
1661   }
1662   ES.runOutstandingMUs();
1663 
1664   // Dispatch any required MaterializationUnits for materialization.
1665   // for (auto &MU : MUs)
1666   //  ES.dispatchMaterialization(*this, std::move(MU));
1667 
1668   SymbolNameSet RemainingSymbols;
1669   for (auto &KV : Unresolved)
1670     RemainingSymbols.insert(KV.first);
1671 
1672   return RemainingSymbols;
1673 }
1674 
1675 bool JITDylib::lookupImpl(
1676     std::shared_ptr<AsynchronousSymbolQuery> &Q,
1677     std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
1678     SymbolLookupSet &Unresolved) {
1679   bool QueryComplete = false;
1680 
1681   std::vector<SymbolStringPtr> ToRemove;
1682   Unresolved.forEachWithRemoval(
1683       [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool {
1684         // Search for the name in Symbols. Skip without removing if not found.
1685         auto SymI = Symbols.find(Name);
1686         if (SymI == Symbols.end())
1687           return false;
1688 
1689         // If the symbol is already in the required state then notify the query
1690         // and remove.
1691         if (SymI->second.getState() >= Q->getRequiredState()) {
1692           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1693           if (Q->isComplete())
1694             QueryComplete = true;
1695           return true;
1696         }
1697 
1698         // If the symbol is lazy, get the MaterialiaztionUnit for it.
1699         if (SymI->second.hasMaterializerAttached()) {
1700           assert(SymI->second.getAddress() == 0 &&
1701                  "Lazy symbol should not have a resolved address");
1702           auto UMII = UnmaterializedInfos.find(Name);
1703           assert(UMII != UnmaterializedInfos.end() &&
1704                  "Lazy symbol should have UnmaterializedInfo");
1705           auto MU = std::move(UMII->second->MU);
1706           assert(MU != nullptr && "Materializer should not be null");
1707 
1708           // Kick all symbols associated with this MaterializationUnit into
1709           // materializing state.
1710           for (auto &KV : MU->getSymbols()) {
1711             auto SymK = Symbols.find(KV.first);
1712             assert(SymK != Symbols.end() && "Missing symbol table entry");
1713             SymK->second.setState(SymbolState::Materializing);
1714             SymK->second.setMaterializerAttached(false);
1715             UnmaterializedInfos.erase(KV.first);
1716           }
1717 
1718           // Add MU to the list of MaterializationUnits to be materialized.
1719           MUs.push_back(std::move(MU));
1720         }
1721 
1722         // Add the query to the PendingQueries list.
1723         assert(SymI->second.isInMaterializationPhase() &&
1724                "By this line the symbol should be materializing");
1725         auto &MI = MaterializingInfos[Name];
1726         MI.addQuery(Q);
1727         Q->addQueryDependence(*this, Name);
1728         return true;
1729       });
1730 
1731   return QueryComplete;
1732 }
1733 
1734 void JITDylib::dump(raw_ostream &OS) {
1735   ES.runSessionLocked([&, this]() {
1736     OS << "JITDylib \"" << JITDylibName << "\" (ES: "
1737        << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
1738        << "Search order: " << SearchOrder << "\n"
1739        << "Symbol table:\n";
1740 
1741     for (auto &KV : Symbols) {
1742       OS << "    \"" << *KV.first << "\": ";
1743       if (auto Addr = KV.second.getAddress())
1744         OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
1745            << " ";
1746       else
1747         OS << "<not resolved> ";
1748 
1749       OS << KV.second.getState();
1750 
1751       if (KV.second.hasMaterializerAttached()) {
1752         OS << " (Materializer ";
1753         auto I = UnmaterializedInfos.find(KV.first);
1754         assert(I != UnmaterializedInfos.end() &&
1755                "Lazy symbol should have UnmaterializedInfo");
1756         OS << I->second->MU.get() << ")\n";
1757       } else
1758         OS << "\n";
1759     }
1760 
1761     if (!MaterializingInfos.empty())
1762       OS << "  MaterializingInfos entries:\n";
1763     for (auto &KV : MaterializingInfos) {
1764       OS << "    \"" << *KV.first << "\":\n"
1765          << "      " << KV.second.pendingQueries().size()
1766          << " pending queries: { ";
1767       for (const auto &Q : KV.second.pendingQueries())
1768         OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1769       OS << "}\n      Dependants:\n";
1770       for (auto &KV2 : KV.second.Dependants)
1771         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1772       OS << "      Unemitted Dependencies:\n";
1773       for (auto &KV2 : KV.second.UnemittedDependencies)
1774         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1775     }
1776   });
1777 }
1778 
1779 void JITDylib::MaterializingInfo::addQuery(
1780     std::shared_ptr<AsynchronousSymbolQuery> Q) {
1781 
1782   auto I = std::lower_bound(
1783       PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1784       [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1785         return V->getRequiredState() <= S;
1786       });
1787   PendingQueries.insert(I.base(), std::move(Q));
1788 }
1789 
1790 void JITDylib::MaterializingInfo::removeQuery(
1791     const AsynchronousSymbolQuery &Q) {
1792   // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1793   auto I =
1794       std::find_if(PendingQueries.begin(), PendingQueries.end(),
1795                    [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1796                      return V.get() == &Q;
1797                    });
1798   assert(I != PendingQueries.end() &&
1799          "Query is not attached to this MaterializingInfo");
1800   PendingQueries.erase(I);
1801 }
1802 
1803 JITDylib::AsynchronousSymbolQueryList
1804 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1805   AsynchronousSymbolQueryList Result;
1806   while (!PendingQueries.empty()) {
1807     if (PendingQueries.back()->getRequiredState() > RequiredState)
1808       break;
1809 
1810     Result.push_back(std::move(PendingQueries.back()));
1811     PendingQueries.pop_back();
1812   }
1813 
1814   return Result;
1815 }
1816 
1817 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1818     : ES(ES), JITDylibName(std::move(Name)) {
1819   SearchOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1820 }
1821 
1822 Error JITDylib::defineImpl(MaterializationUnit &MU) {
1823   SymbolNameSet Duplicates;
1824   std::vector<SymbolStringPtr> ExistingDefsOverridden;
1825   std::vector<SymbolStringPtr> MUDefsOverridden;
1826 
1827   for (const auto &KV : MU.getSymbols()) {
1828     auto I = Symbols.find(KV.first);
1829 
1830     if (I != Symbols.end()) {
1831       if (KV.second.isStrong()) {
1832         if (I->second.getFlags().isStrong() ||
1833             I->second.getState() > SymbolState::NeverSearched)
1834           Duplicates.insert(KV.first);
1835         else {
1836           assert(I->second.getState() == SymbolState::NeverSearched &&
1837                  "Overridden existing def should be in the never-searched "
1838                  "state");
1839           ExistingDefsOverridden.push_back(KV.first);
1840         }
1841       } else
1842         MUDefsOverridden.push_back(KV.first);
1843     }
1844   }
1845 
1846   // If there were any duplicate definitions then bail out.
1847   if (!Duplicates.empty())
1848     return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1849 
1850   // Discard any overridden defs in this MU.
1851   for (auto &S : MUDefsOverridden)
1852     MU.doDiscard(*this, S);
1853 
1854   // Discard existing overridden defs.
1855   for (auto &S : ExistingDefsOverridden) {
1856 
1857     auto UMII = UnmaterializedInfos.find(S);
1858     assert(UMII != UnmaterializedInfos.end() &&
1859            "Overridden existing def should have an UnmaterializedInfo");
1860     UMII->second->MU->doDiscard(*this, S);
1861   }
1862 
1863   // Finally, add the defs from this MU.
1864   for (auto &KV : MU.getSymbols()) {
1865     auto &SymEntry = Symbols[KV.first];
1866     SymEntry.setFlags(KV.second);
1867     SymEntry.setState(SymbolState::NeverSearched);
1868     SymEntry.setMaterializerAttached(true);
1869   }
1870 
1871   return Error::success();
1872 }
1873 
1874 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1875                                  const SymbolNameSet &QuerySymbols) {
1876   for (auto &QuerySymbol : QuerySymbols) {
1877     assert(MaterializingInfos.count(QuerySymbol) &&
1878            "QuerySymbol does not have MaterializingInfo");
1879     auto &MI = MaterializingInfos[QuerySymbol];
1880     MI.removeQuery(Q);
1881   }
1882 }
1883 
1884 void JITDylib::transferEmittedNodeDependencies(
1885     MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1886     MaterializingInfo &EmittedMI) {
1887   for (auto &KV : EmittedMI.UnemittedDependencies) {
1888     auto &DependencyJD = *KV.first;
1889     SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1890 
1891     for (auto &DependencyName : KV.second) {
1892       auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1893 
1894       // Do not add self dependencies.
1895       if (&DependencyMI == &DependantMI)
1896         continue;
1897 
1898       // If we haven't looked up the dependencies for DependencyJD yet, do it
1899       // now and cache the result.
1900       if (!UnemittedDependenciesOnDependencyJD)
1901         UnemittedDependenciesOnDependencyJD =
1902             &DependantMI.UnemittedDependencies[&DependencyJD];
1903 
1904       DependencyMI.Dependants[this].insert(DependantName);
1905       UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1906     }
1907   }
1908 }
1909 
1910 Platform::~Platform() {}
1911 
1912 Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
1913     ExecutionSession &ES,
1914     const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1915 
1916   DenseMap<JITDylib *, SymbolMap> CompoundResult;
1917   Error CompoundErr = Error::success();
1918   std::mutex LookupMutex;
1919   std::condition_variable CV;
1920   uint64_t Count = InitSyms.size();
1921 
1922   LLVM_DEBUG({
1923     dbgs() << "Issuing init-symbol lookup:\n";
1924     for (auto &KV : InitSyms)
1925       dbgs() << "  " << KV.first->getName() << ": " << KV.second << "\n";
1926   });
1927 
1928   for (auto &KV : InitSyms) {
1929     auto *JD = KV.first;
1930     auto Names = std::move(KV.second);
1931     ES.lookup(
1932         LookupKind::Static,
1933         JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),
1934         std::move(Names), SymbolState::Ready,
1935         [&, JD](Expected<SymbolMap> Result) {
1936           {
1937             std::lock_guard<std::mutex> Lock(LookupMutex);
1938             --Count;
1939             if (Result) {
1940               assert(!CompoundResult.count(JD) &&
1941                      "Duplicate JITDylib in lookup?");
1942               CompoundResult[JD] = std::move(*Result);
1943             } else
1944               CompoundErr =
1945                   joinErrors(std::move(CompoundErr), Result.takeError());
1946           }
1947           CV.notify_one();
1948         },
1949         NoDependenciesToRegister);
1950   }
1951 
1952   std::unique_lock<std::mutex> Lock(LookupMutex);
1953   CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1954 
1955   if (CompoundErr)
1956     return std::move(CompoundErr);
1957 
1958   return std::move(CompoundResult);
1959 }
1960 
1961 ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)
1962     : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {
1963 }
1964 
1965 JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {
1966   return runSessionLocked([&, this]() -> JITDylib * {
1967     for (auto &JD : JDs)
1968       if (JD->getName() == Name)
1969         return JD.get();
1970     return nullptr;
1971   });
1972 }
1973 
1974 JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {
1975   assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
1976   return runSessionLocked([&, this]() -> JITDylib & {
1977     JDs.push_back(
1978         std::unique_ptr<JITDylib>(new JITDylib(*this, std::move(Name))));
1979     return *JDs.back();
1980   });
1981 }
1982 
1983 Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
1984   auto &JD = createBareJITDylib(Name);
1985   if (P)
1986     if (auto Err = P->setupJITDylib(JD))
1987       return std::move(Err);
1988   return JD;
1989 }
1990 
1991 void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) {
1992   assert(!!Err && "Error should be in failure state");
1993 
1994   bool SendErrorToQuery;
1995   runSessionLocked([&]() {
1996     Q.detach();
1997     SendErrorToQuery = Q.canStillFail();
1998   });
1999 
2000   if (SendErrorToQuery)
2001     Q.handleFailed(std::move(Err));
2002   else
2003     reportError(std::move(Err));
2004 }
2005 
2006 Expected<SymbolMap> ExecutionSession::legacyLookup(
2007     LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
2008     SymbolState RequiredState,
2009     RegisterDependenciesFunction RegisterDependencies) {
2010 #if LLVM_ENABLE_THREADS
2011   // In the threaded case we use promises to return the results.
2012   std::promise<SymbolMap> PromisedResult;
2013   Error ResolutionError = Error::success();
2014   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2015     if (R)
2016       PromisedResult.set_value(std::move(*R));
2017     else {
2018       ErrorAsOutParameter _(&ResolutionError);
2019       ResolutionError = R.takeError();
2020       PromisedResult.set_value(SymbolMap());
2021     }
2022   };
2023 #else
2024   SymbolMap Result;
2025   Error ResolutionError = Error::success();
2026 
2027   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2028     ErrorAsOutParameter _(&ResolutionError);
2029     if (R)
2030       Result = std::move(*R);
2031     else
2032       ResolutionError = R.takeError();
2033   };
2034 #endif
2035 
2036   auto Query = std::make_shared<AsynchronousSymbolQuery>(
2037       SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete));
2038   // FIXME: This should be run session locked along with the registration code
2039   // and error reporting below.
2040   SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
2041 
2042   // If the query was lodged successfully then register the dependencies,
2043   // otherwise fail it with an error.
2044   if (UnresolvedSymbols.empty())
2045     RegisterDependencies(Query->QueryRegistrations);
2046   else {
2047     bool DeliverError = runSessionLocked([&]() {
2048       Query->detach();
2049       return Query->canStillFail();
2050     });
2051     auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
2052     if (DeliverError)
2053       Query->handleFailed(std::move(Err));
2054     else
2055       reportError(std::move(Err));
2056   }
2057 
2058 #if LLVM_ENABLE_THREADS
2059   auto ResultFuture = PromisedResult.get_future();
2060   auto Result = ResultFuture.get();
2061   if (ResolutionError)
2062     return std::move(ResolutionError);
2063   return std::move(Result);
2064 
2065 #else
2066   if (ResolutionError)
2067     return std::move(ResolutionError);
2068 
2069   return Result;
2070 #endif
2071 }
2072 
2073 void ExecutionSession::lookup(
2074     LookupKind K, const JITDylibSearchOrder &SearchOrder,
2075     SymbolLookupSet Symbols, SymbolState RequiredState,
2076     SymbolsResolvedCallback NotifyComplete,
2077     RegisterDependenciesFunction RegisterDependencies) {
2078 
2079   LLVM_DEBUG({
2080     runSessionLocked([&]() {
2081       dbgs() << "Looking up " << Symbols << " in " << SearchOrder
2082              << " (required state: " << RequiredState << ")\n";
2083     });
2084   });
2085 
2086   // lookup can be re-entered recursively if running on a single thread. Run any
2087   // outstanding MUs in case this query depends on them, otherwise this lookup
2088   // will starve waiting for a result from an MU that is stuck in the queue.
2089   runOutstandingMUs();
2090 
2091   auto Unresolved = std::move(Symbols);
2092   std::map<JITDylib *, MaterializationUnitList> CollectedMUsMap;
2093   auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
2094                                                      std::move(NotifyComplete));
2095   bool QueryComplete = false;
2096 
2097   auto LodgingErr = runSessionLocked([&]() -> Error {
2098     auto LodgeQuery = [&]() -> Error {
2099       for (auto &KV : SearchOrder) {
2100         assert(KV.first && "JITDylibList entries must not be null");
2101         assert(!CollectedMUsMap.count(KV.first) &&
2102                "JITDylibList should not contain duplicate entries");
2103 
2104         auto &JD = *KV.first;
2105         auto JDLookupFlags = KV.second;
2106         if (auto Err = JD.lodgeQuery(CollectedMUsMap[&JD], Q, K, JDLookupFlags,
2107                                      Unresolved))
2108           return Err;
2109       }
2110 
2111       // Strip any weakly referenced symbols that were not found.
2112       Unresolved.forEachWithRemoval(
2113           [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) {
2114             if (Flags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2115               Q->dropSymbol(Name);
2116               return true;
2117             }
2118             return false;
2119           });
2120 
2121       if (!Unresolved.empty())
2122         return make_error<SymbolsNotFound>(Unresolved.getSymbolNames());
2123 
2124       return Error::success();
2125     };
2126 
2127     if (auto Err = LodgeQuery()) {
2128       // Query failed.
2129 
2130       // Disconnect the query from its dependencies.
2131       Q->detach();
2132 
2133       // Replace the MUs.
2134       for (auto &KV : CollectedMUsMap)
2135         for (auto &MU : KV.second)
2136           KV.first->replace(std::move(MU));
2137 
2138       return Err;
2139     }
2140 
2141     // Query lodged successfully.
2142 
2143     // Record whether this query is fully ready / resolved. We will use
2144     // this to call handleFullyResolved/handleFullyReady outside the session
2145     // lock.
2146     QueryComplete = Q->isComplete();
2147 
2148     // Call the register dependencies function.
2149     if (RegisterDependencies && !Q->QueryRegistrations.empty())
2150       RegisterDependencies(Q->QueryRegistrations);
2151 
2152     return Error::success();
2153   });
2154 
2155   if (LodgingErr) {
2156     Q->handleFailed(std::move(LodgingErr));
2157     return;
2158   }
2159 
2160   if (QueryComplete)
2161     Q->handleComplete();
2162 
2163   // Move the MUs to the OutstandingMUs list, then materialize.
2164   {
2165     std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2166 
2167     for (auto &KV : CollectedMUsMap)
2168       for (auto &MU : KV.second)
2169         OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
2170   }
2171 
2172   runOutstandingMUs();
2173 }
2174 
2175 Expected<SymbolMap>
2176 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2177                          const SymbolLookupSet &Symbols, LookupKind K,
2178                          SymbolState RequiredState,
2179                          RegisterDependenciesFunction RegisterDependencies) {
2180 #if LLVM_ENABLE_THREADS
2181   // In the threaded case we use promises to return the results.
2182   std::promise<SymbolMap> PromisedResult;
2183   Error ResolutionError = Error::success();
2184 
2185   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2186     if (R)
2187       PromisedResult.set_value(std::move(*R));
2188     else {
2189       ErrorAsOutParameter _(&ResolutionError);
2190       ResolutionError = R.takeError();
2191       PromisedResult.set_value(SymbolMap());
2192     }
2193   };
2194 
2195 #else
2196   SymbolMap Result;
2197   Error ResolutionError = Error::success();
2198 
2199   auto NotifyComplete = [&](Expected<SymbolMap> R) {
2200     ErrorAsOutParameter _(&ResolutionError);
2201     if (R)
2202       Result = std::move(*R);
2203     else
2204       ResolutionError = R.takeError();
2205   };
2206 #endif
2207 
2208   // Perform the asynchronous lookup.
2209   lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
2210          RegisterDependencies);
2211 
2212 #if LLVM_ENABLE_THREADS
2213   auto ResultFuture = PromisedResult.get_future();
2214   auto Result = ResultFuture.get();
2215 
2216   if (ResolutionError)
2217     return std::move(ResolutionError);
2218 
2219   return std::move(Result);
2220 
2221 #else
2222   if (ResolutionError)
2223     return std::move(ResolutionError);
2224 
2225   return Result;
2226 #endif
2227 }
2228 
2229 Expected<JITEvaluatedSymbol>
2230 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
2231                          SymbolStringPtr Name, SymbolState RequiredState) {
2232   SymbolLookupSet Names({Name});
2233 
2234   if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
2235                               RequiredState, NoDependenciesToRegister)) {
2236     assert(ResultMap->size() == 1 && "Unexpected number of results");
2237     assert(ResultMap->count(Name) && "Missing result for symbol");
2238     return std::move(ResultMap->begin()->second);
2239   } else
2240     return ResultMap.takeError();
2241 }
2242 
2243 Expected<JITEvaluatedSymbol>
2244 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
2245                          SymbolState RequiredState) {
2246   return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
2247 }
2248 
2249 Expected<JITEvaluatedSymbol>
2250 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
2251                          SymbolState RequiredState) {
2252   return lookup(SearchOrder, intern(Name), RequiredState);
2253 }
2254 
2255 void ExecutionSession::dump(raw_ostream &OS) {
2256   runSessionLocked([this, &OS]() {
2257     for (auto &JD : JDs)
2258       JD->dump(OS);
2259   });
2260 }
2261 
2262 void ExecutionSession::runOutstandingMUs() {
2263   while (1) {
2264     std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU;
2265 
2266     {
2267       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2268       if (!OutstandingMUs.empty()) {
2269         JITDylibAndMU = std::move(OutstandingMUs.back());
2270         OutstandingMUs.pop_back();
2271       }
2272     }
2273 
2274     if (JITDylibAndMU.first) {
2275       assert(JITDylibAndMU.second && "JITDylib, but no MU?");
2276       dispatchMaterialization(*JITDylibAndMU.first,
2277                               std::move(JITDylibAndMU.second));
2278     } else
2279       break;
2280   }
2281 }
2282 
2283 } // End namespace orc.
2284 } // End namespace llvm.
2285