LLVM: lib/ExecutionEngine/Orc/Core.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
12#include "llvm/Config/llvm-config.h"
18
19#include <condition_variable>
20#include
21#include
22
23#define DEBUG_TYPE "orc"
24
25namespace llvm {
26namespace orc {
27
37
40
41void MaterializationUnit::anchor() {}
42
44 assert((reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 &&
45 "JITDylib must be two byte aligned");
46 JD->Retain();
47 JDAndFlag.store(reinterpret_cast<uintptr_t>(JD.get()));
48}
49
54
58
62
63void ResourceTracker::makeDefunct() {
64 uintptr_t Val = JDAndFlag.load();
65 Val |= 0x1U;
66 JDAndFlag.store(Val);
67}
68
70
73
77
79 OS << "Resource tracker " << (void *)RT.get() << " became defunct";
80}
81
83 std::shared_ptr SSP,
84 std::shared_ptr Symbols)
86 assert(this->SSP && "String pool cannot be null");
87 assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
88
89
90
91 for (auto &[JD, Syms] : *this->Symbols)
92 JD->Retain();
93}
94
96 for (auto &[JD, Syms] : *Symbols)
97 JD->Release();
98}
99
103
105 OS << "Failed to materialize symbols: " << *Symbols;
106}
107
109 std::shared_ptr SSP, JITDylibSP JD,
111 std::string Explanation)
113 FailedSymbols(std::move(FailedSymbols)), BadDeps(std::move(BadDeps)),
114 Explanation(std::move(Explanation)) {}
115
119
121 OS << "In " << JD->getName() << ", failed to materialize " << FailedSymbols
122 << ", due to unsatisfied dependencies " << BadDeps;
123 if (!Explanation.empty())
124 OS << " (" << Explanation << ")";
125}
126
131 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
132}
133
137 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
138}
139
143
145 OS << "Symbols not found: " << Symbols;
146}
147
149 std::shared_ptr SSP, SymbolNameSet Symbols)
151 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
152}
153
157
159 OS << "Symbols could not be removed: " << Symbols;
160}
161
165
167 OS << "Missing definitions in module " << ModuleName
168 << ": " << Symbols;
169}
170
174
176 OS << "Unexpected definitions in module " << ModuleName
177 << ": " << Symbols;
178}
179
181 JD->getExecutionSession().lookup(
184 [OnComplete = std::move(OnComplete)
185#ifndef NDEBUG
186 ,
187 Name = this->Name
188#endif
191 assert(Result->size() == 1 && "Unexpected number of results");
193 "Result does not contain expected symbol");
194 OnComplete(Result->begin()->second);
195 } else
196 OnComplete(Result.takeError());
197 },
199}
200
204 : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
206 "Cannot query for a symbols that have not reached the resolve state "
207 "yet");
208
209 OutstandingSymbolsCount = Symbols.size();
210
211 for (auto &[Name, Flags] : Symbols)
213}
214
217 auto I = ResolvedSymbols.find(Name);
218 assert(I != ResolvedSymbols.end() &&
219 "Resolving symbol outside the requested set");
221 "Redundantly resolving symbol Name");
222
223
224
226 ResolvedSymbols.erase(I);
227 else
228 I->second = std::move(Sym);
229 --OutstandingSymbolsCount;
230}
231
232void AsynchronousSymbolQuery::handleComplete(ExecutionSession &ES) {
233 assert(OutstandingSymbolsCount == 0 &&
234 "Symbols remain, handleComplete called prematurely");
235
236 class RunQueryCompleteTask : public Task {
237 public:
238 RunQueryCompleteTask(SymbolMap ResolvedSymbols,
240 : ResolvedSymbols(std::move(ResolvedSymbols)),
241 NotifyComplete(std::move(NotifyComplete)) {}
242 void printDescription(raw_ostream &OS) override {
243 OS << "Execute query complete callback for " << ResolvedSymbols;
244 }
245 void run() override { NotifyComplete(std::move(ResolvedSymbols)); }
246
247 private:
250 };
251
252 auto T = std::make_unique(std::move(ResolvedSymbols),
253 std::move(NotifyComplete));
256}
257
258void AsynchronousSymbolQuery::handleFailed(Error Err) {
259 assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
260 OutstandingSymbolsCount == 0 &&
261 "Query should already have been abandoned");
262 NotifyComplete(std::move(Err));
264}
265
266void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
268 bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
269 (void)Added;
270 assert(Added && "Duplicate dependence notification?");
271}
272
273void AsynchronousSymbolQuery::removeQueryDependence(
275 auto QRI = QueryRegistrations.find(&JD);
276 assert(QRI != QueryRegistrations.end() &&
277 "No dependencies registered for JD");
278 assert(QRI->second.count(Name) && "No dependency on Name in JD");
279 QRI->second.erase(Name);
280 if (QRI->second.empty())
281 QueryRegistrations.erase(QRI);
282}
283
284void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) {
285 auto I = ResolvedSymbols.find(Name);
286 assert(I != ResolvedSymbols.end() &&
287 "Redundant removal of weakly-referenced symbol");
288 ResolvedSymbols.erase(I);
289 --OutstandingSymbolsCount;
290}
291
292void AsynchronousSymbolQuery::detach() {
293 ResolvedSymbols.clear();
294 OutstandingSymbolsCount = 0;
295 for (auto &[JD, Syms] : QueryRegistrations)
296 JD->detachQueryHelper(*this, Syms);
297 QueryRegistrations.clear();
298}
299
304 SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {}
305
307 return "";
308}
309
310void ReExportsMaterializationUnit::materialize(
311 std::unique_ptr R) {
312
313 auto &ES = R->getTargetJITDylib().getExecutionSession();
314 JITDylib &TgtJD = R->getTargetJITDylib();
315 JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
316
317
318
319
320 auto RequestedSymbols = R->getRequestedSymbols();
322
323 for (auto &Name : RequestedSymbols) {
324 auto I = Aliases.find(Name);
325 assert(I != Aliases.end() && "Symbol not found in aliases map?");
326 RequestedAliases[Name] = std::move(I->second);
328 }
329
332 dbgs() << "materializing reexports: target = " << TgtJD.getName()
333 << ", source = " << SrcJD.getName() << " " << RequestedAliases
334 << "\n";
335 });
336 });
337
338 if (!Aliases.empty()) {
339 auto Err = SourceJD ? R->replace(reexports(*SourceJD, std::move(Aliases),
340 SourceJDLookupFlags))
342
343 if (Err) {
344
345
347 R->failMaterialization();
348 return;
349 }
350 }
351
352
353
354 struct OnResolveInfo {
355 OnResolveInfo(std::unique_ptr R,
356 SymbolAliasMap Aliases)
357 : R(std::move(R)), Aliases(std::move(Aliases)) {}
358
359 std::unique_ptr R;
361 std::vector SDGs;
362 };
363
364
365
366
367
368
369
370
371
372 std::vector<std::pair<SymbolLookupSet, std::shared_ptr>>
373 QueryInfos;
374 while (!RequestedAliases.empty()) {
375 SymbolNameSet ResponsibilitySymbols;
376 SymbolLookupSet QuerySymbols;
377 SymbolAliasMap QueryAliases;
378
379
380 for (auto &KV : RequestedAliases) {
381
382 if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
383 RequestedAliases.count(KV.second.Aliasee)))
384 continue;
385
386 ResponsibilitySymbols.insert(KV.first);
387 QuerySymbols.add(KV.second.Aliasee,
388 KV.second.AliasFlags.hasMaterializationSideEffectsOnly()
389 ? SymbolLookupFlags::WeaklyReferencedSymbol
390 : SymbolLookupFlags::RequiredSymbol);
391 QueryAliases[KV.first] = std::move(KV.second);
392 }
393
394
395 for (auto &KV : QueryAliases)
396 RequestedAliases.erase(KV.first);
397
398 assert(!QuerySymbols.empty() && "Alias cycle detected!");
399
400 auto NewR = R->delegate(ResponsibilitySymbols);
401 if (!NewR) {
403 R->failMaterialization();
404 return;
405 }
406
407 auto QueryInfo = std::make_shared(std::move(*NewR),
408 std::move(QueryAliases));
409 QueryInfos.push_back(
410 make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
411 }
412
413
414 while (!QueryInfos.empty()) {
415 auto QuerySymbols = std::move(QueryInfos.back().first);
416 auto QueryInfo = std::move(QueryInfos.back().second);
417
418 QueryInfos.pop_back();
419
420 auto RegisterDependencies = [QueryInfo,
422
423 if (Deps.empty())
424 return;
425
426
427 assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
428 "Unexpected dependencies for reexports");
429
430 auto &SrcJDDeps = Deps.find(&SrcJD)->second;
431
432 for (auto &[Alias, AliasInfo] : QueryInfo->Aliases)
433 if (SrcJDDeps.count(AliasInfo.Aliasee))
434 QueryInfo->SDGs.push_back({{Alias}, {{&SrcJD, {AliasInfo.Aliasee}}}});
435 };
436
437 auto OnComplete = [QueryInfo](Expected Result) {
438 auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();
441 for (auto &KV : QueryInfo->Aliases) {
442 assert((KV.second.AliasFlags.hasMaterializationSideEffectsOnly() ||
443 Result->count(KV.second.Aliasee)) &&
444 "Result map missing entry?");
445
446 if (KV.second.AliasFlags.hasMaterializationSideEffectsOnly())
447 continue;
448
449 ResolutionMap[KV.first] = {(*Result)[KV.second.Aliasee].getAddress(),
450 KV.second.AliasFlags};
451 }
452 if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {
454 QueryInfo->R->failMaterialization();
455 return;
456 }
457 if (auto Err = QueryInfo->R->notifyEmitted(QueryInfo->SDGs)) {
459 QueryInfo->R->failMaterialization();
460 return;
461 }
462 } else {
464 QueryInfo->R->failMaterialization();
465 }
466 };
467
471 std::move(RegisterDependencies));
472 }
473}
474
475void ReExportsMaterializationUnit::discard(const JITDylib &JD,
476 const SymbolStringPtr &Name) {
477 assert(Aliases.count(Name) &&
478 "Symbol not covered by this MaterializationUnit");
479 Aliases.erase(Name);
480}
481
482MaterializationUnit::Interface
483ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
485 for (auto &KV : Aliases)
486 SymbolFlags[KV.first] = KV.second.AliasFlags;
487
488 return MaterializationUnit::Interface(std::move(SymbolFlags), nullptr);
489}
490
497
498 if (!Flags)
499 return Flags.takeError();
500
502 for (auto &Name : Symbols) {
503 assert(Flags->count(Name) && "Missing entry in flags map");
505 }
506
508}
509
511public:
512
513
514
522 virtual void complete(std::unique_ptr IPLS) = 0;
524
529
534
535 enum {
539 } GenState = NotInGenerator;
541};
542
544public:
550 OnComplete(std::move(OnComplete)) {}
551
552 void complete(std::unique_ptr IPLS) override {
553 auto &ES = SearchOrder.front().first->getExecutionSession();
554 ES.OL_completeLookupFlags(std::move(IPLS), std::move(OnComplete));
555 }
556
557 void fail(Error Err) override { OnComplete(std::move(Err)); }
558
559private:
561};
562
564public:
568 std::shared_ptr Q,
572 Q(std::move(Q)), RegisterDependencies(std::move(RegisterDependencies)) {
573 }
574
575 void complete(std::unique_ptr IPLS) override {
576 auto &ES = SearchOrder.front().first->getExecutionSession();
577 ES.OL_completeLookup(std::move(IPLS), std::move(Q),
578 std::move(RegisterDependencies));
579 }
580
582 Q->detach();
583 Q->handleFailed(std::move(Err));
584 }
585
586private:
587 std::shared_ptr Q;
589};
590
594 : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
595 Allow(std::move(Allow)) {}
596
601 assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
602
603
605 K, {{&SourceJD, JDLookupFlags}}, LookupSet);
606 if (!Flags)
607 return Flags.takeError();
608
609
611 for (auto &KV : *Flags)
612 if (!Allow || Allow(KV.first))
614
615 if (AliasMap.empty())
617
618
619 return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
620}
621
623 : IPLS(std::move(IPLS)) {}
624
625void LookupState::reset(InProgressLookupState *IPLS) { this->IPLS.reset(IPLS); }
626
631
633 assert(IPLS && "Cannot call continueLookup on empty LookupState");
634 auto &ES = IPLS->SearchOrder.begin()->first->getExecutionSession();
635 ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err));
636}
637
639 std::deque LookupsToFail;
640 {
641 std::lock_guardstd::mutex Lock(M);
642 std::swap(PendingLookups, LookupsToFail);
643 InUse = false;
644 }
645
646 for (auto &LS : LookupsToFail)
648 "Query waiting on DefinitionGenerator that was destroyed",
650}
651
655
657 std::vector TrackersToRemove;
658 ES.runSessionLocked([&]() {
659 assert(State != Closed && "JD is defunct");
660 for (auto &KV : TrackerSymbols)
661 TrackersToRemove.push_back(KV.first);
663 });
664
666 for (auto &RT : TrackersToRemove)
667 Err = joinErrors(std::move(Err), RT->remove());
668 return Err;
669}
670
672 return ES.runSessionLocked([this] {
673 assert(State != Closed && "JD is defunct");
674 if (!DefaultTracker)
676 return DefaultTracker;
677 });
678}
679
681 return ES.runSessionLocked([this] {
682 assert(State == Open && "JD is defunct");
684 return RT;
685 });
686}
687
689
690
691 std::shared_ptr TmpDG;
692
693 ES.runSessionLocked([&] {
694 assert(State == Open && "JD is defunct");
696 [&](const std::shared_ptr &H) {
698 });
699 assert(I != DefGenerators.end() && "Generator not found");
700 TmpDG = std::move(*I);
701 DefGenerators.erase(I);
702 });
703}
704
708
710 if (FromMR.RT->isDefunct())
712
713 std::vector AddedSyms;
714 std::vector RejectedWeakDefs;
715
716 for (auto &[Name, Flags] : SymbolFlags) {
717 auto EntryItr = Symbols.find(Name);
718
719
720 if (EntryItr != Symbols.end()) {
721
722
723 if (!Flags.isWeak()) {
724
725 for (auto &S : AddedSyms)
727
728
730 std::string(*Name), "defineMaterializing operation");
731 }
732
733
734 RejectedWeakDefs.push_back(NonOwningSymbolStringPtr(Name));
735 continue;
736 } else
737 EntryItr =
738 Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
739
740 AddedSyms.push_back(NonOwningSymbolStringPtr(Name));
742 }
743
744
745 while (!RejectedWeakDefs.empty()) {
747 RejectedWeakDefs.pop_back();
748 }
749
751 });
752}
753
755 std::unique_ptr MU) {
756 assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
757 std::unique_ptr MustRunMU;
758 std::unique_ptr MustRunMR;
759
760 auto Err =
761 ES.runSessionLocked([&, this]() -> Error {
762 if (FromMR.RT->isDefunct())
764
765#ifndef NDEBUG
766 for (auto &KV : MU->getSymbols()) {
767 auto SymI = Symbols.find(KV.first);
768 assert(SymI != Symbols.end() && "Replacing unknown symbol");
770 "Can not replace a symbol that ha is not materializing");
771 assert(!SymI->second.hasMaterializerAttached() &&
772 "Symbol should not have materializer attached already");
773 assert(UnmaterializedInfos.count(KV.first) == 0 &&
774 "Symbol being replaced should have no UnmaterializedInfo");
775 }
776#endif
777
778
779
780
781
782 for (auto &KV : MU->getSymbols()) {
783 auto MII = MaterializingInfos.find(KV.first);
784 if (MII != MaterializingInfos.end()) {
785 if (MII->second.hasQueriesPending()) {
786 MustRunMR = ES.createMaterializationResponsibility(
787 *FromMR.RT, std::move(MU->SymbolFlags),
788 std::move(MU->InitSymbol));
789 MustRunMU = std::move(MU);
791 }
792 }
793 }
794
795
796 auto UMI = std::make_shared(std::move(MU),
797 FromMR.RT.get());
798 for (auto &KV : UMI->MU->getSymbols()) {
799 auto SymI = Symbols.find(KV.first);
801 "Can not replace a symbol that is not materializing");
802 assert(!SymI->second.hasMaterializerAttached() &&
803 "Can not replace a symbol that has a materializer attached");
804 assert(UnmaterializedInfos.count(KV.first) == 0 &&
805 "Unexpected materializer entry in map");
806 SymI->second.setAddress(SymI->second.getAddress());
807 SymI->second.setMaterializerAttached(true);
808
809 auto &UMIEntry = UnmaterializedInfos[KV.first];
810 assert((!UMIEntry || !UMIEntry->MU) &&
811 "Replacing symbol with materializer still attached");
812 UMIEntry = UMI;
813 }
814
816 });
817
818 if (Err)
819 return Err;
820
821 if (MustRunMU) {
822 assert(MustRunMR && "MustRunMU set implies MustRunMR set");
823 ES.dispatchTask(std::make_unique(
824 std::move(MustRunMU), std::move(MustRunMR)));
825 } else {
826 assert(!MustRunMR && "MustRunMU unset implies MustRunMR unset");
827 }
828
830}
831
832Expected<std::unique_ptr>
835
836 return ES.runSessionLocked(
837 [&]() -> Expected<std::unique_ptr> {
838 if (FromMR.RT->isDefunct())
840
841 return ES.createMaterializationResponsibility(
842 *FromMR.RT, std::move(SymbolFlags), std::move(InitSymbol));
843 });
844}
845
847JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
848 return ES.runSessionLocked([&]() {
850
851 for (auto &KV : SymbolFlags) {
852 assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
853 assert(Symbols.find(KV.first)->second.getState() !=
856 "getRequestedSymbols can only be called for symbols that have "
857 "started materializing");
858 auto I = MaterializingInfos.find(KV.first);
859 if (I == MaterializingInfos.end())
860 continue;
861
862 if (I->second.hasQueriesPending())
863 RequestedSymbols.insert(KV.first);
864 }
865
866 return RequestedSymbols;
867 });
868}
869
872 AsynchronousSymbolQuerySet CompletedQueries;
873
874 if (auto Err = ES.runSessionLocked([&, this]() -> Error {
875 if (MR.RT->isDefunct())
876 return make_error(MR.RT);
877
878 if (State != Open)
879 return make_error("JITDylib " + getName() +
880 " is defunct",
881 inconvertibleErrorCode());
882
883 struct WorklistEntry {
884 SymbolTable::iterator SymI;
885 ExecutorSymbolDef ResolvedSym;
886 };
887
889 std::vector Worklist;
891
892
894
895 assert(!KV.second.getFlags().hasError() &&
896 "Resolution result can not have error flag set");
897
898 auto SymI = Symbols.find(KV.first);
899
900 assert(SymI != Symbols.end() && "Symbol not found");
901 assert(!SymI->second.hasMaterializerAttached() &&
902 "Resolving symbol with materializer attached?");
904 "Symbol should be materializing");
905 assert(SymI->second.getAddress() == ExecutorAddr() &&
906 "Symbol has already been resolved");
907
908 if (SymI->second.getFlags().hasError())
909 SymbolsInErrorState.insert(KV.first);
910 else {
912 [[maybe_unused]] auto WeakOrCommon =
914 assert((KV.second.getFlags() & WeakOrCommon) &&
915 "Common symbols must be resolved as common or weak");
916 assert((KV.second.getFlags() & ~WeakOrCommon) ==
918 "Resolving symbol with incorrect flags");
919
920 } else
921 assert(KV.second.getFlags() == SymI->second.getFlags() &&
922 "Resolved flags should match the declared flags");
923
924 Worklist.push_back(
925 {SymI, {KV.second.getAddress(), SymI->second.getFlags()}});
926 }
927 }
928
929
930 if (!SymbolsInErrorState.empty()) {
931 auto FailedSymbolsDepMap = std::make_shared();
932 (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
933 return make_error(
934 getExecutionSession().getSymbolStringPool(),
935 std::move(FailedSymbolsDepMap));
936 }
937
938 while (!Worklist.empty()) {
939 auto SymI = Worklist.back().SymI;
940 auto ResolvedSym = Worklist.back().ResolvedSym;
941 Worklist.pop_back();
942
943 auto &Name = SymI->first;
944
945
946 JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
947 SymI->second.setAddress(ResolvedSym.getAddress());
948 SymI->second.setFlags(ResolvedFlags);
949 SymI->second.setState(SymbolState::Resolved);
950
951 auto MII = MaterializingInfos.find(Name);
952 if (MII == MaterializingInfos.end())
953 continue;
954
955 auto &MI = MII->second;
956 for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
957 Q->notifySymbolMetRequiredState(Name, ResolvedSym);
958 if (Q->isComplete())
959 CompletedQueries.insert(std::move(Q));
960 }
961 }
962
964 }))
965 return Err;
966
967
968 for (auto &Q : CompletedQueries) {
969 assert(Q->isComplete() && "Q not completed");
970 Q->handleComplete(ES);
971 }
972
974}
975
976void JITDylib::unlinkMaterializationResponsibility(
977 MaterializationResponsibility &MR) {
979 auto I = TrackerMRs.find(MR.RT.get());
980 assert(I != TrackerMRs.end() && "No MRs in TrackerMRs list for RT");
981 assert(I->second.count(&MR) && "MR not in TrackerMRs list for RT");
982 I->second.erase(&MR);
983 if (I->second.empty())
984 TrackerMRs.erase(MR.RT.get());
985 });
986}
987
988void JITDylib::shrinkMaterializationInfoMemory() {
989
990
991
992 if (UnmaterializedInfos.empty())
993 UnmaterializedInfos.clear();
994
995 if (MaterializingInfos.empty())
996 MaterializingInfos.clear();
997}
998
1000 bool LinkAgainstThisJITDylibFirst) {
1001 ES.runSessionLocked([&]() {
1002 assert(State == Open && "JD is defunct");
1003 if (LinkAgainstThisJITDylibFirst) {
1004 LinkOrder.clear();
1005 if (NewLinkOrder.empty() || NewLinkOrder.front().first != this)
1006 LinkOrder.push_back(
1009 } else
1010 LinkOrder = std::move(NewLinkOrder);
1011 });
1012}
1013
1015 ES.runSessionLocked([&]() {
1016 for (auto &KV : NewLinks) {
1017
1019 continue;
1020
1021 LinkOrder.push_back(std::move(KV));
1022 }
1023 });
1024}
1025
1027 ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });
1028}
1029
1032 ES.runSessionLocked([&]() {
1033 assert(State == Open && "JD is defunct");
1034 for (auto &KV : LinkOrder)
1035 if (KV.first == &OldJD) {
1036 KV = {&NewJD, JDLookupFlags};
1037 break;
1038 }
1039 });
1040}
1041
1043 ES.runSessionLocked([&]() {
1044 assert(State == Open && "JD is defunct");
1046 [&](const JITDylibSearchOrder::value_type &KV) {
1047 return KV.first == &JD;
1048 });
1049 if (I != LinkOrder.end())
1050 LinkOrder.erase(I);
1051 });
1052}
1053
1055 return ES.runSessionLocked([&]() -> Error {
1056 assert(State == Open && "JD is defunct");
1057 using SymbolMaterializerItrPair =
1058 std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1059 std::vector SymbolsToRemove;
1062
1063 for (auto &Name : Names) {
1064 auto I = Symbols.find(Name);
1065
1066
1067 if (I == Symbols.end()) {
1068 Missing.insert(Name);
1069 continue;
1070 }
1071
1072
1076 continue;
1077 }
1078
1079 auto UMII = I->second.hasMaterializerAttached()
1080 ? UnmaterializedInfos.find(Name)
1081 : UnmaterializedInfos.end();
1082 SymbolsToRemove.push_back(std::make_pair(I, UMII));
1083 }
1084
1085
1086 if (!Missing.empty())
1088 std::move(Missing));
1089
1090
1094
1095
1096 for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1097 auto UMII = SymbolMaterializerItrPair.second;
1098
1099
1100 if (UMII != UnmaterializedInfos.end()) {
1101 UMII->second->MU->doDiscard(*this, UMII->first);
1102 UnmaterializedInfos.erase(UMII);
1103 }
1104
1105 auto SymI = SymbolMaterializerItrPair.first;
1106 Symbols.erase(SymI);
1107 }
1108
1109 shrinkMaterializationInfoMemory();
1110
1112 });
1113}
1114
1116 ES.runSessionLocked([&, this]() {
1117 OS << "JITDylib \"" << getName() << "\" (ES: "
1118 << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES))
1119 << ", State = ";
1120 switch (State) {
1121 case Open:
1122 OS << "Open";
1123 break;
1124 case Closing:
1125 OS << "Closing";
1126 break;
1127 case Closed:
1128 OS << "Closed";
1129 break;
1130 }
1131 OS << ")\n";
1132 if (State == Closed)
1133 return;
1134 OS << "Link order: " << LinkOrder << "\n"
1135 << "Symbol table:\n";
1136
1137
1138 std::vector<std::pair<SymbolStringPtr, SymbolTableEntry *>> SymbolsSorted;
1139 for (auto &KV : Symbols)
1140 SymbolsSorted.emplace_back(KV.first, &KV.second);
1141 std::sort(SymbolsSorted.begin(), SymbolsSorted.end(),
1142 [](const auto &L, const auto &R) { return *L.first < *R.first; });
1143
1144 for (auto &KV : SymbolsSorted) {
1145 OS << " \"" << *KV.first << "\": ";
1146 if (auto Addr = KV.second->getAddress())
1147 OS << Addr;
1148 else
1149 OS << " ";
1150
1151 OS << " " << KV.second->getFlags() << " " << KV.second->getState();
1152
1153 if (KV.second->hasMaterializerAttached()) {
1154 OS << " (Materializer ";
1155 auto I = UnmaterializedInfos.find(KV.first);
1156 assert(I != UnmaterializedInfos.end() &&
1157 "Lazy symbol should have UnmaterializedInfo");
1158 OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";
1159 } else
1160 OS << "\n";
1161 }
1162
1163 if (!MaterializingInfos.empty())
1164 OS << " MaterializingInfos entries:\n";
1165 for (auto &KV : MaterializingInfos) {
1166 OS << " \"" << *KV.first << "\":\n"
1167 << " " << KV.second.pendingQueries().size()
1168 << " pending queries: { ";
1169 for (const auto &Q : KV.second.pendingQueries())
1170 OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1171 OS << "}\n";
1172 }
1173 });
1174}
1175
1176void JITDylib::MaterializingInfo::addQuery(
1177 std::shared_ptr Q) {
1178
1180 llvm::reverse(PendingQueries), Q->getRequiredState(),
1181 [](const std::shared_ptr &V, SymbolState S) {
1182 return V->getRequiredState() <= S;
1183 });
1184 PendingQueries.insert(I.base(), std::move(Q));
1185}
1186
1187void JITDylib::MaterializingInfo::removeQuery(
1188 const AsynchronousSymbolQuery &Q) {
1189
1191 PendingQueries, [&Q](const std::shared_ptr &V) {
1192 return V.get() == &Q;
1193 });
1194 if (I != PendingQueries.end())
1195 PendingQueries.erase(I);
1196}
1197
1198JITDylib::AsynchronousSymbolQueryList
1199JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1200 AsynchronousSymbolQueryList Result;
1201 while (!PendingQueries.empty()) {
1202 if (PendingQueries.back()->getRequiredState() > RequiredState)
1203 break;
1204
1205 Result.push_back(std::move(PendingQueries.back()));
1206 PendingQueries.pop_back();
1207 }
1208
1210}
1211
1212JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1213 : JITLinkDylib(std::move(Name)), ES(ES) {
1215}
1216
1217JITDylib::RemoveTrackerResult JITDylib::IL_removeTracker(ResourceTracker &RT) {
1218
1219 assert(State != Closed && "JD is defunct");
1220
1223
1224 if (&RT == DefaultTracker.get()) {
1226 for (auto &KV : TrackerSymbols)
1228
1229 for (auto &KV : Symbols) {
1230 auto &Sym = KV.first;
1231 if (!TrackedSymbols.count(Sym))
1232 SymbolsToRemove.push_back(Sym);
1233 }
1234
1235 DefaultTracker.reset();
1236 } else {
1237
1238 auto I = TrackerSymbols.find(&RT);
1239 if (I != TrackerSymbols.end()) {
1240 SymbolsToRemove = std::move(I->second);
1241 TrackerSymbols.erase(I);
1242 }
1243
1244 }
1245
1246 for (auto &Sym : SymbolsToRemove) {
1247 assert(Symbols.count(Sym) && "Symbol not in symbol table");
1248
1249
1250 auto MII = MaterializingInfos.find(Sym);
1251 if (MII != MaterializingInfos.end())
1252 SymbolsToFail.push_back(Sym);
1253 }
1254
1255 auto [QueriesToFail, FailedSymbols] =
1256 ES.IL_failSymbols(*this, std::move(SymbolsToFail));
1257
1258 std::vector<std::unique_ptr> DefunctMUs;
1259
1260
1261 for (auto &Sym : SymbolsToRemove) {
1262 auto I = Symbols.find(Sym);
1263 assert(I != Symbols.end() && "Symbol not present in table");
1264
1265
1266 if (I->second.hasMaterializerAttached()) {
1267
1268 auto J = UnmaterializedInfos.find(Sym);
1269 assert(J != UnmaterializedInfos.end() &&
1270 "Symbol table indicates MU present, but no UMI record");
1271 if (J->second->MU)
1272 DefunctMUs.push_back(std::move(J->second->MU));
1273 UnmaterializedInfos.erase(J);
1274 } else {
1275 assert(!UnmaterializedInfos.count(Sym) &&
1276 "Symbol has materializer attached");
1277 }
1278
1279 Symbols.erase(I);
1280 }
1281
1282 shrinkMaterializationInfoMemory();
1283
1284 return {std::move(QueriesToFail), std::move(FailedSymbols),
1285 std::move(DefunctMUs)};
1286}
1287
1289 assert(State != Closed && "JD is defunct");
1290 assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker");
1291 assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib");
1292 assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib");
1293
1294
1295 for (auto &KV : UnmaterializedInfos) {
1296 if (KV.second->RT == &SrcRT)
1297 KV.second->RT = &DstRT;
1298 }
1299
1300
1301 {
1302 auto I = TrackerMRs.find(&SrcRT);
1303 if (I != TrackerMRs.end()) {
1304 auto &SrcMRs = I->second;
1305 auto &DstMRs = TrackerMRs[&DstRT];
1306 for (auto *MR : SrcMRs)
1307 MR->RT = &DstRT;
1308 if (DstMRs.empty())
1309 DstMRs = std::move(SrcMRs);
1310 else
1311 DstMRs.insert_range(SrcMRs);
1312
1313
1314 TrackerMRs.erase(&SrcRT);
1315 }
1316 }
1317
1318
1319
1320 if (&DstRT == DefaultTracker.get()) {
1321 TrackerSymbols.erase(&SrcRT);
1322 return;
1323 }
1324
1325
1326
1327 if (&SrcRT == DefaultTracker.get()) {
1328 assert(!TrackerSymbols.count(&SrcRT) &&
1329 "Default tracker should not appear in TrackerSymbols");
1330
1332
1334 for (auto &KV : TrackerSymbols)
1335 CurrentlyTrackedSymbols.insert_range(KV.second);
1336
1337 for (auto &KV : Symbols) {
1338 auto &Sym = KV.first;
1339 if (!CurrentlyTrackedSymbols.count(Sym))
1340 SymbolsToTrack.push_back(Sym);
1341 }
1342
1343 TrackerSymbols[&DstRT] = std::move(SymbolsToTrack);
1344 return;
1345 }
1346
1347 auto &DstTrackedSymbols = TrackerSymbols[&DstRT];
1348
1349
1350
1351 auto SI = TrackerSymbols.find(&SrcRT);
1352 if (SI == TrackerSymbols.end())
1353 return;
1354
1355 DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size());
1356 for (auto &Sym : SI->second)
1357 DstTrackedSymbols.push_back(std::move(Sym));
1358 TrackerSymbols.erase(SI);
1359}
1360
1362 LLVM_DEBUG({ dbgs() << " " << MU.getSymbols() << "\n"; });
1363
1365 std::vector ExistingDefsOverridden;
1366 std::vector MUDefsOverridden;
1367
1368 for (const auto &KV : MU.getSymbols()) {
1369 auto I = Symbols.find(KV.first);
1370
1371 if (I != Symbols.end()) {
1372 if (KV.second.isStrong()) {
1373 if (I->second.getFlags().isStrong() ||
1375 Duplicates.insert(KV.first);
1376 else {
1378 "Overridden existing def should be in the never-searched "
1379 "state");
1380 ExistingDefsOverridden.push_back(KV.first);
1381 }
1382 } else
1383 MUDefsOverridden.push_back(KV.first);
1384 }
1385 }
1386
1387
1388 if (!Duplicates.empty()) {
1390 { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; });
1392 MU.getName().str());
1393 }
1394
1395
1397 if (!MUDefsOverridden.empty())
1398 dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n";
1399 });
1400 for (auto &S : MUDefsOverridden)
1401 MU.doDiscard(*this, S);
1402
1403
1405 if (!ExistingDefsOverridden.empty())
1406 dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden
1407 << "\n";
1408 });
1409 for (auto &S : ExistingDefsOverridden) {
1410
1411 auto UMII = UnmaterializedInfos.find(S);
1412 assert(UMII != UnmaterializedInfos.end() &&
1413 "Overridden existing def should have an UnmaterializedInfo");
1414 UMII->second->MU->doDiscard(*this, S);
1415 }
1416
1417
1418 for (auto &KV : MU.getSymbols()) {
1419 auto &SymEntry = Symbols[KV.first];
1420 SymEntry.setFlags(KV.second);
1422 SymEntry.setMaterializerAttached(true);
1423 }
1424
1426}
1427
1428void JITDylib::installMaterializationUnit(
1429 std::unique_ptr MU, ResourceTracker &RT) {
1430
1431
1432 if (&RT != DefaultTracker.get()) {
1433 auto &TS = TrackerSymbols[&RT];
1434 TS.reserve(TS.size() + MU->getSymbols().size());
1435 for (auto &KV : MU->getSymbols())
1436 TS.push_back(KV.first);
1437 }
1438
1439 auto UMI = std::make_shared(std::move(MU), &RT);
1440 for (auto &KV : UMI->MU->getSymbols())
1441 UnmaterializedInfos[KV.first] = UMI;
1442}
1443
1446 for (auto &QuerySymbol : QuerySymbols) {
1447 auto MII = MaterializingInfos.find(QuerySymbol);
1448 if (MII != MaterializingInfos.end())
1449 MII->second.removeQuery(Q);
1450 }
1451}
1452
1454
1458
1461 std::mutex LookupMutex;
1462 std::condition_variable CV;
1464
1466 dbgs() << "Issuing init-symbol lookup:\n";
1467 for (auto &KV : InitSyms)
1468 dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
1469 });
1470
1471 for (auto &KV : InitSyms) {
1472 auto *JD = KV.first;
1473 auto Names = std::move(KV.second);
1479 {
1480 std::lock_guardstd::mutex Lock(LookupMutex);
1484 "Duplicate JITDylib in lookup?");
1485 CompoundResult[JD] = std::move(*Result);
1486 } else
1487 CompoundErr =
1489 }
1490 CV.notify_one();
1491 },
1493 }
1494
1495 std::unique_lockstd::mutex Lock(LookupMutex);
1496 CV.wait(Lock, [&] { return Count == 0; });
1497
1498 if (CompoundErr)
1499 return std::move(CompoundErr);
1500
1501 return std::move(CompoundResult);
1502}
1503
1507
1508 class TriggerOnComplete {
1509 public:
1511 TriggerOnComplete(OnCompleteFn OnComplete)
1512 : OnComplete(std::move(OnComplete)) {}
1513 ~TriggerOnComplete() { OnComplete(std::move(LookupResult)); }
1514 void reportResult(Error Err) {
1515 std::lock_guardstd::mutex Lock(ResultMutex);
1516 LookupResult = joinErrors(std::move(LookupResult), std::move(Err));
1517 }
1518
1519 private:
1520 std::mutex ResultMutex;
1522 OnCompleteFn OnComplete;
1523 };
1524
1526 dbgs() << "Issuing init-symbol lookup:\n";
1527 for (auto &KV : InitSyms)
1528 dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
1529 });
1530
1531 auto TOC = std::make_shared(std::move(OnComplete));
1532
1533 for (auto &KV : InitSyms) {
1534 auto *JD = KV.first;
1535 auto Names = std::move(KV.second);
1541 TOC->reportResult(Result.takeError());
1542 },
1544 }
1545}
1546
1548
1549 if (MR)
1550 MR->failMaterialization();
1551}
1552
1554 OS << "Materialization task: " << MU->getName() << " in "
1555 << MR->getTargetJITDylib().getName();
1556}
1557
1559 assert(MU && "MU should not be null");
1560 assert(MR && "MR should not be null");
1561 MU->materialize(std::move(MR));
1562}
1563
1565
1567
1570
1571 this->EPC->ES = this;
1572}
1573
1575
1576 assert(!SessionOpen &&
1577 "Session still open. Did you forget to call endSession?");
1578}
1579
1581 LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
1582
1584
1585#ifdef EXPENSIVE_CHECKS
1586 verifySessionState("Entering ExecutionSession::endSession");
1587#endif
1588
1589 SessionOpen = false;
1590 return JDs;
1591 });
1592
1593 std::reverse(JDsToRemove.begin(), JDsToRemove.end());
1594
1596
1597 Err = joinErrors(std::move(Err), EPC->disconnect());
1598
1599 return Err;
1600}
1601
1605
1608 assert(!ResourceManagers.empty() && "No managers registered");
1609 if (ResourceManagers.back() == &RM)
1610 ResourceManagers.pop_back();
1611 else {
1612 auto I = llvm::find(ResourceManagers, &RM);
1613 assert(I != ResourceManagers.end() && "RM not registered");
1614 ResourceManagers.erase(I);
1615 }
1616 });
1617}
1618
1621 for (auto &JD : JDs)
1622 if (JD->getName() == Name)
1623 return JD.get();
1624 return nullptr;
1625 });
1626}
1627
1631 assert(SessionOpen && "Cannot create JITDylib after session is closed");
1632 JDs.push_back(new JITDylib(*this, std::move(Name)));
1633 return *JDs.back();
1634 });
1635}
1636
1639 if (P)
1640 if (auto Err = P->setupJITDylib(JD))
1641 return std::move(Err);
1642 return JD;
1643}
1644
1646
1648 for (auto &JD : JDsToRemove) {
1649 assert(JD->State == JITDylib::Open && "JD already closed");
1650 JD->State = JITDylib::Closing;
1652 assert(I != JDs.end() && "JD does not appear in session JDs");
1653 JDs.erase(I);
1654 }
1655 });
1656
1657
1659 for (auto JD : JDsToRemove) {
1660 Err = joinErrors(std::move(Err), JD->clear());
1661 if (P)
1662 Err = joinErrors(std::move(Err), P->teardownJITDylib(*JD));
1663 }
1664
1665
1667 for (auto &JD : JDsToRemove) {
1668 assert(JD->State == JITDylib::Closing && "JD should be closing");
1669 JD->State = JITDylib::Closed;
1670 assert(JD->Symbols.empty() && "JD.Symbols is not empty after clear");
1671 assert(JD->UnmaterializedInfos.empty() &&
1672 "JD.UnmaterializedInfos is not empty after clear");
1673 assert(JD->MaterializingInfos.empty() &&
1674 "JD.MaterializingInfos is not empty after clear");
1675 assert(JD->TrackerSymbols.empty() &&
1676 "TrackerSymbols is not empty after clear");
1677 JD->DefGenerators.clear();
1678 JD->LinkOrder.clear();
1679 }
1680 });
1681
1682 return Err;
1683}
1684
1687 if (JDs.empty())
1688 return std::vector();
1689
1690 auto &ES = JDs.front()->getExecutionSession();
1691 return ES.runSessionLocked([&]() -> Expected<std::vector> {
1693 std::vector Result;
1694
1695 for (auto &JD : JDs) {
1696
1697 if (JD->State != Open)
1699 "Error building link order: " + JD->getName() + " is defunct",
1701 if (Visited.count(JD.get()))
1702 continue;
1703
1706 Visited.insert(JD.get());
1707
1708 while (!WorkStack.empty()) {
1709 Result.push_back(std::move(WorkStack.back()));
1711
1713 auto &JD = *KV.first;
1714 if (!Visited.insert(&JD).second)
1715 continue;
1717 }
1718 }
1719 }
1721 });
1722}
1723
1731
1735
1739
1743
1744 OL_applyQueryPhase1(std::make_unique(
1745 K, std::move(SearchOrder), std::move(LookupSet),
1746 std::move(OnComplete)),
1748}
1749
1753
1754 std::promise<MSVCPExpected> ResultP;
1755 OL_applyQueryPhase1(std::make_unique(
1756 K, std::move(SearchOrder), std::move(LookupSet),
1758 ResultP.set_value(std::move(Result));
1759 }),
1761
1762 auto ResultF = ResultP.get_future();
1763 return ResultF.get();
1764}
1765
1771
1774 dbgs() << "Looking up " << Symbols << " in " << SearchOrder
1775 << " (required state: " << RequiredState << ")\n";
1776 });
1777 });
1778
1779
1780
1781
1782 dispatchOutstandingMUs();
1783
1784 auto Unresolved = std::move(Symbols);
1785 auto Q = std::make_shared(Unresolved, RequiredState,
1786 std::move(NotifyComplete));
1787
1788 auto IPLS = std::make_unique(
1789 K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q),
1790 std::move(RegisterDependencies));
1791
1792 OL_applyQueryPhase1(std::move(IPLS), Error::success());
1793}
1794
1800#if LLVM_ENABLE_THREADS
1801
1802 std::promise<MSVCPExpected> PromisedResult;
1803
1805 PromisedResult.set_value(std::move(R));
1806 };
1807
1808#else
1811
1814 if (R)
1815 Result = std::move(*R);
1816 else
1817 ResolutionError = R.takeError();
1818 };
1819#endif
1820
1821
1822 lookup(K, SearchOrder, std::move(Symbols), RequiredState,
1823 std::move(NotifyComplete), RegisterDependencies);
1824
1825#if LLVM_ENABLE_THREADS
1826 return PromisedResult.get_future().get();
1827#else
1828 if (ResolutionError)
1829 return std::move(ResolutionError);
1830
1832#endif
1833}
1834
1839
1842 assert(ResultMap->size() == 1 && "Unexpected number of results");
1843 assert(ResultMap->count(Name) && "Missing result for symbol");
1844 return std::move(ResultMap->begin()->second);
1845 } else
1846 return ResultMap.takeError();
1847}
1848
1854
1858 return lookup(SearchOrder, intern(Name), RequiredState);
1859}
1860
1863
1867 if (!TagSyms)
1868 return TagSyms.takeError();
1869
1870
1871 std::lock_guardstd::mutex Lock(JITDispatchHandlersMutex);
1872
1873
1874 for (auto &[TagName, TagSym] : *TagSyms) {
1875 auto TagAddr = TagSym.getAddress();
1876 if (JITDispatchHandlers.count(TagAddr))
1878 " (for " + *TagName +
1879 ") already registered",
1881 }
1882
1883
1884 for (auto &[TagName, TagSym] : *TagSyms) {
1885 auto TagAddr = TagSym.getAddress();
1886 auto I = WFs.find(TagName);
1888 "JITDispatchHandler implementation missing");
1889 JITDispatchHandlers[TagAddr] =
1890 std::make_shared(std::move(I->second));
1892 dbgs() << "Associated function tag \"" << *TagName << "\" ("
1893 << formatv("{0:x}", TagAddr) << ") with handler\n";
1894 });
1895 }
1896
1898}
1899
1903
1904 std::shared_ptr F;
1905 {
1906 std::lock_guardstd::mutex Lock(JITDispatchHandlersMutex);
1907 auto I = JITDispatchHandlers.find(HandlerFnTagAddr);
1908 if (I != JITDispatchHandlers.end())
1910 }
1911
1912 if (F)
1913 (*F)(std::move(SendResult), ArgBuffer.data(), ArgBuffer.size());
1914 else
1916 ("No function registered for tag " +
1917 formatv("{0:x16}", HandlerFnTagAddr))
1918 .str()));
1919}
1920
1923 for (auto &JD : JDs)
1924 JD->dump(OS);
1925 });
1926}
1927
1928#ifdef EXPENSIVE_CHECKS
1929bool ExecutionSession::verifySessionState(Twine Phase) {
1931 bool AllOk = true;
1932
1933 for (auto &JD : JDs) {
1934
1936 auto &Stream = errs();
1937 if (AllOk)
1938 Stream << "ERROR: Bad ExecutionSession state detected " << Phase
1939 << "\n";
1940 Stream << " In JITDylib " << JD->getName() << ", ";
1941 AllOk = false;
1942 return Stream;
1943 };
1944
1945 if (JD->State != JITDylib::Open) {
1946 LogFailure()
1947 << "state is not Open, but JD is in ExecutionSession list.";
1948 }
1949
1950
1951
1952
1953
1954
1955 for (auto &[Sym, Entry] : JD->Symbols) {
1956
1958 if (Entry.getAddress()) {
1959 LogFailure() << "symbol " << Sym << " has state "
1960 << Entry.getState()
1961 << " (not-yet-resolved) but non-null address "
1962 << Entry.getAddress() << ".\n";
1963 }
1964 }
1965
1966
1967 auto UMIItr = JD->UnmaterializedInfos.find(Sym);
1968 if (Entry.hasMaterializerAttached()) {
1969 if (UMIItr == JD->UnmaterializedInfos.end()) {
1970 LogFailure() << "symbol " << Sym
1971 << " entry claims materializer attached, but "
1972 "UnmaterializedInfos has no corresponding entry.\n";
1973 }
1974 } else if (UMIItr != JD->UnmaterializedInfos.end()) {
1975 LogFailure()
1976 << "symbol " << Sym
1977 << " entry claims no materializer attached, but "
1978 "UnmaterializedInfos has an unexpected entry for it.\n";
1979 }
1980 }
1981
1982
1983
1984 for (auto &[Sym, UMI] : JD->UnmaterializedInfos) {
1985 auto SymItr = JD->Symbols.find(Sym);
1986 if (SymItr == JD->Symbols.end()) {
1987 LogFailure()
1988 << "symbol " << Sym
1989 << " has UnmaterializedInfos entry, but no Symbols entry.\n";
1990 }
1991 }
1992
1993
1994 for (auto &[Sym, MII] : JD->MaterializingInfos) {
1995
1996 auto SymItr = JD->Symbols.find(Sym);
1997 if (SymItr == JD->Symbols.end()) {
1998
1999
2000 LogFailure()
2001 << "symbol " << Sym
2002 << " has MaterializingInfos entry, but no Symbols entry.\n";
2003 } else {
2004
2005
2006
2008 LogFailure()
2009 << "symbol " << Sym
2010 << " is in Ready state, should not have MaterializingInfo.\n";
2011 }
2012
2013
2014 auto CurState = static_cast<SymbolState>(
2015 static_cast<std::underlying_type_t>(
2016 SymItr->second.getState()) + 1);
2017 for (auto &Q : MII.PendingQueries) {
2018 if (Q->getRequiredState() != CurState) {
2019 if (Q->getRequiredState() > CurState)
2020 CurState = Q->getRequiredState();
2021 else
2022 LogFailure() << "symbol " << Sym
2023 << " has stale or misordered queries.\n";
2024 }
2025 }
2026 }
2027 }
2028 }
2029
2030 return AllOk;
2031 });
2032}
2033#endif
2034
2035void ExecutionSession::dispatchOutstandingMUs() {
2036 LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n");
2037 while (true) {
2038 std::optional<std::pair<std::unique_ptr,
2039 std::unique_ptr>>
2040 JMU;
2041
2042 {
2043 std::lock_guardstd::recursive\_mutex Lock(OutstandingMUsMutex);
2044 if (!OutstandingMUs.empty()) {
2045 JMU.emplace(std::move(OutstandingMUs.back()));
2046 OutstandingMUs.pop_back();
2047 }
2048 }
2049
2050 if (!JMU)
2051 break;
2052
2053 assert(JMU->first && "No MU?");
2054 LLVM_DEBUG(dbgs() << " Dispatching \"" << JMU->first->getName() << "\"\n");
2055 dispatchTask(std::make_unique(std::move(JMU->first),
2056 std::move(JMU->second)));
2057 }
2058 LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n");
2059}
2060
2063 dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "
2064 << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2065 });
2066 std::vector<ResourceManager *> CurrentResourceManagers;
2067
2068 JITDylib::RemoveTrackerResult R;
2069
2071 CurrentResourceManagers = ResourceManagers;
2072 RT.makeDefunct();
2073 R = RT.getJITDylib().IL_removeTracker(RT);
2074 });
2075
2076
2077 R.DefunctMUs.clear();
2078
2080
2081 auto &JD = RT.getJITDylib();
2082 for (auto *L : reverse(CurrentResourceManagers))
2084 L->handleRemoveResources(JD, RT.getKeyUnsafe()));
2085
2086 for (auto &Q : R.QueriesToFail)
2088 R.FailedSymbols));
2089
2090 return Err;
2091}
2092
2093void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,
2096 dbgs() << "In " << SrcRT.getJITDylib().getName()
2097 << " transfering resources from tracker "
2098 << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "
2099 << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";
2100 });
2101
2102
2103 if (&DstRT == &SrcRT)
2104 return;
2105
2106 assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&
2107 "Can't transfer resources between JITDylibs");
2109 SrcRT.makeDefunct();
2110 auto &JD = DstRT.getJITDylib();
2111 JD.transferTracker(DstRT, SrcRT);
2112 for (auto *L : reverse(ResourceManagers))
2113 L->handleTransferResources(JD, DstRT.getKeyUnsafe(),
2114 SrcRT.getKeyUnsafe());
2115 });
2116}
2117
2118void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) {
2121 dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "
2122 << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2123 });
2124 if (!RT.isDefunct())
2125 transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(),
2126 RT);
2127 });
2128}
2129
2130Error ExecutionSession::IL_updateCandidatesFor(
2133 return Candidates.forEachWithRemoval(
2134 [&](const SymbolStringPtr &Name,
2136
2137
2138 auto SymI = JD.Symbols.find(Name);
2139 if (SymI == JD.Symbols.end())
2140 return false;
2141
2142
2143
2144
2145
2146
2147 if (!SymI->second.getFlags().isExported() &&
2149 if (NonCandidates)
2150 NonCandidates->add(Name, SymLookupFlags);
2151 return true;
2152 }
2153
2154
2155
2156
2157
2158
2159 if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2163
2164
2165
2166 if (SymI->second.getFlags().hasError()) {
2167 auto FailedSymbolsMap = std::make_shared();
2168 (*FailedSymbolsMap)[&JD] = {Name};
2170 std::move(FailedSymbolsMap));
2171 }
2172
2173
2174 return true;
2175 });
2176}
2177
2178void ExecutionSession::OL_resumeLookupAfterGeneration(
2180
2182 "Should not be called for not-in-generator lookups");
2184
2186
2187 if (auto DG = IPLS.CurDefGeneratorStack.back().lock()) {
2188 IPLS.CurDefGeneratorStack.pop_back();
2189 std::lock_guardstd::mutex Lock(DG->M);
2190
2191
2192
2193 if (DG->PendingLookups.empty()) {
2194 DG->InUse = false;
2195 return;
2196 }
2197
2198
2199 LS = std::move(DG->PendingLookups.front());
2200 DG->PendingLookups.pop_front();
2201 }
2202
2203 if (LS.IPLS) {
2205 dispatchTask(std::make_unique(std::move(LS)));
2206 }
2207}
2208
2209void ExecutionSession::OL_applyQueryPhase1(
2210 std::unique_ptr IPLS, Error Err) {
2211
2213 dbgs() << "Entering OL_applyQueryPhase1:\n"
2214 << " Lookup kind: " << IPLS->K << "\n"
2215 << " Search order: " << IPLS->SearchOrder
2216 << ", Current index = " << IPLS->CurSearchOrderIndex
2217 << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2218 << " Lookup set: " << IPLS->LookupSet << "\n"
2219 << " Definition generator candidates: "
2220 << IPLS->DefGeneratorCandidates << "\n"
2221 << " Definition generator non-candidates: "
2222 << IPLS->DefGeneratorNonCandidates << "\n";
2223 });
2224
2226 OL_resumeLookupAfterGeneration(*IPLS);
2227
2229 "Lookup should not be in InGenerator state here");
2230
2231
2232
2233
2234
2235
2236 while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) {
2237
2238
2239
2240
2241 if (Err)
2242 return IPLS->fail(std::move(Err));
2243
2244
2245 auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex];
2246 auto &JD = *KV.first;
2247 auto JDLookupFlags = KV.second;
2248
2250 dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2251 << ") with lookup set " << IPLS->LookupSet << ":\n";
2252 });
2253
2254
2255 if (IPLS->NewJITDylib) {
2256
2257
2258
2259 SymbolLookupSet Tmp;
2260 std::swap(IPLS->DefGeneratorNonCandidates, Tmp);
2261 IPLS->DefGeneratorCandidates.append(std::move(Tmp));
2262
2264 dbgs() << " First time visiting " << JD.getName()
2265 << ", resetting candidate sets and building generator stack\n";
2266 });
2267
2268
2270 IPLS->CurDefGeneratorStack.reserve(JD.DefGenerators.size());
2272 reverse(JD.DefGenerators));
2273 });
2274
2275
2276 IPLS->NewJITDylib = false;
2277 }
2278
2279
2280
2282
2283
2284 LLVM_DEBUG(dbgs() << " Updating candidate set...\n");
2285 Err = IL_updateCandidatesFor(
2286 JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2287 JD.DefGenerators.empty() ? nullptr
2288 : &IPLS->DefGeneratorNonCandidates);
2290 dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates
2291 << "\n";
2292 });
2293
2294
2295
2296
2298 IPLS->DefGeneratorCandidates.empty())
2299 OL_resumeLookupAfterGeneration(*IPLS);
2300 });
2301
2302
2303
2304 if (Err)
2305 return IPLS->fail(std::move(Err));
2306
2307
2309 if (IPLS->CurDefGeneratorStack.empty())
2310 LLVM_DEBUG(dbgs() << " No generators to run for this JITDylib.\n");
2311 else if (IPLS->DefGeneratorCandidates.empty())
2312 LLVM_DEBUG(dbgs() << " No candidates to generate.\n");
2313 else
2314 dbgs() << " Running " << IPLS->CurDefGeneratorStack.size()
2315 << " remaining generators for "
2316 << IPLS->DefGeneratorCandidates.size() << " candidates\n";
2317 });
2318 while (!IPLS->CurDefGeneratorStack.empty() &&
2319 !IPLS->DefGeneratorCandidates.empty()) {
2320 auto DG = IPLS->CurDefGeneratorStack.back().lock();
2321
2322 if (!DG)
2324 "DefinitionGenerator removed while lookup in progress",
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2337 std::lock_guardstd::mutex Lock(DG->M);
2338 if (DG->InUse) {
2339 DG->PendingLookups.push_back(std::move(IPLS));
2340 return;
2341 }
2342 DG->InUse = true;
2343 }
2344
2346
2347 auto K = IPLS->K;
2348 auto &LookupSet = IPLS->DefGeneratorCandidates;
2349
2350
2351
2352 {
2353 LLVM_DEBUG(dbgs() << " Attempting to generate " << LookupSet << "\n");
2355 Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet);
2356 IPLS = std::move(LS.IPLS);
2357 }
2358
2359
2360
2361 if (IPLS)
2362 OL_resumeLookupAfterGeneration(*IPLS);
2363
2364
2365 if (Err) {
2367 dbgs() << " Error attempting to generate " << LookupSet << "\n";
2368 });
2369 assert(IPLS && "LS cannot be retained if error is returned");
2370 return IPLS->fail(std::move(Err));
2371 }
2372
2373
2374 if (!IPLS) {
2376 { dbgs() << " LookupState captured. Exiting phase1 for now.\n"; });
2377 return;
2378 }
2379
2380
2381
2383 LLVM_DEBUG(dbgs() << " Updating candidate set post-generation\n");
2384 Err = IL_updateCandidatesFor(
2385 JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2386 JD.DefGenerators.empty() ? nullptr
2387 : &IPLS->DefGeneratorNonCandidates);
2388 });
2389
2390
2391 if (Err) {
2392 LLVM_DEBUG(dbgs() << " Error encountered while updating candidates\n");
2393 return IPLS->fail(std::move(Err));
2394 }
2395 }
2396
2397 if (IPLS->DefGeneratorCandidates.empty() &&
2398 IPLS->DefGeneratorNonCandidates.empty()) {
2399
2401 IPLS->CurSearchOrderIndex = IPLS->SearchOrder.size();
2402 break;
2403 } else {
2404
2405
2406 LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n");
2407 ++IPLS->CurSearchOrderIndex;
2408 IPLS->NewJITDylib = true;
2409 }
2410 }
2411
2412
2413 IPLS->DefGeneratorCandidates.remove_if(
2414 [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2416 });
2417
2418
2419
2420
2421 if (IPLS->DefGeneratorCandidates.empty()) {
2423 IPLS->complete(std::move(IPLS));
2424 } else {
2425 LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n");
2428 }
2429}
2430
2431void ExecutionSession::OL_completeLookup(
2432 std::unique_ptr IPLS,
2433 std::shared_ptr Q,
2435
2437 dbgs() << "Entering OL_completeLookup:\n"
2438 << " Lookup kind: " << IPLS->K << "\n"
2439 << " Search order: " << IPLS->SearchOrder
2440 << ", Current index = " << IPLS->CurSearchOrderIndex
2441 << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2442 << " Lookup set: " << IPLS->LookupSet << "\n"
2443 << " Definition generator candidates: "
2444 << IPLS->DefGeneratorCandidates << "\n"
2445 << " Definition generator non-candidates: "
2446 << IPLS->DefGeneratorNonCandidates << "\n";
2447 });
2448
2449 bool QueryComplete = false;
2450 DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs;
2451
2453 for (auto &KV : IPLS->SearchOrder) {
2454 auto &JD = *KV.first;
2455 auto JDLookupFlags = KV.second;
2457 dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2458 << ") with lookup set " << IPLS->LookupSet << ":\n";
2459 });
2460
2461 auto Err = IPLS->LookupSet.forEachWithRemoval(
2462 [&](const SymbolStringPtr &Name,
2465 dbgs() << " Attempting to match \"" << Name << "\" ("
2466 << SymLookupFlags << ")... ";
2467 });
2468
2469
2470
2471 auto SymI = JD.Symbols.find(Name);
2472 if (SymI == JD.Symbols.end()) {
2474 return false;
2475 }
2476
2477
2478
2479 if (!SymI->second.getFlags().isExported() &&
2480 JDLookupFlags ==
2483 return false;
2484 }
2485
2486
2487
2488
2489
2490
2491 if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2494 dbgs() << "error: "
2495 "required, but symbol is has-side-effects-only\n";
2496 });
2499 }
2500
2501
2502
2503 if (SymI->second.getFlags().hasError()) {
2504 LLVM_DEBUG(dbgs() << "error: symbol is in error state\n");
2505 auto FailedSymbolsMap = std::make_shared();
2506 (*FailedSymbolsMap)[&JD] = {Name};
2509 }
2510
2511
2512
2513
2514
2515 if (SymI->second.getState() >= Q->getRequiredState()) {
2517 << "matched, symbol already in required state\n");
2518 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
2519
2520
2521
2523 Q->addQueryDependence(JD, Name);
2524
2525 return true;
2526 }
2527
2528
2529
2530
2531 if (SymI->second.hasMaterializerAttached()) {
2532 assert(SymI->second.getAddress() == ExecutorAddr() &&
2533 "Symbol not resolved but already has address?");
2534 auto UMII = JD.UnmaterializedInfos.find(Name);
2535 assert(UMII != JD.UnmaterializedInfos.end() &&
2536 "Lazy symbol should have UnmaterializedInfo");
2537
2538 auto UMI = UMII->second;
2539 assert(UMI->MU && "Materializer should not be null");
2540 assert(UMI->RT && "Tracker should not be null");
2542 dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()
2543 << " (" << UMI->MU->getName() << ")\n";
2544 });
2545
2546
2547
2548 for (auto &KV : UMI->MU->getSymbols()) {
2549 auto SymK = JD.Symbols.find(KV.first);
2550 assert(SymK != JD.Symbols.end() &&
2551 "No entry for symbol covered by MaterializationUnit");
2552 SymK->second.setMaterializerAttached(false);
2554 JD.UnmaterializedInfos.erase(KV.first);
2555 }
2556
2557
2558 CollectedUMIs[&JD].push_back(std::move(UMI));
2559 } else
2561
2562
2563
2566 "By this line the symbol should be materializing");
2567 auto &MI = JD.MaterializingInfos[Name];
2568 MI.addQuery(Q);
2569 Q->addQueryDependence(JD, Name);
2570
2571 return true;
2572 });
2573
2574 JD.shrinkMaterializationInfoMemory();
2575
2576
2577 if (Err) {
2578
2580 dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";
2581 });
2582
2583
2584 Q->detach();
2585
2586
2587 for (auto &KV : CollectedUMIs) {
2588 auto &JD = *KV.first;
2589 for (auto &UMI : KV.second)
2590 for (auto &KV2 : UMI->MU->getSymbols()) {
2591 assert(!JD.UnmaterializedInfos.count(KV2.first) &&
2592 "Unexpected materializer in map");
2593 auto SymI = JD.Symbols.find(KV2.first);
2594 assert(SymI != JD.Symbols.end() && "Missing symbol entry");
2596 "Can not replace symbol that is not materializing");
2597 assert(!SymI->second.hasMaterializerAttached() &&
2598 "MaterializerAttached flag should not be set");
2599 SymI->second.setMaterializerAttached(true);
2600 JD.UnmaterializedInfos[KV2.first] = UMI;
2601 }
2602 }
2603
2604 return Err;
2605 }
2606 }
2607
2608 LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-referenced symbols\n");
2609 IPLS->LookupSet.forEachWithRemoval(
2610 [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2612 Q->dropSymbol(Name);
2613 return true;
2614 } else
2615 return false;
2616 });
2617
2618 if (!IPLS->LookupSet.empty()) {
2619 LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2621 IPLS->LookupSet.getSymbolNames());
2622 }
2623
2624
2625 QueryComplete = Q->isComplete();
2626
2628 dbgs() << "Query successfully "
2629 << (QueryComplete ? "completed" : "lodged") << "\n";
2630 });
2631
2632
2633 if (!CollectedUMIs.empty()) {
2634 std::lock_guardstd::recursive\_mutex Lock(OutstandingMUsMutex);
2635
2637 for (auto &KV : CollectedUMIs) {
2639 auto &JD = *KV.first;
2640 dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size()
2641 << " MUs.\n";
2642 });
2643 for (auto &UMI : KV.second) {
2644 auto MR = createMaterializationResponsibility(
2645 *UMI->RT, std::move(UMI->MU->SymbolFlags),
2646 std::move(UMI->MU->InitSymbol));
2647 OutstandingMUs.push_back(
2648 std::make_pair(std::move(UMI->MU), std::move(MR)));
2649 }
2650 }
2651 } else
2653
2654 if (RegisterDependencies && !Q->QueryRegistrations.empty()) {
2656 RegisterDependencies(Q->QueryRegistrations);
2657 } else
2658 LLVM_DEBUG(dbgs() << "No dependencies to register\n");
2659
2661 });
2662
2663 if (LodgingErr) {
2665 Q->detach();
2666 Q->handleFailed(std::move(LodgingErr));
2667 return;
2668 }
2669
2670 if (QueryComplete) {
2672 Q->handleComplete(*this);
2673 }
2674
2675 dispatchOutstandingMUs();
2676}
2677
2678void ExecutionSession::OL_completeLookupFlags(
2679 std::unique_ptr IPLS,
2680 unique_function<void(Expected)> OnComplete) {
2681
2684 dbgs() << "Entering OL_completeLookupFlags:\n"
2685 << " Lookup kind: " << IPLS->K << "\n"
2686 << " Search order: " << IPLS->SearchOrder
2687 << ", Current index = " << IPLS->CurSearchOrderIndex
2688 << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2689 << " Lookup set: " << IPLS->LookupSet << "\n"
2690 << " Definition generator candidates: "
2691 << IPLS->DefGeneratorCandidates << "\n"
2692 << " Definition generator non-candidates: "
2693 << IPLS->DefGeneratorNonCandidates << "\n";
2694 });
2695
2697
2698
2699 for (auto &KV : IPLS->SearchOrder) {
2700 auto &JD = *KV.first;
2701 auto JDLookupFlags = KV.second;
2703 dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2704 << ") with lookup set " << IPLS->LookupSet << ":\n";
2705 });
2706
2707 IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name,
2710 dbgs() << " Attempting to match \"" << Name << "\" ("
2711 << SymLookupFlags << ")... ";
2712 });
2713
2714
2715
2716 auto SymI = JD.Symbols.find(Name);
2717 if (SymI == JD.Symbols.end()) {
2719 return false;
2720 }
2721
2722
2723 if (!SymI->second.getFlags().isExported() &&
2726 return false;
2727 }
2728
2730 dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()
2731 << "\n";
2732 });
2733 Result[Name] = SymI->second.getFlags();
2734 return true;
2735 });
2736 }
2737
2738
2739 IPLS->LookupSet.remove_if(
2740 [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2742 });
2743
2744 if (!IPLS->LookupSet.empty()) {
2745 LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2747 IPLS->LookupSet.getSymbolNames());
2748 }
2749
2752 });
2753
2754
2755 LLVM_DEBUG(dbgs() << "Sending result to handler.\n");
2756 OnComplete(std::move(Result));
2757}
2758
2759void ExecutionSession::OL_destroyMaterializationResponsibility(
2761
2762 assert(MR.SymbolFlags.empty() &&
2763 "All symbols should have been explicitly materialized or failed");
2764 MR.JD.unlinkMaterializationResponsibility(MR);
2765}
2766
2767SymbolNameSet ExecutionSession::OL_getRequestedSymbols(
2769 return MR.JD.getRequestedSymbols(MR.SymbolFlags);
2770}
2771
2775 dbgs() << "In " << MR.JD.getName() << " resolving " << Symbols << "\n";
2776 });
2777#ifndef NDEBUG
2778 for (auto &KV : Symbols) {
2779 auto I = MR.SymbolFlags.find(KV.first);
2780 assert(I != MR.SymbolFlags.end() &&
2781 "Resolving symbol outside this responsibility set");
2782 assert(->second.hasMaterializationSideEffectsOnly() &&
2783 "Can't resolve materialization-side-effects-only symbol");
2786 assert((KV.second.getFlags() & WeakOrCommon) &&
2787 "Common symbols must be resolved as common or weak");
2788 assert((KV.second.getFlags() & ~WeakOrCommon) ==
2790 "Resolving symbol with incorrect flags");
2791 } else
2792 assert(KV.second.getFlags() == I->second &&
2793 "Resolving symbol with incorrect flags");
2794 }
2795#endif
2796
2797 return MR.JD.resolve(MR, Symbols);
2798}
2799
2801ExecutionSession::IL_getSymbolState(JITDylib *JD,
2803 if (JD->State != JITDylib::Open)
2804 return WaitingOnGraph::ExternalState::Failed;
2805
2806 auto I = JD->Symbols.find_as(Name);
2807
2808
2809 if (I == JD->Symbols.end())
2810 return WaitingOnGraph::ExternalState::Failed;
2811
2812 if (I->second.getFlags().hasError())
2813 return WaitingOnGraph::ExternalState::Failed;
2814
2816 return WaitingOnGraph::ExternalState::Ready;
2817
2818 return WaitingOnGraph::ExternalState::None;
2819}
2820
2821template <typename UpdateSymbolFn, typename UpdateQueryFn>
2822void ExecutionSession::IL_collectQueries(
2823 JITDylib::AsynchronousSymbolQuerySet &Qs,
2825 UpdateSymbolFn &&UpdateSymbol, UpdateQueryFn &&UpdateQuery) {
2826
2827 for (auto &[JD, Symbols] : QualifiedSymbols) {
2828
2829
2830
2831
2832 assert(JD->State == JITDylib::Open &&
2833 "WaitingOnGraph includes definition in defunct JITDylib");
2834 for (auto &Symbol : Symbols) {
2835
2836 auto I = JD->Symbols.find_as(Symbol);
2837 assert(I != JD->Symbols.end() &&
2838 "Failed Symbol missing from JD symbol table");
2840 UpdateSymbol(Entry);
2841
2842
2843 auto J = JD->MaterializingInfos.find_as(Symbol);
2844 if (J != JD->MaterializingInfos.end()) {
2845 for (auto &Q : J->second.takeAllPendingQueries()) {
2846 UpdateQuery(*Q, *JD, Symbol, Entry);
2847 Qs.insert(std::move(Q));
2848 }
2849 JD->MaterializingInfos.erase(J);
2850 }
2851 }
2852 }
2853}
2854
2855ExpectedExecutionSession::EmitQueries
2857 WaitingOnGraph::SimplifyResult SR) {
2858
2859 if (MR.RT->isDefunct())
2861
2862 auto &TargetJD = MR.getTargetJITDylib();
2863 if (TargetJD.State != JITDylib::Open)
2865 " is defunct",
2867
2868#ifdef EXPENSIVE_CHECKS
2869 verifySessionState("entering ExecutionSession::IL_emit");
2870#endif
2871
2872 auto ER = G.emit(std::move(SR),
2873 [this](JITDylib *JD, NonOwningSymbolStringPtr Name) {
2874 return IL_getSymbolState(JD, Name);
2875 });
2876
2877 EmitQueries EQ;
2878
2879
2880 for (auto &SN : ER.Failed)
2881 IL_collectQueries(
2882 EQ.Failed, SN->defs(),
2883 [](JITDylib::SymbolTableEntry &E) {
2884 E.setFlags(E.getFlags() = JITSymbolFlags::HasError);
2885 },
2886 [&](AsynchronousSymbolQuery &Q, JITDylib &JD,
2887 NonOwningSymbolStringPtr Name, JITDylib::SymbolTableEntry &E) {
2888 auto &FS = EQ.FailedSymsForQuery[&Q];
2889 if (!FS)
2890 FS = std::make_shared();
2891 (*FS)[&JD].insert(SymbolStringPtr(Name));
2892 });
2893
2894 for (auto &FQ : EQ.Failed)
2895 FQ->detach();
2896
2897 for (auto &SN : ER.Ready)
2898 IL_collectQueries(
2899 EQ.Completed, SN->defs(),
2900 [](JITDylib::SymbolTableEntry &E) { E.setState(SymbolState::Ready); },
2901 [](AsynchronousSymbolQuery &Q, JITDylib &JD,
2902 NonOwningSymbolStringPtr Name, JITDylib::SymbolTableEntry &E) {
2903 Q.notifySymbolMetRequiredState(SymbolStringPtr(Name), E.getSymbol());
2904 });
2905
2906
2907
2908 for (auto it = EQ.Completed.begin(), end = EQ.Completed.end(); it != end;) {
2909 if ((*it)->isComplete()) {
2910 ++it;
2911 } else {
2912 it = EQ.Completed.erase(it);
2913 }
2914 }
2915
2916#ifdef EXPENSIVE_CHECKS
2917 verifySessionState("exiting ExecutionSession::IL_emit");
2918#endif
2919
2920 return std::move(EQ);
2921}
2922
2923Error ExecutionSession::OL_notifyEmitted(
2927 dbgs() << "In " << MR.JD.getName() << " emitting " << MR.SymbolFlags
2928 << "\n";
2929 if (!DepGroups.empty()) {
2930 dbgs() << " Initial dependencies:\n";
2931 for (auto &SDG : DepGroups) {
2932 dbgs() << " Symbols: " << SDG.Symbols
2933 << ", Dependencies: " << SDG.Dependencies << "\n";
2934 }
2935 }
2936 });
2937
2938#ifndef NDEBUG
2940 for (auto &DG : DepGroups) {
2941 for (auto &Sym : DG.Symbols) {
2942 assert(MR.SymbolFlags.count(Sym) &&
2943 "DG contains dependence for symbol outside this MR");
2944 assert(Visited.insert(Sym).second &&
2945 "DG contains duplicate entries for Name");
2946 }
2947 }
2948#endif
2949
2950 std::vector<std::unique_ptrWaitingOnGraph::SuperNode> SNs;
2952 {
2953 auto &JDResidual = Residual[&MR.getTargetJITDylib()];
2954 for (auto &[Name, Flags] : MR.getSymbols())
2955 JDResidual.insert(NonOwningSymbolStringPtr(Name));
2956
2957 for (auto &SDG : DepGroups) {
2959 assert(!SDG.Symbols.empty());
2960 auto &JDDefs = Defs[&MR.getTargetJITDylib()];
2961 for (auto &Def : SDG.Symbols) {
2962 JDDefs.insert(NonOwningSymbolStringPtr(Def));
2963 JDResidual.erase(NonOwningSymbolStringPtr(Def));
2964 }
2966 if (!SDG.Dependencies.empty()) {
2967 for (auto &[JD, Syms] : SDG.Dependencies) {
2968 auto &JDDeps = Deps[JD];
2969 for (auto &Dep : Syms)
2970 JDDeps.insert(NonOwningSymbolStringPtr(Dep));
2971 }
2972 }
2973 SNs.push_back(std::make_uniqueWaitingOnGraph::SuperNode(
2974 std::move(Defs), std::move(Deps)));
2975 }
2976 if (!JDResidual.empty())
2977 SNs.push_back(std::make_uniqueWaitingOnGraph::SuperNode(
2979 }
2980
2982
2984 dbgs() << " Simplified dependencies:\n";
2985 for (auto &SN : SR.superNodes()) {
2986
2988 std::vector<JITDylib *> JDs;
2990 JDs.push_back(JD);
2992 return LHS->getName() < RHS->getName();
2993 });
2994 return JDs;
2995 };
2996
2998 std::vector Names(Elems.begin(), Elems.end());
2999 llvm::sort(Names, [](const NonOwningSymbolStringPtr &LHS,
3000 const NonOwningSymbolStringPtr &RHS) {
3002 });
3003 return Names;
3004 };
3005
3006 dbgs() << " Defs: {";
3007 for (auto *JD : SortedLibs(SN->defs())) {
3008 dbgs() << " (" << JD->getName() << ", [";
3009 for (auto &Sym : SortedNames(SN->defs()[JD]))
3010 dbgs() << " " << Sym;
3011 dbgs() << " ])";
3012 }
3013 dbgs() << " }, Deps: {";
3014 for (auto *JD : SortedLibs(SN->deps())) {
3015 dbgs() << " (" << JD->getName() << ", [";
3016 for (auto &Sym : SortedNames(SN->deps()[JD]))
3017 dbgs() << " " << Sym;
3018 dbgs() << " ])";
3019 }
3020 dbgs() << " }\n";
3021 }
3022 });
3023 auto EmitQueries =
3024 runSessionLocked([&]() { return IL_emit(MR, std::move(SR)); });
3025
3026
3027 if (!EmitQueries)
3028 return EmitQueries.takeError();
3029
3030
3031
3032
3033
3035 {
3036 for (auto &FQ : EmitQueries->Failed) {
3037 FQ->detach();
3038 assert(EmitQueries->FailedSymsForQuery.count(FQ.get()) &&
3039 "Missing failed symbols for query");
3040 auto FailedSyms = std::move(EmitQueries->FailedSymsForQuery[FQ.get()]);
3041 for (auto &[JD, Syms] : *FailedSyms) {
3042 auto &BadDepsForJD = BadDeps[JD];
3043 for (auto &Sym : Syms)
3044 BadDepsForJD.insert(Sym);
3045 }
3047 std::move(FailedSyms)));
3048 }
3049 }
3050
3051 for (auto &UQ : EmitQueries->Completed)
3052 UQ->handleComplete(*this);
3053
3054
3055 if (!BadDeps.empty()) {
3057
3058
3059
3060
3061 for (auto &[Name, Flags] : MR.getSymbols())
3062 BadNames.insert(Name);
3063 MR.SymbolFlags.clear();
3066 std::move(BadDeps), "dependencies removed or in error state");
3067 }
3068
3069 MR.SymbolFlags.clear();
3071}
3072
3073Error ExecutionSession::OL_defineMaterializing(
3075
3077 dbgs() << "In " << MR.JD.getName() << " defining materializing symbols "
3078 << NewSymbolFlags << "\n";
3079 });
3080 if (auto AcceptedDefs =
3081 MR.JD.defineMaterializing(MR, std::move(NewSymbolFlags))) {
3082
3083 for (auto &KV : *AcceptedDefs)
3084 MR.SymbolFlags.insert(KV);
3086 } else
3087 return AcceptedDefs.takeError();
3088}
3089
3090std::pair<JITDylib::AsynchronousSymbolQuerySet,
3091 std::shared_ptr>
3092ExecutionSession::IL_failSymbols(JITDylib &JD,
3094
3095#ifdef EXPENSIVE_CHECKS
3096 verifySessionState("entering ExecutionSession::IL_failSymbols");
3097#endif
3098
3099 JITDylib::AsynchronousSymbolQuerySet FailedQueries;
3100 auto Fail = [&](JITDylib *FailJD, NonOwningSymbolStringPtr FailSym) {
3101 auto I = FailJD->Symbols.find_as(FailSym);
3102 assert(I != FailJD->Symbols.end());
3104 auto J = FailJD->MaterializingInfos.find_as(FailSym);
3105 if (J != FailJD->MaterializingInfos.end()) {
3106 for (auto &Q : J->second.takeAllPendingQueries())
3107 FailedQueries.insert(std::move(Q));
3108 FailJD->MaterializingInfos.erase(J);
3109 }
3110 };
3111
3112 auto FailedSymbolsMap = std::make_shared();
3113
3114 {
3115 auto &FailedSymsForJD = (*FailedSymbolsMap)[&JD];
3116 for (auto &Sym : SymbolsToFail) {
3117 FailedSymsForJD.insert(Sym);
3118 Fail(&JD, NonOwningSymbolStringPtr(Sym));
3119 }
3120 }
3121
3123 auto &JDToFail = ToFail[&JD];
3124 for (auto &Sym : SymbolsToFail)
3125 JDToFail.insert(NonOwningSymbolStringPtr(Sym));
3126
3127 auto FailedSNs = G.fail(ToFail);
3128
3129 for (auto &SN : FailedSNs) {
3130 for (auto &[FailJD, Defs] : SN->defs()) {
3131 auto &FailedSymsForFailJD = (*FailedSymbolsMap)[FailJD];
3132 for (auto &Def : Defs) {
3133 FailedSymsForFailJD.insert(SymbolStringPtr(Def));
3134 Fail(FailJD, Def);
3135 }
3136 }
3137 }
3138
3139
3140 for (auto &Q : FailedQueries)
3141 Q->detach();
3142
3143#ifdef EXPENSIVE_CHECKS
3144 verifySessionState("exiting ExecutionSession::IL_failSymbols");
3145#endif
3146
3147 return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap));
3148}
3149
3151
3153 dbgs() << "In " << MR.JD.getName() << " failing materialization for "
3154 << MR.SymbolFlags << "\n";
3155 });
3156
3157 if (MR.SymbolFlags.empty())
3158 return;
3159
3161 for (auto &[Name, Flags] : MR.SymbolFlags)
3162 SymbolsToFail.push_back(Name);
3163 MR.SymbolFlags.clear();
3164
3165 JITDylib::AsynchronousSymbolQuerySet FailedQueries;
3166 std::shared_ptr FailedSymbols;
3167
3168 std::tie(FailedQueries, FailedSymbols) = runSessionLocked([&]() {
3169
3170 if (MR.RT->isDefunct())
3171 return std::pair<JITDylib::AsynchronousSymbolQuerySet,
3172 std::shared_ptr>();
3173 return IL_failSymbols(MR.getTargetJITDylib(), SymbolsToFail);
3174 });
3175
3176 for (auto &Q : FailedQueries) {
3177 Q->detach();
3178 Q->handleFailed(
3180 }
3181}
3182
3184 std::unique_ptr MU) {
3185 for (auto &KV : MU->getSymbols()) {
3186 assert(MR.SymbolFlags.count(KV.first) &&
3187 "Replacing definition outside this responsibility set");
3188 MR.SymbolFlags.erase(KV.first);
3189 }
3190
3191 if (MU->getInitializerSymbol() == MR.InitSymbol)
3192 MR.InitSymbol = nullptr;
3193
3194 LLVM_DEBUG(MR.JD.getExecutionSession().runSessionLocked([&]() {
3195 dbgs() << "In " << MR.JD.getName() << " replacing symbols with " << *MU
3196 << "\n";
3197 }););
3198
3199 return MR.JD.replace(MR, std::move(MU));
3200}
3201
3202Expected<std::unique_ptr>
3205
3206 SymbolStringPtr DelegatedInitSymbol;
3208
3209 for (auto &Name : Symbols) {
3210 auto I = MR.SymbolFlags.find(Name);
3211 assert(I != MR.SymbolFlags.end() &&
3212 "Symbol is not tracked by this MaterializationResponsibility "
3213 "instance");
3214
3215 DelegatedFlags[Name] = std::move(I->second);
3216 if (Name == MR.InitSymbol)
3217 std::swap(MR.InitSymbol, DelegatedInitSymbol);
3218
3219 MR.SymbolFlags.erase(I);
3220 }
3221
3222 return MR.JD.delegate(MR, std::move(DelegatedFlags),
3223 std::move(DelegatedInitSymbol));
3224}
3225
3226#ifndef NDEBUG
3227void ExecutionSession::dumpDispatchInfo(Task &T) {
3229 dbgs() << "Dispatching: ";
3230 T.printDescription(dbgs());
3231 dbgs() << "\n";
3232 });
3233}
3234#endif
3235
3236}
3237}
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
aarch64 falkor hwpf fix Falkor HW Prefetch Fix Late Phase
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static StringRef getName(Value *V)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive,...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Helper for Errors used as out-parameters.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
reference get()
Returns a reference to the stored T value.
bool hasMaterializationSideEffectsOnly() const
Returns true if this symbol is a materialization-side-effects-only symbol.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::pair< iterator, bool > insert(const ValueT &V)
void reserve(size_t Size)
Grow the DenseSet so that it can contain at least NumEntries items before resizing again.
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const std::string & getName() const
Get the name for this JITLinkDylib.
A symbol query that returns results via a callback when results are ready.
LLVM_ABI AsynchronousSymbolQuery(const SymbolLookupSet &Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete)
Create a query for the given symbols.
Definition Core.cpp:201
LLVM_ABI void notifySymbolMetRequiredState(const SymbolStringPtr &Name, ExecutorSymbolDef Sym)
Notify the query that a requested symbol has reached the required state.
Definition Core.cpp:215
Definition generators can be attached to JITDylibs to generate new definitions for otherwise unresolv...
virtual ~DefinitionGenerator()
Definition Core.cpp:638
An ExecutionSession represents a running JIT program.
LLVM_ABI Error endSession()
End the session.
Definition Core.cpp:1580
unique_function< void(shared::WrapperFunctionResult)> SendResultFunction
Send a result to the remote.
void reportError(Error Err)
Report a error for this execution session.
LLVM_ABI void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet Symbols, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)
Search the given JITDylibs to find the flags associated with each of the given symbols.
Definition Core.cpp:1740
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
LLVM_ABI JITDylib * getJITDylibByName(StringRef Name)
Return a pointer to the "name" JITDylib.
Definition Core.cpp:1619
LLVM_ABI JITDylib & createBareJITDylib(std::string Name)
Add a new bare JITDylib to this ExecutionSession.
Definition Core.cpp:1628
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Get the SymbolStringPool for this instance.
LLVM_ABI void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Definition Core.cpp:1766
LLVM_ABI Error registerJITDispatchHandlers(JITDylib &JD, JITDispatchHandlerAssociationMap WFs)
For each tag symbol name, associate the corresponding AsyncHandlerWrapperFunction with the address of...
Definition Core.cpp:1861
LLVM_ABI void registerResourceManager(ResourceManager &RM)
Register the given ResourceManager with this ExecutionSession.
Definition Core.cpp:1602
LLVM_ABI ~ExecutionSession()
Destroy an ExecutionSession.
Definition Core.cpp:1574
LLVM_ABI void runJITDispatchHandler(SendResultFunction SendResult, ExecutorAddr HandlerFnTagAddr, ArrayRef< char > ArgBuffer)
Run a registered jit-side wrapper function.
Definition Core.cpp:1900
LLVM_ABI void deregisterResourceManager(ResourceManager &RM)
Deregister the given ResourceManager with this ExecutionSession.
Definition Core.cpp:1606
LLVM_ABI ExecutionSession(std::unique_ptr< ExecutorProcessControl > EPC)
Construct an ExecutionSession with the given ExecutorProcessControl object.
Definition Core.cpp:1568
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
LLVM_ABI void dump(raw_ostream &OS)
Dump the state of all the JITDylibs in this session.
Definition Core.cpp:1921
LLVM_ABI Error removeJITDylibs(std::vector< JITDylibSP > JDsToRemove)
Removes the given JITDylibs from the ExecutionSession.
Definition Core.cpp:1645
LLVM_ABI Expected< JITDylib & > createJITDylib(std::string Name)
Add a new JITDylib to this ExecutionSession.
Definition Core.cpp:1637
void dispatchTask(std::unique_ptr< Task > T)
Materialize the given unit.
DenseMap< SymbolStringPtr, JITDispatchHandlerFunction > JITDispatchHandlerAssociationMap
A map associating tag names with asynchronous wrapper function implementations in the JIT.
Represents an address in the executor process.
Represents a defining location for a JIT symbol.
const JITSymbolFlags & getFlags() const
FailedToMaterialize(std::shared_ptr< SymbolStringPool > SSP, std::shared_ptr< SymbolDependenceMap > Symbols)
Definition Core.cpp:82
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:100
~FailedToMaterialize() override
Definition Core.cpp:95
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:104
InProgressFullLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, SymbolState RequiredState, std::shared_ptr< AsynchronousSymbolQuery > Q, RegisterDependenciesFunction RegisterDependencies)
Definition Core.cpp:565
void complete(std::unique_ptr< InProgressLookupState > IPLS) override
Definition Core.cpp:575
void fail(Error Err) override
Definition Core.cpp:581
void complete(std::unique_ptr< InProgressLookupState > IPLS) override
Definition Core.cpp:552
void fail(Error Err) override
Definition Core.cpp:557
InProgressLookupFlagsState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)
Definition Core.cpp:545
virtual ~InProgressLookupState()=default
LookupKind K
Definition Core.cpp:525
SymbolLookupSet DefGeneratorCandidates
Definition Core.cpp:532
JITDylibSearchOrder SearchOrder
Definition Core.cpp:526
std::vector< std::weak_ptr< DefinitionGenerator > > CurDefGeneratorStack
Definition Core.cpp:540
@ ResumedForGenerator
Definition Core.cpp:537
@ InGenerator
Definition Core.cpp:538
@ NotInGenerator
Definition Core.cpp:536
size_t CurSearchOrderIndex
Definition Core.cpp:530
SymbolLookupSet LookupSet
Definition Core.cpp:527
virtual void complete(std::unique_ptr< InProgressLookupState > IPLS)=0
InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, SymbolState RequiredState)
Definition Core.cpp:515
SymbolState RequiredState
Definition Core.cpp:528
SymbolLookupSet DefGeneratorNonCandidates
Definition Core.cpp:533
virtual void fail(Error Err)=0
bool NewJITDylib
Definition Core.cpp:531
Represents a JIT'd dynamic library.
LLVM_ABI ~JITDylib()
Definition Core.cpp:652
LLVM_ABI Error remove(const SymbolNameSet &Names)
Tries to remove the given symbols.
Definition Core.cpp:1054
LLVM_ABI Error clear()
Calls remove on all trackers currently associated with this JITDylib.
Definition Core.cpp:656
LLVM_ABI void dump(raw_ostream &OS)
Dump current JITDylib state to OS.
Definition Core.cpp:1115
LLVM_ABI void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD, JITDylibLookupFlags JDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Replace OldJD with NewJD in the link order if OldJD is present.
Definition Core.cpp:1030
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
LLVM_ABI void addToLinkOrder(const JITDylibSearchOrder &NewLinks)
Append the given JITDylibSearchOrder to the link order for this JITDylib (discarding any elements alr...
Definition Core.cpp:1014
LLVM_ABI ResourceTrackerSP createResourceTracker()
Create a resource tracker for this JITDylib.
Definition Core.cpp:680
LLVM_ABI void removeFromLinkOrder(JITDylib &JD)
Remove the given JITDylib from the link order for this JITDylib if it is present.
Definition Core.cpp:1042
LLVM_ABI void setLinkOrder(JITDylibSearchOrder NewSearchOrder, bool LinkAgainstThisJITDylibFirst=true)
Set the link order to be used when fixing up definitions in JITDylib.
Definition Core.cpp:999
LLVM_ABI Expected< std::vector< JITDylibSP > > getReverseDFSLinkOrder()
Rteurn this JITDylib and its transitive dependencies in reverse DFS order based on linkage relationsh...
Definition Core.cpp:1736
LLVM_ABI ResourceTrackerSP getDefaultResourceTracker()
Get the default resource tracker for this JITDylib.
Definition Core.cpp:671
JITDylib(const JITDylib &)=delete
LLVM_ABI void removeGenerator(DefinitionGenerator &G)
Remove a definition generator from this JITDylib.
Definition Core.cpp:688
LLVM_ABI Expected< std::vector< JITDylibSP > > getDFSLinkOrder()
Return this JITDylib and its transitive dependencies in DFS order based on linkage relationships.
Definition Core.cpp:1732
Wraps state for a lookup-in-progress.
LLVM_ABI void continueLookup(Error Err)
Continue the lookup.
Definition Core.cpp:632
LLVM_ABI LookupState & operator=(LookupState &&)
void run() override
Definition Core.cpp:1566
void printDescription(raw_ostream &OS) override
Definition Core.cpp:1564
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
void run() override
Definition Core.cpp:1558
void printDescription(raw_ostream &OS) override
Definition Core.cpp:1553
~MaterializationTask() override
Definition Core.cpp:1547
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
MaterializationUnit(Interface I)
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:162
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:166
Non-owning SymbolStringPool entry pointer.
static void lookupInitSymbolsAsync(unique_function< void(Error)> OnComplete, ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)
Performs an async lookup for the given symbols in each of the given JITDylibs, calling the given hand...
Definition Core.cpp:1504
static Expected< DenseMap< JITDylib *, SymbolMap > > lookupInitSymbols(ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)
A utility function for looking up initializer symbols.
Definition Core.cpp:1455
StringRef getName() const override
Return the name of this materialization unit.
Definition Core.cpp:306
ReExportsMaterializationUnit(JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolAliasMap Aliases)
SourceJD is allowed to be nullptr, in which case the source JITDylib is taken to be whatever JITDylib...
Definition Core.cpp:300
std::function< bool(SymbolStringPtr)> SymbolPredicate
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) override
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
Definition Core.cpp:597
ReexportsGenerator(JITDylib &SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolPredicate Allow=SymbolPredicate())
Create a reexports generator.
Definition Core.cpp:591
Listens for ResourceTracker operations.
virtual ~ResourceManager()
ResourceTrackerDefunct(ResourceTrackerSP RT)
Definition Core.cpp:71
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:78
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:74
API to remove / transfer ownership of JIT resources.
JITDylib & getJITDylib() const
Return the JITDylib targeted by this tracker.
LLVM_ABI void transferTo(ResourceTracker &DstRT)
Transfer all resources associated with this key to the given tracker, which must target the same JITD...
Definition Core.cpp:59
LLVM_ABI ~ResourceTracker()
Definition Core.cpp:50
ResourceTracker(const ResourceTracker &)=delete
LLVM_ABI Error remove()
Remove all resources associated with this key.
Definition Core.cpp:55
LLVM_ABI void lookupAsync(LookupAsyncOnCompleteFn OnComplete) const
Definition Core.cpp:180
unique_function< void(Expected< ExecutorSymbolDef >)> LookupAsyncOnCompleteFn
A set of symbols to look up, each associated with a SymbolLookupFlags value.
static SymbolLookupSet fromMapKeys(const DenseMap< SymbolStringPtr, ValT > &M, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from DenseMap keys.
Pointer to a pooled string representing a symbol name.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:154
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:158
SymbolsCouldNotBeRemoved(std::shared_ptr< SymbolStringPool > SSP, SymbolNameSet Symbols)
Definition Core.cpp:148
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:144
SymbolsNotFound(std::shared_ptr< SymbolStringPool > SSP, SymbolNameSet Symbols)
Definition Core.cpp:127
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:140
Represents an abstract task for ORC to run.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:171
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:175
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition Core.cpp:120
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition Core.cpp:116
UnsatisfiedSymbolDependencies(std::shared_ptr< SymbolStringPool > SSP, JITDylibSP JD, SymbolNameSet FailedSymbols, SymbolDependenceMap BadDeps, std::string Explanation)
Definition Core.cpp:108
DenseSet< ElementId > ElementSet
DenseMap< ContainerId, ElementSet > ContainerElementsMap
static SimplifyResult simplify(std::vector< std::unique_ptr< SuperNode > > SNs)
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
unique_function is a type-erasing functor similar to std::function.
@ C
The default llvm calling convention, compatible with C.
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
IntrusiveRefCntPtr< JITDylib > JITDylibSP
IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP
@ MissingSymbolDefinitions
@ UnexpectedSymbolDefinitions
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
std::function< void(const SymbolDependenceMap &)> RegisterDependenciesFunction
Callback to register the dependencies for a given query.
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, JITDylibLookupFlags SourceJDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...
LLVM_ABI Expected< SymbolAliasMap > buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols)
Build a SymbolAliasMap for the common case where you want to re-export symbols from another JITDylib ...
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
@ MatchExportedSymbolsOnly
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
LookupKind
Describes the kind of lookup being performed.
LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition Core.cpp:38
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap
A map from JITDylibs to sets of symbols.
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
SymbolState
Represents the state that a symbol has reached during materialization.
@ Materializing
Added to the symbol table, never queried.
@ NeverSearched
No symbol should be in this state.
@ Ready
Emitted to memory, but waiting on transitive dependencies.
@ Resolved
Queried, materialization begun.
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
LLVM_ABI std::error_code orcError(OrcErrorCode ErrCode)
unique_function< void(Expected< SymbolMap >)> SymbolsResolvedCallback
Callback to notify client that symbols have been resolved.
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.