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