Skip to content

Commit 9e18594

Browse files
committed
[NamedLazyMemberLoading] Use per-IDC recursion-breaking flag, not sentinel.
The empty sentinel in the lookup table caused recursion-breaking to bottom out in slightly different order than the old eager code, making certain order-sensitive tests fail.
1 parent dfc67d6 commit 9e18594

File tree

2 files changed

+21
-15
lines changed

2 files changed

+21
-15
lines changed

include/swift/AST/DeclContext.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,15 @@ class IterableDeclContext {
610610
mutable llvm::PointerIntPair<Decl *, 2, IterableDeclContextKind>
611611
LastDeclAndKind;
612612

613-
// The DeclID this IDC was deserialized from, if any. Used for named lazy
614-
// member loading, as a key when doing lookup in this IDC.
613+
/// The DeclID this IDC was deserialized from, if any. Used for named lazy
614+
/// member loading, as a key when doing lookup in this IDC.
615615
serialization::DeclID SerialID;
616616

617+
/// Lazy member loading has a variety of feedback loops that need to
618+
/// switch to pseudo-empty-member behaviour to avoid infinite recursion;
619+
/// we use this flag to control them.
620+
bool lazyMemberLoadingInProgress = false;
621+
617622
template<class A, class B, class C>
618623
friend struct ::llvm::cast_convert_val;
619624

@@ -643,6 +648,14 @@ class IterableDeclContext {
643648
return FirstDeclAndLazyMembers.getInt();
644649
}
645650

651+
bool isLoadingLazyMembers() {
652+
return lazyMemberLoadingInProgress;
653+
}
654+
655+
void setLoadingLazyMembers(bool inProgress) {
656+
lazyMemberLoadingInProgress = inProgress;
657+
}
658+
646659
/// Setup the loader for lazily-loaded members.
647660
void setMemberLoader(LazyMemberLoader *loader, uint64_t contextData);
648661

lib/AST/NameLookup.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,15 +1024,6 @@ class swift::MemberLookupTable {
10241024
return Lookup.find(name);
10251025
}
10261026

1027-
/// \brief Add an empty entry to the lookup map for a given name if it does
1028-
/// not yet have one.
1029-
void addEmptyEntry(DeclName name) {
1030-
(void)Lookup[name];
1031-
if (!name.isSimpleName()) {
1032-
(void)Lookup[name.getBaseName()];
1033-
}
1034-
}
1035-
10361027
// \brief Mark all Decls in this table as not-resident in a table, drop
10371028
// references to them. Should only be called when this was not fully-populated
10381029
// from an IterableDeclContext.
@@ -1289,13 +1280,14 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
12891280
MemberLookupTable &LookupTable,
12901281
DeclName name,
12911282
IterableDeclContext *IDC) {
1283+
if (IDC->isLoadingLazyMembers()) {
1284+
return false;
1285+
}
1286+
IDC->setLoadingLazyMembers(true);
12921287
auto ci = ctx.getOrCreateLazyIterableContextData(IDC,
12931288
/*lazyLoader=*/nullptr);
1294-
// Populate LookupTable with an empty vector before we call into our loader,
1295-
// so that any reentry of this routine will find the set-so-far, and not
1296-
// fall into infinite recursion.
1297-
LookupTable.addEmptyEntry(name);
12981289
if (auto res = ci->loader->loadNamedMembers(IDC, name, ci->memberData)) {
1290+
IDC->setLoadingLazyMembers(false);
12991291
if (auto s = ctx.Stats) {
13001292
++s->getFrontendCounters().NamedLazyMemberLoadSuccessCount;
13011293
}
@@ -1304,6 +1296,7 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
13041296
}
13051297
return false;
13061298
} else {
1299+
IDC->setLoadingLazyMembers(false);
13071300
if (auto s = ctx.Stats) {
13081301
++s->getFrontendCounters().NamedLazyMemberLoadFailureCount;
13091302
}

0 commit comments

Comments
 (0)