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