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