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 #include "llvm/Support/FormatVariadic.h"
16 #include "llvm/Support/MSVCErrorWorkarounds.h"
17 
18 #include <condition_variable>
19 #if LLVM_ENABLE_THREADS
20 #include <future>
21 #endif
22 
23 #define DEBUG_TYPE "orc"
24 
25 namespace llvm {
26 namespace orc {
27 
28 char ResourceTrackerDefunct::ID = 0;
29 char FailedToMaterialize::ID = 0;
30 char SymbolsNotFound::ID = 0;
31 char SymbolsCouldNotBeRemoved::ID = 0;
32 char MissingSymbolDefinitions::ID = 0;
33 char UnexpectedSymbolDefinitions::ID = 0;
34 
35 RegisterDependenciesFunction NoDependenciesToRegister =
36     RegisterDependenciesFunction();
37 
38 void MaterializationUnit::anchor() {}
39 
40 ResourceTracker::ResourceTracker(JITDylibSP JD) {
41   assert((reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 &&
42          "JITDylib must be two byte aligned");
43   JD->Retain();
44   JDAndFlag.store(reinterpret_cast<uintptr_t>(JD.get()));
45 }
46 
47 ResourceTracker::~ResourceTracker() {
48   getJITDylib().getExecutionSession().destroyResourceTracker(*this);
49   getJITDylib().Release();
50 }
51 
52 Error ResourceTracker::remove() {
53   return getJITDylib().getExecutionSession().removeResourceTracker(*this);
54 }
55 
56 void ResourceTracker::transferTo(ResourceTracker &DstRT) {
57   getJITDylib().getExecutionSession().transferResourceTracker(DstRT, *this);
58 }
59 
60 void ResourceTracker::makeDefunct() {
61   uintptr_t Val = JDAndFlag.load();
62   Val |= 0x1U;
63   JDAndFlag.store(Val);
64 }
65 
66 ResourceManager::~ResourceManager() {}
67 
68 ResourceTrackerDefunct::ResourceTrackerDefunct(ResourceTrackerSP RT)
69     : RT(std::move(RT)) {}
70 
71 std::error_code ResourceTrackerDefunct::convertToErrorCode() const {
72   return orcError(OrcErrorCode::UnknownORCError);
73 }
74 
75 void ResourceTrackerDefunct::log(raw_ostream &OS) const {
76   OS << "Resource tracker " << (void *)RT.get() << " became defunct";
77 }
78 
79 FailedToMaterialize::FailedToMaterialize(
80     std::shared_ptr<SymbolDependenceMap> Symbols)
81     : Symbols(std::move(Symbols)) {
82   assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
83 }
84 
85 std::error_code FailedToMaterialize::convertToErrorCode() const {
86   return orcError(OrcErrorCode::UnknownORCError);
87 }
88 
89 void FailedToMaterialize::log(raw_ostream &OS) const {
90   OS << "Failed to materialize symbols: " << *Symbols;
91 }
92 
93 SymbolsNotFound::SymbolsNotFound(SymbolNameSet Symbols) {
94   for (auto &Sym : Symbols)
95     this->Symbols.push_back(Sym);
96   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
97 }
98 
99 SymbolsNotFound::SymbolsNotFound(SymbolNameVector Symbols)
100     : Symbols(std::move(Symbols)) {
101   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
102 }
103 
104 std::error_code SymbolsNotFound::convertToErrorCode() const {
105   return orcError(OrcErrorCode::UnknownORCError);
106 }
107 
108 void SymbolsNotFound::log(raw_ostream &OS) const {
109   OS << "Symbols not found: " << Symbols;
110 }
111 
112 SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
113     : Symbols(std::move(Symbols)) {
114   assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
115 }
116 
117 std::error_code SymbolsCouldNotBeRemoved::convertToErrorCode() const {
118   return orcError(OrcErrorCode::UnknownORCError);
119 }
120 
121 void SymbolsCouldNotBeRemoved::log(raw_ostream &OS) const {
122   OS << "Symbols could not be removed: " << Symbols;
123 }
124 
125 std::error_code MissingSymbolDefinitions::convertToErrorCode() const {
126   return orcError(OrcErrorCode::MissingSymbolDefinitions);
127 }
128 
129 void MissingSymbolDefinitions::log(raw_ostream &OS) const {
130   OS << "Missing definitions in module " << ModuleName
131      << ": " << Symbols;
132 }
133 
134 std::error_code UnexpectedSymbolDefinitions::convertToErrorCode() const {
135   return orcError(OrcErrorCode::UnexpectedSymbolDefinitions);
136 }
137 
138 void UnexpectedSymbolDefinitions::log(raw_ostream &OS) const {
139   OS << "Unexpected definitions in module " << ModuleName
140      << ": " << Symbols;
141 }
142 
143 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
144     const SymbolLookupSet &Symbols, SymbolState RequiredState,
145     SymbolsResolvedCallback NotifyComplete)
146     : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
147   assert(RequiredState >= SymbolState::Resolved &&
148          "Cannot query for a symbols that have not reached the resolve state "
149          "yet");
150 
151   OutstandingSymbolsCount = Symbols.size();
152 
153   for (auto &KV : Symbols)
154     ResolvedSymbols[KV.first] = nullptr;
155 }
156 
157 void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
158     const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) {
159   auto I = ResolvedSymbols.find(Name);
160   assert(I != ResolvedSymbols.end() &&
161          "Resolving symbol outside the requested set");
162   assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name");
163 
164   // If this is a materialization-side-effects-only symbol then drop it,
165   // otherwise update its map entry with its resolved address.
166   if (Sym.getFlags().hasMaterializationSideEffectsOnly())
167     ResolvedSymbols.erase(I);
168   else
169     I->second = std::move(Sym);
170   --OutstandingSymbolsCount;
171 }
172 
173 void AsynchronousSymbolQuery::handleComplete() {
174   assert(OutstandingSymbolsCount == 0 &&
175          "Symbols remain, handleComplete called prematurely");
176 
177   auto TmpNotifyComplete = std::move(NotifyComplete);
178   NotifyComplete = SymbolsResolvedCallback();
179   TmpNotifyComplete(std::move(ResolvedSymbols));
180 }
181 
182 void AsynchronousSymbolQuery::handleFailed(Error Err) {
183   assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
184          OutstandingSymbolsCount == 0 &&
185          "Query should already have been abandoned");
186   NotifyComplete(std::move(Err));
187   NotifyComplete = SymbolsResolvedCallback();
188 }
189 
190 void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
191                                                  SymbolStringPtr Name) {
192   bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
193   (void)Added;
194   assert(Added && "Duplicate dependence notification?");
195 }
196 
197 void AsynchronousSymbolQuery::removeQueryDependence(
198     JITDylib &JD, const SymbolStringPtr &Name) {
199   auto QRI = QueryRegistrations.find(&JD);
200   assert(QRI != QueryRegistrations.end() &&
201          "No dependencies registered for JD");
202   assert(QRI->second.count(Name) && "No dependency on Name in JD");
203   QRI->second.erase(Name);
204   if (QRI->second.empty())
205     QueryRegistrations.erase(QRI);
206 }
207 
208 void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) {
209   auto I = ResolvedSymbols.find(Name);
210   assert(I != ResolvedSymbols.end() &&
211          "Redundant removal of weakly-referenced symbol");
212   ResolvedSymbols.erase(I);
213   --OutstandingSymbolsCount;
214 }
215 
216 void AsynchronousSymbolQuery::detach() {
217   ResolvedSymbols.clear();
218   OutstandingSymbolsCount = 0;
219   for (auto &KV : QueryRegistrations)
220     KV.first->detachQueryHelper(*this, KV.second);
221   QueryRegistrations.clear();
222 }
223 
224 AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(
225     SymbolMap Symbols)
226     : MaterializationUnit(extractFlags(Symbols), nullptr),
227       Symbols(std::move(Symbols)) {}
228 
229 StringRef AbsoluteSymbolsMaterializationUnit::getName() const {
230   return "<Absolute Symbols>";
231 }
232 
233 void AbsoluteSymbolsMaterializationUnit::materialize(
234     std::unique_ptr<MaterializationResponsibility> R) {
235   // No dependencies, so these calls can't fail.
236   cantFail(R->notifyResolved(Symbols));
237   cantFail(R->notifyEmitted());
238 }
239 
240 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
241                                                  const SymbolStringPtr &Name) {
242   assert(Symbols.count(Name) && "Symbol is not part of this MU");
243   Symbols.erase(Name);
244 }
245 
246 SymbolFlagsMap
247 AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
248   SymbolFlagsMap Flags;
249   for (const auto &KV : Symbols)
250     Flags[KV.first] = KV.second.getFlags();
251   return Flags;
252 }
253 
254 ReExportsMaterializationUnit::ReExportsMaterializationUnit(
255     JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
256     SymbolAliasMap Aliases)
257     : MaterializationUnit(extractFlags(Aliases), nullptr), SourceJD(SourceJD),
258       SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {}
259 
260 StringRef ReExportsMaterializationUnit::getName() const {
261   return "<Reexports>";
262 }
263 
264 void ReExportsMaterializationUnit::materialize(
265     std::unique_ptr<MaterializationResponsibility> R) {
266 
267   auto &ES = R->getTargetJITDylib().getExecutionSession();
268   JITDylib &TgtJD = R->getTargetJITDylib();
269   JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
270 
271   // Find the set of requested aliases and aliasees. Return any unrequested
272   // aliases back to the JITDylib so as to not prematurely materialize any
273   // aliasees.
274   auto RequestedSymbols = R->getRequestedSymbols();
275   SymbolAliasMap RequestedAliases;
276 
277   for (auto &Name : RequestedSymbols) {
278     auto I = Aliases.find(Name);
279     assert(I != Aliases.end() && "Symbol not found in aliases map?");
280     RequestedAliases[Name] = std::move(I->second);
281     Aliases.erase(I);
282   }
283 
284   LLVM_DEBUG({
285     ES.runSessionLocked([&]() {
286       dbgs() << "materializing reexports: target = " << TgtJD.getName()
287              << ", source = " << SrcJD.getName() << " " << RequestedAliases
288              << "\n";
289     });
290   });
291 
292   if (!Aliases.empty()) {
293     auto Err = SourceJD ? R->replace(reexports(*SourceJD, std::move(Aliases),
294                                                SourceJDLookupFlags))
295                         : R->replace(symbolAliases(std::move(Aliases)));
296 
297     if (Err) {
298       // FIXME: Should this be reported / treated as failure to materialize?
299       // Or should this be treated as a sanctioned bailing-out?
300       ES.reportError(std::move(Err));
301       R->failMaterialization();
302       return;
303     }
304   }
305 
306   // The OnResolveInfo struct will hold the aliases and responsibilty for each
307   // query in the list.
308   struct OnResolveInfo {
309     OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R,
310                   SymbolAliasMap Aliases)
311         : R(std::move(R)), Aliases(std::move(Aliases)) {}
312 
313     std::unique_ptr<MaterializationResponsibility> R;
314     SymbolAliasMap Aliases;
315   };
316 
317   // Build a list of queries to issue. In each round we build a query for the
318   // largest set of aliases that we can resolve without encountering a chain of
319   // aliases (e.g. Foo -> Bar, Bar -> Baz). Such a chain would deadlock as the
320   // query would be waiting on a symbol that it itself had to resolve. Creating
321   // a new query for each link in such a chain eliminates the possibility of
322   // deadlock. In practice chains are likely to be rare, and this algorithm will
323   // usually result in a single query to issue.
324 
325   std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
326       QueryInfos;
327   while (!RequestedAliases.empty()) {
328     SymbolNameSet ResponsibilitySymbols;
329     SymbolLookupSet QuerySymbols;
330     SymbolAliasMap QueryAliases;
331 
332     // Collect as many aliases as we can without including a chain.
333     for (auto &KV : RequestedAliases) {
334       // Chain detected. Skip this symbol for this round.
335       if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
336                                RequestedAliases.count(KV.second.Aliasee)))
337         continue;
338 
339       ResponsibilitySymbols.insert(KV.first);
340       QuerySymbols.add(KV.second.Aliasee,
341                        KV.second.AliasFlags.hasMaterializationSideEffectsOnly()
342                            ? SymbolLookupFlags::WeaklyReferencedSymbol
343                            : SymbolLookupFlags::RequiredSymbol);
344       QueryAliases[KV.first] = std::move(KV.second);
345     }
346 
347     // Remove the aliases collected this round from the RequestedAliases map.
348     for (auto &KV : QueryAliases)
349       RequestedAliases.erase(KV.first);
350 
351     assert(!QuerySymbols.empty() && "Alias cycle detected!");
352 
353     auto NewR = R->delegate(ResponsibilitySymbols);
354     if (!NewR) {
355       ES.reportError(NewR.takeError());
356       R->failMaterialization();
357       return;
358     }
359 
360     auto QueryInfo = std::make_shared<OnResolveInfo>(std::move(*NewR),
361                                                      std::move(QueryAliases));
362     QueryInfos.push_back(
363         make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
364   }
365 
366   // Issue the queries.
367   while (!QueryInfos.empty()) {
368     auto QuerySymbols = std::move(QueryInfos.back().first);
369     auto QueryInfo = std::move(QueryInfos.back().second);
370 
371     QueryInfos.pop_back();
372 
373     auto RegisterDependencies = [QueryInfo,
374                                  &SrcJD](const SymbolDependenceMap &Deps) {
375       // If there were no materializing symbols, just bail out.
376       if (Deps.empty())
377         return;
378 
379       // Otherwise the only deps should be on SrcJD.
380       assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
381              "Unexpected dependencies for reexports");
382 
383       auto &SrcJDDeps = Deps.find(&SrcJD)->second;
384       SymbolDependenceMap PerAliasDepsMap;
385       auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
386 
387       for (auto &KV : QueryInfo->Aliases)
388         if (SrcJDDeps.count(KV.second.Aliasee)) {
389           PerAliasDeps = {KV.second.Aliasee};
390           QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap);
391         }
392     };
393 
394     auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
395       auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();
396       if (Result) {
397         SymbolMap ResolutionMap;
398         for (auto &KV : QueryInfo->Aliases) {
399           assert((KV.second.AliasFlags.hasMaterializationSideEffectsOnly() ||
400                   Result->count(KV.second.Aliasee)) &&
401                  "Result map missing entry?");
402           // Don't try to resolve materialization-side-effects-only symbols.
403           if (KV.second.AliasFlags.hasMaterializationSideEffectsOnly())
404             continue;
405 
406           ResolutionMap[KV.first] = JITEvaluatedSymbol(
407               (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
408         }
409         if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {
410           ES.reportError(std::move(Err));
411           QueryInfo->R->failMaterialization();
412           return;
413         }
414         if (auto Err = QueryInfo->R->notifyEmitted()) {
415           ES.reportError(std::move(Err));
416           QueryInfo->R->failMaterialization();
417           return;
418         }
419       } else {
420         ES.reportError(Result.takeError());
421         QueryInfo->R->failMaterialization();
422       }
423     };
424 
425     ES.lookup(LookupKind::Static,
426               JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
427               QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
428               std::move(RegisterDependencies));
429   }
430 }
431 
432 void ReExportsMaterializationUnit::discard(const JITDylib &JD,
433                                            const SymbolStringPtr &Name) {
434   assert(Aliases.count(Name) &&
435          "Symbol not covered by this MaterializationUnit");
436   Aliases.erase(Name);
437 }
438 
439 SymbolFlagsMap
440 ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
441   SymbolFlagsMap SymbolFlags;
442   for (auto &KV : Aliases)
443     SymbolFlags[KV.first] = KV.second.AliasFlags;
444 
445   return SymbolFlags;
446 }
447 
448 Expected<SymbolAliasMap> buildSimpleReexportsAliasMap(JITDylib &SourceJD,
449                                                       SymbolNameSet Symbols) {
450   SymbolLookupSet LookupSet(Symbols);
451   auto Flags = SourceJD.getExecutionSession().lookupFlags(
452       LookupKind::Static, {{&SourceJD, JITDylibLookupFlags::MatchAllSymbols}},
453       SymbolLookupSet(std::move(Symbols)));
454 
455   if (!Flags)
456     return Flags.takeError();
457 
458   SymbolAliasMap Result;
459   for (auto &Name : Symbols) {
460     assert(Flags->count(Name) && "Missing entry in flags map");
461     Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
462   }
463 
464   return Result;
465 }
466 
467 class InProgressLookupState {
468 public:
469   InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder,
470                         SymbolLookupSet LookupSet, SymbolState RequiredState)
471       : K(K), SearchOrder(std::move(SearchOrder)),
472         LookupSet(std::move(LookupSet)), RequiredState(RequiredState) {
473     DefGeneratorCandidates = this->LookupSet;
474   }
475   virtual ~InProgressLookupState() {}
476   virtual void complete(std::unique_ptr<InProgressLookupState> IPLS) = 0;
477   virtual void fail(Error Err) = 0;
478 
479   LookupKind K;
480   JITDylibSearchOrder SearchOrder;
481   SymbolLookupSet LookupSet;
482   SymbolState RequiredState;
483 
484   std::unique_lock<std::mutex> GeneratorLock;
485   size_t CurSearchOrderIndex = 0;
486   bool NewJITDylib = true;
487   SymbolLookupSet DefGeneratorCandidates;
488   SymbolLookupSet DefGeneratorNonCandidates;
489   std::vector<std::weak_ptr<DefinitionGenerator>> CurDefGeneratorStack;
490 };
491 
492 class InProgressLookupFlagsState : public InProgressLookupState {
493 public:
494   InProgressLookupFlagsState(
495       LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
496       unique_function<void(Expected<SymbolFlagsMap>)> OnComplete)
497       : InProgressLookupState(K, std::move(SearchOrder), std::move(LookupSet),
498                               SymbolState::NeverSearched),
499         OnComplete(std::move(OnComplete)) {}
500 
501   void complete(std::unique_ptr<InProgressLookupState> IPLS) override {
502     GeneratorLock = {}; // Unlock and release.
503     auto &ES = SearchOrder.front().first->getExecutionSession();
504     ES.OL_completeLookupFlags(std::move(IPLS), std::move(OnComplete));
505   }
506 
507   void fail(Error Err) override {
508     GeneratorLock = {}; // Unlock and release.
509     OnComplete(std::move(Err));
510   }
511 
512 private:
513   unique_function<void(Expected<SymbolFlagsMap>)> OnComplete;
514 };
515 
516 class InProgressFullLookupState : public InProgressLookupState {
517 public:
518   InProgressFullLookupState(LookupKind K, JITDylibSearchOrder SearchOrder,
519                             SymbolLookupSet LookupSet,
520                             SymbolState RequiredState,
521                             std::shared_ptr<AsynchronousSymbolQuery> Q,
522                             RegisterDependenciesFunction RegisterDependencies)
523       : InProgressLookupState(K, std::move(SearchOrder), std::move(LookupSet),
524                               RequiredState),
525         Q(std::move(Q)), RegisterDependencies(std::move(RegisterDependencies)) {
526   }
527 
528   void complete(std::unique_ptr<InProgressLookupState> IPLS) override {
529     GeneratorLock = {}; // Unlock and release.
530     auto &ES = SearchOrder.front().first->getExecutionSession();
531     ES.OL_completeLookup(std::move(IPLS), std::move(Q),
532                          std::move(RegisterDependencies));
533   }
534 
535   void fail(Error Err) override {
536     GeneratorLock = {};
537     Q->detach();
538     Q->handleFailed(std::move(Err));
539   }
540 
541 private:
542   std::shared_ptr<AsynchronousSymbolQuery> Q;
543   RegisterDependenciesFunction RegisterDependencies;
544 };
545 
546 ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
547                                        JITDylibLookupFlags SourceJDLookupFlags,
548                                        SymbolPredicate Allow)
549     : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
550       Allow(std::move(Allow)) {}
551 
552 Error ReexportsGenerator::tryToGenerate(LookupState &LS, LookupKind K,
553                                         JITDylib &JD,
554                                         JITDylibLookupFlags JDLookupFlags,
555                                         const SymbolLookupSet &LookupSet) {
556   assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
557 
558   // Use lookupFlags to find the subset of symbols that match our lookup.
559   auto Flags = JD.getExecutionSession().lookupFlags(
560       K, {{&SourceJD, JDLookupFlags}}, LookupSet);
561   if (!Flags)
562     return Flags.takeError();
563 
564   // Create an alias map.
565   orc::SymbolAliasMap AliasMap;
566   for (auto &KV : *Flags)
567     if (!Allow || Allow(KV.first))
568       AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
569 
570   if (AliasMap.empty())
571     return Error::success();
572 
573   // Define the re-exports.
574   return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
575 }
576 
577 LookupState::LookupState(std::unique_ptr<InProgressLookupState> IPLS)
578     : IPLS(std::move(IPLS)) {}
579 
580 void LookupState::reset(InProgressLookupState *IPLS) { this->IPLS.reset(IPLS); }
581 
582 LookupState::~LookupState() {}
583 
584 void LookupState::continueLookup(Error Err) {
585   assert(IPLS && "Cannot call continueLookup on empty LookupState");
586   auto &ES = IPLS->SearchOrder.begin()->first->getExecutionSession();
587   ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err));
588 }
589 
590 DefinitionGenerator::~DefinitionGenerator() {}
591 
592 Error JITDylib::clear() {
593   std::vector<ResourceTrackerSP> TrackersToRemove;
594   ES.runSessionLocked([&]() {
595     for (auto &KV : TrackerSymbols)
596       TrackersToRemove.push_back(KV.first);
597     TrackersToRemove.push_back(getDefaultResourceTracker());
598   });
599 
600   Error Err = Error::success();
601   for (auto &RT : TrackersToRemove)
602     Err = joinErrors(std::move(Err), RT->remove());
603   return Err;
604 }
605 
606 ResourceTrackerSP JITDylib::getDefaultResourceTracker() {
607   return ES.runSessionLocked([this] {
608     if (!DefaultTracker)
609       DefaultTracker = new ResourceTracker(this);
610     return DefaultTracker;
611   });
612 }
613 
614 ResourceTrackerSP JITDylib::createResourceTracker() {
615   return ES.runSessionLocked([this] {
616     ResourceTrackerSP RT = new ResourceTracker(this);
617     return RT;
618   });
619 }
620 
621 void JITDylib::removeGenerator(DefinitionGenerator &G) {
622   std::lock_guard<std::mutex> Lock(GeneratorsMutex);
623   auto I = std::find_if(DefGenerators.begin(), DefGenerators.end(),
624                         [&](const std::shared_ptr<DefinitionGenerator> &H) {
625                           return H.get() == &G;
626                         });
627   assert(I != DefGenerators.end() && "Generator not found");
628   DefGenerators.erase(I);
629 }
630 
631 Expected<SymbolFlagsMap>
632 JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
633 
634   return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
635     std::vector<SymbolTable::iterator> AddedSyms;
636     std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
637 
638     for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
639          SFItr != SFEnd; ++SFItr) {
640 
641       auto &Name = SFItr->first;
642       auto &Flags = SFItr->second;
643 
644       auto EntryItr = Symbols.find(Name);
645 
646       // If the entry already exists...
647       if (EntryItr != Symbols.end()) {
648 
649         // If this is a strong definition then error out.
650         if (!Flags.isWeak()) {
651           // Remove any symbols already added.
652           for (auto &SI : AddedSyms)
653             Symbols.erase(SI);
654 
655           // FIXME: Return all duplicates.
656           return make_error<DuplicateDefinition>(std::string(*Name));
657         }
658 
659         // Otherwise just make a note to discard this symbol after the loop.
660         RejectedWeakDefs.push_back(SFItr);
661         continue;
662       } else
663         EntryItr =
664           Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
665 
666       AddedSyms.push_back(EntryItr);
667       EntryItr->second.setState(SymbolState::Materializing);
668     }
669 
670     // Remove any rejected weak definitions from the SymbolFlags map.
671     while (!RejectedWeakDefs.empty()) {
672       SymbolFlags.erase(RejectedWeakDefs.back());
673       RejectedWeakDefs.pop_back();
674     }
675 
676     return SymbolFlags;
677   });
678 }
679 
680 Error JITDylib::replace(MaterializationResponsibility &FromMR,
681                         std::unique_ptr<MaterializationUnit> MU) {
682   assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
683   std::unique_ptr<MaterializationUnit> MustRunMU;
684   std::unique_ptr<MaterializationResponsibility> MustRunMR;
685 
686   auto Err =
687       ES.runSessionLocked([&, this]() -> Error {
688         auto RT = getTracker(FromMR);
689 
690         if (RT->isDefunct())
691           return make_error<ResourceTrackerDefunct>(std::move(RT));
692 
693 #ifndef NDEBUG
694         for (auto &KV : MU->getSymbols()) {
695           auto SymI = Symbols.find(KV.first);
696           assert(SymI != Symbols.end() && "Replacing unknown symbol");
697           assert(SymI->second.getState() == SymbolState::Materializing &&
698                  "Can not replace a symbol that ha is not materializing");
699           assert(!SymI->second.hasMaterializerAttached() &&
700                  "Symbol should not have materializer attached already");
701           assert(UnmaterializedInfos.count(KV.first) == 0 &&
702                  "Symbol being replaced should have no UnmaterializedInfo");
703         }
704 #endif // NDEBUG
705 
706         // If the tracker is defunct we need to bail out immediately.
707 
708         // If any symbol has pending queries against it then we need to
709         // materialize MU immediately.
710         for (auto &KV : MU->getSymbols()) {
711           auto MII = MaterializingInfos.find(KV.first);
712           if (MII != MaterializingInfos.end()) {
713             if (MII->second.hasQueriesPending()) {
714               MustRunMR = ES.createMaterializationResponsibility(
715                   *RT, std::move(MU->SymbolFlags), std::move(MU->InitSymbol));
716               MustRunMU = std::move(MU);
717               return Error::success();
718             }
719           }
720         }
721 
722         // Otherwise, make MU responsible for all the symbols.
723         auto RTI = MRTrackers.find(&FromMR);
724         assert(RTI != MRTrackers.end() && "No tracker for FromMR");
725         auto UMI =
726             std::make_shared<UnmaterializedInfo>(std::move(MU), RTI->second);
727         for (auto &KV : UMI->MU->getSymbols()) {
728           auto SymI = Symbols.find(KV.first);
729           assert(SymI->second.getState() == SymbolState::Materializing &&
730                  "Can not replace a symbol that is not materializing");
731           assert(!SymI->second.hasMaterializerAttached() &&
732                  "Can not replace a symbol that has a materializer attached");
733           assert(UnmaterializedInfos.count(KV.first) == 0 &&
734                  "Unexpected materializer entry in map");
735           SymI->second.setAddress(SymI->second.getAddress());
736           SymI->second.setMaterializerAttached(true);
737 
738           auto &UMIEntry = UnmaterializedInfos[KV.first];
739           assert((!UMIEntry || !UMIEntry->MU) &&
740                  "Replacing symbol with materializer still attached");
741           UMIEntry = UMI;
742         }
743 
744         return Error::success();
745       });
746 
747   if (Err)
748     return Err;
749 
750   if (MustRunMU) {
751     assert(MustRunMR && "MustRunMU set implies MustRunMR set");
752     ES.dispatchMaterialization(std::move(MustRunMU), std::move(MustRunMR));
753   } else {
754     assert(!MustRunMR && "MustRunMU unset implies MustRunMR unset");
755   }
756 
757   return Error::success();
758 }
759 
760 Expected<std::unique_ptr<MaterializationResponsibility>>
761 JITDylib::delegate(MaterializationResponsibility &FromMR,
762                    SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol) {
763 
764   return ES.runSessionLocked(
765       [&]() -> Expected<std::unique_ptr<MaterializationResponsibility>> {
766         auto RT = getTracker(FromMR);
767 
768         if (RT->isDefunct())
769           return make_error<ResourceTrackerDefunct>(std::move(RT));
770 
771         return ES.createMaterializationResponsibility(
772             *RT, std::move(SymbolFlags), std::move(InitSymbol));
773       });
774 }
775 
776 SymbolNameSet
777 JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
778   return ES.runSessionLocked([&]() {
779     SymbolNameSet RequestedSymbols;
780 
781     for (auto &KV : SymbolFlags) {
782       assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
783       assert(Symbols.find(KV.first)->second.getState() !=
784                  SymbolState::NeverSearched &&
785              Symbols.find(KV.first)->second.getState() != SymbolState::Ready &&
786              "getRequestedSymbols can only be called for symbols that have "
787              "started materializing");
788       auto I = MaterializingInfos.find(KV.first);
789       if (I == MaterializingInfos.end())
790         continue;
791 
792       if (I->second.hasQueriesPending())
793         RequestedSymbols.insert(KV.first);
794     }
795 
796     return RequestedSymbols;
797   });
798 }
799 
800 void JITDylib::addDependencies(const SymbolStringPtr &Name,
801                                const SymbolDependenceMap &Dependencies) {
802   assert(Symbols.count(Name) && "Name not in symbol table");
803   assert(Symbols[Name].getState() < SymbolState::Emitted &&
804          "Can not add dependencies for a symbol that is not materializing");
805 
806   LLVM_DEBUG({
807       dbgs() << "In " << getName() << " adding dependencies for "
808              << *Name << ": " << Dependencies << "\n";
809     });
810 
811   // If Name is already in an error state then just bail out.
812   if (Symbols[Name].getFlags().hasError())
813     return;
814 
815   auto &MI = MaterializingInfos[Name];
816   assert(Symbols[Name].getState() != SymbolState::Emitted &&
817          "Can not add dependencies to an emitted symbol");
818 
819   bool DependsOnSymbolInErrorState = false;
820 
821   // Register dependencies, record whether any depenendency is in the error
822   // state.
823   for (auto &KV : Dependencies) {
824     assert(KV.first && "Null JITDylib in dependency?");
825     auto &OtherJITDylib = *KV.first;
826     auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
827 
828     for (auto &OtherSymbol : KV.second) {
829 
830       // Check the sym entry for the dependency.
831       auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
832 
833       // Assert that this symbol exists and has not reached the ready state
834       // already.
835       assert(OtherSymI != OtherJITDylib.Symbols.end() &&
836              "Dependency on unknown symbol");
837 
838       auto &OtherSymEntry = OtherSymI->second;
839 
840       // If the other symbol is already in the Ready state then there's no
841       // dependency to add.
842       if (OtherSymEntry.getState() == SymbolState::Ready)
843         continue;
844 
845       // If the dependency is in an error state then note this and continue,
846       // we will move this symbol to the error state below.
847       if (OtherSymEntry.getFlags().hasError()) {
848         DependsOnSymbolInErrorState = true;
849         continue;
850       }
851 
852       // If the dependency was not in the error state then add it to
853       // our list of dependencies.
854       auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
855 
856       if (OtherSymEntry.getState() == SymbolState::Emitted)
857         transferEmittedNodeDependencies(MI, Name, OtherMI);
858       else if (&OtherJITDylib != this || OtherSymbol != Name) {
859         OtherMI.Dependants[this].insert(Name);
860         DepsOnOtherJITDylib.insert(OtherSymbol);
861       }
862     }
863 
864     if (DepsOnOtherJITDylib.empty())
865       MI.UnemittedDependencies.erase(&OtherJITDylib);
866   }
867 
868   // If this symbol dependended on any symbols in the error state then move
869   // this symbol to the error state too.
870   if (DependsOnSymbolInErrorState)
871     Symbols[Name].setFlags(Symbols[Name].getFlags() | JITSymbolFlags::HasError);
872 }
873 
874 Error JITDylib::resolve(MaterializationResponsibility &MR,
875                         const SymbolMap &Resolved) {
876   AsynchronousSymbolQuerySet CompletedQueries;
877 
878   if (auto Err = ES.runSessionLocked([&, this]() -> Error {
879         auto RTI = MRTrackers.find(&MR);
880         assert(RTI != MRTrackers.end() && "No resource tracker for MR?");
881         if (RTI->second->isDefunct())
882           return make_error<ResourceTrackerDefunct>(RTI->second);
883 
884         struct WorklistEntry {
885           SymbolTable::iterator SymI;
886           JITEvaluatedSymbol ResolvedSym;
887         };
888 
889         SymbolNameSet SymbolsInErrorState;
890         std::vector<WorklistEntry> Worklist;
891         Worklist.reserve(Resolved.size());
892 
893         // Build worklist and check for any symbols in the error state.
894         for (const auto &KV : Resolved) {
895 
896           assert(!KV.second.getFlags().hasError() &&
897                  "Resolution result can not have error flag set");
898 
899           auto SymI = Symbols.find(KV.first);
900 
901           assert(SymI != Symbols.end() && "Symbol not found");
902           assert(!SymI->second.hasMaterializerAttached() &&
903                  "Resolving symbol with materializer attached?");
904           assert(SymI->second.getState() == SymbolState::Materializing &&
905                  "Symbol should be materializing");
906           assert(SymI->second.getAddress() == 0 &&
907                  "Symbol has already been resolved");
908 
909           if (SymI->second.getFlags().hasError())
910             SymbolsInErrorState.insert(KV.first);
911           else {
912             auto Flags = KV.second.getFlags();
913             Flags &= ~(JITSymbolFlags::Weak | JITSymbolFlags::Common);
914             assert(Flags ==
915                        (SymI->second.getFlags() &
916                         ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&
917                    "Resolved flags should match the declared flags");
918 
919             Worklist.push_back(
920                 {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
921           }
922         }
923 
924         // If any symbols were in the error state then bail out.
925         if (!SymbolsInErrorState.empty()) {
926           auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
927           (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
928           return make_error<FailedToMaterialize>(
929               std::move(FailedSymbolsDepMap));
930         }
931 
932         while (!Worklist.empty()) {
933           auto SymI = Worklist.back().SymI;
934           auto ResolvedSym = Worklist.back().ResolvedSym;
935           Worklist.pop_back();
936 
937           auto &Name = SymI->first;
938 
939           // Resolved symbols can not be weak: discard the weak flag.
940           JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
941           SymI->second.setAddress(ResolvedSym.getAddress());
942           SymI->second.setFlags(ResolvedFlags);
943           SymI->second.setState(SymbolState::Resolved);
944 
945           auto MII = MaterializingInfos.find(Name);
946           if (MII == MaterializingInfos.end())
947             continue;
948 
949           auto &MI = MII->second;
950           for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
951             Q->notifySymbolMetRequiredState(Name, ResolvedSym);
952             Q->removeQueryDependence(*this, Name);
953             if (Q->isComplete())
954               CompletedQueries.insert(std::move(Q));
955           }
956         }
957 
958         return Error::success();
959       }))
960     return Err;
961 
962   // Otherwise notify all the completed queries.
963   for (auto &Q : CompletedQueries) {
964     assert(Q->isComplete() && "Q not completed");
965     Q->handleComplete();
966   }
967 
968   return Error::success();
969 }
970 
971 Error JITDylib::emit(MaterializationResponsibility &MR,
972                      const SymbolFlagsMap &Emitted) {
973   AsynchronousSymbolQuerySet CompletedQueries;
974   DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
975 
976   if (auto Err = ES.runSessionLocked([&, this]() -> Error {
977         auto RTI = MRTrackers.find(&MR);
978         assert(RTI != MRTrackers.end() && "No resource tracker for MR?");
979         if (RTI->second->isDefunct())
980           return make_error<ResourceTrackerDefunct>(RTI->second);
981 
982         SymbolNameSet SymbolsInErrorState;
983         std::vector<SymbolTable::iterator> Worklist;
984 
985         // Scan to build worklist, record any symbols in the erorr state.
986         for (const auto &KV : Emitted) {
987           auto &Name = KV.first;
988 
989           auto SymI = Symbols.find(Name);
990           assert(SymI != Symbols.end() && "No symbol table entry for Name");
991 
992           if (SymI->second.getFlags().hasError())
993             SymbolsInErrorState.insert(Name);
994           else
995             Worklist.push_back(SymI);
996         }
997 
998         // If any symbols were in the error state then bail out.
999         if (!SymbolsInErrorState.empty()) {
1000           auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1001           (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1002           return make_error<FailedToMaterialize>(
1003               std::move(FailedSymbolsDepMap));
1004         }
1005 
1006         // Otherwise update dependencies and move to the emitted state.
1007         while (!Worklist.empty()) {
1008           auto SymI = Worklist.back();
1009           Worklist.pop_back();
1010 
1011           auto &Name = SymI->first;
1012           auto &SymEntry = SymI->second;
1013 
1014           // Move symbol to the emitted state.
1015           assert(((SymEntry.getFlags().hasMaterializationSideEffectsOnly() &&
1016                    SymEntry.getState() == SymbolState::Materializing) ||
1017                   SymEntry.getState() == SymbolState::Resolved) &&
1018                  "Emitting from state other than Resolved");
1019           SymEntry.setState(SymbolState::Emitted);
1020 
1021           auto MII = MaterializingInfos.find(Name);
1022 
1023           // If this symbol has no MaterializingInfo then it's trivially ready.
1024           // Update its state and continue.
1025           if (MII == MaterializingInfos.end()) {
1026             SymEntry.setState(SymbolState::Ready);
1027             continue;
1028           }
1029 
1030           auto &MI = MII->second;
1031 
1032           // For each dependant, transfer this node's emitted dependencies to
1033           // it. If the dependant node is ready (i.e. has no unemitted
1034           // dependencies) then notify any pending queries.
1035           for (auto &KV : MI.Dependants) {
1036             auto &DependantJD = *KV.first;
1037             auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1038             for (auto &DependantName : KV.second) {
1039               auto DependantMII =
1040                   DependantJD.MaterializingInfos.find(DependantName);
1041               assert(DependantMII != DependantJD.MaterializingInfos.end() &&
1042                      "Dependant should have MaterializingInfo");
1043 
1044               auto &DependantMI = DependantMII->second;
1045 
1046               // Remove the dependant's dependency on this node.
1047               assert(DependantMI.UnemittedDependencies.count(this) &&
1048                      "Dependant does not have an unemitted dependencies record "
1049                      "for "
1050                      "this JITDylib");
1051               assert(DependantMI.UnemittedDependencies[this].count(Name) &&
1052                      "Dependant does not count this symbol as a dependency?");
1053 
1054               DependantMI.UnemittedDependencies[this].erase(Name);
1055               if (DependantMI.UnemittedDependencies[this].empty())
1056                 DependantMI.UnemittedDependencies.erase(this);
1057 
1058               // Transfer unemitted dependencies from this node to the
1059               // dependant.
1060               DependantJD.transferEmittedNodeDependencies(DependantMI,
1061                                                           DependantName, MI);
1062 
1063               auto DependantSymI = DependantJD.Symbols.find(DependantName);
1064               assert(DependantSymI != DependantJD.Symbols.end() &&
1065                      "Dependant has no entry in the Symbols table");
1066               auto &DependantSymEntry = DependantSymI->second;
1067 
1068               // If the dependant is emitted and this node was the last of its
1069               // unemitted dependencies then the dependant node is now ready, so
1070               // notify any pending queries on the dependant node.
1071               if (DependantSymEntry.getState() == SymbolState::Emitted &&
1072                   DependantMI.UnemittedDependencies.empty()) {
1073                 assert(DependantMI.Dependants.empty() &&
1074                        "Dependants should be empty by now");
1075 
1076                 // Since this dependant is now ready, we erase its
1077                 // MaterializingInfo and update its materializing state.
1078                 DependantSymEntry.setState(SymbolState::Ready);
1079                 DependantJDReadySymbols.push_back(DependantName);
1080 
1081                 for (auto &Q :
1082                      DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1083                   Q->notifySymbolMetRequiredState(
1084                       DependantName, DependantSymI->second.getSymbol());
1085                   if (Q->isComplete())
1086                     CompletedQueries.insert(Q);
1087                   Q->removeQueryDependence(DependantJD, DependantName);
1088                 }
1089               }
1090             }
1091           }
1092 
1093           auto &ThisJDReadySymbols = ReadySymbols[this];
1094           MI.Dependants.clear();
1095           if (MI.UnemittedDependencies.empty()) {
1096             SymI->second.setState(SymbolState::Ready);
1097             ThisJDReadySymbols.push_back(Name);
1098             for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1099               Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1100               if (Q->isComplete())
1101                 CompletedQueries.insert(Q);
1102               Q->removeQueryDependence(*this, Name);
1103             }
1104           }
1105         }
1106 
1107         return Error::success();
1108       }))
1109     return Err;
1110 
1111   // Otherwise notify all the completed queries.
1112   for (auto &Q : CompletedQueries) {
1113     assert(Q->isComplete() && "Q is not complete");
1114     Q->handleComplete();
1115   }
1116 
1117   return Error::success();
1118 }
1119 
1120 void JITDylib::unlinkMaterializationResponsibility(
1121     MaterializationResponsibility &MR) {
1122   ES.runSessionLocked([&]() {
1123     auto I = MRTrackers.find(&MR);
1124     assert(I != MRTrackers.end() && "MaterializationResponsibility not linked");
1125     MRTrackers.erase(I);
1126   });
1127 }
1128 
1129 std::pair<JITDylib::AsynchronousSymbolQuerySet,
1130           std::shared_ptr<SymbolDependenceMap>>
1131 JITDylib::failSymbols(FailedSymbolsWorklist Worklist) {
1132   AsynchronousSymbolQuerySet FailedQueries;
1133   auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1134 
1135   while (!Worklist.empty()) {
1136     assert(Worklist.back().first && "Failed JITDylib can not be null");
1137     auto &JD = *Worklist.back().first;
1138     auto Name = std::move(Worklist.back().second);
1139     Worklist.pop_back();
1140 
1141     (*FailedSymbolsMap)[&JD].insert(Name);
1142 
1143     assert(JD.Symbols.count(Name) && "No symbol table entry for Name");
1144     auto &Sym = JD.Symbols[Name];
1145 
1146     // Move the symbol into the error state.
1147     // Note that this may be redundant: The symbol might already have been
1148     // moved to this state in response to the failure of a dependence.
1149     Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1150 
1151     // FIXME: Come up with a sane mapping of state to
1152     // presence-of-MaterializingInfo so that we can assert presence / absence
1153     // here, rather than testing it.
1154     auto MII = JD.MaterializingInfos.find(Name);
1155 
1156     if (MII == JD.MaterializingInfos.end())
1157       continue;
1158 
1159     auto &MI = MII->second;
1160 
1161     // Move all dependants to the error state and disconnect from them.
1162     for (auto &KV : MI.Dependants) {
1163       auto &DependantJD = *KV.first;
1164       for (auto &DependantName : KV.second) {
1165         assert(DependantJD.Symbols.count(DependantName) &&
1166                "No symbol table entry for DependantName");
1167         auto &DependantSym = DependantJD.Symbols[DependantName];
1168         DependantSym.setFlags(DependantSym.getFlags() |
1169                               JITSymbolFlags::HasError);
1170 
1171         assert(DependantJD.MaterializingInfos.count(DependantName) &&
1172                "No MaterializingInfo for dependant");
1173         auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1174 
1175         auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1176         assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
1177                "No UnemittedDependencies entry for this JITDylib");
1178         assert(UnemittedDepI->second.count(Name) &&
1179                "No UnemittedDependencies entry for this symbol");
1180         UnemittedDepI->second.erase(Name);
1181         if (UnemittedDepI->second.empty())
1182           DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1183 
1184         // If this symbol is already in the emitted state then we need to
1185         // take responsibility for failing its queries, so add it to the
1186         // worklist.
1187         if (DependantSym.getState() == SymbolState::Emitted) {
1188           assert(DependantMI.Dependants.empty() &&
1189                  "Emitted symbol should not have dependants");
1190           Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1191         }
1192       }
1193     }
1194     MI.Dependants.clear();
1195 
1196     // Disconnect from all unemitted depenencies.
1197     for (auto &KV : MI.UnemittedDependencies) {
1198       auto &UnemittedDepJD = *KV.first;
1199       for (auto &UnemittedDepName : KV.second) {
1200         auto UnemittedDepMII =
1201             UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1202         assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
1203                "Missing MII for unemitted dependency");
1204         assert(UnemittedDepMII->second.Dependants.count(&JD) &&
1205                "JD not listed as a dependant of unemitted dependency");
1206         assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
1207                "Name is not listed as a dependant of unemitted dependency");
1208         UnemittedDepMII->second.Dependants[&JD].erase(Name);
1209         if (UnemittedDepMII->second.Dependants[&JD].empty())
1210           UnemittedDepMII->second.Dependants.erase(&JD);
1211       }
1212     }
1213     MI.UnemittedDependencies.clear();
1214 
1215     // Collect queries to be failed for this MII.
1216     AsynchronousSymbolQueryList ToDetach;
1217     for (auto &Q : MII->second.pendingQueries()) {
1218       // Add the query to the list to be failed and detach it.
1219       FailedQueries.insert(Q);
1220       ToDetach.push_back(Q);
1221     }
1222     for (auto &Q : ToDetach)
1223       Q->detach();
1224 
1225     assert(MI.Dependants.empty() &&
1226            "Can not delete MaterializingInfo with dependants still attached");
1227     assert(MI.UnemittedDependencies.empty() &&
1228            "Can not delete MaterializingInfo with unemitted dependencies "
1229            "still attached");
1230     assert(!MI.hasQueriesPending() &&
1231            "Can not delete MaterializingInfo with queries pending");
1232     JD.MaterializingInfos.erase(MII);
1233   }
1234 
1235   return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap));
1236 }
1237 
1238 void JITDylib::setLinkOrder(JITDylibSearchOrder NewLinkOrder,
1239                             bool LinkAgainstThisJITDylibFirst) {
1240   ES.runSessionLocked([&]() {
1241     if (LinkAgainstThisJITDylibFirst) {
1242       LinkOrder.clear();
1243       if (NewLinkOrder.empty() || NewLinkOrder.front().first != this)
1244         LinkOrder.push_back(
1245             std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1246       LinkOrder.insert(LinkOrder.end(), NewLinkOrder.begin(),
1247                        NewLinkOrder.end());
1248     } else
1249       LinkOrder = std::move(NewLinkOrder);
1250   });
1251 }
1252 
1253 void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) {
1254   ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });
1255 }
1256 
1257 void JITDylib::replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
1258                                   JITDylibLookupFlags JDLookupFlags) {
1259   ES.runSessionLocked([&]() {
1260     for (auto &KV : LinkOrder)
1261       if (KV.first == &OldJD) {
1262         KV = {&NewJD, JDLookupFlags};
1263         break;
1264       }
1265   });
1266 }
1267 
1268 void JITDylib::removeFromLinkOrder(JITDylib &JD) {
1269   ES.runSessionLocked([&]() {
1270     auto I = std::find_if(LinkOrder.begin(), LinkOrder.end(),
1271                           [&](const JITDylibSearchOrder::value_type &KV) {
1272                             return KV.first == &JD;
1273                           });
1274     if (I != LinkOrder.end())
1275       LinkOrder.erase(I);
1276   });
1277 }
1278 
1279 Error JITDylib::remove(const SymbolNameSet &Names) {
1280   return ES.runSessionLocked([&]() -> Error {
1281     using SymbolMaterializerItrPair =
1282         std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1283     std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1284     SymbolNameSet Missing;
1285     SymbolNameSet Materializing;
1286 
1287     for (auto &Name : Names) {
1288       auto I = Symbols.find(Name);
1289 
1290       // Note symbol missing.
1291       if (I == Symbols.end()) {
1292         Missing.insert(Name);
1293         continue;
1294       }
1295 
1296       // Note symbol materializing.
1297       if (I->second.getState() != SymbolState::NeverSearched &&
1298           I->second.getState() != SymbolState::Ready) {
1299         Materializing.insert(Name);
1300         continue;
1301       }
1302 
1303       auto UMII = I->second.hasMaterializerAttached()
1304                       ? UnmaterializedInfos.find(Name)
1305                       : UnmaterializedInfos.end();
1306       SymbolsToRemove.push_back(std::make_pair(I, UMII));
1307     }
1308 
1309     // If any of the symbols are not defined, return an error.
1310     if (!Missing.empty())
1311       return make_error<SymbolsNotFound>(std::move(Missing));
1312 
1313     // If any of the symbols are currently materializing, return an error.
1314     if (!Materializing.empty())
1315       return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1316 
1317     // Remove the symbols.
1318     for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1319       auto UMII = SymbolMaterializerItrPair.second;
1320 
1321       // If there is a materializer attached, call discard.
1322       if (UMII != UnmaterializedInfos.end()) {
1323         UMII->second->MU->doDiscard(*this, UMII->first);
1324         UnmaterializedInfos.erase(UMII);
1325       }
1326 
1327       auto SymI = SymbolMaterializerItrPair.first;
1328       Symbols.erase(SymI);
1329     }
1330 
1331     return Error::success();
1332   });
1333 }
1334 
1335 void JITDylib::dump(raw_ostream &OS) {
1336   ES.runSessionLocked([&, this]() {
1337     OS << "JITDylib \"" << JITDylibName << "\" (ES: "
1338        << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
1339        << "Link order: " << LinkOrder << "\n"
1340        << "Symbol table:\n";
1341 
1342     for (auto &KV : Symbols) {
1343       OS << "    \"" << *KV.first << "\": ";
1344       if (auto Addr = KV.second.getAddress())
1345         OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
1346            << " ";
1347       else
1348         OS << "<not resolved> ";
1349 
1350       OS << KV.second.getFlags() << " " << KV.second.getState();
1351 
1352       if (KV.second.hasMaterializerAttached()) {
1353         OS << " (Materializer ";
1354         auto I = UnmaterializedInfos.find(KV.first);
1355         assert(I != UnmaterializedInfos.end() &&
1356                "Lazy symbol should have UnmaterializedInfo");
1357         OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";
1358       } else
1359         OS << "\n";
1360     }
1361 
1362     if (!MaterializingInfos.empty())
1363       OS << "  MaterializingInfos entries:\n";
1364     for (auto &KV : MaterializingInfos) {
1365       OS << "    \"" << *KV.first << "\":\n"
1366          << "      " << KV.second.pendingQueries().size()
1367          << " pending queries: { ";
1368       for (const auto &Q : KV.second.pendingQueries())
1369         OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1370       OS << "}\n      Dependants:\n";
1371       for (auto &KV2 : KV.second.Dependants)
1372         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1373       OS << "      Unemitted Dependencies:\n";
1374       for (auto &KV2 : KV.second.UnemittedDependencies)
1375         OS << "        " << KV2.first->getName() << ": " << KV2.second << "\n";
1376     }
1377   });
1378 }
1379 
1380 void JITDylib::MaterializingInfo::addQuery(
1381     std::shared_ptr<AsynchronousSymbolQuery> Q) {
1382 
1383   auto I = std::lower_bound(
1384       PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1385       [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1386         return V->getRequiredState() <= S;
1387       });
1388   PendingQueries.insert(I.base(), std::move(Q));
1389 }
1390 
1391 void JITDylib::MaterializingInfo::removeQuery(
1392     const AsynchronousSymbolQuery &Q) {
1393   // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1394   auto I =
1395       std::find_if(PendingQueries.begin(), PendingQueries.end(),
1396                    [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1397                      return V.get() == &Q;
1398                    });
1399   assert(I != PendingQueries.end() &&
1400          "Query is not attached to this MaterializingInfo");
1401   PendingQueries.erase(I);
1402 }
1403 
1404 JITDylib::AsynchronousSymbolQueryList
1405 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1406   AsynchronousSymbolQueryList Result;
1407   while (!PendingQueries.empty()) {
1408     if (PendingQueries.back()->getRequiredState() > RequiredState)
1409       break;
1410 
1411     Result.push_back(std::move(PendingQueries.back()));
1412     PendingQueries.pop_back();
1413   }
1414 
1415   return Result;
1416 }
1417 
1418 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1419     : ES(ES), JITDylibName(std::move(Name)) {
1420   LinkOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1421 }
1422 
1423 ResourceTrackerSP JITDylib::getTracker(MaterializationResponsibility &MR) {
1424   auto I = MRTrackers.find(&MR);
1425   assert(I != MRTrackers.end() && "MR is not linked");
1426   assert(I->second && "Linked tracker is null");
1427   return I->second;
1428 }
1429 
1430 std::pair<JITDylib::AsynchronousSymbolQuerySet,
1431           std::shared_ptr<SymbolDependenceMap>>
1432 JITDylib::removeTracker(ResourceTracker &RT) {
1433   // Note: Should be called under the session lock.
1434 
1435   SymbolNameVector SymbolsToRemove;
1436   std::vector<std::pair<JITDylib *, SymbolStringPtr>> SymbolsToFail;
1437 
1438   if (&RT == DefaultTracker.get()) {
1439     SymbolNameSet TrackedSymbols;
1440     for (auto &KV : TrackerSymbols)
1441       for (auto &Sym : KV.second)
1442         TrackedSymbols.insert(Sym);
1443 
1444     for (auto &KV : Symbols) {
1445       auto &Sym = KV.first;
1446       if (!TrackedSymbols.count(Sym))
1447         SymbolsToRemove.push_back(Sym);
1448     }
1449 
1450     DefaultTracker.reset();
1451   } else {
1452     /// Check for a non-default tracker.
1453     auto I = TrackerSymbols.find(&RT);
1454     if (I != TrackerSymbols.end()) {
1455       SymbolsToRemove = std::move(I->second);
1456       TrackerSymbols.erase(I);
1457     }
1458     // ... if not found this tracker was already defunct. Nothing to do.
1459   }
1460 
1461   for (auto &Sym : SymbolsToRemove) {
1462     assert(Symbols.count(Sym) && "Symbol not in symbol table");
1463 
1464     // If there is a MaterializingInfo then collect any queries to fail.
1465     auto MII = MaterializingInfos.find(Sym);
1466     if (MII != MaterializingInfos.end())
1467       SymbolsToFail.push_back({this, Sym});
1468   }
1469 
1470   AsynchronousSymbolQuerySet QueriesToFail;
1471   auto Result = failSymbols(std::move(SymbolsToFail));
1472 
1473   // Removed symbols should be taken out of the table altogether.
1474   for (auto &Sym : SymbolsToRemove) {
1475     auto I = Symbols.find(Sym);
1476     assert(I != Symbols.end() && "Symbol not present in table");
1477 
1478     // Remove Materializer if present.
1479     if (I->second.hasMaterializerAttached()) {
1480       // FIXME: Should this discard the symbols?
1481       UnmaterializedInfos.erase(Sym);
1482     } else {
1483       assert(!UnmaterializedInfos.count(Sym) &&
1484              "Symbol has materializer attached");
1485     }
1486 
1487     Symbols.erase(I);
1488   }
1489 
1490   return Result;
1491 }
1492 
1493 void JITDylib::transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT) {
1494   assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker");
1495   assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib");
1496   assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib");
1497 
1498   // Update trackers for any not-yet materialized units.
1499   for (auto &KV : UnmaterializedInfos) {
1500     if (KV.second->RT == &SrcRT)
1501       KV.second->RT = &DstRT;
1502   }
1503 
1504   // Update trackers for any active materialization responsibilities.
1505   for (auto &KV : MRTrackers) {
1506     if (KV.second == &SrcRT)
1507       KV.second = &DstRT;
1508   }
1509 
1510   // If we're transfering to the default tracker we just need to delete the
1511   // tracked symbols for the source tracker.
1512   if (&DstRT == DefaultTracker.get()) {
1513     TrackerSymbols.erase(&SrcRT);
1514     return;
1515   }
1516 
1517   // If we're transferring from the default tracker we need to find all
1518   // currently untracked symbols.
1519   if (&SrcRT == DefaultTracker.get()) {
1520     assert(!TrackerSymbols.count(&SrcRT) &&
1521            "Default tracker should not appear in TrackerSymbols");
1522 
1523     SymbolNameVector SymbolsToTrack;
1524 
1525     SymbolNameSet CurrentlyTrackedSymbols;
1526     for (auto &KV : TrackerSymbols)
1527       for (auto &Sym : KV.second)
1528         CurrentlyTrackedSymbols.insert(Sym);
1529 
1530     for (auto &KV : Symbols) {
1531       auto &Sym = KV.first;
1532       if (!CurrentlyTrackedSymbols.count(Sym))
1533         SymbolsToTrack.push_back(Sym);
1534     }
1535 
1536     TrackerSymbols[&DstRT] = std::move(SymbolsToTrack);
1537     return;
1538   }
1539 
1540   auto &DstTrackedSymbols = TrackerSymbols[&DstRT];
1541 
1542   // Finally if neither SrtRT or DstRT are the default tracker then
1543   // just append DstRT's tracked symbols to SrtRT's.
1544   auto SI = TrackerSymbols.find(&SrcRT);
1545   if (SI == TrackerSymbols.end())
1546     return;
1547 
1548   DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size());
1549   for (auto &Sym : SI->second)
1550     DstTrackedSymbols.push_back(std::move(Sym));
1551   TrackerSymbols.erase(SI);
1552 }
1553 
1554 Error JITDylib::defineImpl(MaterializationUnit &MU) {
1555 
1556   LLVM_DEBUG({ dbgs() << "  " << MU.getSymbols() << "\n"; });
1557 
1558   SymbolNameSet Duplicates;
1559   std::vector<SymbolStringPtr> ExistingDefsOverridden;
1560   std::vector<SymbolStringPtr> MUDefsOverridden;
1561 
1562   for (const auto &KV : MU.getSymbols()) {
1563     auto I = Symbols.find(KV.first);
1564 
1565     if (I != Symbols.end()) {
1566       if (KV.second.isStrong()) {
1567         if (I->second.getFlags().isStrong() ||
1568             I->second.getState() > SymbolState::NeverSearched)
1569           Duplicates.insert(KV.first);
1570         else {
1571           assert(I->second.getState() == SymbolState::NeverSearched &&
1572                  "Overridden existing def should be in the never-searched "
1573                  "state");
1574           ExistingDefsOverridden.push_back(KV.first);
1575         }
1576       } else
1577         MUDefsOverridden.push_back(KV.first);
1578     }
1579   }
1580 
1581   // If there were any duplicate definitions then bail out.
1582   if (!Duplicates.empty()) {
1583     LLVM_DEBUG(
1584         { dbgs() << "  Error: Duplicate symbols " << Duplicates << "\n"; });
1585     return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1586   }
1587 
1588   // Discard any overridden defs in this MU.
1589   LLVM_DEBUG({
1590     if (!MUDefsOverridden.empty())
1591       dbgs() << "  Defs in this MU overridden: " << MUDefsOverridden << "\n";
1592   });
1593   for (auto &S : MUDefsOverridden)
1594     MU.doDiscard(*this, S);
1595 
1596   // Discard existing overridden defs.
1597   LLVM_DEBUG({
1598     if (!ExistingDefsOverridden.empty())
1599       dbgs() << "  Existing defs overridden by this MU: " << MUDefsOverridden
1600              << "\n";
1601   });
1602   for (auto &S : ExistingDefsOverridden) {
1603 
1604     auto UMII = UnmaterializedInfos.find(S);
1605     assert(UMII != UnmaterializedInfos.end() &&
1606            "Overridden existing def should have an UnmaterializedInfo");
1607     UMII->second->MU->doDiscard(*this, S);
1608   }
1609 
1610   // Finally, add the defs from this MU.
1611   for (auto &KV : MU.getSymbols()) {
1612     auto &SymEntry = Symbols[KV.first];
1613     SymEntry.setFlags(KV.second);
1614     SymEntry.setState(SymbolState::NeverSearched);
1615     SymEntry.setMaterializerAttached(true);
1616   }
1617 
1618   return Error::success();
1619 }
1620 
1621 void JITDylib::installMaterializationUnit(
1622     std::unique_ptr<MaterializationUnit> MU, ResourceTracker &RT) {
1623 
1624   /// defineImpl succeeded.
1625   if (&RT != DefaultTracker.get()) {
1626     auto &TS = TrackerSymbols[&RT];
1627     TS.reserve(TS.size() + MU->getSymbols().size());
1628     for (auto &KV : MU->getSymbols())
1629       TS.push_back(KV.first);
1630   }
1631 
1632   auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU), &RT);
1633   for (auto &KV : UMI->MU->getSymbols())
1634     UnmaterializedInfos[KV.first] = UMI;
1635 }
1636 
1637 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1638                                  const SymbolNameSet &QuerySymbols) {
1639   for (auto &QuerySymbol : QuerySymbols) {
1640     assert(MaterializingInfos.count(QuerySymbol) &&
1641            "QuerySymbol does not have MaterializingInfo");
1642     auto &MI = MaterializingInfos[QuerySymbol];
1643     MI.removeQuery(Q);
1644   }
1645 }
1646 
1647 void JITDylib::transferEmittedNodeDependencies(
1648     MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1649     MaterializingInfo &EmittedMI) {
1650   for (auto &KV : EmittedMI.UnemittedDependencies) {
1651     auto &DependencyJD = *KV.first;
1652     SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1653 
1654     for (auto &DependencyName : KV.second) {
1655       auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1656 
1657       // Do not add self dependencies.
1658       if (&DependencyMI == &DependantMI)
1659         continue;
1660 
1661       // If we haven't looked up the dependencies for DependencyJD yet, do it
1662       // now and cache the result.
1663       if (!UnemittedDependenciesOnDependencyJD)
1664         UnemittedDependenciesOnDependencyJD =
1665             &DependantMI.UnemittedDependencies[&DependencyJD];
1666 
1667       DependencyMI.Dependants[this].insert(DependantName);
1668       UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1669     }
1670   }
1671 }
1672 
1673 Platform::~Platform() {}
1674 
1675 Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
1676     ExecutionSession &ES,
1677     const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1678 
1679   DenseMap<JITDylib *, SymbolMap> CompoundResult;
1680   Error CompoundErr = Error::success();
1681   std::mutex LookupMutex;
1682   std::condition_variable CV;
1683   uint64_t Count = InitSyms.size();
1684 
1685   LLVM_DEBUG({
1686     dbgs() << "Issuing init-symbol lookup:\n";
1687     for (auto &KV : InitSyms)
1688       dbgs() << "  " << KV.first->getName() << ": " << KV.second << "\n";
1689   });
1690 
1691   for (auto &KV : InitSyms) {
1692     auto *JD = KV.first;
1693     auto Names = std::move(KV.second);
1694     ES.lookup(
1695         LookupKind::Static,
1696         JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),
1697         std::move(Names), SymbolState::Ready,
1698         [&, JD](Expected<SymbolMap> Result) {
1699           {
1700             std::lock_guard<std::mutex> Lock(LookupMutex);
1701             --Count;
1702             if (Result) {
1703               assert(!CompoundResult.count(JD) &&
1704                      "Duplicate JITDylib in lookup?");
1705               CompoundResult[JD] = std::move(*Result);
1706             } else
1707               CompoundErr =
1708                   joinErrors(std::move(CompoundErr), Result.takeError());
1709           }
1710           CV.notify_one();
1711         },
1712         NoDependenciesToRegister);
1713   }
1714 
1715   std::unique_lock<std::mutex> Lock(LookupMutex);
1716   CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1717 
1718   if (CompoundErr)
1719     return std::move(CompoundErr);
1720 
1721   return std::move(CompoundResult);
1722 }
1723 
1724 ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)
1725     : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {}
1726 
1727 Error ExecutionSession::endSession() {
1728   LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
1729 
1730   std::vector<JITDylibSP> JITDylibsToClose = runSessionLocked([&] {
1731     SessionOpen = false;
1732     return std::move(JDs);
1733   });
1734 
1735   // TODO: notifiy platform? run static deinits?
1736 
1737   Error Err = Error::success();
1738   for (auto &JD : JITDylibsToClose)
1739     Err = joinErrors(std::move(Err), JD->clear());
1740   return Err;
1741 }
1742 
1743 void ExecutionSession::registerResourceManager(ResourceManager &RM) {
1744   runSessionLocked([&] { ResourceManagers.push_back(&RM); });
1745 }
1746 
1747 void ExecutionSession::deregisterResourceManager(ResourceManager &RM) {
1748   runSessionLocked([&] {
1749     assert(!ResourceManagers.empty() && "No managers registered");
1750     if (ResourceManagers.back() == &RM)
1751       ResourceManagers.pop_back();
1752     else {
1753       auto I = llvm::find(ResourceManagers, &RM);
1754       assert(I != ResourceManagers.end() && "RM not registered");
1755       ResourceManagers.erase(I);
1756     }
1757   });
1758 }
1759 
1760 JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {
1761   return runSessionLocked([&, this]() -> JITDylib * {
1762     for (auto &JD : JDs)
1763       if (JD->getName() == Name)
1764         return JD.get();
1765     return nullptr;
1766   });
1767 }
1768 
1769 JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {
1770   assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
1771   return runSessionLocked([&, this]() -> JITDylib & {
1772     JDs.push_back(new JITDylib(*this, std::move(Name)));
1773     return *JDs.back();
1774   });
1775 }
1776 
1777 Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
1778   auto &JD = createBareJITDylib(Name);
1779   if (P)
1780     if (auto Err = P->setupJITDylib(JD))
1781       return std::move(Err);
1782   return JD;
1783 }
1784 
1785 std::vector<JITDylibSP> JITDylib::getDFSLinkOrder(ArrayRef<JITDylibSP> JDs) {
1786   if (JDs.empty())
1787     return {};
1788 
1789   auto &ES = JDs.front()->getExecutionSession();
1790   return ES.runSessionLocked([&]() {
1791     DenseSet<JITDylib *> Visited;
1792     std::vector<JITDylibSP> Result;
1793 
1794     for (auto &JD : JDs) {
1795 
1796       if (Visited.count(JD.get()))
1797         continue;
1798 
1799       SmallVector<JITDylibSP, 64> WorkStack;
1800       WorkStack.push_back(JD);
1801       Visited.insert(JD.get());
1802 
1803       while (!WorkStack.empty()) {
1804         Result.push_back(std::move(WorkStack.back()));
1805         WorkStack.pop_back();
1806 
1807         for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) {
1808           auto &JD = *KV.first;
1809           if (Visited.count(&JD))
1810             continue;
1811           Visited.insert(&JD);
1812           WorkStack.push_back(&JD);
1813         }
1814       }
1815     }
1816     return Result;
1817   });
1818 }
1819 
1820 std::vector<JITDylibSP>
1821 JITDylib::getReverseDFSLinkOrder(ArrayRef<JITDylibSP> JDs) {
1822   auto Tmp = getDFSLinkOrder(JDs);
1823   std::reverse(Tmp.begin(), Tmp.end());
1824   return Tmp;
1825 }
1826 
1827 std::vector<JITDylibSP> JITDylib::getDFSLinkOrder() {
1828   return getDFSLinkOrder({this});
1829 }
1830 
1831 std::vector<JITDylibSP> JITDylib::getReverseDFSLinkOrder() {
1832   return getReverseDFSLinkOrder({this});
1833 }
1834 
1835 void ExecutionSession::lookupFlags(
1836     LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
1837     unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
1838 
1839   OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
1840                           K, std::move(SearchOrder), std::move(LookupSet),
1841                           std::move(OnComplete)),
1842                       Error::success());
1843 }
1844 
1845 Expected<SymbolFlagsMap>
1846 ExecutionSession::lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder,
1847                               SymbolLookupSet LookupSet) {
1848 
1849   std::promise<MSVCPExpected<SymbolFlagsMap>> ResultP;
1850   OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
1851                           K, std::move(SearchOrder), std::move(LookupSet),
1852                           [&ResultP](Expected<SymbolFlagsMap> Result) {
1853                             ResultP.set_value(std::move(Result));
1854                           }),
1855                       Error::success());
1856 
1857   auto ResultF = ResultP.get_future();
1858   return ResultF.get();
1859 }
1860 
1861 void ExecutionSession::lookup(
1862     LookupKind K, const JITDylibSearchOrder &SearchOrder,
1863     SymbolLookupSet Symbols, SymbolState RequiredState,
1864     SymbolsResolvedCallback NotifyComplete,
1865     RegisterDependenciesFunction RegisterDependencies) {
1866 
1867   LLVM_DEBUG({
1868     runSessionLocked([&]() {
1869       dbgs() << "Looking up " << Symbols << " in " << SearchOrder
1870              << " (required state: " << RequiredState << ")\n";
1871     });
1872   });
1873 
1874   // lookup can be re-entered recursively if running on a single thread. Run any
1875   // outstanding MUs in case this query depends on them, otherwise this lookup
1876   // will starve waiting for a result from an MU that is stuck in the queue.
1877   dispatchOutstandingMUs();
1878 
1879   auto Unresolved = std::move(Symbols);
1880   auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
1881                                                      std::move(NotifyComplete));
1882 
1883   auto IPLS = std::make_unique<InProgressFullLookupState>(
1884       K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q),
1885       std::move(RegisterDependencies));
1886 
1887   OL_applyQueryPhase1(std::move(IPLS), Error::success());
1888 }
1889 
1890 Expected<SymbolMap>
1891 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
1892                          const SymbolLookupSet &Symbols, LookupKind K,
1893                          SymbolState RequiredState,
1894                          RegisterDependenciesFunction RegisterDependencies) {
1895 #if LLVM_ENABLE_THREADS
1896   // In the threaded case we use promises to return the results.
1897   std::promise<SymbolMap> PromisedResult;
1898   Error ResolutionError = Error::success();
1899 
1900   auto NotifyComplete = [&](Expected<SymbolMap> R) {
1901     if (R)
1902       PromisedResult.set_value(std::move(*R));
1903     else {
1904       ErrorAsOutParameter _(&ResolutionError);
1905       ResolutionError = R.takeError();
1906       PromisedResult.set_value(SymbolMap());
1907     }
1908   };
1909 
1910 #else
1911   SymbolMap Result;
1912   Error ResolutionError = Error::success();
1913 
1914   auto NotifyComplete = [&](Expected<SymbolMap> R) {
1915     ErrorAsOutParameter _(&ResolutionError);
1916     if (R)
1917       Result = std::move(*R);
1918     else
1919       ResolutionError = R.takeError();
1920   };
1921 #endif
1922 
1923   // Perform the asynchronous lookup.
1924   lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
1925          RegisterDependencies);
1926 
1927 #if LLVM_ENABLE_THREADS
1928   auto ResultFuture = PromisedResult.get_future();
1929   auto Result = ResultFuture.get();
1930 
1931   if (ResolutionError)
1932     return std::move(ResolutionError);
1933 
1934   return std::move(Result);
1935 
1936 #else
1937   if (ResolutionError)
1938     return std::move(ResolutionError);
1939 
1940   return Result;
1941 #endif
1942 }
1943 
1944 Expected<JITEvaluatedSymbol>
1945 ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,
1946                          SymbolStringPtr Name, SymbolState RequiredState) {
1947   SymbolLookupSet Names({Name});
1948 
1949   if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
1950                               RequiredState, NoDependenciesToRegister)) {
1951     assert(ResultMap->size() == 1 && "Unexpected number of results");
1952     assert(ResultMap->count(Name) && "Missing result for symbol");
1953     return std::move(ResultMap->begin()->second);
1954   } else
1955     return ResultMap.takeError();
1956 }
1957 
1958 Expected<JITEvaluatedSymbol>
1959 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,
1960                          SymbolState RequiredState) {
1961   return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
1962 }
1963 
1964 Expected<JITEvaluatedSymbol>
1965 ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,
1966                          SymbolState RequiredState) {
1967   return lookup(SearchOrder, intern(Name), RequiredState);
1968 }
1969 
1970 void ExecutionSession::dump(raw_ostream &OS) {
1971   runSessionLocked([this, &OS]() {
1972     for (auto &JD : JDs)
1973       JD->dump(OS);
1974   });
1975 }
1976 
1977 void ExecutionSession::dispatchOutstandingMUs() {
1978   LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n");
1979   while (1) {
1980     Optional<std::pair<std::unique_ptr<MaterializationUnit>,
1981                        std::unique_ptr<MaterializationResponsibility>>>
1982         JMU;
1983 
1984     {
1985       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
1986       if (!OutstandingMUs.empty()) {
1987         JMU.emplace(std::move(OutstandingMUs.back()));
1988         OutstandingMUs.pop_back();
1989       }
1990     }
1991 
1992     if (!JMU)
1993       break;
1994 
1995     assert(JMU->first && "No MU?");
1996     LLVM_DEBUG(dbgs() << "  Dispatching \"" << JMU->first->getName() << "\"\n");
1997     dispatchMaterialization(std::move(JMU->first), std::move(JMU->second));
1998   }
1999   LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n");
2000 }
2001 
2002 Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) {
2003   LLVM_DEBUG({
2004     dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "
2005            << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2006   });
2007   std::vector<ResourceManager *> CurrentResourceManagers;
2008 
2009   JITDylib::AsynchronousSymbolQuerySet QueriesToFail;
2010   std::shared_ptr<SymbolDependenceMap> FailedSymbols;
2011 
2012   runSessionLocked([&] {
2013     CurrentResourceManagers = ResourceManagers;
2014     RT.makeDefunct();
2015     std::tie(QueriesToFail, FailedSymbols) = RT.getJITDylib().removeTracker(RT);
2016   });
2017 
2018   Error Err = Error::success();
2019 
2020   for (auto *L : reverse(CurrentResourceManagers))
2021     Err =
2022         joinErrors(std::move(Err), L->handleRemoveResources(RT.getKeyUnsafe()));
2023 
2024   for (auto &Q : QueriesToFail)
2025     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
2026 
2027   return Err;
2028 }
2029 
2030 void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,
2031                                                ResourceTracker &SrcRT) {
2032   LLVM_DEBUG({
2033     dbgs() << "In " << SrcRT.getJITDylib().getName()
2034            << " transfering resources from tracker "
2035            << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "
2036            << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";
2037   });
2038 
2039   // No-op transfers are allowed and do not invalidate the source.
2040   if (&DstRT == &SrcRT)
2041     return;
2042 
2043   assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&
2044          "Can't transfer resources between JITDylibs");
2045   runSessionLocked([&]() {
2046     SrcRT.makeDefunct();
2047     auto &JD = DstRT.getJITDylib();
2048     JD.transferTracker(DstRT, SrcRT);
2049     for (auto *L : reverse(ResourceManagers))
2050       L->handleTransferResources(DstRT.getKeyUnsafe(), SrcRT.getKeyUnsafe());
2051   });
2052 }
2053 
2054 void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) {
2055   runSessionLocked([&]() {
2056     LLVM_DEBUG({
2057       dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "
2058              << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2059     });
2060     if (!RT.isDefunct())
2061       transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(),
2062                               RT);
2063   });
2064 }
2065 
2066 Error ExecutionSession::IL_updateCandidatesFor(
2067     JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
2068     SymbolLookupSet &Candidates, SymbolLookupSet *NonCandidates) {
2069   return Candidates.forEachWithRemoval(
2070       [&](const SymbolStringPtr &Name,
2071           SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
2072         /// Search for the symbol. If not found then continue without
2073         /// removal.
2074         auto SymI = JD.Symbols.find(Name);
2075         if (SymI == JD.Symbols.end())
2076           return false;
2077 
2078         // If this is a non-exported symbol and we're matching exported
2079         // symbols only then remove this symbol from the candidates list.
2080         //
2081         // If we're tracking non-candidates then add this to the non-candidate
2082         // list.
2083         if (!SymI->second.getFlags().isExported() &&
2084             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) {
2085           if (NonCandidates)
2086             NonCandidates->add(Name, SymLookupFlags);
2087           return true;
2088         }
2089 
2090         // If we match against a materialization-side-effects only symbol
2091         // then make sure it is weakly-referenced. Otherwise bail out with
2092         // an error.
2093         // FIXME: Use a "materialization-side-effects-only symbols must be
2094         // weakly referenced" specific error here to reduce confusion.
2095         if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2096             SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol)
2097           return make_error<SymbolsNotFound>(SymbolNameVector({Name}));
2098 
2099         // If we matched against this symbol but it is in the error state
2100         // then bail out and treat it as a failure to materialize.
2101         if (SymI->second.getFlags().hasError()) {
2102           auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
2103           (*FailedSymbolsMap)[&JD] = {Name};
2104           return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
2105         }
2106 
2107         // Otherwise this is a match. Remove it from the candidate set.
2108         return true;
2109       });
2110 }
2111 
2112 void ExecutionSession::OL_applyQueryPhase1(
2113     std::unique_ptr<InProgressLookupState> IPLS, Error Err) {
2114 
2115   LLVM_DEBUG({
2116     dbgs() << "Entering OL_applyQueryPhase1:\n"
2117            << "  Lookup kind: " << IPLS->K << "\n"
2118            << "  Search order: " << IPLS->SearchOrder
2119            << ", Current index = " << IPLS->CurSearchOrderIndex
2120            << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2121            << "  Lookup set: " << IPLS->LookupSet << "\n"
2122            << "  Definition generator candidates: "
2123            << IPLS->DefGeneratorCandidates << "\n"
2124            << "  Definition generator non-candidates: "
2125            << IPLS->DefGeneratorNonCandidates << "\n";
2126   });
2127 
2128   // FIXME: We should attach the query as we go: This provides a result in a
2129   // single pass in the common case where all symbols have already reached the
2130   // required state. The query could be detached again in the 'fail' method on
2131   // IPLS. Phase 2 would be reduced to collecting and dispatching the MUs.
2132 
2133   while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) {
2134 
2135     // If we've been handed an error or received one back from a generator then
2136     // fail the query. We don't need to unlink: At this stage the query hasn't
2137     // actually been lodged.
2138     if (Err)
2139       return IPLS->fail(std::move(Err));
2140 
2141     // Get the next JITDylib and lookup flags.
2142     auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex];
2143     auto &JD = *KV.first;
2144     auto JDLookupFlags = KV.second;
2145 
2146     LLVM_DEBUG({
2147       dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2148              << ") with lookup set " << IPLS->LookupSet << ":\n";
2149     });
2150 
2151     // If we've just reached a new JITDylib then perform some setup.
2152     if (IPLS->NewJITDylib) {
2153 
2154       // Acquire the generator lock for this JITDylib.
2155       IPLS->GeneratorLock = std::unique_lock<std::mutex>(JD.GeneratorsMutex);
2156 
2157       // Add any non-candidates from the last JITDylib (if any) back on to the
2158       // list of definition candidates for this JITDylib, reset definition
2159       // non-candiates to the empty set.
2160       SymbolLookupSet Tmp;
2161       std::swap(IPLS->DefGeneratorNonCandidates, Tmp);
2162       IPLS->DefGeneratorCandidates.append(std::move(Tmp));
2163 
2164       LLVM_DEBUG({
2165         dbgs() << "  First time visiting " << JD.getName()
2166                << ", resetting candidate sets and building generator stack\n";
2167       });
2168 
2169       // Build the definition generator stack for this JITDylib.
2170       for (auto &DG : reverse(JD.DefGenerators))
2171         IPLS->CurDefGeneratorStack.push_back(DG);
2172 
2173       // Flag that we've done our initialization.
2174       IPLS->NewJITDylib = false;
2175     }
2176 
2177     // Remove any generation candidates that are already defined (and match) in
2178     // this JITDylib.
2179     runSessionLocked([&] {
2180       // Update the list of candidates (and non-candidates) for definition
2181       // generation.
2182       LLVM_DEBUG(dbgs() << "  Updating candidate set...\n");
2183       Err = IL_updateCandidatesFor(
2184           JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2185           JD.DefGenerators.empty() ? nullptr
2186                                    : &IPLS->DefGeneratorNonCandidates);
2187       LLVM_DEBUG({
2188         dbgs() << "    Remaining candidates = " << IPLS->DefGeneratorCandidates
2189                << "\n";
2190       });
2191     });
2192 
2193     // If we encountered an error while filtering generation candidates then
2194     // bail out.
2195     if (Err)
2196       return IPLS->fail(std::move(Err));
2197 
2198     /// Apply any definition generators on the stack.
2199     LLVM_DEBUG({
2200       if (IPLS->CurDefGeneratorStack.empty())
2201         LLVM_DEBUG(dbgs() << "  No generators to run for this JITDylib.\n");
2202       else if (IPLS->DefGeneratorCandidates.empty())
2203         LLVM_DEBUG(dbgs() << "  No candidates to generate.\n");
2204       else
2205         dbgs() << "  Running " << IPLS->CurDefGeneratorStack.size()
2206                << " remaining generators for "
2207                << IPLS->DefGeneratorCandidates.size() << " candidates\n";
2208     });
2209     while (!IPLS->CurDefGeneratorStack.empty() &&
2210            !IPLS->DefGeneratorCandidates.empty()) {
2211       auto DG = IPLS->CurDefGeneratorStack.back().lock();
2212       IPLS->CurDefGeneratorStack.pop_back();
2213 
2214       if (!DG)
2215         return IPLS->fail(make_error<StringError>(
2216             "DefinitionGenerator removed while lookup in progress",
2217             inconvertibleErrorCode()));
2218 
2219       auto K = IPLS->K;
2220       auto &LookupSet = IPLS->DefGeneratorCandidates;
2221 
2222       // Run the generator. If the generator takes ownership of QA then this
2223       // will break the loop.
2224       {
2225         LLVM_DEBUG(dbgs() << "  Attempting to generate " << LookupSet << "\n");
2226         LookupState LS(std::move(IPLS));
2227         Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet);
2228         IPLS = std::move(LS.IPLS);
2229       }
2230 
2231       // If there was an error then fail the query.
2232       if (Err) {
2233         LLVM_DEBUG({
2234           dbgs() << "  Error attempting to generate " << LookupSet << "\n";
2235         });
2236         assert(IPLS && "LS cannot be retained if error is returned");
2237         return IPLS->fail(std::move(Err));
2238       }
2239 
2240       // Otherwise if QA was captured then break the loop.
2241       if (!IPLS) {
2242         LLVM_DEBUG(
2243             { dbgs() << "  LookupState captured. Exiting phase1 for now.\n"; });
2244         return;
2245       }
2246 
2247       // Otherwise if we're continuing around the loop then update candidates
2248       // for the next round.
2249       runSessionLocked([&] {
2250         LLVM_DEBUG(dbgs() << "  Updating candidate set post-generation\n");
2251         Err = IL_updateCandidatesFor(
2252             JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2253             JD.DefGenerators.empty() ? nullptr
2254                                      : &IPLS->DefGeneratorNonCandidates);
2255       });
2256 
2257       // If updating candidates failed then fail the query.
2258       if (Err) {
2259         LLVM_DEBUG(dbgs() << "  Error encountered while updating candidates\n");
2260         return IPLS->fail(std::move(Err));
2261       }
2262     }
2263 
2264     // If we get here then we've moved on to the next JITDylib.
2265     LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n");
2266     ++IPLS->CurSearchOrderIndex;
2267     IPLS->NewJITDylib = true;
2268   }
2269 
2270   // Remove any weakly referenced candidates that could not be found/generated.
2271   IPLS->DefGeneratorCandidates.remove_if(
2272       [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2273         return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
2274       });
2275 
2276   // If we get here then we've finished searching all JITDylibs.
2277   // If we matched all symbols then move to phase 2, otherwise fail the query
2278   // with a SymbolsNotFound error.
2279   if (IPLS->DefGeneratorCandidates.empty()) {
2280     LLVM_DEBUG(dbgs() << "Phase 1 succeeded.\n");
2281     IPLS->complete(std::move(IPLS));
2282   } else {
2283     LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n");
2284     IPLS->fail(make_error<SymbolsNotFound>(
2285         IPLS->DefGeneratorCandidates.getSymbolNames()));
2286   }
2287 }
2288 
2289 void ExecutionSession::OL_completeLookup(
2290     std::unique_ptr<InProgressLookupState> IPLS,
2291     std::shared_ptr<AsynchronousSymbolQuery> Q,
2292     RegisterDependenciesFunction RegisterDependencies) {
2293 
2294   LLVM_DEBUG({
2295     dbgs() << "Entering OL_completeLookup:\n"
2296            << "  Lookup kind: " << IPLS->K << "\n"
2297            << "  Search order: " << IPLS->SearchOrder
2298            << ", Current index = " << IPLS->CurSearchOrderIndex
2299            << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2300            << "  Lookup set: " << IPLS->LookupSet << "\n"
2301            << "  Definition generator candidates: "
2302            << IPLS->DefGeneratorCandidates << "\n"
2303            << "  Definition generator non-candidates: "
2304            << IPLS->DefGeneratorNonCandidates << "\n";
2305   });
2306 
2307   bool QueryComplete = false;
2308   DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs;
2309 
2310   auto LodgingErr = runSessionLocked([&]() -> Error {
2311     for (auto &KV : IPLS->SearchOrder) {
2312       auto &JD = *KV.first;
2313       auto JDLookupFlags = KV.second;
2314       LLVM_DEBUG({
2315         dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2316                << ") with lookup set " << IPLS->LookupSet << ":\n";
2317       });
2318 
2319       auto Err = IPLS->LookupSet.forEachWithRemoval(
2320           [&](const SymbolStringPtr &Name,
2321               SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
2322             LLVM_DEBUG({
2323               dbgs() << "  Attempting to match \"" << Name << "\" ("
2324                      << SymLookupFlags << ")... ";
2325             });
2326 
2327             /// Search for the symbol. If not found then continue without
2328             /// removal.
2329             auto SymI = JD.Symbols.find(Name);
2330             if (SymI == JD.Symbols.end()) {
2331               LLVM_DEBUG(dbgs() << "skipping: not present\n");
2332               return false;
2333             }
2334 
2335             // If this is a non-exported symbol and we're matching exported
2336             // symbols only then skip this symbol without removal.
2337             if (!SymI->second.getFlags().isExported() &&
2338                 JDLookupFlags ==
2339                     JITDylibLookupFlags::MatchExportedSymbolsOnly) {
2340               LLVM_DEBUG(dbgs() << "skipping: not exported\n");
2341               return false;
2342             }
2343 
2344             // If we match against a materialization-side-effects only symbol
2345             // then make sure it is weakly-referenced. Otherwise bail out with
2346             // an error.
2347             // FIXME: Use a "materialization-side-effects-only symbols must be
2348             // weakly referenced" specific error here to reduce confusion.
2349             if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2350                 SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol) {
2351               LLVM_DEBUG({
2352                 dbgs() << "error: "
2353                           "required, but symbol is has-side-effects-only\n";
2354               });
2355               return make_error<SymbolsNotFound>(SymbolNameVector({Name}));
2356             }
2357 
2358             // If we matched against this symbol but it is in the error state
2359             // then bail out and treat it as a failure to materialize.
2360             if (SymI->second.getFlags().hasError()) {
2361               LLVM_DEBUG(dbgs() << "error: symbol is in error state\n");
2362               auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
2363               (*FailedSymbolsMap)[&JD] = {Name};
2364               return make_error<FailedToMaterialize>(
2365                   std::move(FailedSymbolsMap));
2366             }
2367 
2368             // Otherwise this is a match.
2369 
2370             // If this symbol is already in the requried state then notify the
2371             // query, remove the symbol and continue.
2372             if (SymI->second.getState() >= Q->getRequiredState()) {
2373               LLVM_DEBUG(dbgs()
2374                          << "matched, symbol already in required state\n");
2375               Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
2376               return true;
2377             }
2378 
2379             // Otherwise this symbol does not yet meet the required state. Check
2380             // whether it has a materializer attached, and if so prepare to run
2381             // it.
2382             if (SymI->second.hasMaterializerAttached()) {
2383               assert(SymI->second.getAddress() == 0 &&
2384                      "Symbol not resolved but already has address?");
2385               auto UMII = JD.UnmaterializedInfos.find(Name);
2386               assert(UMII != JD.UnmaterializedInfos.end() &&
2387                      "Lazy symbol should have UnmaterializedInfo");
2388 
2389               auto UMI = UMII->second;
2390               assert(UMI->MU && "Materializer should not be null");
2391               assert(UMI->RT && "Tracker should not be null");
2392               LLVM_DEBUG({
2393                 dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()
2394                        << " (" << UMI->MU->getName() << ")\n";
2395               });
2396 
2397               // Move all symbols associated with this MaterializationUnit into
2398               // materializing state.
2399               for (auto &KV : UMI->MU->getSymbols()) {
2400                 auto SymK = JD.Symbols.find(KV.first);
2401                 assert(SymK != JD.Symbols.end() &&
2402                        "No entry for symbol covered by MaterializationUnit");
2403                 SymK->second.setMaterializerAttached(false);
2404                 SymK->second.setState(SymbolState::Materializing);
2405                 JD.UnmaterializedInfos.erase(KV.first);
2406               }
2407 
2408               // Add MU to the list of MaterializationUnits to be materialized.
2409               CollectedUMIs[&JD].push_back(std::move(UMI));
2410             } else
2411               LLVM_DEBUG(dbgs() << "matched, registering query");
2412 
2413             // Add the query to the PendingQueries list and continue, deleting
2414             // the element from the lookup set.
2415             assert(SymI->second.getState() != SymbolState::NeverSearched &&
2416                    SymI->second.getState() != SymbolState::Ready &&
2417                    "By this line the symbol should be materializing");
2418             auto &MI = JD.MaterializingInfos[Name];
2419             MI.addQuery(Q);
2420             Q->addQueryDependence(JD, Name);
2421 
2422             return true;
2423           });
2424 
2425       // Handle failure.
2426       if (Err) {
2427 
2428         LLVM_DEBUG({
2429           dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";
2430         });
2431 
2432         // Detach the query.
2433         Q->detach();
2434 
2435         // Replace the MUs.
2436         for (auto &KV : CollectedUMIs) {
2437           auto &JD = *KV.first;
2438           for (auto &UMI : KV.second)
2439             for (auto &KV2 : UMI->MU->getSymbols()) {
2440               assert(!JD.UnmaterializedInfos.count(KV2.first) &&
2441                      "Unexpected materializer in map");
2442               auto SymI = JD.Symbols.find(KV2.first);
2443               assert(SymI != JD.Symbols.end() && "Missing symbol entry");
2444               assert(SymI->second.getState() == SymbolState::Materializing &&
2445                      "Can not replace symbol that is not materializing");
2446               assert(!SymI->second.hasMaterializerAttached() &&
2447                      "MaterializerAttached flag should not be set");
2448               SymI->second.setMaterializerAttached(true);
2449               JD.UnmaterializedInfos[KV2.first] = UMI;
2450             }
2451         }
2452 
2453         return Err;
2454       }
2455     }
2456 
2457     LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-refererced symbols\n");
2458     IPLS->LookupSet.forEachWithRemoval(
2459         [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2460           if (SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2461             Q->dropSymbol(Name);
2462             return true;
2463           } else
2464             return false;
2465         });
2466 
2467     if (!IPLS->LookupSet.empty()) {
2468       LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2469       return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames());
2470     }
2471 
2472     // Record whether the query completed.
2473     QueryComplete = Q->isComplete();
2474 
2475     LLVM_DEBUG({
2476       dbgs() << "Query successfully "
2477              << (QueryComplete ? "completed" : "lodged") << "\n";
2478     });
2479 
2480     // Move the collected MUs to the OutstandingMUs list.
2481     if (!CollectedUMIs.empty()) {
2482       std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2483 
2484       LLVM_DEBUG(dbgs() << "Adding MUs to dispatch:\n");
2485       for (auto &KV : CollectedUMIs) {
2486         auto &JD = *KV.first;
2487         LLVM_DEBUG({
2488           dbgs() << "  For " << JD.getName() << ": Adding " << KV.second.size()
2489                  << " MUs.\n";
2490         });
2491         for (auto &UMI : KV.second) {
2492           std::unique_ptr<MaterializationResponsibility> MR(
2493               new MaterializationResponsibility(
2494                   &JD, std::move(UMI->MU->SymbolFlags),
2495                   std::move(UMI->MU->InitSymbol)));
2496           JD.MRTrackers[MR.get()] = UMI->RT;
2497           OutstandingMUs.push_back(
2498               std::make_pair(std::move(UMI->MU), std::move(MR)));
2499         }
2500       }
2501     } else
2502       LLVM_DEBUG(dbgs() << "No MUs to dispatch.\n");
2503 
2504     if (RegisterDependencies && !Q->QueryRegistrations.empty()) {
2505       LLVM_DEBUG(dbgs() << "Registering dependencies\n");
2506       RegisterDependencies(Q->QueryRegistrations);
2507     } else
2508       LLVM_DEBUG(dbgs() << "No dependencies to register\n");
2509 
2510     return Error::success();
2511   });
2512 
2513   if (LodgingErr) {
2514     LLVM_DEBUG(dbgs() << "Failing query\n");
2515     Q->detach();
2516     Q->handleFailed(std::move(LodgingErr));
2517     return;
2518   }
2519 
2520   if (QueryComplete) {
2521     LLVM_DEBUG(dbgs() << "Completing query\n");
2522     Q->handleComplete();
2523   }
2524 
2525   dispatchOutstandingMUs();
2526 }
2527 
2528 void ExecutionSession::OL_completeLookupFlags(
2529     std::unique_ptr<InProgressLookupState> IPLS,
2530     unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
2531 
2532   auto Result = runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
2533     LLVM_DEBUG({
2534       dbgs() << "Entering OL_completeLookupFlags:\n"
2535              << "  Lookup kind: " << IPLS->K << "\n"
2536              << "  Search order: " << IPLS->SearchOrder
2537              << ", Current index = " << IPLS->CurSearchOrderIndex
2538              << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2539              << "  Lookup set: " << IPLS->LookupSet << "\n"
2540              << "  Definition generator candidates: "
2541              << IPLS->DefGeneratorCandidates << "\n"
2542              << "  Definition generator non-candidates: "
2543              << IPLS->DefGeneratorNonCandidates << "\n";
2544     });
2545 
2546     SymbolFlagsMap Result;
2547 
2548     // Attempt to find flags for each symbol.
2549     for (auto &KV : IPLS->SearchOrder) {
2550       auto &JD = *KV.first;
2551       auto JDLookupFlags = KV.second;
2552       LLVM_DEBUG({
2553         dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2554                << ") with lookup set " << IPLS->LookupSet << ":\n";
2555       });
2556 
2557       IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name,
2558                                              SymbolLookupFlags SymLookupFlags) {
2559         LLVM_DEBUG({
2560           dbgs() << "  Attempting to match \"" << Name << "\" ("
2561                  << SymLookupFlags << ")... ";
2562         });
2563 
2564         // Search for the symbol. If not found then continue without removing
2565         // from the lookup set.
2566         auto SymI = JD.Symbols.find(Name);
2567         if (SymI == JD.Symbols.end()) {
2568           LLVM_DEBUG(dbgs() << "skipping: not present\n");
2569           return false;
2570         }
2571 
2572         // If this is a non-exported symbol then it doesn't match. Skip it.
2573         if (!SymI->second.getFlags().isExported() &&
2574             JDLookupFlags == JITDylibLookupFlags::MatchExportedSymbolsOnly) {
2575           LLVM_DEBUG(dbgs() << "skipping: not exported\n");
2576           return false;
2577         }
2578 
2579         LLVM_DEBUG({
2580           dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()
2581                  << "\n";
2582         });
2583         Result[Name] = SymI->second.getFlags();
2584         return true;
2585       });
2586     }
2587 
2588     // Remove any weakly referenced symbols that haven't been resolved.
2589     IPLS->LookupSet.remove_if(
2590         [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2591           return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
2592         });
2593 
2594     if (!IPLS->LookupSet.empty()) {
2595       LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2596       return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames());
2597     }
2598 
2599     LLVM_DEBUG(dbgs() << "Succeded, result = " << Result << "\n");
2600     return Result;
2601   });
2602 
2603   // Run the callback on the result.
2604   LLVM_DEBUG(dbgs() << "Sending result to handler.\n");
2605   OnComplete(std::move(Result));
2606 }
2607 
2608 void ExecutionSession::OL_destroyMaterializationResponsibility(
2609     MaterializationResponsibility &MR) {
2610 
2611   assert(MR.SymbolFlags.empty() &&
2612          "All symbols should have been explicitly materialized or failed");
2613   MR.JD->unlinkMaterializationResponsibility(MR);
2614 }
2615 
2616 SymbolNameSet ExecutionSession::OL_getRequestedSymbols(
2617     const MaterializationResponsibility &MR) {
2618   return MR.JD->getRequestedSymbols(MR.SymbolFlags);
2619 }
2620 
2621 Error ExecutionSession::OL_notifyResolved(MaterializationResponsibility &MR,
2622                                           const SymbolMap &Symbols) {
2623   LLVM_DEBUG({
2624     dbgs() << "In " << MR.JD->getName() << " resolving " << Symbols << "\n";
2625   });
2626 #ifndef NDEBUG
2627   for (auto &KV : Symbols) {
2628     auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
2629     auto I = MR.SymbolFlags.find(KV.first);
2630     assert(I != MR.SymbolFlags.end() &&
2631            "Resolving symbol outside this responsibility set");
2632     assert(!I->second.hasMaterializationSideEffectsOnly() &&
2633            "Can't resolve materialization-side-effects-only symbol");
2634     assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&
2635            "Resolving symbol with incorrect flags");
2636   }
2637 #endif
2638 
2639   return MR.JD->resolve(MR, Symbols);
2640 }
2641 
2642 Error ExecutionSession::OL_notifyEmitted(MaterializationResponsibility &MR) {
2643   LLVM_DEBUG({
2644     dbgs() << "In " << MR.JD->getName() << " emitting " << MR.SymbolFlags << "\n";
2645   });
2646 
2647   if (auto Err = MR.JD->emit(MR, MR.SymbolFlags))
2648     return Err;
2649 
2650   MR.SymbolFlags.clear();
2651   return Error::success();
2652 }
2653 
2654 Error ExecutionSession::OL_defineMaterializing(
2655     MaterializationResponsibility &MR, SymbolFlagsMap NewSymbolFlags) {
2656 
2657   LLVM_DEBUG({
2658     dbgs() << "In " << MR.JD->getName() << " defining materializing symbols "
2659            << NewSymbolFlags << "\n";
2660   });
2661   if (auto AcceptedDefs = MR.JD->defineMaterializing(std::move(NewSymbolFlags))) {
2662     // Add all newly accepted symbols to this responsibility object.
2663     for (auto &KV : *AcceptedDefs)
2664       MR.SymbolFlags.insert(KV);
2665     return Error::success();
2666   } else
2667     return AcceptedDefs.takeError();
2668 }
2669 
2670 void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) {
2671 
2672   LLVM_DEBUG({
2673     dbgs() << "In " << MR.JD->getName() << " failing materialization for "
2674            << MR.SymbolFlags << "\n";
2675   });
2676 
2677   JITDylib::FailedSymbolsWorklist Worklist;
2678 
2679   for (auto &KV : MR.SymbolFlags)
2680     Worklist.push_back(std::make_pair(MR.JD.get(), KV.first));
2681   MR.SymbolFlags.clear();
2682 
2683   if (Worklist.empty())
2684     return;
2685 
2686   JITDylib::AsynchronousSymbolQuerySet FailedQueries;
2687   std::shared_ptr<SymbolDependenceMap> FailedSymbols;
2688 
2689   runSessionLocked([&]() {
2690     auto RTI = MR.JD->MRTrackers.find(&MR);
2691     assert(RTI != MR.JD->MRTrackers.end() && "No tracker for this");
2692     if (RTI->second->isDefunct())
2693       return;
2694 
2695     std::tie(FailedQueries, FailedSymbols) =
2696         JITDylib::failSymbols(std::move(Worklist));
2697   });
2698 
2699   for (auto &Q : FailedQueries)
2700     Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
2701 }
2702 
2703 Error ExecutionSession::OL_replace(MaterializationResponsibility &MR,
2704                                    std::unique_ptr<MaterializationUnit> MU) {
2705   for (auto &KV : MU->getSymbols()) {
2706     assert(MR.SymbolFlags.count(KV.first) &&
2707            "Replacing definition outside this responsibility set");
2708     MR.SymbolFlags.erase(KV.first);
2709   }
2710 
2711   if (MU->getInitializerSymbol() == MR.InitSymbol)
2712     MR.InitSymbol = nullptr;
2713 
2714   LLVM_DEBUG(MR.JD->getExecutionSession().runSessionLocked([&]() {
2715     dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU
2716            << "\n";
2717   }););
2718 
2719   return MR.JD->replace(MR, std::move(MU));
2720 }
2721 
2722 Expected<std::unique_ptr<MaterializationResponsibility>>
2723 ExecutionSession::OL_delegate(MaterializationResponsibility &MR,
2724                               const SymbolNameSet &Symbols) {
2725 
2726   SymbolStringPtr DelegatedInitSymbol;
2727   SymbolFlagsMap DelegatedFlags;
2728 
2729   for (auto &Name : Symbols) {
2730     auto I = MR.SymbolFlags.find(Name);
2731     assert(I != MR.SymbolFlags.end() &&
2732            "Symbol is not tracked by this MaterializationResponsibility "
2733            "instance");
2734 
2735     DelegatedFlags[Name] = std::move(I->second);
2736     if (Name == MR.InitSymbol)
2737       std::swap(MR.InitSymbol, DelegatedInitSymbol);
2738 
2739     MR.SymbolFlags.erase(I);
2740   }
2741 
2742   return MR.JD->delegate(MR, std::move(DelegatedFlags),
2743                          std::move(DelegatedInitSymbol));
2744 }
2745 
2746 void ExecutionSession::OL_addDependencies(
2747     MaterializationResponsibility &MR, const SymbolStringPtr &Name,
2748     const SymbolDependenceMap &Dependencies) {
2749   LLVM_DEBUG({
2750     dbgs() << "Adding dependencies for " << Name << ": " << Dependencies
2751            << "\n";
2752   });
2753   assert(MR.SymbolFlags.count(Name) &&
2754          "Symbol not covered by this MaterializationResponsibility instance");
2755   MR.JD->addDependencies(Name, Dependencies);
2756 }
2757 
2758 void ExecutionSession::OL_addDependenciesForAll(
2759     MaterializationResponsibility &MR,
2760     const SymbolDependenceMap &Dependencies) {
2761   LLVM_DEBUG({
2762     dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": "
2763            << Dependencies << "\n";
2764   });
2765   for (auto &KV : MR.SymbolFlags)
2766     MR.JD->addDependencies(KV.first, Dependencies);
2767 }
2768 
2769 #ifndef NDEBUG
2770 void ExecutionSession::dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU) {
2771   runSessionLocked([&]() {
2772     dbgs() << "Dispatching " << MU << " for " << JD.getName() << "\n";
2773   });
2774 }
2775 #endif // NDEBUG
2776 
2777 } // End namespace orc.
2778 } // End namespace llvm.
2779