LLVM  15.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::Weak | JITSymbolFlags::Common);
974  assert(Flags ==
975  (SymI->second.getFlags() &
976  ~(JITSymbolFlags::Weak | JITSymbolFlags::Common)) &&
977  "Resolved flags should match the declared flags");
978 
979  Worklist.push_back(
980  {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
981  }
982  }
983 
984  // If any symbols were in the error state then bail out.
985  if (!SymbolsInErrorState.empty()) {
986  auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
987  (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
988  return make_error<FailedToMaterialize>(
989  getExecutionSession().getSymbolStringPool(),
990  std::move(FailedSymbolsDepMap));
991  }
992 
993  while (!Worklist.empty()) {
994  auto SymI = Worklist.back().SymI;
995  auto ResolvedSym = Worklist.back().ResolvedSym;
996  Worklist.pop_back();
997 
998  auto &Name = SymI->first;
999 
1000  // Resolved symbols can not be weak: discard the weak flag.
1001  JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
1002  SymI->second.setAddress(ResolvedSym.getAddress());
1003  SymI->second.setFlags(ResolvedFlags);
1004  SymI->second.setState(SymbolState::Resolved);
1005 
1006  auto MII = MaterializingInfos.find(Name);
1007  if (MII == MaterializingInfos.end())
1008  continue;
1009 
1010  auto &MI = MII->second;
1011  for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
1012  Q->notifySymbolMetRequiredState(Name, ResolvedSym);
1013  Q->removeQueryDependence(*this, Name);
1014  if (Q->isComplete())
1015  CompletedQueries.insert(std::move(Q));
1016  }
1017  }
1018 
1019  return Error::success();
1020  }))
1021  return Err;
1022 
1023  // Otherwise notify all the completed queries.
1024  for (auto &Q : CompletedQueries) {
1025  assert(Q->isComplete() && "Q not completed");
1026  Q->handleComplete(ES);
1027  }
1028 
1029  return Error::success();
1030 }
1031 
1032 Error JITDylib::emit(MaterializationResponsibility &MR,
1033  const SymbolFlagsMap &Emitted) {
1034  AsynchronousSymbolQuerySet CompletedQueries;
1035  DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
1036 
1037  if (auto Err = ES.runSessionLocked([&, this]() -> Error {
1038  if (MR.RT->isDefunct())
1039  return make_error<ResourceTrackerDefunct>(MR.RT);
1040 
1041  if (State != Open)
1042  return make_error<StringError>("JITDylib " + getName() +
1043  " is defunct",
1044  inconvertibleErrorCode());
1045 
1046  SymbolNameSet SymbolsInErrorState;
1047  std::vector<SymbolTable::iterator> Worklist;
1048 
1049  // Scan to build worklist, record any symbols in the erorr state.
1050  for (const auto &KV : Emitted) {
1051  auto &Name = KV.first;
1052 
1053  auto SymI = Symbols.find(Name);
1054  assert(SymI != Symbols.end() && "No symbol table entry for Name");
1055 
1056  if (SymI->second.getFlags().hasError())
1057  SymbolsInErrorState.insert(Name);
1058  else
1059  Worklist.push_back(SymI);
1060  }
1061 
1062  // If any symbols were in the error state then bail out.
1063  if (!SymbolsInErrorState.empty()) {
1064  auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1065  (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1066  return make_error<FailedToMaterialize>(
1067  getExecutionSession().getSymbolStringPool(),
1068  std::move(FailedSymbolsDepMap));
1069  }
1070 
1071  // Otherwise update dependencies and move to the emitted state.
1072  while (!Worklist.empty()) {
1073  auto SymI = Worklist.back();
1074  Worklist.pop_back();
1075 
1076  auto &Name = SymI->first;
1077  auto &SymEntry = SymI->second;
1078 
1079  // Move symbol to the emitted state.
1080  assert(((SymEntry.getFlags().hasMaterializationSideEffectsOnly() &&
1081  SymEntry.getState() == SymbolState::Materializing) ||
1082  SymEntry.getState() == SymbolState::Resolved) &&
1083  "Emitting from state other than Resolved");
1084  SymEntry.setState(SymbolState::Emitted);
1085 
1086  auto MII = MaterializingInfos.find(Name);
1087 
1088  // If this symbol has no MaterializingInfo then it's trivially ready.
1089  // Update its state and continue.
1090  if (MII == MaterializingInfos.end()) {
1091  SymEntry.setState(SymbolState::Ready);
1092  continue;
1093  }
1094 
1095  auto &MI = MII->second;
1096 
1097  // For each dependant, transfer this node's emitted dependencies to
1098  // it. If the dependant node is ready (i.e. has no unemitted
1099  // dependencies) then notify any pending queries.
1100  for (auto &KV : MI.Dependants) {
1101  auto &DependantJD = *KV.first;
1102  auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1103  for (auto &DependantName : KV.second) {
1104  auto DependantMII =
1105  DependantJD.MaterializingInfos.find(DependantName);
1106  assert(DependantMII != DependantJD.MaterializingInfos.end() &&
1107  "Dependant should have MaterializingInfo");
1108 
1109  auto &DependantMI = DependantMII->second;
1110 
1111  // Remove the dependant's dependency on this node.
1112  assert(DependantMI.UnemittedDependencies.count(this) &&
1113  "Dependant does not have an unemitted dependencies record "
1114  "for "
1115  "this JITDylib");
1116  assert(DependantMI.UnemittedDependencies[this].count(Name) &&
1117  "Dependant does not count this symbol as a dependency?");
1118 
1119  DependantMI.UnemittedDependencies[this].erase(Name);
1120  if (DependantMI.UnemittedDependencies[this].empty())
1121  DependantMI.UnemittedDependencies.erase(this);
1122 
1123  // Transfer unemitted dependencies from this node to the
1124  // dependant.
1125  DependantJD.transferEmittedNodeDependencies(DependantMI,
1126  DependantName, MI);
1127 
1128  auto DependantSymI = DependantJD.Symbols.find(DependantName);
1129  assert(DependantSymI != DependantJD.Symbols.end() &&
1130  "Dependant has no entry in the Symbols table");
1131  auto &DependantSymEntry = DependantSymI->second;
1132 
1133  // If the dependant is emitted and this node was the last of its
1134  // unemitted dependencies then the dependant node is now ready, so
1135  // notify any pending queries on the dependant node.
1136  if (DependantSymEntry.getState() == SymbolState::Emitted &&
1137  DependantMI.UnemittedDependencies.empty()) {
1138  assert(DependantMI.Dependants.empty() &&
1139  "Dependants should be empty by now");
1140 
1141  // Since this dependant is now ready, we erase its
1142  // MaterializingInfo and update its materializing state.
1143  DependantSymEntry.setState(SymbolState::Ready);
1144  DependantJDReadySymbols.push_back(DependantName);
1145 
1146  for (auto &Q :
1147  DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1148  Q->notifySymbolMetRequiredState(
1149  DependantName, DependantSymI->second.getSymbol());
1150  if (Q->isComplete())
1151  CompletedQueries.insert(Q);
1152  Q->removeQueryDependence(DependantJD, DependantName);
1153  }
1154  DependantJD.MaterializingInfos.erase(DependantMII);
1155  }
1156  }
1157  }
1158 
1159  auto &ThisJDReadySymbols = ReadySymbols[this];
1160  MI.Dependants.clear();
1161  if (MI.UnemittedDependencies.empty()) {
1162  SymI->second.setState(SymbolState::Ready);
1163  ThisJDReadySymbols.push_back(Name);
1164  for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1165  Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1166  if (Q->isComplete())
1167  CompletedQueries.insert(Q);
1168  Q->removeQueryDependence(*this, Name);
1169  }
1170  MaterializingInfos.erase(MII);
1171  }
1172  }
1173 
1174  return Error::success();
1175  }))
1176  return Err;
1177 
1178  // Otherwise notify all the completed queries.
1179  for (auto &Q : CompletedQueries) {
1180  assert(Q->isComplete() && "Q is not complete");
1181  Q->handleComplete(ES);
1182  }
1183 
1184  return Error::success();
1185 }
1186 
1187 void JITDylib::unlinkMaterializationResponsibility(
1188  MaterializationResponsibility &MR) {
1189  ES.runSessionLocked([&]() {
1190  auto I = TrackerMRs.find(MR.RT.get());
1191  assert(I != TrackerMRs.end() && "No MRs in TrackerMRs list for RT");
1192  assert(I->second.count(&MR) && "MR not in TrackerMRs list for RT");
1193  I->second.erase(&MR);
1194  if (I->second.empty())
1195  TrackerMRs.erase(MR.RT.get());
1196  });
1197 }
1198 
1199 std::pair<JITDylib::AsynchronousSymbolQuerySet,
1200  std::shared_ptr<SymbolDependenceMap>>
1201 JITDylib::failSymbols(FailedSymbolsWorklist Worklist) {
1202  AsynchronousSymbolQuerySet FailedQueries;
1203  auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1204 
1205  while (!Worklist.empty()) {
1206  assert(Worklist.back().first && "Failed JITDylib can not be null");
1207  auto &JD = *Worklist.back().first;
1208  auto Name = std::move(Worklist.back().second);
1209  Worklist.pop_back();
1210 
1211  (*FailedSymbolsMap)[&JD].insert(Name);
1212 
1213  // Look up the symbol to fail.
1214  auto SymI = JD.Symbols.find(Name);
1215 
1216  // It's possible that this symbol has already been removed, e.g. if a
1217  // materialization failure happens concurrently with a ResourceTracker or
1218  // JITDylib removal. In that case we can safely skip this symbol and
1219  // continue.
1220  if (SymI == JD.Symbols.end())
1221  continue;
1222  auto &Sym = SymI->second;
1223 
1224  // Move the symbol into the error state.
1225  // Note that this may be redundant: The symbol might already have been
1226  // moved to this state in response to the failure of a dependence.
1227  Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1228 
1229  // FIXME: Come up with a sane mapping of state to
1230  // presence-of-MaterializingInfo so that we can assert presence / absence
1231  // here, rather than testing it.
1232  auto MII = JD.MaterializingInfos.find(Name);
1233 
1234  if (MII == JD.MaterializingInfos.end())
1235  continue;
1236 
1237  auto &MI = MII->second;
1238 
1239  // Move all dependants to the error state and disconnect from them.
1240  for (auto &KV : MI.Dependants) {
1241  auto &DependantJD = *KV.first;
1242  for (auto &DependantName : KV.second) {
1243  assert(DependantJD.Symbols.count(DependantName) &&
1244  "No symbol table entry for DependantName");
1245  auto &DependantSym = DependantJD.Symbols[DependantName];
1246  DependantSym.setFlags(DependantSym.getFlags() |
1247  JITSymbolFlags::HasError);
1248 
1249  assert(DependantJD.MaterializingInfos.count(DependantName) &&
1250  "No MaterializingInfo for dependant");
1251  auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1252 
1253  auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1254  assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
1255  "No UnemittedDependencies entry for this JITDylib");
1256  assert(UnemittedDepI->second.count(Name) &&
1257  "No UnemittedDependencies entry for this symbol");
1258  UnemittedDepI->second.erase(Name);
1259  if (UnemittedDepI->second.empty())
1260  DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1261 
1262  // If this symbol is already in the emitted state then we need to
1263  // take responsibility for failing its queries, so add it to the
1264  // worklist.
1265  if (DependantSym.getState() == SymbolState::Emitted) {
1266  assert(DependantMI.Dependants.empty() &&
1267  "Emitted symbol should not have dependants");
1268  Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1269  }
1270  }
1271  }
1272  MI.Dependants.clear();
1273 
1274  // Disconnect from all unemitted depenencies.
1275  for (auto &KV : MI.UnemittedDependencies) {
1276  auto &UnemittedDepJD = *KV.first;
1277  for (auto &UnemittedDepName : KV.second) {
1278  auto UnemittedDepMII =
1279  UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1280  assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
1281  "Missing MII for unemitted dependency");
1282  assert(UnemittedDepMII->second.Dependants.count(&JD) &&
1283  "JD not listed as a dependant of unemitted dependency");
1284  assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
1285  "Name is not listed as a dependant of unemitted dependency");
1286  UnemittedDepMII->second.Dependants[&JD].erase(Name);
1287  if (UnemittedDepMII->second.Dependants[&JD].empty())
1288  UnemittedDepMII->second.Dependants.erase(&JD);
1289  }
1290  }
1291  MI.UnemittedDependencies.clear();
1292 
1293  // Collect queries to be failed for this MII.
1294  AsynchronousSymbolQueryList ToDetach;
1295  for (auto &Q : MII->second.pendingQueries()) {
1296  // Add the query to the list to be failed and detach it.
1297  FailedQueries.insert(Q);
1298  ToDetach.push_back(Q);
1299  }
1300  for (auto &Q : ToDetach)
1301  Q->detach();
1302 
1303  assert(MI.Dependants.empty() &&
1304  "Can not delete MaterializingInfo with dependants still attached");
1305  assert(MI.UnemittedDependencies.empty() &&
1306  "Can not delete MaterializingInfo with unemitted dependencies "
1307  "still attached");
1308  assert(!MI.hasQueriesPending() &&
1309  "Can not delete MaterializingInfo with queries pending");
1310  JD.MaterializingInfos.erase(MII);
1311  }
1312 
1313  return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap));
1314 }
1315 
1316 void JITDylib::setLinkOrder(JITDylibSearchOrder NewLinkOrder,
1317  bool LinkAgainstThisJITDylibFirst) {
1318  ES.runSessionLocked([&]() {
1319  assert(State == Open && "JD is defunct");
1320  if (LinkAgainstThisJITDylibFirst) {
1321  LinkOrder.clear();
1322  if (NewLinkOrder.empty() || NewLinkOrder.front().first != this)
1323  LinkOrder.push_back(
1324  std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1325  llvm::append_range(LinkOrder, NewLinkOrder);
1326  } else
1327  LinkOrder = std::move(NewLinkOrder);
1328  });
1329 }
1330 
1331 void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) {
1332  ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });
1333 }
1334 
1335 void JITDylib::replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
1336  JITDylibLookupFlags JDLookupFlags) {
1337  ES.runSessionLocked([&]() {
1338  assert(State == Open && "JD is defunct");
1339  for (auto &KV : LinkOrder)
1340  if (KV.first == &OldJD) {
1341  KV = {&NewJD, JDLookupFlags};
1342  break;
1343  }
1344  });
1345 }
1346 
1347 void JITDylib::removeFromLinkOrder(JITDylib &JD) {
1348  ES.runSessionLocked([&]() {
1349  assert(State == Open && "JD is defunct");
1350  auto I = llvm::find_if(LinkOrder,
1351  [&](const JITDylibSearchOrder::value_type &KV) {
1352  return KV.first == &JD;
1353  });
1354  if (I != LinkOrder.end())
1355  LinkOrder.erase(I);
1356  });
1357 }
1358 
1360  return ES.runSessionLocked([&]() -> Error {
1361  assert(State == Open && "JD is defunct");
1362  using SymbolMaterializerItrPair =
1363  std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1364  std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1365  SymbolNameSet Missing;
1367 
1368  for (auto &Name : Names) {
1369  auto I = Symbols.find(Name);
1370 
1371  // Note symbol missing.
1372  if (I == Symbols.end()) {
1373  Missing.insert(Name);
1374  continue;
1375  }
1376 
1377  // Note symbol materializing.
1378  if (I->second.getState() != SymbolState::NeverSearched &&
1379  I->second.getState() != SymbolState::Ready) {
1380  Materializing.insert(Name);
1381  continue;
1382  }
1383 
1384  auto UMII = I->second.hasMaterializerAttached()
1385  ? UnmaterializedInfos.find(Name)
1386  : UnmaterializedInfos.end();
1387  SymbolsToRemove.push_back(std::make_pair(I, UMII));
1388  }
1389 
1390  // If any of the symbols are not defined, return an error.
1391  if (!Missing.empty())
1392  return make_error<SymbolsNotFound>(ES.getSymbolStringPool(),
1393  std::move(Missing));
1394 
1395  // If any of the symbols are currently materializing, return an error.
1396  if (!Materializing.empty())
1397  return make_error<SymbolsCouldNotBeRemoved>(ES.getSymbolStringPool(),
1399 
1400  // Remove the symbols.
1401  for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1402  auto UMII = SymbolMaterializerItrPair.second;
1403 
1404  // If there is a materializer attached, call discard.
1405  if (UMII != UnmaterializedInfos.end()) {
1406  UMII->second->MU->doDiscard(*this, UMII->first);
1407  UnmaterializedInfos.erase(UMII);
1408  }
1409 
1410  auto SymI = SymbolMaterializerItrPair.first;
1411  Symbols.erase(SymI);
1412  }
1413 
1414  return Error::success();
1415  });
1416 }
1417 
1419  ES.runSessionLocked([&, this]() {
1420  OS << "JITDylib \"" << getName() << "\" (ES: "
1421  << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES))
1422  << ", State = ";
1423  switch (State) {
1424  case Open:
1425  OS << "Open";
1426  break;
1427  case Closing:
1428  OS << "Closing";
1429  break;
1430  case Closed:
1431  OS << "Closed";
1432  break;
1433  }
1434  OS << ")\n";
1435  if (State == Closed)
1436  return;
1437  OS << "Link order: " << LinkOrder << "\n"
1438  << "Symbol table:\n";
1439 
1440  for (auto &KV : Symbols) {
1441  OS << " \"" << *KV.first << "\": ";
1442  if (auto Addr = KV.second.getAddress())
1443  OS << format("0x%016" PRIx64, Addr);
1444  else
1445  OS << "<not resolved> ";
1446 
1447  OS << " " << KV.second.getFlags() << " " << KV.second.getState();
1448 
1449  if (KV.second.hasMaterializerAttached()) {
1450  OS << " (Materializer ";
1451  auto I = UnmaterializedInfos.find(KV.first);
1452  assert(I != UnmaterializedInfos.end() &&
1453  "Lazy symbol should have UnmaterializedInfo");
1454  OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";
1455  } else
1456  OS << "\n";
1457  }
1458 
1459  if (!MaterializingInfos.empty())
1460  OS << " MaterializingInfos entries:\n";
1461  for (auto &KV : MaterializingInfos) {
1462  OS << " \"" << *KV.first << "\":\n"
1463  << " " << KV.second.pendingQueries().size()
1464  << " pending queries: { ";
1465  for (const auto &Q : KV.second.pendingQueries())
1466  OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1467  OS << "}\n Dependants:\n";
1468  for (auto &KV2 : KV.second.Dependants)
1469  OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
1470  OS << " Unemitted Dependencies:\n";
1471  for (auto &KV2 : KV.second.UnemittedDependencies)
1472  OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
1473  assert((Symbols[KV.first].getState() != SymbolState::Ready ||
1474  !KV.second.pendingQueries().empty() ||
1475  !KV.second.Dependants.empty() ||
1476  !KV.second.UnemittedDependencies.empty()) &&
1477  "Stale materializing info entry");
1478  }
1479  });
1480 }
1481 
1482 void JITDylib::MaterializingInfo::addQuery(
1483  std::shared_ptr<AsynchronousSymbolQuery> Q) {
1484 
1485  auto I = std::lower_bound(
1486  PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1487  [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1488  return V->getRequiredState() <= S;
1489  });
1490  PendingQueries.insert(I.base(), std::move(Q));
1491 }
1492 
1493 void JITDylib::MaterializingInfo::removeQuery(
1494  const AsynchronousSymbolQuery &Q) {
1495  // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1496  auto I = llvm::find_if(
1497  PendingQueries, [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1498  return V.get() == &Q;
1499  });
1500  assert(I != PendingQueries.end() &&
1501  "Query is not attached to this MaterializingInfo");
1502  PendingQueries.erase(I);
1503 }
1504 
1505 JITDylib::AsynchronousSymbolQueryList
1506 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1507  AsynchronousSymbolQueryList Result;
1508  while (!PendingQueries.empty()) {
1509  if (PendingQueries.back()->getRequiredState() > RequiredState)
1510  break;
1511 
1512  Result.push_back(std::move(PendingQueries.back()));
1513  PendingQueries.pop_back();
1514  }
1515 
1516  return Result;
1517 }
1518 
1519 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1520  : JITLinkDylib(std::move(Name)), ES(ES) {
1521  LinkOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1522 }
1523 
1524 std::pair<JITDylib::AsynchronousSymbolQuerySet,
1525  std::shared_ptr<SymbolDependenceMap>>
1526 JITDylib::removeTracker(ResourceTracker &RT) {
1527  // Note: Should be called under the session lock.
1528  assert(State != Closed && "JD is defunct");
1529 
1530  SymbolNameVector SymbolsToRemove;
1531  std::vector<std::pair<JITDylib *, SymbolStringPtr>> SymbolsToFail;
1532 
1533  if (&RT == DefaultTracker.get()) {
1534  SymbolNameSet TrackedSymbols;
1535  for (auto &KV : TrackerSymbols)
1536  for (auto &Sym : KV.second)
1537  TrackedSymbols.insert(Sym);
1538 
1539  for (auto &KV : Symbols) {
1540  auto &Sym = KV.first;
1541  if (!TrackedSymbols.count(Sym))
1542  SymbolsToRemove.push_back(Sym);
1543  }
1544 
1545  DefaultTracker.reset();
1546  } else {
1547  /// Check for a non-default tracker.
1548  auto I = TrackerSymbols.find(&RT);
1549  if (I != TrackerSymbols.end()) {
1550  SymbolsToRemove = std::move(I->second);
1551  TrackerSymbols.erase(I);
1552  }
1553  // ... if not found this tracker was already defunct. Nothing to do.
1554  }
1555 
1556  for (auto &Sym : SymbolsToRemove) {
1557  assert(Symbols.count(Sym) && "Symbol not in symbol table");
1558 
1559  // If there is a MaterializingInfo then collect any queries to fail.
1560  auto MII = MaterializingInfos.find(Sym);
1561  if (MII != MaterializingInfos.end())
1562  SymbolsToFail.push_back({this, Sym});
1563  }
1564 
1565  AsynchronousSymbolQuerySet QueriesToFail;
1566  auto Result = failSymbols(std::move(SymbolsToFail));
1567 
1568  // Removed symbols should be taken out of the table altogether.
1569  for (auto &Sym : SymbolsToRemove) {
1570  auto I = Symbols.find(Sym);
1571  assert(I != Symbols.end() && "Symbol not present in table");
1572 
1573  // Remove Materializer if present.
1574  if (I->second.hasMaterializerAttached()) {
1575  // FIXME: Should this discard the symbols?
1576  UnmaterializedInfos.erase(Sym);
1577  } else {
1578  assert(!UnmaterializedInfos.count(Sym) &&
1579  "Symbol has materializer attached");
1580  }
1581 
1582  Symbols.erase(I);
1583  }
1584 
1585  return Result;
1586 }
1587 
1588 void JITDylib::transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT) {
1589  assert(State != Closed && "JD is defunct");
1590  assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker");
1591  assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib");
1592  assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib");
1593 
1594  // Update trackers for any not-yet materialized units.
1595  for (auto &KV : UnmaterializedInfos) {
1596  if (KV.second->RT == &SrcRT)
1597  KV.second->RT = &DstRT;
1598  }
1599 
1600  // Update trackers for any active materialization responsibilities.
1601  {
1602  auto I = TrackerMRs.find(&SrcRT);
1603  if (I != TrackerMRs.end()) {
1604  auto &SrcMRs = I->second;
1605  auto &DstMRs = TrackerMRs[&DstRT];
1606  for (auto *MR : SrcMRs)
1607  MR->RT = &DstRT;
1608  if (DstMRs.empty())
1609  DstMRs = std::move(SrcMRs);
1610  else
1611  for (auto *MR : SrcMRs)
1612  DstMRs.insert(MR);
1613  // Erase SrcRT entry in TrackerMRs. Use &SrcRT key rather than iterator I
1614  // for this, since I may have been invalidated by 'TrackerMRs[&DstRT]'.
1615  TrackerMRs.erase(&SrcRT);
1616  }
1617  }
1618 
1619  // If we're transfering to the default tracker we just need to delete the
1620  // tracked symbols for the source tracker.
1621  if (&DstRT == DefaultTracker.get()) {
1622  TrackerSymbols.erase(&SrcRT);
1623  return;
1624  }
1625 
1626  // If we're transferring from the default tracker we need to find all
1627  // currently untracked symbols.
1628  if (&SrcRT == DefaultTracker.get()) {
1629  assert(!TrackerSymbols.count(&SrcRT) &&
1630  "Default tracker should not appear in TrackerSymbols");
1631 
1632  SymbolNameVector SymbolsToTrack;
1633 
1634  SymbolNameSet CurrentlyTrackedSymbols;
1635  for (auto &KV : TrackerSymbols)
1636  for (auto &Sym : KV.second)
1637  CurrentlyTrackedSymbols.insert(Sym);
1638 
1639  for (auto &KV : Symbols) {
1640  auto &Sym = KV.first;
1641  if (!CurrentlyTrackedSymbols.count(Sym))
1642  SymbolsToTrack.push_back(Sym);
1643  }
1644 
1645  TrackerSymbols[&DstRT] = std::move(SymbolsToTrack);
1646  return;
1647  }
1648 
1649  auto &DstTrackedSymbols = TrackerSymbols[&DstRT];
1650 
1651  // Finally if neither SrtRT or DstRT are the default tracker then
1652  // just append DstRT's tracked symbols to SrtRT's.
1653  auto SI = TrackerSymbols.find(&SrcRT);
1654  if (SI == TrackerSymbols.end())
1655  return;
1656 
1657  DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size());
1658  for (auto &Sym : SI->second)
1659  DstTrackedSymbols.push_back(std::move(Sym));
1660  TrackerSymbols.erase(SI);
1661 }
1662 
1663 Error JITDylib::defineImpl(MaterializationUnit &MU) {
1664 
1665  LLVM_DEBUG({ dbgs() << " " << MU.getSymbols() << "\n"; });
1666 
1667  SymbolNameSet Duplicates;
1668  std::vector<SymbolStringPtr> ExistingDefsOverridden;
1669  std::vector<SymbolStringPtr> MUDefsOverridden;
1670 
1671  for (const auto &KV : MU.getSymbols()) {
1672  auto I = Symbols.find(KV.first);
1673 
1674  if (I != Symbols.end()) {
1675  if (KV.second.isStrong()) {
1676  if (I->second.getFlags().isStrong() ||
1677  I->second.getState() > SymbolState::NeverSearched)
1678  Duplicates.insert(KV.first);
1679  else {
1680  assert(I->second.getState() == SymbolState::NeverSearched &&
1681  "Overridden existing def should be in the never-searched "
1682  "state");
1683  ExistingDefsOverridden.push_back(KV.first);
1684  }
1685  } else
1686  MUDefsOverridden.push_back(KV.first);
1687  }
1688  }
1689 
1690  // If there were any duplicate definitions then bail out.
1691  if (!Duplicates.empty()) {
1692  LLVM_DEBUG(
1693  { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; });
1694  return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1695  }
1696 
1697  // Discard any overridden defs in this MU.
1698  LLVM_DEBUG({
1699  if (!MUDefsOverridden.empty())
1700  dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n";
1701  });
1702  for (auto &S : MUDefsOverridden)
1703  MU.doDiscard(*this, S);
1704 
1705  // Discard existing overridden defs.
1706  LLVM_DEBUG({
1707  if (!ExistingDefsOverridden.empty())
1708  dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden
1709  << "\n";
1710  });
1711  for (auto &S : ExistingDefsOverridden) {
1712 
1713  auto UMII = UnmaterializedInfos.find(S);
1714  assert(UMII != UnmaterializedInfos.end() &&
1715  "Overridden existing def should have an UnmaterializedInfo");
1716  UMII->second->MU->doDiscard(*this, S);
1717  }
1718 
1719  // Finally, add the defs from this MU.
1720  for (auto &KV : MU.getSymbols()) {
1721  auto &SymEntry = Symbols[KV.first];
1722  SymEntry.setFlags(KV.second);
1723  SymEntry.setState(SymbolState::NeverSearched);
1724  SymEntry.setMaterializerAttached(true);
1725  }
1726 
1727  return Error::success();
1728 }
1729 
1730 void JITDylib::installMaterializationUnit(
1731  std::unique_ptr<MaterializationUnit> MU, ResourceTracker &RT) {
1732 
1733  /// defineImpl succeeded.
1734  if (&RT != DefaultTracker.get()) {
1735  auto &TS = TrackerSymbols[&RT];
1736  TS.reserve(TS.size() + MU->getSymbols().size());
1737  for (auto &KV : MU->getSymbols())
1738  TS.push_back(KV.first);
1739  }
1740 
1741  auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU), &RT);
1742  for (auto &KV : UMI->MU->getSymbols())
1743  UnmaterializedInfos[KV.first] = UMI;
1744 }
1745 
1746 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1747  const SymbolNameSet &QuerySymbols) {
1748  for (auto &QuerySymbol : QuerySymbols) {
1749  assert(MaterializingInfos.count(QuerySymbol) &&
1750  "QuerySymbol does not have MaterializingInfo");
1751  auto &MI = MaterializingInfos[QuerySymbol];
1752  MI.removeQuery(Q);
1753  }
1754 }
1755 
1756 void JITDylib::transferEmittedNodeDependencies(
1757  MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1758  MaterializingInfo &EmittedMI) {
1759  for (auto &KV : EmittedMI.UnemittedDependencies) {
1760  auto &DependencyJD = *KV.first;
1761  SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1762 
1763  for (auto &DependencyName : KV.second) {
1764  auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1765 
1766  // Do not add self dependencies.
1767  if (&DependencyMI == &DependantMI)
1768  continue;
1769 
1770  // If we haven't looked up the dependencies for DependencyJD yet, do it
1771  // now and cache the result.
1772  if (!UnemittedDependenciesOnDependencyJD)
1773  UnemittedDependenciesOnDependencyJD =
1774  &DependantMI.UnemittedDependencies[&DependencyJD];
1775 
1776  DependencyMI.Dependants[this].insert(DependantName);
1777  UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1778  }
1779  }
1780 }
1781 
1782 Platform::~Platform() = default;
1783 
1785  ExecutionSession &ES,
1786  const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1787 
1788  DenseMap<JITDylib *, SymbolMap> CompoundResult;
1789  Error CompoundErr = Error::success();
1790  std::mutex LookupMutex;
1791  std::condition_variable CV;
1792  uint64_t Count = InitSyms.size();
1793 
1794  LLVM_DEBUG({
1795  dbgs() << "Issuing init-symbol lookup:\n";
1796  for (auto &KV : InitSyms)
1797  dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
1798  });
1799 
1800  for (auto &KV : InitSyms) {
1801  auto *JD = KV.first;
1802  auto Names = std::move(KV.second);
1803  ES.lookup(
1806  std::move(Names), SymbolState::Ready,
1807  [&, JD](Expected<SymbolMap> Result) {
1808  {
1809  std::lock_guard<std::mutex> Lock(LookupMutex);
1810  --Count;
1811  if (Result) {
1812  assert(!CompoundResult.count(JD) &&
1813  "Duplicate JITDylib in lookup?");
1814  CompoundResult[JD] = std::move(*Result);
1815  } else
1816  CompoundErr =
1817  joinErrors(std::move(CompoundErr), Result.takeError());
1818  }
1819  CV.notify_one();
1820  },
1822  }
1823 
1824  std::unique_lock<std::mutex> Lock(LookupMutex);
1825  CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1826 
1827  if (CompoundErr)
1828  return std::move(CompoundErr);
1829 
1830  return std::move(CompoundResult);
1831 }
1832 
1834  unique_function<void(Error)> OnComplete, ExecutionSession &ES,
1835  const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1836 
1837  class TriggerOnComplete {
1838  public:
1839  using OnCompleteFn = unique_function<void(Error)>;
1840  TriggerOnComplete(OnCompleteFn OnComplete)
1841  : OnComplete(std::move(OnComplete)) {}
1842  ~TriggerOnComplete() { OnComplete(std::move(LookupResult)); }
1843  void reportResult(Error Err) {
1844  std::lock_guard<std::mutex> Lock(ResultMutex);
1846  }
1847 
1848  private:
1849  std::mutex ResultMutex;
1851  OnCompleteFn OnComplete;
1852  };
1853 
1854  LLVM_DEBUG({
1855  dbgs() << "Issuing init-symbol lookup:\n";
1856  for (auto &KV : InitSyms)
1857  dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
1858  });
1859 
1860  auto TOC = std::make_shared<TriggerOnComplete>(std::move(OnComplete));
1861 
1862  for (auto &KV : InitSyms) {
1863  auto *JD = KV.first;
1864  auto Names = std::move(KV.second);
1865  ES.lookup(
1868  std::move(Names), SymbolState::Ready,
1869  [TOC](Expected<SymbolMap> Result) {
1870  TOC->reportResult(Result.takeError());
1871  },
1873  }
1874 }
1875 
1877  OS << "Materialization task: " << MU->getName() << " in "
1878  << MR->getTargetJITDylib().getName();
1879 }
1880 
1881 void MaterializationTask::run() { MU->materialize(std::move(MR)); }
1882 
1883 ExecutionSession::ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC)
1884  : EPC(std::move(EPC)) {
1885  // Associated EPC and this.
1886  this->EPC->ES = this;
1887 }
1888 
1890  // You must call endSession prior to destroying the session.
1891  assert(!SessionOpen &&
1892  "Session still open. Did you forget to call endSession?");
1893 }
1894 
1896  LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
1897 
1898  std::vector<JITDylibSP> JITDylibsToClose = runSessionLocked([&] {
1899  SessionOpen = false;
1900  return std::move(JDs);
1901  });
1902 
1903  // TODO: notifiy platform? run static deinits?
1904 
1905  Error Err = Error::success();
1906  for (auto &JD : reverse(JITDylibsToClose))
1907  Err = joinErrors(std::move(Err), JD->clear());
1908 
1909  Err = joinErrors(std::move(Err), EPC->disconnect());
1910 
1911  return Err;
1912 }
1913 
1915  runSessionLocked([&] { ResourceManagers.push_back(&RM); });
1916 }
1917 
1919  runSessionLocked([&] {
1920  assert(!ResourceManagers.empty() && "No managers registered");
1921  if (ResourceManagers.back() == &RM)
1922  ResourceManagers.pop_back();
1923  else {
1924  auto I = llvm::find(ResourceManagers, &RM);
1925  assert(I != ResourceManagers.end() && "RM not registered");
1926  ResourceManagers.erase(I);
1927  }
1928  });
1929 }
1930 
1932  return runSessionLocked([&, this]() -> JITDylib * {
1933  for (auto &JD : JDs)
1934  if (JD->getName() == Name)
1935  return JD.get();
1936  return nullptr;
1937  });
1938 }
1939 
1941  assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
1942  return runSessionLocked([&, this]() -> JITDylib & {
1943  JDs.push_back(new JITDylib(*this, std::move(Name)));
1944  return *JDs.back();
1945  });
1946 }
1947 
1949  auto &JD = createBareJITDylib(Name);
1950  if (P)
1951  if (auto Err = P->setupJITDylib(JD))
1952  return std::move(Err);
1953  return JD;
1954 }
1955 
1957  // Keep JD alive throughout this routine, even if all other references
1958  // have been dropped.
1959  JITDylibSP JDKeepAlive = &JD;
1960 
1961  // Set JD to 'Closing' state and remove JD from the ExecutionSession.
1962  runSessionLocked([&] {
1963  assert(JD.State == JITDylib::Open && "JD already closed");
1964  JD.State = JITDylib::Closing;
1965  auto I = llvm::find(JDs, &JD);
1966  assert(I != JDs.end() && "JD does not appear in session JDs");
1967  JDs.erase(I);
1968  });
1969 
1970  // Clear the JITDylib. Hold on to any error while we clean up the
1971  // JITDylib members below.
1972  auto Err = JD.clear();
1973 
1974  // Notify the platform of the teardown.
1975  if (P)
1976  Err = joinErrors(std::move(Err), P->teardownJITDylib(JD));
1977 
1978  // Set JD to closed state. Clear remaining data structures.
1979  runSessionLocked([&] {
1980  assert(JD.State == JITDylib::Closing && "JD should be closing");
1981  JD.State = JITDylib::Closed;
1982  assert(JD.Symbols.empty() && "JD.Symbols is not empty after clear");
1983  assert(JD.UnmaterializedInfos.empty() &&
1984  "JD.UnmaterializedInfos is not empty after clear");
1985  assert(JD.MaterializingInfos.empty() &&
1986  "JD.MaterializingInfos is not empty after clear");
1987  assert(JD.TrackerSymbols.empty() &&
1988  "TrackerSymbols is not empty after clear");
1989  JD.DefGenerators.clear();
1990  JD.LinkOrder.clear();
1991  });
1992  return Err;
1993 }
1994 
1997  if (JDs.empty())
1998  return std::vector<JITDylibSP>();
1999 
2000  auto &ES = JDs.front()->getExecutionSession();
2001  return ES.runSessionLocked([&]() -> Expected<std::vector<JITDylibSP>> {
2002  DenseSet<JITDylib *> Visited;
2003  std::vector<JITDylibSP> Result;
2004 
2005  for (auto &JD : JDs) {
2006 
2007  if (JD->State != Open)
2008  return make_error<StringError>(
2009  "Error building link order: " + JD->getName() + " is defunct",
2011  if (Visited.count(JD.get()))
2012  continue;
2013 
2014  SmallVector<JITDylibSP, 64> WorkStack;
2015  WorkStack.push_back(JD);
2016  Visited.insert(JD.get());
2017 
2018  while (!WorkStack.empty()) {
2019  Result.push_back(std::move(WorkStack.back()));
2020  WorkStack.pop_back();
2021 
2022  for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) {
2023  auto &JD = *KV.first;
2024  if (!Visited.insert(&JD).second)
2025  continue;
2026  WorkStack.push_back(&JD);
2027  }
2028  }
2029  }
2030  return Result;
2031  });
2032 }
2033 
2036  auto Result = getDFSLinkOrder(JDs);
2037  if (Result)
2038  std::reverse(Result->begin(), Result->end());
2039  return Result;
2040 }
2041 
2043  return getDFSLinkOrder({this});
2044 }
2045 
2047  return getReverseDFSLinkOrder({this});
2048 }
2049 
2051  LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
2052  unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
2053 
2054  OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
2055  K, std::move(SearchOrder), std::move(LookupSet),
2056  std::move(OnComplete)),
2057  Error::success());
2058 }
2059 
2062  SymbolLookupSet LookupSet) {
2063 
2064  std::promise<MSVCPExpected<SymbolFlagsMap>> ResultP;
2065  OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
2066  K, std::move(SearchOrder), std::move(LookupSet),
2067  [&ResultP](Expected<SymbolFlagsMap> Result) {
2068  ResultP.set_value(std::move(Result));
2069  }),
2070  Error::success());
2071 
2072  auto ResultF = ResultP.get_future();
2073  return ResultF.get();
2074 }
2075 
2077  LookupKind K, const JITDylibSearchOrder &SearchOrder,
2078  SymbolLookupSet Symbols, SymbolState RequiredState,
2079  SymbolsResolvedCallback NotifyComplete,
2080  RegisterDependenciesFunction RegisterDependencies) {
2081 
2082  LLVM_DEBUG({
2083  runSessionLocked([&]() {
2084  dbgs() << "Looking up " << Symbols << " in " << SearchOrder
2085  << " (required state: " << RequiredState << ")\n";
2086  });
2087  });
2088 
2089  // lookup can be re-entered recursively if running on a single thread. Run any
2090  // outstanding MUs in case this query depends on them, otherwise this lookup
2091  // will starve waiting for a result from an MU that is stuck in the queue.
2092  dispatchOutstandingMUs();
2093 
2094  auto Unresolved = std::move(Symbols);
2095  auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
2096  std::move(NotifyComplete));
2097 
2098  auto IPLS = std::make_unique<InProgressFullLookupState>(
2099  K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q),
2100  std::move(RegisterDependencies));
2101 
2102  OL_applyQueryPhase1(std::move(IPLS), Error::success());
2103 }
2104 
2107  SymbolLookupSet Symbols, LookupKind K,
2108  SymbolState RequiredState,
2109  RegisterDependenciesFunction RegisterDependencies) {
2110 #if LLVM_ENABLE_THREADS
2111  // In the threaded case we use promises to return the results.
2112  std::promise<SymbolMap> PromisedResult;
2113  Error ResolutionError = Error::success();
2114 
2115  auto NotifyComplete = [&](Expected<SymbolMap> R) {
2116  if (R)
2117  PromisedResult.set_value(std::move(*R));
2118  else {
2119  ErrorAsOutParameter _(&ResolutionError);
2120  ResolutionError = R.takeError();
2121  PromisedResult.set_value(SymbolMap());
2122  }
2123  };
2124 
2125 #else
2126  SymbolMap Result;
2127  Error ResolutionError = Error::success();
2128 
2129  auto NotifyComplete = [&](Expected<SymbolMap> R) {
2130  ErrorAsOutParameter _(&ResolutionError);
2131  if (R)
2132  Result = std::move(*R);
2133  else
2134  ResolutionError = R.takeError();
2135  };
2136 #endif
2137 
2138  // Perform the asynchronous lookup.
2139  lookup(K, SearchOrder, std::move(Symbols), RequiredState, NotifyComplete,
2140  RegisterDependencies);
2141 
2142 #if LLVM_ENABLE_THREADS
2143  auto ResultFuture = PromisedResult.get_future();
2144  auto Result = ResultFuture.get();
2145 
2146  if (ResolutionError)
2147  return std::move(ResolutionError);
2148 
2149  return std::move(Result);
2150 
2151 #else
2152  if (ResolutionError)
2153  return std::move(ResolutionError);
2154 
2155  return Result;
2156 #endif
2157 }
2158 
2161  SymbolStringPtr Name, SymbolState RequiredState) {
2162  SymbolLookupSet Names({Name});
2163 
2164  if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
2165  RequiredState, NoDependenciesToRegister)) {
2166  assert(ResultMap->size() == 1 && "Unexpected number of results");
2167  assert(ResultMap->count(Name) && "Missing result for symbol");
2168  return std::move(ResultMap->begin()->second);
2169  } else
2170  return ResultMap.takeError();
2171 }
2172 
2175  SymbolState RequiredState) {
2176  return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
2177 }
2178 
2181  SymbolState RequiredState) {
2182  return lookup(SearchOrder, intern(Name), RequiredState);
2183 }
2184 
2187 
2188  auto TagAddrs = lookup({{&JD, JITDylibLookupFlags::MatchAllSymbols}},
2191  if (!TagAddrs)
2192  return TagAddrs.takeError();
2193 
2194  // Associate tag addresses with implementations.
2195  std::lock_guard<std::mutex> Lock(JITDispatchHandlersMutex);
2196  for (auto &KV : *TagAddrs) {
2197  auto TagAddr = KV.second.getAddress();
2198  if (JITDispatchHandlers.count(TagAddr))
2199  return make_error<StringError>("Tag " + formatv("{0:x16}", TagAddr) +
2200  " (for " + *KV.first +
2201  ") already registered",
2203  auto I = WFs.find(KV.first);
2204  assert(I != WFs.end() && I->second &&
2205  "JITDispatchHandler implementation missing");
2206  JITDispatchHandlers[KV.second.getAddress()] =
2207  std::make_shared<JITDispatchHandlerFunction>(std::move(I->second));
2208  LLVM_DEBUG({
2209  dbgs() << "Associated function tag \"" << *KV.first << "\" ("
2210  << formatv("{0:x}", KV.second.getAddress()) << ") with handler\n";
2211  });
2212  }
2213  return Error::success();
2214 }
2215 
2217  SendResultFunction SendResult, JITTargetAddress HandlerFnTagAddr,
2218  ArrayRef<char> ArgBuffer) {
2219 
2220  std::shared_ptr<JITDispatchHandlerFunction> F;
2221  {
2222  std::lock_guard<std::mutex> Lock(JITDispatchHandlersMutex);
2223  auto I = JITDispatchHandlers.find(HandlerFnTagAddr);
2224  if (I != JITDispatchHandlers.end())
2225  F = I->second;
2226  }
2227 
2228  if (F)
2229  (*F)(std::move(SendResult), ArgBuffer.data(), ArgBuffer.size());
2230  else
2232  ("No function registered for tag " +
2233  formatv("{0:x16}", HandlerFnTagAddr))
2234  .str()));
2235 }
2236 
2238  runSessionLocked([this, &OS]() {
2239  for (auto &JD : JDs)
2240  JD->dump(OS);
2241  });
2242 }
2243 
2244 void ExecutionSession::dispatchOutstandingMUs() {
2245  LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n");
2246  while (true) {
2248  std::unique_ptr<MaterializationResponsibility>>>
2249  JMU;
2250 
2251  {
2252  std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2253  if (!OutstandingMUs.empty()) {
2254  JMU.emplace(std::move(OutstandingMUs.back()));
2255  OutstandingMUs.pop_back();
2256  }
2257  }
2258 
2259  if (!JMU)
2260  break;
2261 
2262  assert(JMU->first && "No MU?");
2263  LLVM_DEBUG(dbgs() << " Dispatching \"" << JMU->first->getName() << "\"\n");
2264  dispatchTask(std::make_unique<MaterializationTask>(std::move(JMU->first),
2265  std::move(JMU->second)));
2266  }
2267  LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n");
2268 }
2269 
2270 Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) {
2271  LLVM_DEBUG({
2272  dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "
2273  << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2274  });
2275  std::vector<ResourceManager *> CurrentResourceManagers;
2276 
2277  JITDylib::AsynchronousSymbolQuerySet QueriesToFail;
2278  std::shared_ptr<SymbolDependenceMap> FailedSymbols;
2279 
2280  runSessionLocked([&] {
2281  CurrentResourceManagers = ResourceManagers;
2282  RT.makeDefunct();
2283  std::tie(QueriesToFail, FailedSymbols) = RT.getJITDylib().removeTracker(RT);
2284  });
2285 
2286  Error Err = Error::success();
2287 
2288  for (auto *L : reverse(CurrentResourceManagers))
2289  Err =
2290  joinErrors(std::move(Err), L->handleRemoveResources(RT.getKeyUnsafe()));
2291 
2292  for (auto &Q : QueriesToFail)
2293  Q->handleFailed(
2294  make_error<FailedToMaterialize>(getSymbolStringPool(), FailedSymbols));
2295 
2296  return Err;
2297 }
2298 
2299 void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,
2300  ResourceTracker &SrcRT) {
2301  LLVM_DEBUG({
2302  dbgs() << "In " << SrcRT.getJITDylib().getName()
2303  << " transfering resources from tracker "
2304  << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "
2305  << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";
2306  });
2307 
2308  // No-op transfers are allowed and do not invalidate the source.
2309  if (&DstRT == &SrcRT)
2310  return;
2311 
2312  assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&
2313  "Can't transfer resources between JITDylibs");
2314  runSessionLocked([&]() {
2315  SrcRT.makeDefunct();
2316  auto &JD = DstRT.getJITDylib();
2317  JD.transferTracker(DstRT, SrcRT);
2318  for (auto *L : reverse(ResourceManagers))
2319  L->handleTransferResources(DstRT.getKeyUnsafe(), SrcRT.getKeyUnsafe());
2320  });
2321 }
2322 
2323 void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) {
2324  runSessionLocked([&]() {
2325  LLVM_DEBUG({
2326  dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "
2327  << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2328  });
2329  if (!RT.isDefunct())
2330  transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(),
2331  RT);
2332  });
2333 }
2334 
2335 Error ExecutionSession::IL_updateCandidatesFor(
2336  JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
2337  SymbolLookupSet &Candidates, SymbolLookupSet *NonCandidates) {
2338  return Candidates.forEachWithRemoval(
2339  [&](const SymbolStringPtr &Name,
2340  SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
2341  /// Search for the symbol. If not found then continue without
2342  /// removal.
2343  auto SymI = JD.Symbols.find(Name);
2344  if (SymI == JD.Symbols.end())
2345  return false;
2346 
2347  // If this is a non-exported symbol and we're matching exported
2348  // symbols only then remove this symbol from the candidates list.
2349  //
2350  // If we're tracking non-candidates then add this to the non-candidate
2351  // list.
2352  if (!SymI->second.getFlags().isExported() &&
2354  if (NonCandidates)
2355  NonCandidates->add(Name, SymLookupFlags);
2356  return true;
2357  }
2358 
2359  // If we match against a materialization-side-effects only symbol
2360  // then make sure it is weakly-referenced. Otherwise bail out with
2361  // an error.
2362  // FIXME: Use a "materialization-side-effects-only symbols must be
2363  // weakly referenced" specific error here to reduce confusion.
2364  if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2366  return make_error<SymbolsNotFound>(getSymbolStringPool(),
2367  SymbolNameVector({Name}));
2368 
2369  // If we matched against this symbol but it is in the error state
2370  // then bail out and treat it as a failure to materialize.
2371  if (SymI->second.getFlags().hasError()) {
2372  auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
2373  (*FailedSymbolsMap)[&JD] = {Name};
2374  return make_error<FailedToMaterialize>(getSymbolStringPool(),
2375  std::move(FailedSymbolsMap));
2376  }
2377 
2378  // Otherwise this is a match. Remove it from the candidate set.
2379  return true;
2380  });
2381 }
2382 
2383 void ExecutionSession::OL_applyQueryPhase1(
2384  std::unique_ptr<InProgressLookupState> IPLS, Error Err) {
2385 
2386  LLVM_DEBUG({
2387  dbgs() << "Entering OL_applyQueryPhase1:\n"
2388  << " Lookup kind: " << IPLS->K << "\n"
2389  << " Search order: " << IPLS->SearchOrder
2390  << ", Current index = " << IPLS->CurSearchOrderIndex
2391  << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2392  << " Lookup set: " << IPLS->LookupSet << "\n"
2393  << " Definition generator candidates: "
2394  << IPLS->DefGeneratorCandidates << "\n"
2395  << " Definition generator non-candidates: "
2396  << IPLS->DefGeneratorNonCandidates << "\n";
2397  });
2398 
2399  // FIXME: We should attach the query as we go: This provides a result in a
2400  // single pass in the common case where all symbols have already reached the
2401  // required state. The query could be detached again in the 'fail' method on
2402  // IPLS. Phase 2 would be reduced to collecting and dispatching the MUs.
2403 
2404  while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) {
2405 
2406  // If we've been handed an error or received one back from a generator then
2407  // fail the query. We don't need to unlink: At this stage the query hasn't
2408  // actually been lodged.
2409  if (Err)
2410  return IPLS->fail(std::move(Err));
2411 
2412  // Get the next JITDylib and lookup flags.
2413  auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex];
2414  auto &JD = *KV.first;
2415  auto JDLookupFlags = KV.second;
2416 
2417  LLVM_DEBUG({
2418  dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2419  << ") with lookup set " << IPLS->LookupSet << ":\n";
2420  });
2421 
2422  // If we've just reached a new JITDylib then perform some setup.
2423  if (IPLS->NewJITDylib) {
2424 
2425  // Acquire the generator lock for this JITDylib.
2426  IPLS->GeneratorLock = std::unique_lock<std::mutex>(JD.GeneratorsMutex);
2427 
2428  // Add any non-candidates from the last JITDylib (if any) back on to the
2429  // list of definition candidates for this JITDylib, reset definition
2430  // non-candiates to the empty set.
2431  SymbolLookupSet Tmp;
2432  std::swap(IPLS->DefGeneratorNonCandidates, Tmp);
2433  IPLS->DefGeneratorCandidates.append(std::move(Tmp));
2434 
2435  LLVM_DEBUG({
2436  dbgs() << " First time visiting " << JD.getName()
2437  << ", resetting candidate sets and building generator stack\n";
2438  });
2439 
2440  // Build the definition generator stack for this JITDylib.
2441  runSessionLocked([&] {
2442  IPLS->CurDefGeneratorStack.reserve(JD.DefGenerators.size());
2443  for (auto &DG : reverse(JD.DefGenerators))
2444  IPLS->CurDefGeneratorStack.push_back(DG);
2445  });
2446 
2447  // Flag that we've done our initialization.
2448  IPLS->NewJITDylib = false;
2449  }
2450 
2451  // Remove any generation candidates that are already defined (and match) in
2452  // this JITDylib.
2453  runSessionLocked([&] {
2454  // Update the list of candidates (and non-candidates) for definition
2455  // generation.
2456  LLVM_DEBUG(dbgs() << " Updating candidate set...\n");
2457  Err = IL_updateCandidatesFor(
2458  JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2459  JD.DefGenerators.empty() ? nullptr
2460  : &IPLS->DefGeneratorNonCandidates);
2461  LLVM_DEBUG({
2462  dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates
2463  << "\n";
2464  });
2465  });
2466 
2467  // If we encountered an error while filtering generation candidates then
2468  // bail out.
2469  if (Err)
2470  return IPLS->fail(std::move(Err));
2471 
2472  /// Apply any definition generators on the stack.
2473  LLVM_DEBUG({
2474  if (IPLS->CurDefGeneratorStack.empty())
2475  LLVM_DEBUG(dbgs() << " No generators to run for this JITDylib.\n");
2476  else if (IPLS->DefGeneratorCandidates.empty())
2477  LLVM_DEBUG(dbgs() << " No candidates to generate.\n");
2478  else
2479  dbgs() << " Running " << IPLS->CurDefGeneratorStack.size()
2480  << " remaining generators for "
2481  << IPLS->DefGeneratorCandidates.size() << " candidates\n";
2482  });
2483  while (!IPLS->CurDefGeneratorStack.empty() &&
2484  !IPLS->DefGeneratorCandidates.empty()) {
2485  auto DG = IPLS->CurDefGeneratorStack.back().lock();
2486  IPLS->CurDefGeneratorStack.pop_back();
2487 
2488  if (!DG)
2489  return IPLS->fail(make_error<StringError>(
2490  "DefinitionGenerator removed while lookup in progress",
2492 
2493  auto K = IPLS->K;
2494  auto &LookupSet = IPLS->DefGeneratorCandidates;
2495 
2496  // Run the generator. If the generator takes ownership of QA then this
2497  // will break the loop.
2498  {
2499  LLVM_DEBUG(dbgs() << " Attempting to generate " << LookupSet << "\n");
2500  LookupState LS(std::move(IPLS));
2501  Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet);
2502  IPLS = std::move(LS.IPLS);
2503  }
2504 
2505  // If there was an error then fail the query.
2506  if (Err) {
2507  LLVM_DEBUG({
2508  dbgs() << " Error attempting to generate " << LookupSet << "\n";
2509  });
2510  assert(IPLS && "LS cannot be retained if error is returned");
2511  return IPLS->fail(std::move(Err));
2512  }
2513 
2514  // Otherwise if QA was captured then break the loop.
2515  if (!IPLS) {
2516  LLVM_DEBUG(
2517  { dbgs() << " LookupState captured. Exiting phase1 for now.\n"; });
2518  return;
2519  }
2520 
2521  // Otherwise if we're continuing around the loop then update candidates
2522  // for the next round.
2523  runSessionLocked([&] {
2524  LLVM_DEBUG(dbgs() << " Updating candidate set post-generation\n");
2525  Err = IL_updateCandidatesFor(
2526  JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2527  JD.DefGenerators.empty() ? nullptr
2528  : &IPLS->DefGeneratorNonCandidates);
2529  });
2530 
2531  // If updating candidates failed then fail the query.
2532  if (Err) {
2533  LLVM_DEBUG(dbgs() << " Error encountered while updating candidates\n");
2534  return IPLS->fail(std::move(Err));
2535  }
2536  }
2537 
2538  if (IPLS->DefGeneratorCandidates.empty() &&
2539  IPLS->DefGeneratorNonCandidates.empty()) {
2540  // Early out if there are no remaining symbols.
2541  LLVM_DEBUG(dbgs() << "All symbols matched.\n");
2542  IPLS->CurSearchOrderIndex = IPLS->SearchOrder.size();
2543  break;
2544  } else {
2545  // If we get here then we've moved on to the next JITDylib with candidates
2546  // remaining.
2547  LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n");
2548  ++IPLS->CurSearchOrderIndex;
2549  IPLS->NewJITDylib = true;
2550  }
2551  }
2552 
2553  // Remove any weakly referenced candidates that could not be found/generated.
2554  IPLS->DefGeneratorCandidates.remove_if(
2555  [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2556  return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
2557  });
2558 
2559  // If we get here then we've finished searching all JITDylibs.
2560  // If we matched all symbols then move to phase 2, otherwise fail the query
2561  // with a SymbolsNotFound error.
2562  if (IPLS->DefGeneratorCandidates.empty()) {
2563  LLVM_DEBUG(dbgs() << "Phase 1 succeeded.\n");
2564  IPLS->complete(std::move(IPLS));
2565  } else {
2566  LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n");
2567  IPLS->fail(make_error<SymbolsNotFound>(
2568  getSymbolStringPool(), IPLS->DefGeneratorCandidates.getSymbolNames()));
2569  }
2570 }
2571 
2572 void ExecutionSession::OL_completeLookup(
2573  std::unique_ptr<InProgressLookupState> IPLS,
2574  std::shared_ptr<AsynchronousSymbolQuery> Q,
2575  RegisterDependenciesFunction RegisterDependencies) {
2576 
2577  LLVM_DEBUG({
2578  dbgs() << "Entering OL_completeLookup:\n"
2579  << " Lookup kind: " << IPLS->K << "\n"
2580  << " Search order: " << IPLS->SearchOrder
2581  << ", Current index = " << IPLS->CurSearchOrderIndex
2582  << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2583  << " Lookup set: " << IPLS->LookupSet << "\n"
2584  << " Definition generator candidates: "
2585  << IPLS->DefGeneratorCandidates << "\n"
2586  << " Definition generator non-candidates: "
2587  << IPLS->DefGeneratorNonCandidates << "\n";
2588  });
2589 
2590  bool QueryComplete = false;
2591  DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs;
2592 
2593  auto LodgingErr = runSessionLocked([&]() -> Error {
2594  for (auto &KV : IPLS->SearchOrder) {
2595  auto &JD = *KV.first;
2596  auto JDLookupFlags = KV.second;
2597  LLVM_DEBUG({
2598  dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2599  << ") with lookup set " << IPLS->LookupSet << ":\n";
2600  });
2601 
2602  auto Err = IPLS->LookupSet.forEachWithRemoval(
2603  [&](const SymbolStringPtr &Name,
2604  SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
2605  LLVM_DEBUG({
2606  dbgs() << " Attempting to match \"" << Name << "\" ("
2607  << SymLookupFlags << ")... ";
2608  });
2609 
2610  /// Search for the symbol. If not found then continue without
2611  /// removal.
2612  auto SymI = JD.Symbols.find(Name);
2613  if (SymI == JD.Symbols.end()) {
2614  LLVM_DEBUG(dbgs() << "skipping: not present\n");
2615  return false;
2616  }
2617 
2618  // If this is a non-exported symbol and we're matching exported
2619  // symbols only then skip this symbol without removal.
2620  if (!SymI->second.getFlags().isExported() &&
2621  JDLookupFlags ==
2623  LLVM_DEBUG(dbgs() << "skipping: not exported\n");
2624  return false;
2625  }
2626 
2627  // If we match against a materialization-side-effects only symbol
2628  // then make sure it is weakly-referenced. Otherwise bail out with
2629  // an error.
2630  // FIXME: Use a "materialization-side-effects-only symbols must be
2631  // weakly referenced" specific error here to reduce confusion.
2632  if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2633  SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol) {
2634  LLVM_DEBUG({
2635  dbgs() << "error: "
2636  "required, but symbol is has-side-effects-only\n";
2637  });
2638  return make_error<SymbolsNotFound>(getSymbolStringPool(),
2639  SymbolNameVector({Name}));
2640  }
2641 
2642  // If we matched against this symbol but it is in the error state
2643  // then bail out and treat it as a failure to materialize.
2644  if (SymI->second.getFlags().hasError()) {
2645  LLVM_DEBUG(dbgs() << "error: symbol is in error state\n");
2646  auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
2647  (*FailedSymbolsMap)[&JD] = {Name};
2648  return make_error<FailedToMaterialize>(
2649  getSymbolStringPool(), std::move(FailedSymbolsMap));
2650  }
2651 
2652  // Otherwise this is a match.
2653 
2654  // If this symbol is already in the requried state then notify the
2655  // query, remove the symbol and continue.
2656  if (SymI->second.getState() >= Q->getRequiredState()) {
2657  LLVM_DEBUG(dbgs()
2658  << "matched, symbol already in required state\n");
2659  Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
2660  return true;
2661  }
2662 
2663  // Otherwise this symbol does not yet meet the required state. Check
2664  // whether it has a materializer attached, and if so prepare to run
2665  // it.
2666  if (SymI->second.hasMaterializerAttached()) {
2667  assert(SymI->second.getAddress() == 0 &&
2668  "Symbol not resolved but already has address?");
2669  auto UMII = JD.UnmaterializedInfos.find(Name);
2670  assert(UMII != JD.UnmaterializedInfos.end() &&
2671  "Lazy symbol should have UnmaterializedInfo");
2672 
2673  auto UMI = UMII->second;
2674  assert(UMI->MU && "Materializer should not be null");
2675  assert(UMI->RT && "Tracker should not be null");
2676  LLVM_DEBUG({
2677  dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()
2678  << " (" << UMI->MU->getName() << ")\n";
2679  });
2680 
2681  // Move all symbols associated with this MaterializationUnit into
2682  // materializing state.
2683  for (auto &KV : UMI->MU->getSymbols()) {
2684  auto SymK = JD.Symbols.find(KV.first);
2685  assert(SymK != JD.Symbols.end() &&
2686  "No entry for symbol covered by MaterializationUnit");
2687  SymK->second.setMaterializerAttached(false);
2688  SymK->second.setState(SymbolState::Materializing);
2689  JD.UnmaterializedInfos.erase(KV.first);
2690  }
2691 
2692  // Add MU to the list of MaterializationUnits to be materialized.
2693  CollectedUMIs[&JD].push_back(std::move(UMI));
2694  } else
2695  LLVM_DEBUG(dbgs() << "matched, registering query");
2696 
2697  // Add the query to the PendingQueries list and continue, deleting
2698  // the element from the lookup set.
2699  assert(SymI->second.getState() != SymbolState::NeverSearched &&
2700  SymI->second.getState() != SymbolState::Ready &&
2701  "By this line the symbol should be materializing");
2702  auto &MI = JD.MaterializingInfos[Name];
2703  MI.addQuery(Q);
2704  Q->addQueryDependence(JD, Name);
2705 
2706  return true;
2707  });
2708 
2709  // Handle failure.
2710  if (Err) {
2711 
2712  LLVM_DEBUG({
2713  dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";
2714  });
2715 
2716  // Detach the query.
2717  Q->detach();
2718 
2719  // Replace the MUs.
2720  for (auto &KV : CollectedUMIs) {
2721  auto &JD = *KV.first;
2722  for (auto &UMI : KV.second)
2723  for (auto &KV2 : UMI->MU->getSymbols()) {
2724  assert(!JD.UnmaterializedInfos.count(KV2.first) &&
2725  "Unexpected materializer in map");
2726  auto SymI = JD.Symbols.find(KV2.first);
2727  assert(SymI != JD.Symbols.end() && "Missing symbol entry");
2728  assert(SymI->second.getState() == SymbolState::Materializing &&
2729  "Can not replace symbol that is not materializing");
2730  assert(!SymI->second.hasMaterializerAttached() &&
2731  "MaterializerAttached flag should not be set");
2732  SymI->second.setMaterializerAttached(true);
2733  JD.UnmaterializedInfos[KV2.first] = UMI;
2734  }
2735  }
2736 
2737  return Err;
2738  }
2739  }
2740 
2741  LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-referenced symbols\n");
2742  IPLS->LookupSet.forEachWithRemoval(
2743  [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2744  if (SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2745  Q->dropSymbol(Name);
2746  return true;
2747  } else
2748  return false;
2749  });
2750 
2751  if (!IPLS->LookupSet.empty()) {
2752  LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2753  return make_error<SymbolsNotFound>(getSymbolStringPool(),
2754  IPLS->LookupSet.getSymbolNames());
2755  }
2756 
2757  // Record whether the query completed.
2758  QueryComplete = Q->isComplete();
2759 
2760  LLVM_DEBUG({
2761  dbgs() << "Query successfully "
2762  << (QueryComplete ? "completed" : "lodged") << "\n";
2763  });
2764 
2765  // Move the collected MUs to the OutstandingMUs list.
2766  if (!CollectedUMIs.empty()) {
2767  std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2768 
2769  LLVM_DEBUG(dbgs() << "Adding MUs to dispatch:\n");
2770  for (auto &KV : CollectedUMIs) {
2771  LLVM_DEBUG({
2772  auto &JD = *KV.first;
2773  dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size()
2774  << " MUs.\n";
2775  });
2776  for (auto &UMI : KV.second) {
2777  auto MR = createMaterializationResponsibility(
2778  *UMI->RT, std::move(UMI->MU->SymbolFlags),
2779  std::move(UMI->MU->InitSymbol));
2780  OutstandingMUs.push_back(
2781  std::make_pair(std::move(UMI->MU), std::move(MR)));
2782  }
2783  }
2784  } else
2785  LLVM_DEBUG(dbgs() << "No MUs to dispatch.\n");
2786 
2787  if (RegisterDependencies && !Q->QueryRegistrations.empty()) {
2788  LLVM_DEBUG(dbgs() << "Registering dependencies\n");
2789  RegisterDependencies(Q->QueryRegistrations);
2790  } else
2791  LLVM_DEBUG(dbgs() << "No dependencies to register\n");
2792 
2793  return Error::success();
2794  });
2795 
2796  if (LodgingErr) {
2797  LLVM_DEBUG(dbgs() << "Failing query\n");
2798  Q->detach();
2799  Q->handleFailed(std::move(LodgingErr));
2800  return;
2801  }
2802 
2803  if (QueryComplete) {
2804  LLVM_DEBUG(dbgs() << "Completing query\n");
2805  Q->handleComplete(*this);
2806  }
2807 
2808  dispatchOutstandingMUs();
2809 }
2810 
2811 void ExecutionSession::OL_completeLookupFlags(
2812  std::unique_ptr<InProgressLookupState> IPLS,
2813  unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
2814 
2815  auto Result = runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
2816  LLVM_DEBUG({
2817  dbgs() << "Entering OL_completeLookupFlags:\n"
2818  << " Lookup kind: " << IPLS->K << "\n"
2819  << " Search order: " << IPLS->SearchOrder
2820  << ", Current index = " << IPLS->CurSearchOrderIndex
2821  << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2822  << " Lookup set: " << IPLS->LookupSet << "\n"
2823  << " Definition generator candidates: "
2824  << IPLS->DefGeneratorCandidates << "\n"
2825  << " Definition generator non-candidates: "
2826  << IPLS->DefGeneratorNonCandidates << "\n";
2827  });
2828 
2830 
2831  // Attempt to find flags for each symbol.
2832  for (auto &KV : IPLS->SearchOrder) {
2833  auto &JD = *KV.first;
2834  auto JDLookupFlags = KV.second;
2835  LLVM_DEBUG({
2836  dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2837  << ") with lookup set " << IPLS->LookupSet << ":\n";
2838  });
2839 
2840  IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name,
2841  SymbolLookupFlags SymLookupFlags) {
2842  LLVM_DEBUG({
2843  dbgs() << " Attempting to match \"" << Name << "\" ("
2844  << SymLookupFlags << ")... ";
2845  });
2846 
2847  // Search for the symbol. If not found then continue without removing
2848  // from the lookup set.
2849  auto SymI = JD.Symbols.find(Name);
2850  if (SymI == JD.Symbols.end()) {
2851  LLVM_DEBUG(dbgs() << "skipping: not present\n");
2852  return false;
2853  }
2854 
2855  // If this is a non-exported symbol then it doesn't match. Skip it.
2856  if (!SymI->second.getFlags().isExported() &&
2858  LLVM_DEBUG(dbgs() << "skipping: not exported\n");
2859  return false;
2860  }
2861 
2862  LLVM_DEBUG({
2863  dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()
2864  << "\n";
2865  });
2866  Result[Name] = SymI->second.getFlags();
2867  return true;
2868  });
2869  }
2870 
2871  // Remove any weakly referenced symbols that haven't been resolved.
2872  IPLS->LookupSet.remove_if(
2873  [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2874  return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
2875  });
2876 
2877  if (!IPLS->LookupSet.empty()) {
2878  LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2879  return make_error<SymbolsNotFound>(getSymbolStringPool(),
2880  IPLS->LookupSet.getSymbolNames());
2881  }
2882 
2883  LLVM_DEBUG(dbgs() << "Succeded, result = " << Result << "\n");
2884  return Result;
2885  });
2886 
2887  // Run the callback on the result.
2888  LLVM_DEBUG(dbgs() << "Sending result to handler.\n");
2889  OnComplete(std::move(Result));
2890 }
2891 
2892 void ExecutionSession::OL_destroyMaterializationResponsibility(
2893  MaterializationResponsibility &MR) {
2894 
2895  assert(MR.SymbolFlags.empty() &&
2896  "All symbols should have been explicitly materialized or failed");
2897  MR.JD.unlinkMaterializationResponsibility(MR);
2898 }
2899 
2900 SymbolNameSet ExecutionSession::OL_getRequestedSymbols(
2901  const MaterializationResponsibility &MR) {
2902  return MR.JD.getRequestedSymbols(MR.SymbolFlags);
2903 }
2904 
2905 Error ExecutionSession::OL_notifyResolved(MaterializationResponsibility &MR,
2906  const SymbolMap &Symbols) {
2907  LLVM_DEBUG({
2908  dbgs() << "In " << MR.JD.getName() << " resolving " << Symbols << "\n";
2909  });
2910 #ifndef NDEBUG
2911  for (auto &KV : Symbols) {
2912  auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
2913  auto I = MR.SymbolFlags.find(KV.first);
2914  assert(I != MR.SymbolFlags.end() &&
2915  "Resolving symbol outside this responsibility set");
2916  assert(!I->second.hasMaterializationSideEffectsOnly() &&
2917  "Can't resolve materialization-side-effects-only symbol");
2918  assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&
2919  "Resolving symbol with incorrect flags");
2920  }
2921 #endif
2922 
2923  return MR.JD.resolve(MR, Symbols);
2924 }
2925 
2926 Error ExecutionSession::OL_notifyEmitted(MaterializationResponsibility &MR) {
2927  LLVM_DEBUG({
2928  dbgs() << "In " << MR.JD.getName() << " emitting " << MR.SymbolFlags
2929  << "\n";
2930  });
2931 
2932  if (auto Err = MR.JD.emit(MR, MR.SymbolFlags))
2933  return Err;
2934 
2935  MR.SymbolFlags.clear();
2936  return Error::success();
2937 }
2938 
2939 Error ExecutionSession::OL_defineMaterializing(
2940  MaterializationResponsibility &MR, SymbolFlagsMap NewSymbolFlags) {
2941 
2942  LLVM_DEBUG({
2943  dbgs() << "In " << MR.JD.getName() << " defining materializing symbols "
2944  << NewSymbolFlags << "\n";
2945  });
2946  if (auto AcceptedDefs =
2947  MR.JD.defineMaterializing(std::move(NewSymbolFlags))) {
2948  // Add all newly accepted symbols to this responsibility object.
2949  for (auto &KV : *AcceptedDefs)
2950  MR.SymbolFlags.insert(KV);
2951  return Error::success();
2952  } else
2953  return AcceptedDefs.takeError();
2954 }
2955 
2956 void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) {
2957 
2958  LLVM_DEBUG({
2959  dbgs() << "In " << MR.JD.getName() << " failing materialization for "
2960  << MR.SymbolFlags << "\n";
2961  });
2962 
2963  JITDylib::FailedSymbolsWorklist Worklist;
2964 
2965  for (auto &KV : MR.SymbolFlags)
2966  Worklist.push_back(std::make_pair(&MR.JD, KV.first));
2967  MR.SymbolFlags.clear();
2968 
2969  if (Worklist.empty())
2970  return;
2971 
2972  JITDylib::AsynchronousSymbolQuerySet FailedQueries;
2973  std::shared_ptr<SymbolDependenceMap> FailedSymbols;
2974 
2975  runSessionLocked([&]() {
2976  // If the tracker is defunct then there's nothing to do here.
2977  if (MR.RT->isDefunct())
2978  return;
2979 
2980  std::tie(FailedQueries, FailedSymbols) =
2981  JITDylib::failSymbols(std::move(Worklist));
2982  });
2983 
2984  for (auto &Q : FailedQueries)
2985  Q->handleFailed(
2986  make_error<FailedToMaterialize>(getSymbolStringPool(), FailedSymbols));
2987 }
2988 
2989 Error ExecutionSession::OL_replace(MaterializationResponsibility &MR,
2990  std::unique_ptr<MaterializationUnit> MU) {
2991  for (auto &KV : MU->getSymbols()) {
2992  assert(MR.SymbolFlags.count(KV.first) &&
2993  "Replacing definition outside this responsibility set");
2994  MR.SymbolFlags.erase(KV.first);
2995  }
2996 
2997  if (MU->getInitializerSymbol() == MR.InitSymbol)
2998  MR.InitSymbol = nullptr;
2999 
3000  LLVM_DEBUG(MR.JD.getExecutionSession().runSessionLocked([&]() {
3001  dbgs() << "In " << MR.JD.getName() << " replacing symbols with " << *MU
3002  << "\n";
3003  }););
3004 
3005  return MR.JD.replace(MR, std::move(MU));
3006 }
3007 
3008 Expected<std::unique_ptr<MaterializationResponsibility>>
3009 ExecutionSession::OL_delegate(MaterializationResponsibility &MR,
3010  const SymbolNameSet &Symbols) {
3011 
3012  SymbolStringPtr DelegatedInitSymbol;
3013  SymbolFlagsMap DelegatedFlags;
3014 
3015  for (auto &Name : Symbols) {
3016  auto I = MR.SymbolFlags.find(Name);
3017  assert(I != MR.SymbolFlags.end() &&
3018  "Symbol is not tracked by this MaterializationResponsibility "
3019  "instance");
3020 
3021  DelegatedFlags[Name] = std::move(I->second);
3022  if (Name == MR.InitSymbol)
3023  std::swap(MR.InitSymbol, DelegatedInitSymbol);
3024 
3025  MR.SymbolFlags.erase(I);
3026  }
3027 
3028  return MR.JD.delegate(MR, std::move(DelegatedFlags),
3029  std::move(DelegatedInitSymbol));
3030 }
3031 
3032 void ExecutionSession::OL_addDependencies(
3033  MaterializationResponsibility &MR, const SymbolStringPtr &Name,
3034  const SymbolDependenceMap &Dependencies) {
3035  LLVM_DEBUG({
3036  dbgs() << "Adding dependencies for " << Name << ": " << Dependencies
3037  << "\n";
3038  });
3039  assert(MR.SymbolFlags.count(Name) &&
3040  "Symbol not covered by this MaterializationResponsibility instance");
3041  MR.JD.addDependencies(Name, Dependencies);
3042 }
3043 
3044 void ExecutionSession::OL_addDependenciesForAll(
3045  MaterializationResponsibility &MR,
3046  const SymbolDependenceMap &Dependencies) {
3047  LLVM_DEBUG({
3048  dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": "
3049  << Dependencies << "\n";
3050  });
3051  for (auto &KV : MR.SymbolFlags)
3052  MR.JD.addDependencies(KV.first, Dependencies);
3053 }
3054 
3055 #ifndef NDEBUG
3056 void ExecutionSession::dumpDispatchInfo(Task &T) {
3057  runSessionLocked([&]() {
3058  dbgs() << "Dispatching: ";
3059  T.printDescription(dbgs());
3060  dbgs() << "\n";
3061  });
3062 }
3063 #endif // NDEBUG
3064 
3065 } // End namespace orc.
3066 } // 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:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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:202
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:1931
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:1736
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:1185
llvm::orc::ExecutionSession::removeJITDylib
Error removeJITDylib(JITDylib &JD)
Closes the given JITDylib.
Definition: Core.cpp:1956
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:304
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::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:380
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:1914
llvm::orc::MaterializationTask::run
void run() override
Definition: Core.cpp:1881
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:147
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:1833
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:82
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:2216
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:240
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::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
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:2237
llvm::Expected
class LLVM_NODISCARD Expected
Definition: raw_ostream.h:39
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:2185
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:119
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:1784
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:54
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:1940
llvm::orc::ExecutionSession::endSession
Error endSession()
End the session.
Definition: Core.cpp:1895
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:1876
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:2042
llvm::orc::ExecutionSession::~ExecutionSession
~ExecutionSession()
Destroy an ExecutionSession.
Definition: Core.cpp:1889
llvm::DenseMapBase::clear
void clear()
Definition: DenseMap.h:112
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:1637
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:2046
llvm::Optional::emplace
void emplace(ArgTypes &&... Args)
Create a new object by constructing it in place with the given arguments.
Definition: Optional.h:287
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:2050
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:716
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:152
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:1675
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:1883
ModuleName
Definition: ItaniumDemangle.h:989
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::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:1918
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:469
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::JITSymbolFlags::Weak
@ Weak
Definition: JITSymbol.h:82
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:58
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:1823
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:209
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:1948
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:1644
llvm::orc::SymbolFlagsMap
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
Definition: Core.h:116
llvm::DenseMapBase::empty
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:98
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:77
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:101
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:2076
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::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