Core.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. //===----- Core.cpp - Core ORC APIs (MaterializationUnit, VSO, etc.) ------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/ExecutionEngine/Orc/Core.h"
  10. #include "llvm/Config/llvm-config.h"
  11. #include "llvm/ExecutionEngine/Orc/OrcError.h"
  12. #include "llvm/Support/Format.h"
  13. #if LLVM_ENABLE_THREADS
  14. #include <future>
  15. #endif
  16. namespace llvm {
  17. namespace orc {
  18. char FailedToMaterialize::ID = 0;
  19. char FailedToResolve::ID = 0;
  20. char FailedToFinalize::ID = 0;
  21. void MaterializationUnit::anchor() {}
  22. void SymbolResolver::anchor() {}
  23. raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
  24. if (Flags.isWeak())
  25. OS << 'W';
  26. else if (Flags.isCommon())
  27. OS << 'C';
  28. else
  29. OS << 'S';
  30. if (Flags.isExported())
  31. OS << 'E';
  32. else
  33. OS << 'H';
  34. return OS;
  35. }
  36. raw_ostream &operator<<(raw_ostream &OS, const JITEvaluatedSymbol &Sym) {
  37. OS << format("0x%016x", Sym.getAddress()) << " " << Sym.getFlags();
  38. return OS;
  39. }
  40. raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) {
  41. OS << "\"" << *KV.first << "\": " << KV.second;
  42. return OS;
  43. }
  44. raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) {
  45. OS << "{";
  46. if (!Symbols.empty()) {
  47. OS << " \"" << **Symbols.begin() << "\"";
  48. for (auto &Sym : make_range(std::next(Symbols.begin()), Symbols.end()))
  49. OS << ", \"" << *Sym << "\"";
  50. }
  51. OS << " }";
  52. return OS;
  53. }
  54. raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) {
  55. OS << "{";
  56. if (!Symbols.empty()) {
  57. OS << " {" << *Symbols.begin() << "}";
  58. for (auto &Sym : make_range(std::next(Symbols.begin()), Symbols.end()))
  59. OS << ", {" << Sym << "}";
  60. }
  61. OS << " }";
  62. return OS;
  63. }
  64. raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) {
  65. OS << "{";
  66. if (SymbolFlags.empty()) {
  67. OS << " {\"" << *SymbolFlags.begin()->first
  68. << "\": " << SymbolFlags.begin()->second << "}";
  69. for (auto &KV :
  70. make_range(std::next(SymbolFlags.begin()), SymbolFlags.end()))
  71. OS << ", {\"" << *KV.first << "\": " << KV.second << "}";
  72. }
  73. OS << " }";
  74. return OS;
  75. }
  76. FailedToResolve::FailedToResolve(SymbolNameSet Symbols)
  77. : Symbols(std::move(Symbols)) {
  78. assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
  79. }
  80. std::error_code FailedToResolve::convertToErrorCode() const {
  81. return orcError(OrcErrorCode::UnknownORCError);
  82. }
  83. void FailedToResolve::log(raw_ostream &OS) const {
  84. OS << "Failed to resolve symbols: " << Symbols;
  85. }
  86. FailedToFinalize::FailedToFinalize(SymbolNameSet Symbols)
  87. : Symbols(std::move(Symbols)) {
  88. assert(!this->Symbols.empty() && "Can not fail to finalize an empty set");
  89. }
  90. std::error_code FailedToFinalize::convertToErrorCode() const {
  91. return orcError(OrcErrorCode::UnknownORCError);
  92. }
  93. void FailedToFinalize::log(raw_ostream &OS) const {
  94. OS << "Failed to finalize symbols: " << Symbols;
  95. }
  96. AsynchronousSymbolQuery::AsynchronousSymbolQuery(
  97. const SymbolNameSet &Symbols, SymbolsResolvedCallback NotifySymbolsResolved,
  98. SymbolsReadyCallback NotifySymbolsReady)
  99. : NotifySymbolsResolved(std::move(NotifySymbolsResolved)),
  100. NotifySymbolsReady(std::move(NotifySymbolsReady)) {
  101. assert(this->NotifySymbolsResolved &&
  102. "Symbols resolved callback must be set");
  103. assert(this->NotifySymbolsReady && "Symbols ready callback must be set");
  104. OutstandingResolutions = OutstandingFinalizations = Symbols.size();
  105. }
  106. void AsynchronousSymbolQuery::notifyMaterializationFailed(Error Err) {
  107. if (OutstandingResolutions != 0)
  108. NotifySymbolsResolved(std::move(Err));
  109. else if (OutstandingFinalizations != 0)
  110. NotifySymbolsReady(std::move(Err));
  111. else
  112. consumeError(std::move(Err));
  113. OutstandingResolutions = OutstandingFinalizations = 0;
  114. }
  115. void AsynchronousSymbolQuery::resolve(SymbolStringPtr Name,
  116. JITEvaluatedSymbol Sym) {
  117. // If OutstandingResolutions is zero we must have errored out already. Just
  118. // ignore this.
  119. if (OutstandingResolutions == 0)
  120. return;
  121. assert(!Symbols.count(Name) && "Symbol has already been assigned an address");
  122. Symbols.insert(std::make_pair(std::move(Name), std::move(Sym)));
  123. --OutstandingResolutions;
  124. if (OutstandingResolutions == 0)
  125. NotifySymbolsResolved(std::move(Symbols));
  126. }
  127. void AsynchronousSymbolQuery::finalizeSymbol() {
  128. // If OutstandingFinalizations is zero we must have errored out already. Just
  129. // ignore this.
  130. if (OutstandingFinalizations == 0)
  131. return;
  132. assert(OutstandingFinalizations > 0 && "All symbols already finalized");
  133. --OutstandingFinalizations;
  134. if (OutstandingFinalizations == 0)
  135. NotifySymbolsReady(Error::success());
  136. }
  137. MaterializationResponsibility::MaterializationResponsibility(
  138. VSO &V, SymbolFlagsMap SymbolFlags)
  139. : V(V), SymbolFlags(std::move(SymbolFlags)) {
  140. assert(!this->SymbolFlags.empty() && "Materializing nothing?");
  141. }
  142. MaterializationResponsibility::~MaterializationResponsibility() {
  143. assert(SymbolFlags.empty() &&
  144. "All symbols should have been explicitly materialized or failed");
  145. }
  146. void MaterializationResponsibility::resolve(const SymbolMap &Symbols) {
  147. #ifndef NDEBUG
  148. for (auto &KV : Symbols) {
  149. auto I = SymbolFlags.find(KV.first);
  150. assert(I != SymbolFlags.end() &&
  151. "Resolving symbol outside this responsibility set");
  152. assert(KV.second.getFlags() == I->second &&
  153. "Resolving symbol with incorrect flags");
  154. }
  155. #endif
  156. V.resolve(Symbols);
  157. }
  158. void MaterializationResponsibility::finalize() {
  159. SymbolNameSet SymbolNames;
  160. for (auto &KV : SymbolFlags)
  161. SymbolNames.insert(KV.first);
  162. SymbolFlags.clear();
  163. V.finalize(SymbolNames);
  164. }
  165. void MaterializationResponsibility::notifyMaterializationFailed() {
  166. SymbolNameSet SymbolNames;
  167. for (auto &KV : SymbolFlags)
  168. SymbolNames.insert(KV.first);
  169. SymbolFlags.clear();
  170. V.notifyMaterializationFailed(SymbolNames);
  171. }
  172. MaterializationResponsibility
  173. MaterializationResponsibility::delegate(SymbolNameSet Symbols) {
  174. SymbolFlagsMap ExtractedFlags;
  175. for (auto &S : Symbols) {
  176. auto I = SymbolFlags.find(S);
  177. ExtractedFlags.insert(*I);
  178. SymbolFlags.erase(I);
  179. }
  180. return MaterializationResponsibility(V, std::move(ExtractedFlags));
  181. }
  182. VSO::Materializer::Materializer(std::unique_ptr<MaterializationUnit> MU,
  183. MaterializationResponsibility R)
  184. : MU(std::move(MU)), R(std::move(R)) {}
  185. void VSO::Materializer::operator()() { MU->materialize(std::move(R)); }
  186. VSO::UnmaterializedInfo::UnmaterializedInfo(
  187. std::unique_ptr<MaterializationUnit> MU)
  188. : MU(std::move(MU)), Symbols(this->MU->getSymbols()) {}
  189. void VSO::UnmaterializedInfo::discard(VSO &V, SymbolStringPtr Name) {
  190. assert(MU && "No materializer attached");
  191. MU->discard(V, Name);
  192. auto I = Symbols.find(Name);
  193. assert(I != Symbols.end() && "Symbol not found in this MU");
  194. Symbols.erase(I);
  195. }
  196. VSO::SymbolTableEntry::SymbolTableEntry(JITSymbolFlags Flags,
  197. UnmaterializedInfoIterator UMII)
  198. : Flags(Flags), UMII(std::move(UMII)) {
  199. // We *don't* expect isLazy to be set here. That's for the VSO to do.
  200. assert(!Flags.isLazy() && "Initial flags include lazy?");
  201. assert(!Flags.isMaterializing() && "Initial flags include materializing");
  202. this->Flags |= JITSymbolFlags::Lazy;
  203. }
  204. VSO::SymbolTableEntry::SymbolTableEntry(JITSymbolFlags Flags)
  205. : Flags(Flags), Address(0) {
  206. // We *don't* expect isMaterializing to be set here. That's for the VSO to do.
  207. assert(!Flags.isLazy() && "Initial flags include lazy?");
  208. assert(!Flags.isMaterializing() && "Initial flags include materializing");
  209. this->Flags |= JITSymbolFlags::Materializing;
  210. }
  211. VSO::SymbolTableEntry::SymbolTableEntry(JITEvaluatedSymbol Sym)
  212. : Flags(Sym.getFlags()), Address(Sym.getAddress()) {
  213. assert(!Flags.isLazy() && !Flags.isMaterializing() &&
  214. "This constructor is for final symbols only");
  215. }
  216. VSO::SymbolTableEntry::SymbolTableEntry(SymbolTableEntry &&Other)
  217. : Flags(Other.Flags), Address(0) {
  218. if (this->Flags.isLazy())
  219. UMII = std::move(Other.UMII);
  220. else
  221. Address = Other.Address;
  222. }
  223. VSO::SymbolTableEntry &VSO::SymbolTableEntry::
  224. operator=(SymbolTableEntry &&Other) {
  225. destroy();
  226. Flags = std::move(Other.Flags);
  227. if (Other.Flags.isLazy()) {
  228. UMII = std::move(Other.UMII);
  229. } else
  230. Address = Other.Address;
  231. return *this;
  232. }
  233. VSO::SymbolTableEntry::~SymbolTableEntry() { destroy(); }
  234. void VSO::SymbolTableEntry::replaceWith(VSO &V, SymbolStringPtr Name,
  235. JITEvaluatedSymbol Sym) {
  236. assert(!Flags.isMaterializing() &&
  237. "Attempting to replace definition during materialization?");
  238. if (Flags.isLazy()) {
  239. UMII->discard(V, Name);
  240. if (UMII->Symbols.empty())
  241. V.UnmaterializedInfos.erase(UMII);
  242. }
  243. destroy();
  244. Flags = Sym.getFlags();
  245. Address = Sym.getAddress();
  246. }
  247. void VSO::SymbolTableEntry::replaceWith(VSO &V, SymbolStringPtr Name,
  248. JITSymbolFlags NewFlags,
  249. UnmaterializedInfoIterator NewUMII) {
  250. assert(!Flags.isMaterializing() &&
  251. "Attempting to replace definition during materialization?");
  252. if (Flags.isLazy()) {
  253. UMII->discard(V, Name);
  254. if (UMII->Symbols.empty())
  255. V.UnmaterializedInfos.erase(UMII);
  256. }
  257. destroy();
  258. Flags = NewFlags;
  259. UMII = std::move(NewUMII);
  260. }
  261. void VSO::SymbolTableEntry::replaceMaterializing(VSO &V, SymbolStringPtr Name,
  262. JITSymbolFlags NewFlags) {
  263. assert(!NewFlags.isWeak() &&
  264. "Can't define a lazy symbol in materializing mode");
  265. assert(!NewFlags.isLazy() && !NewFlags.isMaterializing() &&
  266. "Flags should not be in lazy or materializing state");
  267. if (Flags.isLazy()) {
  268. UMII->discard(V, Name);
  269. if (UMII->Symbols.empty())
  270. V.UnmaterializedInfos.erase(UMII);
  271. }
  272. destroy();
  273. Flags = NewFlags;
  274. Flags |= JITSymbolFlags::Materializing;
  275. Address = 0;
  276. }
  277. void VSO::SymbolTableEntry::notifyMaterializing() {
  278. assert(Flags.isLazy() && "Can only start materializing from lazy state");
  279. UMII.~UnmaterializedInfoIterator();
  280. Flags &= ~JITSymbolFlags::Lazy;
  281. Flags |= JITSymbolFlags::Materializing;
  282. Address = 0;
  283. }
  284. void VSO::SymbolTableEntry::resolve(VSO &V, JITEvaluatedSymbol Sym) {
  285. assert(!Flags.isLazy() && Flags.isMaterializing() &&
  286. "Can only resolve in materializing state");
  287. Flags = Sym.getFlags();
  288. Flags |= JITSymbolFlags::Materializing;
  289. Address = Sym.getAddress();
  290. assert(Address != 0 && "Can not resolve to null");
  291. }
  292. void VSO::SymbolTableEntry::finalize() {
  293. assert(Address != 0 && "Cannot finalize with null address");
  294. assert(Flags.isMaterializing() && !Flags.isLazy() &&
  295. "Symbol should be in materializing state");
  296. Flags &= ~JITSymbolFlags::Materializing;
  297. }
  298. void VSO::SymbolTableEntry::destroy() {
  299. if (Flags.isLazy())
  300. UMII.~UnmaterializedInfoIterator();
  301. }
  302. VSO::RelativeLinkageStrength VSO::compareLinkage(Optional<JITSymbolFlags> Old,
  303. JITSymbolFlags New) {
  304. if (Old == None)
  305. return llvm::orc::VSO::NewDefinitionIsStronger;
  306. if (Old->isStrong()) {
  307. if (New.isStrong())
  308. return llvm::orc::VSO::DuplicateDefinition;
  309. else
  310. return llvm::orc::VSO::ExistingDefinitionIsStronger;
  311. } else {
  312. if (New.isStrong())
  313. return llvm::orc::VSO::NewDefinitionIsStronger;
  314. else
  315. return llvm::orc::VSO::ExistingDefinitionIsStronger;
  316. }
  317. }
  318. VSO::RelativeLinkageStrength
  319. VSO::compareLinkage(SymbolStringPtr Name, JITSymbolFlags NewFlags) const {
  320. auto I = Symbols.find(Name);
  321. return compareLinkage(
  322. I == Symbols.end() ? None : Optional<JITSymbolFlags>(I->second.Flags),
  323. NewFlags);
  324. }
  325. Error VSO::define(SymbolMap NewSymbols) {
  326. Error Err = Error::success();
  327. for (auto &KV : NewSymbols) {
  328. auto I = Symbols.find(KV.first);
  329. auto LinkageResult = compareLinkage(
  330. I == Symbols.end() ? None : Optional<JITSymbolFlags>(I->second.Flags),
  331. KV.second.getFlags());
  332. // Silently discard weaker definitions.
  333. if (LinkageResult == ExistingDefinitionIsStronger)
  334. continue;
  335. // Report duplicate definition errors.
  336. if (LinkageResult == DuplicateDefinition) {
  337. Err = joinErrors(std::move(Err),
  338. make_error<orc::DuplicateDefinition>(*KV.first));
  339. continue;
  340. }
  341. if (I != Symbols.end())
  342. I->second.replaceWith(*this, I->first, KV.second);
  343. else
  344. Symbols.insert(std::make_pair(KV.first, std::move(KV.second)));
  345. }
  346. return Err;
  347. }
  348. Error VSO::defineLazy(std::unique_ptr<MaterializationUnit> MU) {
  349. auto UMII = UnmaterializedInfos.insert(UnmaterializedInfos.end(),
  350. UnmaterializedInfo(std::move(MU)));
  351. Error Err = Error::success();
  352. for (auto &KV : UMII->Symbols) {
  353. auto I = Symbols.find(KV.first);
  354. assert((I == Symbols.end() ||
  355. !I->second.Flags.isMaterializing()) &&
  356. "Attempt to replace materializing symbol definition");
  357. auto LinkageResult = compareLinkage(
  358. I == Symbols.end() ? None : Optional<JITSymbolFlags>(I->second.Flags),
  359. KV.second);
  360. // Discard weaker definitions.
  361. if (LinkageResult == ExistingDefinitionIsStronger) {
  362. UMII->discard(*this, KV.first);
  363. continue;
  364. }
  365. // Report duplicate definition errors.
  366. if (LinkageResult == DuplicateDefinition) {
  367. Err = joinErrors(std::move(Err),
  368. make_error<orc::DuplicateDefinition>(*KV.first));
  369. // Duplicate definitions are discarded, so remove the duplicates from
  370. // materializer.
  371. UMII->discard(*this, KV.first);
  372. continue;
  373. }
  374. // Existing definition was weaker. Replace it.
  375. if (I != Symbols.end())
  376. I->second.replaceWith(*this, KV.first, KV.second, UMII);
  377. else
  378. Symbols.insert(
  379. std::make_pair(KV.first, SymbolTableEntry(KV.second, UMII)));
  380. }
  381. if (UMII->Symbols.empty())
  382. UnmaterializedInfos.erase(UMII);
  383. return Err;
  384. }
  385. SymbolNameSet VSO::lookupFlags(SymbolFlagsMap &Flags, SymbolNameSet Names) {
  386. for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) {
  387. auto Tmp = I++;
  388. auto SymI = Symbols.find(*Tmp);
  389. // If the symbol isn't in this dylib then just continue.
  390. if (SymI == Symbols.end())
  391. continue;
  392. Names.erase(Tmp);
  393. Flags[SymI->first] =
  394. JITSymbolFlags::stripTransientFlags(SymI->second.Flags);
  395. }
  396. return Names;
  397. }
  398. VSO::LookupResult VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Query,
  399. SymbolNameSet Names) {
  400. MaterializerList Materializers;
  401. for (SymbolNameSet::iterator I = Names.begin(), E = Names.end(); I != E;) {
  402. auto Tmp = I++;
  403. auto SymI = Symbols.find(*Tmp);
  404. // If the symbol isn't in this dylib then just continue.
  405. if (SymI == Symbols.end())
  406. continue;
  407. // The symbol is in the VSO. Erase it from Names and proceed.
  408. Names.erase(Tmp);
  409. // If this symbol has not been materialized yet grab its materializer,
  410. // move all of its sibling symbols to the materializing state, and
  411. // delete its unmaterialized info.
  412. if (SymI->second.Flags.isLazy()) {
  413. assert(SymI->second.UMII->MU &&
  414. "Lazy symbol has no materializer attached");
  415. auto MU = std::move(SymI->second.UMII->MU);
  416. auto SymbolFlags = std::move(SymI->second.UMII->Symbols);
  417. UnmaterializedInfos.erase(SymI->second.UMII);
  418. for (auto &KV : SymbolFlags) {
  419. auto SiblingI = Symbols.find(KV.first);
  420. MaterializingInfos.insert(
  421. std::make_pair(SiblingI->first, MaterializingInfo()));
  422. SiblingI->second.notifyMaterializing();
  423. }
  424. Materializers.push_back(Materializer(
  425. std::move(MU),
  426. MaterializationResponsibility(*this, std::move(SymbolFlags))));
  427. }
  428. // If this symbol already has a fully materialized value, just use it.
  429. if (!SymI->second.Flags.isMaterializing()) {
  430. Query->resolve(SymI->first, JITEvaluatedSymbol(SymI->second.Address,
  431. SymI->second.Flags));
  432. Query->finalizeSymbol();
  433. continue;
  434. }
  435. // If this symbol is materializing, then get (or create) its
  436. // MaterializingInfo struct and appaend the query.
  437. auto J = MaterializingInfos.find(SymI->first);
  438. assert(J != MaterializingInfos.end() && "Missing MaterializingInfo");
  439. if (SymI->second.Address) {
  440. auto Sym = JITEvaluatedSymbol(SymI->second.Address, SymI->second.Flags);
  441. Query->resolve(SymI->first, Sym);
  442. assert(J->second.PendingResolution.empty() &&
  443. "Queries still pending resolution on resolved symbol?");
  444. J->second.PendingFinalization.push_back(Query);
  445. } else {
  446. assert(J->second.PendingFinalization.empty() &&
  447. "Queries pendiing finalization on unresolved symbol?");
  448. J->second.PendingResolution.push_back(Query);
  449. }
  450. }
  451. return {std::move(Materializers), std::move(Names)};
  452. }
  453. void VSO::resolve(const SymbolMap &SymbolValues) {
  454. for (auto &KV : SymbolValues) {
  455. auto I = Symbols.find(KV.first);
  456. assert(I != Symbols.end() && "Resolving symbol not present in this dylib");
  457. I->second.resolve(*this, KV.second);
  458. auto J = MaterializingInfos.find(KV.first);
  459. if (J == MaterializingInfos.end())
  460. continue;
  461. assert(J->second.PendingFinalization.empty() &&
  462. "Queries already pending finalization?");
  463. for (auto &Q : J->second.PendingResolution)
  464. Q->resolve(KV.first, KV.second);
  465. J->second.PendingFinalization = std::move(J->second.PendingResolution);
  466. J->second.PendingResolution = MaterializingInfo::QueryList();
  467. }
  468. }
  469. void VSO::notifyMaterializationFailed(const SymbolNameSet &Names) {
  470. assert(!Names.empty() && "Failed to materialize empty set?");
  471. std::map<std::shared_ptr<AsynchronousSymbolQuery>, SymbolNameSet>
  472. ResolutionFailures;
  473. std::map<std::shared_ptr<AsynchronousSymbolQuery>, SymbolNameSet>
  474. FinalizationFailures;
  475. for (auto &S : Names) {
  476. auto I = Symbols.find(S);
  477. assert(I != Symbols.end() && "Symbol not present in this VSO");
  478. auto J = MaterializingInfos.find(S);
  479. if (J != MaterializingInfos.end()) {
  480. if (J->second.PendingFinalization.empty()) {
  481. for (auto &Q : J->second.PendingResolution)
  482. ResolutionFailures[Q].insert(S);
  483. } else {
  484. for (auto &Q : J->second.PendingFinalization)
  485. FinalizationFailures[Q].insert(S);
  486. }
  487. MaterializingInfos.erase(J);
  488. }
  489. Symbols.erase(I);
  490. }
  491. for (auto &KV : ResolutionFailures)
  492. KV.first->notifyMaterializationFailed(
  493. make_error<FailedToResolve>(std::move(KV.second)));
  494. for (auto &KV : FinalizationFailures)
  495. KV.first->notifyMaterializationFailed(
  496. make_error<FailedToFinalize>(std::move(KV.second)));
  497. }
  498. void VSO::finalize(const SymbolNameSet &SymbolsToFinalize) {
  499. for (auto &S : SymbolsToFinalize) {
  500. auto I = Symbols.find(S);
  501. assert(I != Symbols.end() && "Finalizing symbol not present in this dylib");
  502. auto J = MaterializingInfos.find(S);
  503. if (J != MaterializingInfos.end()) {
  504. assert(J->second.PendingResolution.empty() &&
  505. "Queries still pending resolution?");
  506. for (auto &Q : J->second.PendingFinalization)
  507. Q->finalizeSymbol();
  508. MaterializingInfos.erase(J);
  509. }
  510. I->second.finalize();
  511. }
  512. }
  513. Expected<SymbolMap> lookup(const std::vector<VSO *> &VSOs, SymbolNameSet Names,
  514. MaterializationDispatcher DispatchMaterialization) {
  515. #if LLVM_ENABLE_THREADS
  516. // In the threaded case we use promises to return the results.
  517. std::promise<SymbolMap> PromisedResult;
  518. std::mutex ErrMutex;
  519. Error ResolutionError = Error::success();
  520. std::promise<void> PromisedReady;
  521. Error ReadyError = Error::success();
  522. auto OnResolve = [&](Expected<SymbolMap> Result) {
  523. if (Result)
  524. PromisedResult.set_value(std::move(*Result));
  525. else {
  526. {
  527. ErrorAsOutParameter _(&ResolutionError);
  528. std::lock_guard<std::mutex> Lock(ErrMutex);
  529. ResolutionError = Result.takeError();
  530. }
  531. PromisedResult.set_value(SymbolMap());
  532. }
  533. };
  534. auto OnReady = [&](Error Err) {
  535. if (Err) {
  536. ErrorAsOutParameter _(&ReadyError);
  537. std::lock_guard<std::mutex> Lock(ErrMutex);
  538. ReadyError = std::move(Err);
  539. }
  540. PromisedReady.set_value();
  541. };
  542. #else
  543. SymbolMap Result;
  544. Error ResolutionError = Error::success();
  545. Error ReadyError = Error::success();
  546. auto OnResolve = [&](Expected<SymbolMap> R) {
  547. ErrorAsOutParameter _(&ResolutionError);
  548. if (R)
  549. Result = std::move(*R);
  550. else
  551. ResolutionError = R.takeError();
  552. };
  553. auto OnReady = [&](Error Err) {
  554. ErrorAsOutParameter _(&ReadyError);
  555. if (Err)
  556. ReadyError = std::move(Err);
  557. };
  558. #endif
  559. auto Query = std::make_shared<AsynchronousSymbolQuery>(
  560. Names, std::move(OnResolve), std::move(OnReady));
  561. SymbolNameSet UnresolvedSymbols(std::move(Names));
  562. for (auto *V : VSOs) {
  563. if (UnresolvedSymbols.empty())
  564. break;
  565. assert(V && "VSO pointers in VSOs list should be non-null");
  566. auto LR = V->lookup(Query, UnresolvedSymbols);
  567. UnresolvedSymbols = std::move(LR.UnresolvedSymbols);
  568. for (auto &M : LR.Materializers)
  569. DispatchMaterialization(std::move(M));
  570. }
  571. #if LLVM_ENABLE_THREADS
  572. auto ResultFuture = PromisedResult.get_future();
  573. auto Result = ResultFuture.get();
  574. {
  575. std::lock_guard<std::mutex> Lock(ErrMutex);
  576. if (ResolutionError) {
  577. // ReadyError will never be assigned. Consume the success value.
  578. cantFail(std::move(ReadyError));
  579. return std::move(ResolutionError);
  580. }
  581. }
  582. auto ReadyFuture = PromisedReady.get_future();
  583. ReadyFuture.get();
  584. {
  585. std::lock_guard<std::mutex> Lock(ErrMutex);
  586. if (ReadyError)
  587. return std::move(ReadyError);
  588. }
  589. return std::move(Result);
  590. #else
  591. if (ResolutionError) {
  592. // ReadyError will never be assigned. Consume the success value.
  593. cantFail(std::move(ReadyError));
  594. return std::move(ResolutionError);
  595. }
  596. if (ReadyError)
  597. return std::move(ReadyError);
  598. return Result;
  599. #endif
  600. }
  601. /// @brief Look up a symbol by searching a list of VSOs.
  602. Expected<JITEvaluatedSymbol>
  603. lookup(const std::vector<VSO *> VSOs, SymbolStringPtr Name,
  604. MaterializationDispatcher DispatchMaterialization) {
  605. SymbolNameSet Names({Name});
  606. if (auto ResultMap =
  607. lookup(VSOs, std::move(Names), std::move(DispatchMaterialization))) {
  608. assert(ResultMap->size() == 1 && "Unexpected number of results");
  609. assert(ResultMap->count(Name) && "Missing result for symbol");
  610. return ResultMap->begin()->second;
  611. } else
  612. return ResultMap.takeError();
  613. }
  614. void ExecutionSession::logErrorsToStdErr(Error Err) {
  615. logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: ");
  616. }
  617. } // End namespace orc.
  618. } // End namespace llvm.