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