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