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