llvm.org GIT mirror llvm / 883ef72
[ORC] Update symbol lookup to use a single callback with a required symbol state rather than two callbacks. The asynchronous lookup API (which the synchronous lookup API wraps for convenience) used to take two callbacks: OnResolved (called once all requested symbols had an address assigned) and OnReady to be called once all requested symbols were safe to access). This patch updates the asynchronous lookup API to take a single 'OnComplete' callback and a required state (SymbolState) to determine when the callback should be made. This simplifies the common use case (where the client is interested in a specific state) and will generalize neatly as new states are introduced to track runtime initialization of symbols. Clients who were making use of both callbacks in a single query will now need to issue two queries (one for SymbolState::Resolved and another for SymbolState::Ready). Synchronous lookup API clients who were explicitly passing the WaitOnReady argument will now need neeed to pass a SymbolState instead (for 'WaitOnReady == true' use SymbolState::Ready, for 'WaitOnReady == false' use SymbolState::Resolved). Synchronous lookup API clients who were using default arugment values should see no change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362832 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames a month ago
13 changed file(s) with 464 addition(s) and 644 deletion(s). Raw diff Collapse all Expand all
3232 class MaterializationUnit;
3333 class MaterializationResponsibility;
3434 class JITDylib;
35 enum class SymbolState : uint8_t;
3536
3637 /// VModuleKey provides a unique identifier (allocated and managed by
3738 /// ExecutionSessions) for a module added to the JIT.
5556 /// A list of (JITDylib*, bool) pairs.
5657 using JITDylibSearchList = std::vector>;
5758
59 struct SymbolAliasMapEntry {
60 SymbolAliasMapEntry() = default;
61 SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
62 : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
63
64 SymbolStringPtr Aliasee;
65 JITSymbolFlags AliasFlags;
66 };
67
68 /// A map of Symbols to (Symbol, Flags) pairs.
69 using SymbolAliasMap = DenseMap;
70
5871 /// Render a SymbolStringPtr.
5972 raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
6073
8699 /// Render a JITDylibSearchList.
87100 raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs);
88101
102 /// Render a SymbolAliasMap.
103 raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
104
105 /// Render a SymbolState.
106 raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
107
89108 /// Callback to notify client that symbols have been resolved.
90109 using SymbolsResolvedCallback = std::function)>;
91
92 /// Callback to notify client that symbols are ready for execution.
93 using SymbolsReadyCallback = std::function;
94110
95111 /// Callback to register the dependencies for a given query.
96112 using RegisterDependenciesFunction =
331347 return llvm::make_unique(
332348 std::move(Symbols), std::move(K));
333349 }
334
335 struct SymbolAliasMapEntry {
336 SymbolAliasMapEntry() = default;
337 SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
338 : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
339
340 SymbolStringPtr Aliasee;
341 JITSymbolFlags AliasFlags;
342 };
343
344 /// A map of Symbols to (Symbol, Flags) pairs.
345 using SymbolAliasMap = DenseMap;
346350
347351 /// A materialization unit for symbol aliases. Allows existing symbols to be
348352 /// aliased with alternate flags.
425429 SymbolPredicate Allow;
426430 };
427431
432 /// Represents the state that a symbol has reached during materialization.
433 enum class SymbolState : uint8_t {
434 Invalid, /// No symbol should be in this state.
435 NeverSearched, /// Added to the symbol table, never queried.
436 Materializing, /// Queried, materialization begun.
437 Resolved, /// Assigned address, still materializing.
438 Ready = 0x3f /// Ready and safe for clients to access.
439 };
440
428441 /// A symbol query that returns results via a callback when results are
429442 /// ready.
430443 ///
435448 friend class JITSymbolResolverAdapter;
436449
437450 public:
438
439 /// Create a query for the given symbols, notify-resolved and
440 /// notify-ready callbacks.
451 /// Create a query for the given symbols. The NotifyComplete
452 /// callback will be called once all queried symbols reach the given
453 /// minimum state.
441454 AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
442 SymbolsResolvedCallback NotifySymbolsResolved,
443 SymbolsReadyCallback NotifySymbolsReady);
444
445 /// Set the resolved symbol information for the given symbol name.
446 void resolve(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym);
455 SymbolState RequiredState,
456 SymbolsResolvedCallback NotifyComplete);
457
458 /// Notify the query that a requested symbol has reached the required state.
459 void notifySymbolMetRequiredState(const SymbolStringPtr &Name,
460 JITEvaluatedSymbol Sym);
447461
448462 /// Returns true if all symbols covered by this query have been
449463 /// resolved.
450 bool isFullyResolved() const { return NotYetResolvedCount == 0; }
451
452 /// Call the NotifySymbolsResolved callback.
453 ///
454 /// This should only be called if all symbols covered by the query have been
455 /// resolved.
456 void handleFullyResolved();
457
458 /// Notify the query that a requested symbol is ready for execution.
459 void notifySymbolReady();
460
461 /// Returns true if all symbols covered by this query are ready.
462 bool isFullyReady() const { return NotYetReadyCount == 0; }
463
464 /// Calls the NotifySymbolsReady callback.
465 ///
466 /// This should only be called if all symbols covered by this query are ready.
467 void handleFullyReady();
468
469 private:
464 bool isComplete() const { return OutstandingSymbolsCount == 0; }
465
466 /// Call the NotifyComplete callback.
467 ///
468 /// This should only be called if all symbols covered by the query have
469 /// reached the specified state.
470 void handleComplete();
471
472 private:
473 SymbolState getRequiredState() { return RequiredState; }
474
470475 void addQueryDependence(JITDylib &JD, SymbolStringPtr Name);
471476
472477 void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
477482
478483 void detach();
479484
480 SymbolsResolvedCallback NotifySymbolsResolved;
481 SymbolsReadyCallback NotifySymbolsReady;
485 SymbolsResolvedCallback NotifyComplete;
482486 SymbolDependenceMap QueryRegistrations;
483487 SymbolMap ResolvedSymbols;
484 size_t NotYetResolvedCount;
485 size_t NotYetReadyCount;
488 size_t OutstandingSymbolsCount;
489 SymbolState RequiredState;
486490 };
487491
488492 /// A symbol table that supports asynchoronous symbol queries.
625629 DenseMap>;
626630
627631 struct MaterializingInfo {
628 AsynchronousSymbolQueryList PendingQueries;
629632 SymbolDependenceMap Dependants;
630633 SymbolDependenceMap UnemittedDependencies;
631634 bool IsEmitted = false;
635
636 void addQuery(std::shared_ptr Q);
637 void removeQuery(const AsynchronousSymbolQuery &Q);
638 AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState);
639 AsynchronousSymbolQueryList takeAllQueries();
640 bool hasQueriesPending() const { return !PendingQueries.empty(); }
641 const AsynchronousSymbolQueryList &pendingQueries() const {
642 return PendingQueries;
643 }
644
645 private:
646 AsynchronousSymbolQueryList PendingQueries;
632647 };
633648
634649 using MaterializingInfosMap = DenseMap;
635
636 using LookupImplActionFlags = enum {
637 None = 0,
638 NotifyFullyResolved = 1 << 0U,
639 NotifyFullyReady = 1 << 1U,
640 LLVM_MARK_AS_BITMASK_ENUM(NotifyFullyReady)
641 };
642
643 enum class SymbolState : uint8_t {
644 Invalid, // No symbol should be in this state.
645 NeverSearched, // Added to the symbol table, never queried.
646 Materializing, // Queried, materialization begun.
647 Resolved, // Assigned address, still materializing.
648 Ready = 0x3f // Ready and safe for clients to access.
649 };
650650
651651 class SymbolTableEntry {
652652 public:
712712 SymbolNameSet &Unresolved, bool MatchNonExported,
713713 MaterializationUnitList &MUs);
714714
715 LookupImplActionFlags
716 lookupImpl(std::shared_ptr &Q,
717 std::vector> &MUs,
718 SymbolNameSet &Unresolved);
715 bool lookupImpl(std::shared_ptr &Q,
716 std::vector> &MUs,
717 SymbolNameSet &Unresolved);
719718
720719 void detachQueryHelper(AsynchronousSymbolQuery &Q,
721720 const SymbolNameSet &QuerySymbols);
832831 /// Do not use -- this will be removed soon.
833832 Expected
834833 legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
835 bool WaiUntilReady,
834 SymbolState RequiredState,
836835 RegisterDependenciesFunction RegisterDependencies);
837836
838837 /// Search the given JITDylib list for the given symbols.
842841 /// (hidden visibility) symbols in that dylib (true means match against
843842 /// non-exported symbols, false means do not match).
844843 ///
845 /// The OnResolve callback will be called once all requested symbols are
846 /// resolved, or if an error occurs prior to resolution.
847 ///
848 /// The OnReady callback will be called once all requested symbols are ready,
849 /// or if an error occurs after resolution but before all symbols are ready.
844 /// The NotifyComplete callback will be called once all requested symbols
845 /// reach the required state.
850846 ///
851847 /// If all symbols are found, the RegisterDependencies function will be called
852848 /// while the session lock is held. This gives clients a chance to register
858854 /// client to get an address to call) then the value NoDependenciesToRegister
859855 /// can be used.
860856 void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
861 SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
857 SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
862858 RegisterDependenciesFunction RegisterDependencies);
863859
864860 /// Blocking version of lookup above. Returns the resolved symbol map.
870866 /// error will be reported via reportErrors.
871867 Expected lookup(const JITDylibSearchList &SearchOrder,
872868 const SymbolNameSet &Symbols,
869 SymbolState RequiredState = SymbolState::Ready,
873870 RegisterDependenciesFunction RegisterDependencies =
874 NoDependenciesToRegister,
875 bool WaitUntilReady = true);
871 NoDependenciesToRegister);
876872
877873 /// Convenience version of blocking lookup.
878874 /// Searches each of the JITDylibs in the search order in turn for the given
895891 /// Materialize the given unit.
896892 void dispatchMaterialization(JITDylib &JD,
897893 std::unique_ptr MU) {
898 LLVM_DEBUG(runSessionLocked([&]() {
899 dbgs() << "Compiling, for " << JD.getName() << ", " << *MU
900 << "\n";
901 }););
894 LLVM_DEBUG({
895 runSessionLocked([&]() {
896 dbgs() << "Dispatching " << *MU << " for " << JD.getName() << "\n";
897 });
898 });
902899 DispatchMaterialization(JD, std::move(MU));
903900 }
904901
147147 for (auto &S : Symbols) {
148148 if (JITSymbol Sym = FindSymbol(*S)) {
149149 if (auto Addr = Sym.getAddress()) {
150 Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
151 Query.notifySymbolReady();
150 Query.notifySymbolMetRequiredState(
151 S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
152152 NewSymbolsResolved = true;
153153 } else {
154154 ES.legacyFailQuery(Query, Addr.takeError());
161161 SymbolsNotFound.insert(S);
162162 }
163163
164 if (NewSymbolsResolved && Query.isFullyResolved())
165 Query.handleFullyResolved();
166
167 if (NewSymbolsResolved && Query.isFullyReady())
168 Query.handleFullyReady();
164 if (NewSymbolsResolved && Query.isComplete())
165 Query.handleComplete();
169166
170167 return SymbolsNotFound;
171168 }
218218 return OS;
219219 }
220220
221 raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases) {
222 OS << "{";
223 for (auto &KV : Aliases)
224 OS << " " << *KV.first << ": " << KV.second.Aliasee << " "
225 << KV.second.AliasFlags;
226 OS << " }\n";
227 return OS;
228 }
229
230 raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S) {
231 switch (S) {
232 case SymbolState::Invalid:
233 return OS << "Invalid";
234 case SymbolState::NeverSearched:
235 return OS << "Never-Searched";
236 case SymbolState::Materializing:
237 return OS << "Materializing";
238 case SymbolState::Resolved:
239 return OS << "Resolved";
240 case SymbolState::Ready:
241 return OS << "Ready";
242 }
243 llvm_unreachable("Invalid state");
244 }
245
221246 FailedToMaterialize::FailedToMaterialize(SymbolNameSet Symbols)
222247 : Symbols(std::move(Symbols)) {
223248 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
258283 }
259284
260285 AsynchronousSymbolQuery::AsynchronousSymbolQuery(
261 const SymbolNameSet &Symbols, SymbolsResolvedCallback NotifySymbolsResolved,
262 SymbolsReadyCallback NotifySymbolsReady)
263 : NotifySymbolsResolved(std::move(NotifySymbolsResolved)),
264 NotifySymbolsReady(std::move(NotifySymbolsReady)) {
265 NotYetResolvedCount = NotYetReadyCount = Symbols.size();
286 const SymbolNameSet &Symbols, SymbolState RequiredState,
287 SymbolsResolvedCallback NotifyComplete)
288 : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
289 assert(RequiredState >= SymbolState::Resolved &&
290 "Cannot query for a symbols that have not reached the resolve state "
291 "yet");
292
293 OutstandingSymbolsCount = Symbols.size();
266294
267295 for (auto &S : Symbols)
268296 ResolvedSymbols[S] = nullptr;
269297 }
270298
271 void AsynchronousSymbolQuery::resolve(const SymbolStringPtr &Name,
272 JITEvaluatedSymbol Sym) {
299 void AsynchronousSymbolQuery::notifySymbolMetRequiredState(
300 const SymbolStringPtr &Name, JITEvaluatedSymbol Sym) {
273301 auto I = ResolvedSymbols.find(Name);
274302 assert(I != ResolvedSymbols.end() &&
275303 "Resolving symbol outside the requested set");
276304 assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name");
277305 I->second = std::move(Sym);
278 --NotYetResolvedCount;
279 }
280
281 void AsynchronousSymbolQuery::handleFullyResolved() {
282 assert(NotYetResolvedCount == 0 && "Not fully resolved?");
283
284 if (!NotifySymbolsResolved) {
285 // handleFullyResolved may be called by handleFullyReady (see comments in
286 // that method), in which case this is a no-op, so bail out.
287 assert(!NotifySymbolsReady &&
288 "NotifySymbolsResolved already called or an error occurred");
289 return;
290 }
291
292 auto TmpNotifySymbolsResolved = std::move(NotifySymbolsResolved);
293 NotifySymbolsResolved = SymbolsResolvedCallback();
294 TmpNotifySymbolsResolved(std::move(ResolvedSymbols));
295 }
296
297 void AsynchronousSymbolQuery::notifySymbolReady() {
298 assert(NotYetReadyCount != 0 && "All symbols already emitted");
299 --NotYetReadyCount;
300 }
301
302 void AsynchronousSymbolQuery::handleFullyReady() {
303 assert(NotifySymbolsReady &&
304 "NotifySymbolsReady already called or an error occurred");
305
306 auto TmpNotifySymbolsReady = std::move(NotifySymbolsReady);
307 NotifySymbolsReady = SymbolsReadyCallback();
308
309 if (NotYetResolvedCount == 0 && NotifySymbolsResolved) {
310 // The NotifyResolved callback of one query must have caused this query to
311 // become ready (i.e. there is still a handleFullyResolved callback waiting
312 // to be made back up the stack). Fold the handleFullyResolved call into
313 // this one before proceeding. This will cause the call further up the
314 // stack to become a no-op.
315 handleFullyResolved();
316 }
317
318 assert(QueryRegistrations.empty() &&
319 "Query is still registered with some symbols");
320 assert(!NotifySymbolsResolved && "Resolution not applied yet");
321 TmpNotifySymbolsReady(Error::success());
322 }
323
324 bool AsynchronousSymbolQuery::canStillFail() {
325 return (NotifySymbolsResolved || NotifySymbolsReady);
326 }
306 --OutstandingSymbolsCount;
307 }
308
309 void AsynchronousSymbolQuery::handleComplete() {
310 assert(OutstandingSymbolsCount == 0 &&
311 "Symbols remain, handleComplete called prematurely");
312
313 auto TmpNotifyComplete = std::move(NotifyComplete);
314 NotifyComplete = SymbolsResolvedCallback();
315 TmpNotifyComplete(std::move(ResolvedSymbols));
316 }
317
318 bool AsynchronousSymbolQuery::canStillFail() { return !!NotifyComplete; }
327319
328320 void AsynchronousSymbolQuery::handleFailed(Error Err) {
329321 assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
330 NotYetResolvedCount == 0 && NotYetReadyCount == 0 &&
322 OutstandingSymbolsCount == 0 &&
331323 "Query should already have been abandoned");
332 if (NotifySymbolsResolved) {
333 NotifySymbolsResolved(std::move(Err));
334 NotifySymbolsResolved = SymbolsResolvedCallback();
335 } else {
336 assert(NotifySymbolsReady && "Failed after both callbacks issued?");
337 NotifySymbolsReady(std::move(Err));
338 }
339 NotifySymbolsReady = SymbolsReadyCallback();
324 NotifyComplete(std::move(Err));
325 NotifyComplete = SymbolsResolvedCallback();
340326 }
341327
342328 void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
359345
360346 void AsynchronousSymbolQuery::detach() {
361347 ResolvedSymbols.clear();
362 NotYetResolvedCount = 0;
363 NotYetReadyCount = 0;
348 OutstandingSymbolsCount = 0;
364349 for (auto &KV : QueryRegistrations)
365350 KV.first->detachQueryHelper(*this, KV.second);
366351 QueryRegistrations.clear();
547532 Aliases.erase(I);
548533 }
549534
535 LLVM_DEBUG({
536 ES.runSessionLocked([&]() {
537 dbgs() << "materializing reexports: target = " << TgtJD.getName()
538 << ", source = " << SrcJD.getName() << " " << RequestedAliases
539 << "\n";
540 });
541 });
542
550543 if (!Aliases.empty()) {
551544 if (SourceJD)
552545 R.replace(reexports(*SourceJD, std::move(Aliases), MatchNonExported));
629622 }
630623 };
631624
632 auto OnResolve = [QueryInfo](Expected Result) {
625 auto OnComplete = [QueryInfo](Expected Result) {
633626 if (Result) {
634627 SymbolMap ResolutionMap;
635628 for (auto &KV : QueryInfo->Aliases) {
647640 }
648641 };
649642
650 auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
651
652643 ES.lookup(JITDylibSearchList({{&SrcJD, MatchNonExported}}), QuerySymbols,
653 std::move(OnResolve), std::move(OnReady),
644 SymbolState::Resolved, std::move(OnComplete),
654645 std::move(RegisterDependencies));
655646 }
656647 }
775766 for (auto &KV : MU->getSymbols()) {
776767 auto MII = MaterializingInfos.find(KV.first);
777768 if (MII != MaterializingInfos.end()) {
778 if (!MII->second.PendingQueries.empty())
769 if (MII->second.hasQueriesPending())
779770 return std::move(MU);
780771 }
781772 }
816807 if (I == MaterializingInfos.end())
817808 continue;
818809
819 if (!I->second.PendingQueries.empty())
810 if (I->second.hasQueriesPending())
820811 RequestedSymbols.insert(KV.first);
821812 }
822813
863854 }
864855
865856 void JITDylib::resolve(const SymbolMap &Resolved) {
866 auto FullyResolvedQueries = ES.runSessionLocked([&, this]() {
867 AsynchronousSymbolQuerySet FullyResolvedQueries;
857 auto CompletedQueries = ES.runSessionLocked([&, this]() {
858 AsynchronousSymbolQuerySet CompletedQueries;
868859 for (const auto &KV : Resolved) {
869860 auto &Name = KV.first;
870861 auto Sym = KV.second;
890881 I->second.setState(SymbolState::Resolved);
891882
892883 auto &MI = MaterializingInfos[Name];
893 for (auto &Q : MI.PendingQueries) {
894 Q->resolve(Name, Sym);
895 if (Q->isFullyResolved())
896 FullyResolvedQueries.insert(Q);
884 for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
885 Q->notifySymbolMetRequiredState(Name, Sym);
886 if (Q->isComplete())
887 CompletedQueries.insert(std::move(Q));
897888 }
898889 }
899890
900 return FullyResolvedQueries;
901 });
902
903 for (auto &Q : FullyResolvedQueries) {
904 assert(Q->isFullyResolved() && "Q not fully resolved");
905 Q->handleFullyResolved();
891 return CompletedQueries;
892 });
893
894 for (auto &Q : CompletedQueries) {
895 assert(Q->isComplete() && "Q not completed");
896 Q->handleComplete();
906897 }
907898 }
908899
909900 void JITDylib::emit(const SymbolFlagsMap &Emitted) {
910 auto FullyReadyQueries = ES.runSessionLocked([&, this]() {
911 AsynchronousSymbolQuerySet ReadyQueries;
901 auto CompletedQueries = ES.runSessionLocked([&, this]() {
902 AsynchronousSymbolQuerySet CompletedQueries;
912903
913904 for (const auto &KV : Emitted) {
914905 const auto &Name = KV.first;
950941 DependantMI.UnemittedDependencies.empty()) {
951942 assert(DependantMI.Dependants.empty() &&
952943 "Dependants should be empty by now");
953 for (auto &Q : DependantMI.PendingQueries) {
954 Q->notifySymbolReady();
955 if (Q->isFullyReady())
956 ReadyQueries.insert(Q);
944
945 // Since this dependant is now ready, we erase its MaterializingInfo
946 // and update its materializing state.
947 auto DependantSymI = DependantJD.Symbols.find(DependantName);
948 assert(DependantSymI != DependantJD.Symbols.end() &&
949 "Dependant has no entry in the Symbols table");
950 DependantSymI->second.setState(SymbolState::Ready);
951
952 for (auto &Q : DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
953 Q->notifySymbolMetRequiredState(
954 DependantName, DependantSymI->second.getSymbol());
955 if (Q->isComplete())
956 CompletedQueries.insert(Q);
957957 Q->removeQueryDependence(DependantJD, DependantName);
958958 }
959959
960 // Since this dependant is now ready, we erase its MaterializingInfo
961 // and update its materializing state.
962 assert(DependantJD.Symbols.count(DependantName) &&
963 "Dependant has no entry in the Symbols table");
964 DependantJD.Symbols[DependantName].setState(SymbolState::Ready);
965960 DependantJD.MaterializingInfos.erase(DependantMII);
966961 }
967962 }
970965 MI.IsEmitted = true;
971966
972967 if (MI.UnemittedDependencies.empty()) {
973 for (auto &Q : MI.PendingQueries) {
974 Q->notifySymbolReady();
975 if (Q->isFullyReady())
976 ReadyQueries.insert(Q);
968 auto SymI = Symbols.find(Name);
969 assert(SymI != Symbols.end() && "Symbol has no entry in Symbols table");
970 SymI->second.setState(SymbolState::Ready);
971 for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
972 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
973 if (Q->isComplete())
974 CompletedQueries.insert(Q);
977975 Q->removeQueryDependence(*this, Name);
978976 }
979 assert(Symbols.count(Name) &&
980 "Symbol has no entry in the Symbols table");
981 Symbols[Name].setState(SymbolState::Ready);
982977 MaterializingInfos.erase(MII);
983978 }
984979 }
985980
986 return ReadyQueries;
987 });
988
989 for (auto &Q : FullyReadyQueries) {
990 assert(Q->isFullyReady() && "Q is not fully ready");
991 Q->handleFullyReady();
981 return CompletedQueries;
982 });
983
984 for (auto &Q : CompletedQueries) {
985 assert(Q->isComplete() && "Q is not complete");
986 Q->handleComplete();
992987 }
993988 }
994989
998993
999994 auto FailedQueriesToNotify = ES.runSessionLocked([&, this]() {
1000995 AsynchronousSymbolQuerySet FailedQueries;
996 std::vector MIIsToRemove;
1001997
1002998 for (auto &Name : FailedSymbols) {
1003999 auto I = Symbols.find(Name);
10321028 // This has to be a copy, and the copy has to come before the abandon
10331029 // operation: Each Q.detach() call will reach back into this
10341030 // PendingQueries list to remove Q.
1035 for (auto &Q : MII->second.PendingQueries)
1031 for (auto &Q : MII->second.pendingQueries())
10361032 FailedQueries.insert(Q);
10371033
1038 for (auto &Q : FailedQueries)
1039 Q->detach();
1040
1041 assert(MII->second.PendingQueries.empty() &&
1034 MIIsToRemove.push_back(std::move(MII));
1035 }
1036
1037 // Detach failed queries.
1038 for (auto &Q : FailedQueries)
1039 Q->detach();
1040
1041 // Remove the MaterializingInfos.
1042 for (auto &MII : MIIsToRemove) {
1043 assert(!MII->second.hasQueriesPending() &&
10421044 "Queries remain after symbol was failed");
10431045
10441046 MaterializingInfos.erase(MII);
12271229 if (!SymI->second.getFlags().isExported() && !MatchNonExported)
12281230 continue;
12291231
1230 // If we matched against Name in JD, mark it to be removed from the Unresolved
1231 // set.
1232 // If we matched against Name in JD, mark it to be removed from the
1233 // Unresolved set.
12321234 ToRemove.push_back(Name);
12331235
1234 if (SymI->second.getState() >= SymbolState::Resolved) {
1235 assert(!SymI->second.hasMaterializerAttached() &&
1236 "Resolved symbols should not have materializers attached");
1237 Q->resolve(Name, SymI->second.getSymbol());
1238 if (SymI->second.getState() == SymbolState::Ready) {
1239 Q->notifySymbolReady();
1240 continue;
1241 }
1242 } else if (SymI->second.hasMaterializerAttached()) {
1236 // If this symbol already meets the required state for then notify the
1237 // query and continue.
1238 if (SymI->second.getState() >= Q->getRequiredState()) {
1239 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1240 continue;
1241 }
1242
1243 // Otherwise this symbol does not yet meet the required state. Check whether
1244 // it has a materializer attached, and if so prepare to run it.
1245 if (SymI->second.hasMaterializerAttached()) {
12431246 assert(SymI->second.getAddress() == 0 &&
12441247 "Symbol not resolved but already has address?");
12451248 auto UMII = UnmaterializedInfos.find(Name);
12651268 assert(SymI->second.isInMaterializationPhase() &&
12661269 "By this line the symbol should be materializing");
12671270 auto &MI = MaterializingInfos[Name];
1268 MI.PendingQueries.push_back(Q);
1271 MI.addQuery(Q);
12691272 Q->addQueryDependence(*this, Name);
12701273 }
12711274
12811284
12821285 ES.runOutstandingMUs();
12831286
1284 LookupImplActionFlags ActionFlags = None;
1287 bool QueryComplete = false;
12851288 std::vector> MUs;
12861289
12871290 SymbolNameSet Unresolved = std::move(Names);
12881291 auto Err = ES.runSessionLocked([&, this]() -> Error {
1289 ActionFlags = lookupImpl(Q, MUs, Unresolved);
1292 QueryComplete = lookupImpl(Q, MUs, Unresolved);
12901293 if (DefGenerator && !Unresolved.empty()) {
1291 assert(ActionFlags == None &&
1292 "ActionFlags set but unresolved symbols remain?");
1294 assert(!QueryComplete && "query complete but unresolved symbols remain?");
12931295 auto NewDefs = DefGenerator(*this, Unresolved);
12941296 if (!NewDefs)
12951297 return NewDefs.takeError();
12961298 if (!NewDefs->empty()) {
12971299 for (auto &D : *NewDefs)
12981300 Unresolved.erase(D);
1299 ActionFlags = lookupImpl(Q, MUs, *NewDefs);
1301 QueryComplete = lookupImpl(Q, MUs, *NewDefs);
13001302 assert(NewDefs->empty() &&
13011303 "All fallback defs should have been found by lookupImpl");
13021304 }
13071309 if (Err)
13081310 return std::move(Err);
13091311
1310 assert((MUs.empty() || ActionFlags == None) &&
1312 assert((MUs.empty() || !QueryComplete) &&
13111313 "If action flags are set, there should be no work to do (so no MUs)");
13121314
1313 if (ActionFlags & NotifyFullyResolved)
1314 Q->handleFullyResolved();
1315
1316 if (ActionFlags & NotifyFullyReady)
1317 Q->handleFullyReady();
1315 if (QueryComplete)
1316 Q->handleComplete();
13181317
13191318 // FIXME: Swap back to the old code below once RuntimeDyld works with
13201319 // callbacks from asynchronous queries.
13331332 return Unresolved;
13341333 }
13351334
1336 JITDylib::LookupImplActionFlags
1337 JITDylib::lookupImpl(std::shared_ptr &Q,
1338 std::vector> &MUs,
1339 SymbolNameSet &Unresolved) {
1340 LookupImplActionFlags ActionFlags = None;
1335 bool JITDylib::lookupImpl(
1336 std::shared_ptr &Q,
1337 std::vector> &MUs,
1338 SymbolNameSet &Unresolved) {
1339 bool QueryComplete = false;
1340
13411341 std::vector ToRemove;
1342
13431342 for (auto Name : Unresolved) {
13441343
13451344 // Search for the name in Symbols. Skip it if not found.
13501349 // If we found Name, mark it to be removed from the Unresolved set.
13511350 ToRemove.push_back(Name);
13521351
1353 // If the symbol has an address then resolve it.
1354 if (SymI->second.getAddress() != 0) {
1355 Q->resolve(Name, SymI->second.getSymbol());
1356 if (Q->isFullyResolved())
1357 ActionFlags |= NotifyFullyResolved;
1352 if (SymI->second.getState() >= Q->getRequiredState()) {
1353 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1354 if (Q->isComplete())
1355 QueryComplete = true;
1356 continue;
13581357 }
13591358
13601359 // If the symbol is lazy, get the MaterialiaztionUnit for it.
13791378
13801379 // Add MU to the list of MaterializationUnits to be materialized.
13811380 MUs.push_back(std::move(MU));
1382 } else if (SymI->second.getState() == SymbolState::Ready) {
1383 Q->notifySymbolReady();
1384 if (Q->isFullyReady())
1385 ActionFlags |= NotifyFullyReady;
1386 continue;
13871381 }
13881382
13891383 // Add the query to the PendingQueries list.
13901384 assert(SymI->second.isInMaterializationPhase() &&
13911385 "By this line the symbol should be materializing");
13921386 auto &MI = MaterializingInfos[Name];
1393 MI.PendingQueries.push_back(Q);
1387 MI.addQuery(Q);
13941388 Q->addQueryDependence(*this, Name);
13951389 }
13961390
13981392 for (auto &Name : ToRemove)
13991393 Unresolved.erase(Name);
14001394
1401 return ActionFlags;
1395 return QueryComplete;
14021396 }
14031397
14041398 void JITDylib::dump(raw_ostream &OS) {
14201414 else
14211415 OS << " ";
14221416
1423 switch (KV.second.getState()) {
1424 case SymbolState::Invalid:
1425 OS << "Invalid";
1426 break;
1427 case SymbolState::NeverSearched:
1428 OS << "Never-Searched";
1429 break;
1430 case SymbolState::Materializing:
1431 OS << "Materializing";
1432 break;
1433 case SymbolState::Resolved:
1434 OS << "Resolved";
1435 break;
1436 case SymbolState::Ready:
1437 OS << "Ready";
1438 break;
1439 // default: llvm_unreachable("Invalid state"); break;
1440 }
1417 OS << KV.second.getState();
14411418
14421419 if (KV.second.hasMaterializerAttached()) {
14431420 OS << " (Materializer ";
14551432 OS << " \"" << *KV.first << "\":\n"
14561433 << " IsEmitted = " << (KV.second.IsEmitted ? "true" : "false")
14571434 << "\n"
1458 << " " << KV.second.PendingQueries.size()
1435 << " " << KV.second.pendingQueries().size()
14591436 << " pending queries: { ";
1460 for (auto &Q : KV.second.PendingQueries)
1461 OS << Q.get() << " ";
1437 for (const auto &Q : KV.second.pendingQueries())
1438 OS << Q.get() << " (" << Q->getRequiredState() << ") ";
14621439 OS << "}\n Dependants:\n";
14631440 for (auto &KV2 : KV.second.Dependants)
14641441 OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
14671444 OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
14681445 }
14691446 });
1447 }
1448
1449 void JITDylib::MaterializingInfo::addQuery(
1450 std::shared_ptr Q) {
1451
1452 auto I = std::lower_bound(
1453 PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1454 [](const std::shared_ptr &V, SymbolState S) {
1455 return V->getRequiredState() <= S;
1456 });
1457 PendingQueries.insert(I.base(), std::move(Q));
1458 }
1459
1460 void JITDylib::MaterializingInfo::removeQuery(
1461 const AsynchronousSymbolQuery &Q) {
1462 // FIXME: Implement 'find_as' for shared_ptr/T*.
1463 auto I =
1464 std::find_if(PendingQueries.begin(), PendingQueries.end(),
1465 [&Q](const std::shared_ptr &V) {
1466 return V.get() == &Q;
1467 });
1468 assert(I != PendingQueries.end() &&
1469 "Query is not attached to this MaterializingInfo");
1470 PendingQueries.erase(I);
1471 }
1472
1473 JITDylib::AsynchronousSymbolQueryList
1474 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1475 AsynchronousSymbolQueryList Result;
1476 while (!PendingQueries.empty()) {
1477 if (PendingQueries.back()->getRequiredState() > RequiredState)
1478 break;
1479
1480 Result.push_back(std::move(PendingQueries.back()));
1481 PendingQueries.pop_back();
1482 }
1483
1484 return Result;
1485 }
1486
1487 JITDylib::AsynchronousSymbolQueryList
1488 JITDylib::MaterializingInfo::takeAllQueries() {
1489 AsynchronousSymbolQueryList Result;
1490 std::swap(Result, PendingQueries);
1491 return Result;
14701492 }
14711493
14721494 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
15321554 assert(MaterializingInfos.count(QuerySymbol) &&
15331555 "QuerySymbol does not have MaterializingInfo");
15341556 auto &MI = MaterializingInfos[QuerySymbol];
1535
1536 auto IdenticalQuery =
1537 [&](const std::shared_ptr &R) {
1538 return R.get() == &Q;
1539 };
1540
1541 auto I = std::find_if(MI.PendingQueries.begin(), MI.PendingQueries.end(),
1542 IdenticalQuery);
1543 assert(I != MI.PendingQueries.end() &&
1544 "Query Q should be in the PendingQueries list for QuerySymbol");
1545 MI.PendingQueries.erase(I);
1557 MI.removeQuery(Q);
15461558 }
15471559 }
15481560
16201632
16211633 Expected ExecutionSession::legacyLookup(
16221634 LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
1623 bool WaitUntilReady, RegisterDependenciesFunction RegisterDependencies) {
1635 SymbolState RequiredState,
1636 RegisterDependenciesFunction RegisterDependencies) {
16241637 #if LLVM_ENABLE_THREADS
16251638 // In the threaded case we use promises to return the results.
16261639 std::promise PromisedResult;
1627 std::mutex ErrMutex;
16281640 Error ResolutionError = Error::success();
1629 std::promise PromisedReady;
1630 Error ReadyError = Error::success();
1631 auto OnResolve = [&](Expected R) {
1641 auto NotifyComplete = [&](Expected R) {
16321642 if (R)
16331643 PromisedResult.set_value(std::move(*R));
16341644 else {
1635 {
1636 ErrorAsOutParameter _(&ResolutionError);
1637 std::lock_guard Lock(ErrMutex);
1638 ResolutionError = R.takeError();
1639 }
1645 ErrorAsOutParameter _(&ResolutionError);
1646 ResolutionError = R.takeError();
16401647 PromisedResult.set_value(SymbolMap());
16411648 }
16421649 };
1643
1644 std::function OnReady;
1645 if (WaitUntilReady) {
1646 OnReady = [&](Error Err) {
1647 if (Err) {
1648 ErrorAsOutParameter _(&ReadyError);
1649 std::lock_guard Lock(ErrMutex);
1650 ReadyError = std::move(Err);
1651 }
1652 PromisedReady.set_value();
1653 };
1654 } else {
1655 OnReady = [&](Error Err) {
1656 if (Err)
1657 reportError(std::move(Err));
1658 };
1659 }
1660
16611650 #else
16621651 SymbolMap Result;
16631652 Error ResolutionError = Error::success();
1664 Error ReadyError = Error::success();
1665
1666 auto OnResolve = [&](Expected R) {
1653
1654 auto NotifyComplete = [&](Expected R) {
16671655 ErrorAsOutParameter _(&ResolutionError);
16681656 if (R)
16691657 Result = std::move(*R);
16701658 else
16711659 ResolutionError = R.takeError();
16721660 };
1673
1674 std::function OnReady;
1675 if (WaitUntilReady) {
1676 OnReady = [&](Error Err) {
1677 ErrorAsOutParameter _(&ReadyError);
1678 if (Err)
1679 ReadyError = std::move(Err);
1680 };
1681 } else {
1682 OnReady = [&](Error Err) {
1683 if (Err)
1684 reportError(std::move(Err));
1685 };
1686 }
16871661 #endif
16881662
16891663 auto Query = std::make_shared(
1690 Names, std::move(OnResolve), std::move(OnReady));
1664 Names, RequiredState, std::move(NotifyComplete));
16911665 // FIXME: This should be run session locked along with the registration code
16921666 // and error reporting below.
16931667 SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names));
17111685 #if LLVM_ENABLE_THREADS
17121686 auto ResultFuture = PromisedResult.get_future();
17131687 auto Result = ResultFuture.get();
1714
1715 {
1716 std::lock_guard Lock(ErrMutex);
1717 if (ResolutionError) {
1718 // ReadyError will never be assigned. Consume the success value.
1719 cantFail(std::move(ReadyError));
1720 return std::move(ResolutionError);
1721 }
1722 }
1723
1724 if (WaitUntilReady) {
1725 auto ReadyFuture = PromisedReady.get_future();
1726 ReadyFuture.get();
1727
1728 {
1729 std::lock_guard Lock(ErrMutex);
1730 if (ReadyError)
1731 return std::move(ReadyError);
1732 }
1733 } else
1734 cantFail(std::move(ReadyError));
1735
1688 if (ResolutionError)
1689 return std::move(ResolutionError);
17361690 return std::move(Result);
17371691
17381692 #else
1739 if (ResolutionError) {
1740 // ReadyError will never be assigned. Consume the success value.
1741 cantFail(std::move(ReadyError));
1693 if (ResolutionError)
17421694 return std::move(ResolutionError);
1743 }
1744
1745 if (ReadyError)
1746 return std::move(ReadyError);
17471695
17481696 return Result;
17491697 #endif
17511699
17521700 void ExecutionSession::lookup(
17531701 const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
1754 SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
1702 SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
17551703 RegisterDependenciesFunction RegisterDependencies) {
1704
1705 LLVM_DEBUG({
1706 runSessionLocked([&]() {
1707 dbgs() << "Looking up " << Symbols << " in " << SearchOrder
1708 << " (required state: " << RequiredState << ")\n";
1709 });
1710 });
17561711
17571712 // lookup can be re-entered recursively if running on a single thread. Run any
17581713 // outstanding MUs in case this query depends on them, otherwise this lookup
17611716
17621717 auto Unresolved = std::move(Symbols);
17631718 std::map CollectedMUsMap;
1764 auto Q = std::make_shared(
1765 Unresolved, std::move(OnResolve), std::move(OnReady));
1766 bool QueryIsFullyResolved = false;
1767 bool QueryIsFullyReady = false;
1719 auto Q = std::make_shared(Unresolved, RequiredState,
1720 std::move(NotifyComplete));
1721 bool QueryComplete = false;
17681722
17691723 auto LodgingErr = runSessionLocked([&]() -> Error {
17701724 auto LodgeQuery = [&]() -> Error {
18051759 // Record whether this query is fully ready / resolved. We will use
18061760 // this to call handleFullyResolved/handleFullyReady outside the session
18071761 // lock.
1808 QueryIsFullyResolved = Q->isFullyResolved();
1809 QueryIsFullyReady = Q->isFullyReady();
1762 QueryComplete = Q->isComplete();
18101763
18111764 // Call the register dependencies function.
18121765 if (RegisterDependencies && !Q->QueryRegistrations.empty())
18181771 if (LodgingErr) {
18191772 Q->handleFailed(std::move(LodgingErr));
18201773 return;
1821 } else {
1822 if (QueryIsFullyResolved)
1823 Q->handleFullyResolved();
1824 if (QueryIsFullyReady)
1825 Q->handleFullyReady();
1826 }
1774 }
1775
1776 if (QueryComplete)
1777 Q->handleComplete();
18271778
18281779 // Move the MUs to the OutstandingMUs list, then materialize.
18291780 {
18371788 runOutstandingMUs();
18381789 }
18391790
1840 Expected ExecutionSession::lookup(
1841 const JITDylibSearchList &SearchOrder, const SymbolNameSet &Symbols,
1842 RegisterDependenciesFunction RegisterDependencies, bool WaitUntilReady) {
1791 Expected
1792 ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
1793 const SymbolNameSet &Symbols,
1794 SymbolState RequiredState,
1795 RegisterDependenciesFunction RegisterDependencies) {
18431796 #if LLVM_ENABLE_THREADS
18441797 // In the threaded case we use promises to return the results.
18451798 std::promise PromisedResult;
1846 std::mutex ErrMutex;
18471799 Error ResolutionError = Error::success();
1848 std::promise PromisedReady;
1849 Error ReadyError = Error::success();
1850 auto OnResolve = [&](Expected R) {
1800
1801 auto NotifyComplete = [&](Expected R) {
18511802 if (R)
18521803 PromisedResult.set_value(std::move(*R));
18531804 else {
1854 {
1855 ErrorAsOutParameter _(&ResolutionError);
1856 std::lock_guard Lock(ErrMutex);
1857 ResolutionError = R.takeError();
1858 }
1805 ErrorAsOutParameter _(&ResolutionError);
1806 ResolutionError = R.takeError();
18591807 PromisedResult.set_value(SymbolMap());
18601808 }
18611809 };
1862
1863 std::function OnReady;
1864 if (WaitUntilReady) {
1865 OnReady = [&](Error Err) {
1866 if (Err) {
1867 ErrorAsOutParameter _(&ReadyError);
1868 std::lock_guard Lock(ErrMutex);
1869 ReadyError = std::move(Err);
1870 }
1871 PromisedReady.set_value();
1872 };
1873 } else {
1874 OnReady = [&](Error Err) {
1875 if (Err)
1876 reportError(std::move(Err));
1877 };
1878 }
18791810
18801811 #else
18811812 SymbolMap Result;
18821813 Error ResolutionError = Error::success();
1883 Error ReadyError = Error::success();
1884
1885 auto OnResolve = [&](Expected R) {
1814
1815 auto NotifyComplete = [&](Expected R) {
18861816 ErrorAsOutParameter _(&ResolutionError);
18871817 if (R)
18881818 Result = std::move(*R);
18891819 else
18901820 ResolutionError = R.takeError();
18911821 };
1892
1893 std::function OnReady;
1894 if (WaitUntilReady) {
1895 OnReady = [&](Error Err) {
1896 ErrorAsOutParameter _(&ReadyError);
1897 if (Err)
1898 ReadyError = std::move(Err);
1899 };
1900 } else {
1901 OnReady = [&](Error Err) {
1902 if (Err)
1903 reportError(std::move(Err));
1904 };
1905 }
19061822 #endif
19071823
19081824 // Perform the asynchronous lookup.
1909 lookup(SearchOrder, Symbols, OnResolve, OnReady, RegisterDependencies);
1825 lookup(SearchOrder, Symbols, RequiredState, NotifyComplete,
1826 RegisterDependencies);
19101827
19111828 #if LLVM_ENABLE_THREADS
19121829 auto ResultFuture = PromisedResult.get_future();
19131830 auto Result = ResultFuture.get();
19141831
1915 {
1916 std::lock_guard Lock(ErrMutex);
1917 if (ResolutionError) {
1918 // ReadyError will never be assigned. Consume the success value.
1919 cantFail(std::move(ReadyError));
1920 return std::move(ResolutionError);
1921 }
1922 }
1923
1924 if (WaitUntilReady) {
1925 auto ReadyFuture = PromisedReady.get_future();
1926 ReadyFuture.get();
1927
1928 {
1929 std::lock_guard Lock(ErrMutex);
1930 if (ReadyError)
1931 return std::move(ReadyError);
1932 }
1933 } else
1934 cantFail(std::move(ReadyError));
1832 if (ResolutionError)
1833 return std::move(ResolutionError);
19351834
19361835 return std::move(Result);
19371836
19381837 #else
1939 if (ResolutionError) {
1940 // ReadyError will never be assigned. Consume the success value.
1941 cantFail(std::move(ReadyError));
1838 if (ResolutionError)
19421839 return std::move(ResolutionError);
1943 }
1944
1945 if (ReadyError)
1946 return std::move(ReadyError);
19471840
19481841 return Result;
19491842 #endif
19541847 SymbolStringPtr Name) {
19551848 SymbolNameSet Names({Name});
19561849
1957 if (auto ResultMap = lookup(SearchOrder, std::move(Names),
1958 NoDependenciesToRegister, true)) {
1850 if (auto ResultMap = lookup(SearchOrder, std::move(Names), SymbolState::Ready,
1851 NoDependenciesToRegister)) {
19591852 assert(ResultMap->size() == 1 && "Unexpected number of results");
19601853 assert(ResultMap->count(Name) && "Missing result for symbol");
19611854 return std::move(ResultMap->begin()->second);
128128
129129 auto &ES = JD.getExecutionSession();
130130 if (auto CtorDtorMap =
131 ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names),
132 NoDependenciesToRegister, true)) {
131 ES.lookup(JITDylibSearchList({{&JD, true}}), std::move(Names))) {
133132 for (auto &KV : CtorDtorsByPriority) {
134133 for (auto &Name : KV.second) {
135134 assert(CtorDtorMap->count(Name) && "No entry for Name");
5050 SymbolName = I->second.second;
5151 }
5252
53 auto LookupResult = ES.lookup(JITDylibSearchList({{SourceJD, true}}),
54 {SymbolName}, NoDependenciesToRegister, true);
53 auto LookupResult =
54 ES.lookup(JITDylibSearchList({{SourceJD, true}}), SymbolName);
5555
5656 if (!LookupResult) {
5757 ES.reportError(LookupResult.takeError());
5858 return ErrorHandlerAddr;
5959 }
6060
61 assert(LookupResult->size() == 1 && "Unexpected number of results");
62 assert(LookupResult->count(SymbolName) && "Unexpected result");
63
64 auto ResolvedAddr = LookupResult->begin()->second.getAddress();
61 auto ResolvedAddr = LookupResult->getAddress();
6562
6663 std::shared_ptr NotifyResolved = nullptr;
6764 {
3535 };
3636
3737 auto Q = std::make_shared(
38 InternedSymbols, OnResolvedWithUnwrap,
39 [this](Error Err) { ES.reportError(std::move(Err)); });
38 InternedSymbols, SymbolState::Resolved, OnResolvedWithUnwrap);
4039
4140 auto Unresolved = R.lookup(Q, InternedSymbols);
4241 if (Unresolved.empty()) {
6868 }
6969 };
7070
71 ES.lookup(
72 SearchOrder, std::move(InternedSymbols), std::move(OnResolve),
73 // OnReady:
74 [&ES](Error Err) { ES.reportError(std::move(Err)); },
75 // RegisterDependencies:
76 [this](const SymbolDependenceMap &Deps) {
77 registerDependencies(Deps);
78 });
71 ES.lookup(SearchOrder, std::move(InternedSymbols), SymbolState::Resolved,
72 std::move(OnResolve), [this](const SymbolDependenceMap &Deps) {
73 registerDependencies(Deps);
74 });
7975 }
8076
8177 void notifyResolved(AtomGraph &G) override {
152152 for (auto &S : Symbols) {
153153 if (auto Sym = findSymbol(*S)) {
154154 if (auto Addr = Sym.getAddress()) {
155 Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
156 Query->notifySymbolReady();
155 Query->notifySymbolMetRequiredState(
156 S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
157157 } else {
158158 Stack.ES.legacyFailQuery(*Query, Addr.takeError());
159159 return orc::SymbolNameSet();
165165 UnresolvedSymbols.insert(S);
166166 }
167167
168 if (Query->isFullyResolved())
169 Query->handleFullyResolved();
170
171 if (Query->isFullyReady())
172 Query->handleFullyReady();
168 if (Query->isComplete())
169 Query->handleComplete();
173170
174171 return UnresolvedSymbols;
175172 }
175175 for (auto &S : Symbols) {
176176 if (auto Sym = M.findMangledSymbol(*S)) {
177177 if (auto Addr = Sym.getAddress()) {
178 Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
179 Query->notifySymbolReady();
178 Query->notifySymbolMetRequiredState(
179 S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
180180 NewSymbolsResolved = true;
181181 } else {
182182 M.ES.legacyFailQuery(*Query, Addr.takeError());
188188 } else {
189189 if (auto Sym2 = M.ClientResolver->findSymbol(*S)) {
190190 if (auto Addr = Sym2.getAddress()) {
191 Query->resolve(S, JITEvaluatedSymbol(*Addr, Sym2.getFlags()));
192 Query->notifySymbolReady();
191 Query->notifySymbolMetRequiredState(
192 S, JITEvaluatedSymbol(*Addr, Sym2.getFlags()));
193193 NewSymbolsResolved = true;
194194 } else {
195195 M.ES.legacyFailQuery(*Query, Addr.takeError());
203203 }
204204 }
205205
206 if (NewSymbolsResolved && Query->isFullyResolved())
207 Query->handleFullyResolved();
208
209 if (NewSymbolsResolved && Query->isFullyReady())
210 Query->handleFullyReady();
206 if (NewSymbolsResolved && Query->isComplete())
207 Query->handleComplete();
211208
212209 return UnresolvedSymbols;
213210 }
4040 OnResolved(Result);
4141 };
4242
43 // We're not waiting for symbols to be ready. Just log any errors.
44 auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
45
4643 // Register dependencies for all symbols contained in this set.
4744 auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
4845 MR.addDependenciesForAll(Deps);
5148 JITDylibSearchList SearchOrder;
5249 MR.getTargetJITDylib().withSearchOrderDo(
5350 [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
54 ES.lookup(SearchOrder, InternedSymbols, OnResolvedWithUnwrap, OnReady,
55 RegisterDependencies);
51 ES.lookup(SearchOrder, InternedSymbols, SymbolState::Resolved,
52 OnResolvedWithUnwrap, RegisterDependencies);
5653 }
5754
5855 Expected getResponsibilitySet(const LookupSet &Symbols) {
2222 namespace {
2323
2424 TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
25 bool OnResolutionRun = false;
26 bool OnReadyRun = false;
27
28 auto OnResolution = [&](Expected Result) {
25 bool OnCompletionRun = false;
26
27 auto OnCompletion = [&](Expected Result) {
2928 EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
3029 auto &Resolved = *Result;
3130 auto I = Resolved.find(Foo);
3231 EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
3332 EXPECT_EQ(I->second.getAddress(), FooAddr)
3433 << "Resolution returned incorrect result";
35 OnResolutionRun = true;
36 };
37 auto OnReady = [&](Error Err) {
38 cantFail(std::move(Err));
39 OnReadyRun = true;
34 OnCompletionRun = true;
4035 };
4136
4237 std::shared_ptr FooMR;
4742 FooMR = std::make_shared(std::move(R));
4843 })));
4944
50 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolution, OnReady,
51 NoDependenciesToRegister);
52
53 EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
54 EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
45 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
46 OnCompletion, NoDependenciesToRegister);
47
48 EXPECT_FALSE(OnCompletionRun) << "Should not have been resolved yet";
5549
5650 FooMR->resolve({{Foo, FooSym}});
5751
58 EXPECT_TRUE(OnResolutionRun) << "Should have been resolved";
59 EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
52 EXPECT_FALSE(OnCompletionRun) << "Should not be ready yet";
6053
6154 FooMR->emit();
6255
63 EXPECT_TRUE(OnReadyRun) << "Should have been marked ready";
56 EXPECT_TRUE(OnCompletionRun) << "Should have been marked ready";
6457 }
6558
6659 TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
67 bool OnResolutionRun = false;
68 bool OnReadyRun = false;
69
70 auto OnResolution = [&](Expected Result) {
60 bool OnCompletionRun = false;
61
62 auto OnCompletion = [&](Expected Result) {
7163 EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
7264 auto Msg = toString(Result.takeError());
7365 EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
74 OnResolutionRun = true;
75 };
76 auto OnReady = [&](Error Err) {
77 cantFail(std::move(Err));
78 OnReadyRun = true;
79 };
80
81 AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
66 OnCompletionRun = true;
67 };
68
69 AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), SymbolState::Ready,
70 OnCompletion);
8271
8372 ES.legacyFailQuery(Q,
8473 make_error("xyz", inconvertibleErrorCode()));
8574
86 EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
87 EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
75 EXPECT_TRUE(OnCompletionRun) << "OnCompletionCallback was not run";
8876 }
8977
9078 TEST_F(CoreAPIsStandardTest, EmptyLookup) {
91 bool OnResolvedRun = false;
92 bool OnReadyRun = false;
93
94 auto OnResolution = [&](Expected Result) {
79 bool OnCompletionRun = false;
80
81 auto OnCompletion = [&](Expected Result) {
9582 cantFail(std::move(Result));
96 OnResolvedRun = true;
97 };
98
99 auto OnReady = [&](Error Err) {
100 cantFail(std::move(Err));
101 OnReadyRun = true;
102 };
103
104 ES.lookup(JITDylibSearchList({{&JD, false}}), {}, OnResolution, OnReady,
105 NoDependenciesToRegister);
106
107 EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
108 EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
83 OnCompletionRun = true;
84 };
85
86 ES.lookup(JITDylibSearchList({{&JD, false}}), {}, SymbolState::Ready,
87 OnCompletion, NoDependenciesToRegister);
88
89 EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
10990 }
11091
11192 TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
147128 ADD_FAILURE() << "\"Baz\" discarded unexpectedly";
148129 })));
149130
150 bool OnResolvedRun = false;
151 bool OnReadyRun = false;
152 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Baz},
153 [&](Expected Result) {
154 EXPECT_TRUE(!!Result) << "OnResolved failed unexpectedly";
155 consumeError(Result.takeError());
156 OnResolvedRun = true;
157 },
158 [&](Error Err) {
159 EXPECT_FALSE(!!Err) << "OnReady failed unexpectedly";
160 consumeError(std::move(Err));
161 OnReadyRun = true;
162 },
163 NoDependenciesToRegister);
131 bool OnCompletionRun = false;
132 ES.lookup(
133 JITDylibSearchList({{&JD, false}}), {Foo, Baz}, SymbolState::Ready,
134 [&](Expected Result) {
135 cantFail(Result.takeError());
136 OnCompletionRun = true;
137 },
138 NoDependenciesToRegister);
164139
165140 {
166141 // Attempt 1: Search for a missing symbol, Qux.
192167 EXPECT_TRUE(BarDiscarded) << "\"Bar\" should have been discarded";
193168 EXPECT_TRUE(BarMaterializerDestructed)
194169 << "\"Bar\"'s materializer should have been destructed";
195 EXPECT_TRUE(OnResolvedRun) << "OnResolved should have been run";
196 EXPECT_TRUE(OnReadyRun) << "OnReady should have been run";
170 EXPECT_TRUE(OnCompletionRun) << "OnCompletion should have been run";
197171 }
198172
199173 TEST_F(CoreAPIsStandardTest, ChainedJITDylibLookup) {
201175
202176 auto &JD2 = ES.createJITDylib("JD2");
203177
204 bool OnResolvedRun = false;
205 bool OnReadyRun = false;
178 bool OnCompletionRun = false;
206179
207180 auto Q = std::make_shared(
208 SymbolNameSet({Foo}),
181 SymbolNameSet({Foo}), SymbolState::Ready,
209182 [&](Expected Result) {
210183 cantFail(std::move(Result));
211 OnResolvedRun = true;
212 },
213 [&](Error Err) {
214 cantFail(std::move(Err));
215 OnReadyRun = true;
184 OnCompletionRun = true;
216185 });
217186
218187 cantFail(JD2.legacyLookup(Q, cantFail(JD.legacyLookup(Q, {Foo}))));
219188
220 EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
221 EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
189 EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
222190 }
223191
224192 TEST_F(CoreAPIsStandardTest, LookupWithHiddenSymbols) {
395363 cantFail(JD.define(FooMU));
396364
397365 bool FooReady = false;
398 auto OnResolution = [](Expected R) { cantFail(std::move(R)); };
399 auto OnReady = [&](Error Err) {
400 cantFail(std::move(Err));
366 auto OnCompletion = [&](Expected Result) {
367 cantFail(std::move(Result));
401368 FooReady = true;
402369 };
403370
404 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
405 std::move(OnReady), NoDependenciesToRegister);
371 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
372 OnCompletion, NoDependenciesToRegister);
406373
407374 FooR->resolve({{Foo, FooSym}});
408375 FooR->emit();
451418 FooResolved = true;
452419 };
453420
454 auto OnFooReady = [&](Error Err) {
455 cantFail(std::move(Err));
421 auto OnFooReady = [&](Expected Result) {
422 cantFail(std::move(Result));
456423 FooReady = true;
457424 };
458425
459 // Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
426 // Issue lookups for Foo. Use NoDependenciesToRegister: We're going to add
460427 // the dependencies manually below.
461 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
462 std::move(OnFooResolution), std::move(OnFooReady),
463 NoDependenciesToRegister);
428 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
429 std::move(OnFooResolution), NoDependenciesToRegister);
430
431 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
432 std::move(OnFooReady), NoDependenciesToRegister);
464433
465434 bool BarResolved = false;
466435 bool BarReady = false;
469438 BarResolved = true;
470439 };
471440
472 auto OnBarReady = [&](Error Err) {
473 cantFail(std::move(Err));
441 auto OnBarReady = [&](Expected Result) {
442 cantFail(std::move(Result));
474443 BarReady = true;
475444 };
476445
477 ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar},
478 std::move(OnBarResolution), std::move(OnBarReady),
479 NoDependenciesToRegister);
446 ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Resolved,
447 std::move(OnBarResolution), NoDependenciesToRegister);
448
449 ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
450 std::move(OnBarReady), NoDependenciesToRegister);
480451
481452 bool BazResolved = false;
482453 bool BazReady = false;
486457 BazResolved = true;
487458 };
488459
489 auto OnBazReady = [&](Error Err) {
490 cantFail(std::move(Err));
460 auto OnBazReady = [&](Expected Result) {
461 cantFail(std::move(Result));
491462 BazReady = true;
492463 };
493464
494 ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz},
495 std::move(OnBazResolution), std::move(OnBazReady),
496 NoDependenciesToRegister);
465 ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Resolved,
466 std::move(OnBazResolution), NoDependenciesToRegister);
467
468 ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Ready,
469 std::move(OnBazReady), NoDependenciesToRegister);
497470
498471 // Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
499472 FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
598571
599572 SymbolNameSet Names({Foo});
600573
601 bool OnResolutionRun = false;
602 bool OnReadyRun = false;
603
604 auto OnResolution = [&](Expected Result) {
574 bool OnCompletionRun = false;
575
576 auto OnCompletion = [&](Expected Result) {
605577 EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
606578 auto I = Result->find(Foo);
607579 EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
608580 EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
609581 << "Resolution returned incorrect result";
610 OnResolutionRun = true;
611 };
612
613 auto OnReady = [&](Error Err) {
614 cantFail(std::move(Err));
615 OnReadyRun = true;
616 };
617
618 ES.lookup(JITDylibSearchList({{&JD, false}}), Names, std::move(OnResolution),
619 std::move(OnReady), NoDependenciesToRegister);
582 OnCompletionRun = true;
583 };
584
585 ES.lookup(JITDylibSearchList({{&JD, false}}), Names, SymbolState::Ready,
586 std::move(OnCompletion), NoDependenciesToRegister);
620587
621588 EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
622589 EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
623 EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
624 EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
590 EXPECT_TRUE(OnCompletionRun) << "OnResolutionCallback was not run";
625591 }
626592
627593 TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
651617 cantFail(JD.define(MU1));
652618 cantFail(JD.define(MU2));
653619
654 bool OnResolvedRun = false;
655 bool OnReadyRun = false;
656
657 auto OnResolution = [&](Expected Result) {
620 bool OnCompletionRun = false;
621
622 auto OnCompletion = [&](Expected Result) {
658623 cantFail(std::move(Result));
659 OnResolvedRun = true;
660 };
661
662 auto OnReady = [&](Error Err) {
663 cantFail(std::move(Err));
664 OnReadyRun = true;
665 };
666
667 ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, std::move(OnResolution),
668 std::move(OnReady), NoDependenciesToRegister);
669
670 EXPECT_TRUE(OnResolvedRun) << "OnResolved not run";
671 EXPECT_TRUE(OnReadyRun) << "OnReady not run";
624 OnCompletionRun = true;
625 };
626
627 ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
628 std::move(OnCompletion), NoDependenciesToRegister);
629
630 EXPECT_TRUE(OnCompletionRun) << "OnCompletion not run";
672631 EXPECT_TRUE(BarMaterialized) << "Bar was not materialized at all";
673632 EXPECT_TRUE(DuplicateBarDiscarded)
674633 << "Duplicate bar definition not discarded";
724683 auto MU = llvm::make_unique(
725684 SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak},
726685 {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}),
727 [&](MaterializationResponsibility R) { R.failMaterialization(); });
686 [&](MaterializationResponsibility R) {
687 dbgs() << "Before failMat:\n";
688 ES.dump(dbgs());
689 R.failMaterialization();
690 });
728691
729692 cantFail(JD.define(MU));
730693
762725
763726 ES.lookup(
764727 JITDylibSearchList({{&JD, false}}), SymbolNameSet({Baz}),
728 SymbolState::Resolved,
765729 [&R](Expected Result) {
766730 // Called when "baz" is resolved. We don't actually depend
767731 // on or care about baz, but use it to trigger failure of
771735 cantFail(std::move(Result));
772736 R.failMaterialization();
773737 },
774 [](Error Err) { cantFail(std::move(Err)); },
775738 [&](const SymbolDependenceMap &Deps) {
776739 R.addDependenciesForAll(Deps);
777740 });
922885 });
923886
924887 cantFail(JD.define(MU));
925 auto OnResolution = [](Expected Result) {
888 auto OnCompletion = [](Expected Result) {
926889 cantFail(std::move(Result));
927890 };
928891
929 auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
930
931 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
932 std::move(OnReady), NoDependenciesToRegister);
892 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
893 std::move(OnCompletion), NoDependenciesToRegister);
933894
934895 auto MU2 = llvm::make_unique(
935896 SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
4141 EXPECT_EQ(RS.count(Bar), 1U)
4242 << "getResponsibilitySet result incorrect. Should be {'bar'}";
4343
44 bool OnResolvedRun = false;
44 bool OnCompletionRun = false;
4545
46 auto OnResolved = [&](Expected Result) {
47 OnResolvedRun = true;
46 auto OnCompletion = [&](Expected Result) {
47 OnCompletionRun = true;
4848 EXPECT_TRUE(!!Result) << "Unexpected error";
4949 EXPECT_EQ(Result->size(), 2U) << "Unexpected number of resolved symbols";
5050 EXPECT_EQ(Result->count(Foo), 1U) << "Missing lookup result for foo";
5454 EXPECT_EQ((*Result)[Bar].getAddress(), BarSym.getAddress())
5555 << "Incorrect address for bar";
5656 };
57 auto OnReady = [&](Error Err) {
58 EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
59 };
6057
61 auto Q = std::make_shared(SymbolNameSet({Foo, Bar}),
62 OnResolved, OnReady);
58 auto Q = std::make_shared(
59 SymbolNameSet({Foo, Bar}), SymbolState::Resolved, OnCompletion);
6360 auto Unresolved =
6461 Resolver->lookup(std::move(Q), SymbolNameSet({Foo, Bar, Baz}));
6562
6663 EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
6764 EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to not be resolved";
68 EXPECT_TRUE(OnResolvedRun) << "OnResolved was never run";
65 EXPECT_TRUE(OnCompletionRun) << "OnCompletion was never run";
6966 }
7067
7168 TEST_F(LegacyAPIsStandardTest, LegacyLookupHelpersFn) {
9794 EXPECT_FALSE(BarMaterialized)
9895 << "lookupFlags should not have materialized bar";
9996
100 bool OnResolvedRun = false;
101 bool OnReadyRun = false;
102 auto OnResolved = [&](Expected Result) {
103 OnResolvedRun = true;
97 bool OnCompletionRun = false;
98 auto OnCompletion = [&](Expected Result) {
99 OnCompletionRun = true;
104100 EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
105101
106102 EXPECT_EQ(Result->size(), 2U) << "Wrong number of symbols resolved";
113109 EXPECT_EQ((*Result)[Bar].getFlags(), BarSym.getFlags())
114110 << "Wrong flags for bar";
115111 };
116 auto OnReady = [&](Error Err) {
117 EXPECT_FALSE(!!Err) << "Finalization unexpectedly failed";
118 OnReadyRun = true;
119 };
120112
121 AsynchronousSymbolQuery Q({Foo, Bar}, OnResolved, OnReady);
113 AsynchronousSymbolQuery Q({Foo, Bar}, SymbolState::Resolved, OnCompletion);
122114 auto Unresolved =
123115 lookupWithLegacyFn(ES, Q, SymbolNameSet({Foo, Bar, Baz}), LegacyLookup);
124116
125 EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run";
126 EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
117 EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run";
127118 EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
128119 EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to be unresolved";
129120 }
6060 cantFail(std::move(R));
6161 };
6262
63 auto OnReadyDoNothing = [](Error Err) { cantFail(std::move(Err)); };
64
6563 ObjLayer.setProcessAllSections(ProcessAllSections);
6664 cantFail(ObjLayer.add(JD, std::move(Obj), ES.allocateVModule()));
67 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolveDoNothing,
68 OnReadyDoNothing, NoDependenciesToRegister);
65 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
66 OnResolveDoNothing, NoDependenciesToRegister);
67
6968 return DebugSectionSeen;
7069 }
7170
159158 ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
160159
161160 cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
162 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
163 [](Expected R) { cantFail(std::move(R)); },
164 [](Error Err) { cantFail(std::move(Err)); },
165 NoDependenciesToRegister);
161 ES.lookup(
162 JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
163 [](Expected R) { cantFail(std::move(R)); },
164 NoDependenciesToRegister);
166165 }
167166
168167 TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {
224223 ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true);
225224
226225 cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
227 ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
228 [](Expected R) { cantFail(std::move(R)); },
229 [](Error Err) { cantFail(std::move(Err)); },
230 NoDependenciesToRegister);
226 ES.lookup(
227 JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
228 [](Expected R) { cantFail(std::move(R)); },
229 NoDependenciesToRegister);
231230 }
232231
233232 } // end anonymous namespace