Core.cpp 106 KB

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