Core.cpp 71 KB

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