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