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