Skip to content

Commit 78d14f9

Browse files
authored
Merge pull request #23 from apple/master
[pull] swiftwasm from apple:master
2 parents 7ffd4e2 + 2da9601 commit 78d14f9

File tree

12 files changed

+184
-91
lines changed

12 files changed

+184
-91
lines changed

include/swift/AST/Decl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,6 +3326,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
33263326
friend class ExtensionDecl;
33273327
friend class DeclContext;
33283328
friend class IterableDeclContext;
3329+
friend class DirectLookupRequest;
33293330
friend ArrayRef<ValueDecl *>
33303331
ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const;
33313332

@@ -3400,6 +3401,12 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
34003401
/// Whether to include @_implements members.
34013402
/// Used by conformance-checking to find special @_implements members.
34023403
IncludeAttrImplements = 1 << 0,
3404+
/// Whether to avoid loading lazy members from any new extensions that would otherwise be found
3405+
/// by deserialization.
3406+
///
3407+
/// Used by the module loader to break recursion and as an optimization e.g. when it is known that a
3408+
/// particular member declaration will never appear in an extension.
3409+
IgnoreNewExtensions = 1 << 1,
34033410
};
34043411

34053412
/// Find all of the declarations with the given name within this nominal type
@@ -7413,6 +7420,9 @@ ParameterList *getParameterList(ValueDecl *source);
74137420
/// nullptr if the source does not have a parameter list.
74147421
const ParamDecl *getParameterAt(const ValueDecl *source, unsigned index);
74157422

7423+
void simple_display(llvm::raw_ostream &out,
7424+
OptionSet<NominalTypeDecl::LookupDirectFlags> options);
7425+
74167426
/// Display Decl subclasses.
74177427
void simple_display(llvm::raw_ostream &out, const Decl *decl);
74187428

include/swift/AST/DeclContext.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -681,18 +681,9 @@ enum class IterableDeclContextKind : uint8_t {
681681
/// Note that an iterable declaration context must inherit from both
682682
/// \c IterableDeclContext and \c DeclContext.
683683
class IterableDeclContext {
684-
enum LazyMembers : unsigned {
685-
Present = 1 << 0,
686-
687-
/// Lazy member loading has a variety of feedback loops that need to
688-
/// switch to pseudo-empty-member behaviour to avoid infinite recursion;
689-
/// we use this flag to control them.
690-
InProgress = 1 << 1,
691-
};
692-
693684
/// The first declaration in this context along with a bit indicating whether
694685
/// the members of this context will be lazily produced.
695-
mutable llvm::PointerIntPair<Decl *, 2, LazyMembers> FirstDeclAndLazyMembers;
686+
mutable llvm::PointerIntPair<Decl *, 1, bool> FirstDeclAndLazyMembers;
696687

697688
/// The last declaration in this context, used for efficient insertion,
698689
/// along with the kind of iterable declaration context.
@@ -780,20 +771,7 @@ class IterableDeclContext {
780771

781772
/// Check whether there are lazily-loaded members.
782773
bool hasLazyMembers() const {
783-
return FirstDeclAndLazyMembers.getInt() & LazyMembers::Present;
784-
}
785-
786-
bool isLoadingLazyMembers() {
787-
return FirstDeclAndLazyMembers.getInt() & LazyMembers::InProgress;
788-
}
789-
790-
void setLoadingLazyMembers(bool inProgress) {
791-
LazyMembers status = FirstDeclAndLazyMembers.getInt();
792-
if (inProgress)
793-
status = LazyMembers(status | LazyMembers::InProgress);
794-
else
795-
status = LazyMembers(status & ~LazyMembers::InProgress);
796-
FirstDeclAndLazyMembers.setInt(status);
774+
return FirstDeclAndLazyMembers.getInt();
797775
}
798776

799777
/// Setup the loader for lazily-loaded members.

include/swift/AST/NameLookupRequests.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,54 @@ class QualifiedLookupRequest
467467
NLOptions opts) const;
468468
};
469469

470+
/// The input type for a direct lookup request.
471+
class DirectLookupDescriptor final {
472+
using LookupOptions = OptionSet<NominalTypeDecl::LookupDirectFlags>;
473+
474+
public:
475+
NominalTypeDecl *DC;
476+
DeclName Name;
477+
LookupOptions Options;
478+
479+
DirectLookupDescriptor(NominalTypeDecl *dc, DeclName name,
480+
LookupOptions options = {})
481+
: DC(dc), Name(name), Options(options) {}
482+
483+
friend llvm::hash_code hash_value(const DirectLookupDescriptor &desc) {
484+
return llvm::hash_combine(desc.Name, desc.DC, desc.Options.toRaw());
485+
}
486+
487+
friend bool operator==(const DirectLookupDescriptor &lhs,
488+
const DirectLookupDescriptor &rhs) {
489+
return lhs.Name == rhs.Name && lhs.DC == rhs.DC &&
490+
lhs.Options.toRaw() == rhs.Options.toRaw();
491+
}
492+
493+
friend bool operator!=(const DirectLookupDescriptor &lhs,
494+
const DirectLookupDescriptor &rhs) {
495+
return !(lhs == rhs);
496+
}
497+
};
498+
499+
void simple_display(llvm::raw_ostream &out, const DirectLookupDescriptor &desc);
500+
501+
SourceLoc extractNearestSourceLoc(const DirectLookupDescriptor &desc);
502+
503+
class DirectLookupRequest
504+
: public SimpleRequest<DirectLookupRequest,
505+
TinyPtrVector<ValueDecl *>(DirectLookupDescriptor),
506+
CacheKind::Uncached> {
507+
public:
508+
using SimpleRequest::SimpleRequest;
509+
510+
private:
511+
friend SimpleRequest;
512+
513+
// Evaluation.
514+
llvm::Expected<TinyPtrVector<ValueDecl *>>
515+
evaluate(Evaluator &evaluator, DirectLookupDescriptor desc) const;
516+
};
517+
470518
#define SWIFT_TYPEID_ZONE NameLookup
471519
#define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def"
472520
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/NameLookupTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ SWIFT_REQUEST(NameLookup, AnyObjectLookupRequest,
2121
SWIFT_REQUEST(NameLookup, CustomAttrNominalRequest,
2222
NominalTypeDecl *(CustomAttr *, DeclContext *), Cached,
2323
NoLocationInfo)
24+
SWIFT_REQUEST(NameLookup, DirectLookupRequest,
25+
TinyPtrVector<ValueDecl *>(DirectLookupDescriptor), Uncached,
26+
NoLocationInfo)
2427
SWIFT_REQUEST(NameLookup, ExpandASTScopeRequest,
2528
ast_scope::ASTScopeImpl* (ast_scope::ASTScopeImpl*, ast_scope::ScopeCreator*),
2629
SeparatelyCached,

include/swift/Basic/Statistics.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,6 @@ FRONTEND_STATISTIC(Sema, NumLazyRequirementSignaturesLoaded)
240240
/// Number of lazy iterable declaration contexts constructed.
241241
FRONTEND_STATISTIC(Sema, NumLazyIterableDeclContexts)
242242

243-
/// Number of direct member-name lookups performed on nominal types.
244-
FRONTEND_STATISTIC(Sema, NominalTypeLookupDirectCount)
245-
246243
/// Number of member-name lookups that avoided loading all members.
247244
FRONTEND_STATISTIC(Sema, NamedLazyMemberLoadSuccessCount)
248245

lib/AST/Decl.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4648,7 +4648,8 @@ ValueDecl *ProtocolDecl::getSingleRequirement(DeclName name) const {
46484648
}
46494649

46504650
AssociatedTypeDecl *ProtocolDecl::getAssociatedType(Identifier name) const {
4651-
auto results = const_cast<ProtocolDecl *>(this)->lookupDirect(name);
4651+
const auto flags = NominalTypeDecl::LookupDirectFlags::IgnoreNewExtensions;
4652+
auto results = const_cast<ProtocolDecl *>(this)->lookupDirect(name, flags);
46524653
for (auto candidate : results) {
46534654
if (candidate->getDeclContext() == this &&
46544655
isa<AssociatedTypeDecl>(candidate)) {
@@ -7917,6 +7918,15 @@ void swift::simple_display(llvm::raw_ostream &out, const Decl *decl) {
79177918
}
79187919
}
79197920

7921+
void swift::simple_display(llvm::raw_ostream &out,
7922+
OptionSet<NominalTypeDecl::LookupDirectFlags> opts) {
7923+
out << "{ ";
7924+
using LookupFlags = NominalTypeDecl::LookupDirectFlags;
7925+
if (opts.contains(LookupFlags::IncludeAttrImplements))
7926+
out << "IncludeAttrImplements";
7927+
out << " }";
7928+
}
7929+
79207930
void swift::simple_display(llvm::raw_ostream &out, const ValueDecl *decl) {
79217931
if (decl) decl->dumpRef(out);
79227932
else out << "(null)";

lib/AST/DeclContext.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,7 @@ void IterableDeclContext::setMemberLoader(LazyMemberLoader *loader,
798798

799799
ASTContext &ctx = getASTContext();
800800
auto contextInfo = ctx.getOrCreateLazyIterableContextData(this, loader);
801-
auto lazyMembers = FirstDeclAndLazyMembers.getInt() | LazyMembers::Present;
802-
FirstDeclAndLazyMembers.setInt(LazyMembers(lazyMembers));
801+
FirstDeclAndLazyMembers.setInt(true);
803802
contextInfo->memberData = contextData;
804803

805804
++NumLazyIterableDeclContexts;
@@ -855,12 +854,11 @@ void IterableDeclContext::loadAllMembers() const {
855854
return;
856855

857856
// Don't try to load all members re-entrant-ly.
858-
auto contextInfo = ctx.getOrCreateLazyIterableContextData(this,
859-
/*lazyLoader=*/nullptr);
860-
auto lazyMembers = FirstDeclAndLazyMembers.getInt() & ~LazyMembers::Present;
861-
FirstDeclAndLazyMembers.setInt(LazyMembers(lazyMembers));
857+
FirstDeclAndLazyMembers.setInt(false);
862858

863859
const Decl *container = getDecl();
860+
auto contextInfo = ctx.getOrCreateLazyIterableContextData(this,
861+
/*lazyLoader=*/nullptr);
864862
contextInfo->loader->loadAllMembers(const_cast<Decl *>(container),
865863
contextInfo->memberData);
866864

lib/AST/NameLookup.cpp

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,11 +1148,9 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
11481148
MemberLookupTable &LookupTable,
11491149
DeclBaseName name,
11501150
IterableDeclContext *IDC) {
1151-
IDC->setLoadingLazyMembers(true);
11521151
auto ci = ctx.getOrCreateLazyIterableContextData(IDC,
11531152
/*lazyLoader=*/nullptr);
11541153
if (auto res = ci->loader->loadNamedMembers(IDC, name, ci->memberData)) {
1155-
IDC->setLoadingLazyMembers(false);
11561154
if (auto s = ctx.Stats) {
11571155
++s->getFrontendCounters().NamedLazyMemberLoadSuccessCount;
11581156
}
@@ -1161,7 +1159,6 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
11611159
}
11621160
return false;
11631161
} else {
1164-
IDC->setLoadingLazyMembers(false);
11651162
if (auto s = ctx.Stats) {
11661163
++s->getFrontendCounters().NamedLazyMemberLoadFailureCount;
11671164
}
@@ -1210,25 +1207,21 @@ void NominalTypeDecl::prepareLookupTable() {
12101207

12111208
if (hasLazyMembers()) {
12121209
assert(!hasUnparsedMembers());
1213-
1214-
// Lazy members: if the table needs population, populate the table _only
1215-
// from those members already in the IDC member list_ such as implicits or
1216-
// globals-as-members.
12171210
LookupTable->addMembers(getCurrentMembersWithoutLoading());
1218-
for (auto e : getExtensions()) {
1219-
// If we can lazy-load this extension, only take the members we've loaded
1220-
// so far.
1221-
if (e->wasDeserialized() || e->hasClangNode()) {
1222-
LookupTable->addMembers(e->getCurrentMembersWithoutLoading());
1223-
continue;
1224-
}
1225-
1226-
// Else, load all the members into the table.
1227-
LookupTable->addMembers(e->getMembers());
1228-
}
12291211
} else {
12301212
LookupTable->addMembers(getMembers());
1231-
LookupTable->updateLookupTable(this);
1213+
}
1214+
1215+
for (auto e : getExtensions()) {
1216+
// If we can lazy-load this extension, only take the members we've loaded
1217+
// so far.
1218+
if (e->wasDeserialized() || e->hasClangNode()) {
1219+
LookupTable->addMembers(e->getCurrentMembersWithoutLoading());
1220+
continue;
1221+
}
1222+
1223+
// Else, load all the members into the table.
1224+
LookupTable->addMembers(e->getMembers());
12321225
}
12331226
}
12341227

@@ -1257,34 +1250,42 @@ maybeFilterOutAttrImplements(TinyPtrVector<ValueDecl *> decls,
12571250
TinyPtrVector<ValueDecl *>
12581251
NominalTypeDecl::lookupDirect(DeclName name,
12591252
OptionSet<LookupDirectFlags> flags) {
1260-
ASTContext &ctx = getASTContext();
1261-
if (auto s = ctx.Stats) {
1262-
++s->getFrontendCounters().NominalTypeLookupDirectCount;
1263-
}
1253+
return evaluateOrDefault(getASTContext().evaluator,
1254+
DirectLookupRequest({this, name, flags}), {});
1255+
}
1256+
1257+
llvm::Expected<TinyPtrVector<ValueDecl *>>
1258+
DirectLookupRequest::evaluate(Evaluator &evaluator,
1259+
DirectLookupDescriptor desc) const {
1260+
const auto &name = desc.Name;
1261+
const auto flags = desc.Options;
1262+
auto *decl = desc.DC;
12641263

12651264
// We only use NamedLazyMemberLoading when a user opts-in and we have
12661265
// not yet loaded all the members into the IDC list in the first place.
1266+
ASTContext &ctx = decl->getASTContext();
12671267
const bool useNamedLazyMemberLoading = (ctx.LangOpts.NamedLazyMemberLoading &&
1268-
hasLazyMembers());
1269-
1268+
decl->hasLazyMembers());
1269+
const bool disableAdditionalExtensionLoading =
1270+
flags.contains(NominalTypeDecl::LookupDirectFlags::IgnoreNewExtensions);
12701271
const bool includeAttrImplements =
1271-
flags.contains(LookupDirectFlags::IncludeAttrImplements);
1272+
flags.contains(NominalTypeDecl::LookupDirectFlags::IncludeAttrImplements);
12721273

1273-
LLVM_DEBUG(llvm::dbgs() << getNameStr() << ".lookupDirect("
1274+
LLVM_DEBUG(llvm::dbgs() << decl->getNameStr() << ".lookupDirect("
12741275
<< name << ")"
1275-
<< ", hasLazyMembers()=" << hasLazyMembers()
1276-
<< ", useNamedLazyMemberLoading=" << useNamedLazyMemberLoading
1276+
<< ", hasLazyMembers()=" << decl->hasLazyMembers()
1277+
<< ", useNamedLazyMemberLoading="
1278+
<< useNamedLazyMemberLoading
12771279
<< "\n");
12781280

1279-
1280-
prepareLookupTable();
1281+
decl->prepareLookupTable();
12811282

12821283
auto tryCacheLookup =
1283-
[=](MemberLookupTable *table,
1284+
[=](MemberLookupTable &table,
12841285
DeclName name) -> Optional<TinyPtrVector<ValueDecl *>> {
12851286
// Look for a declaration with this name.
1286-
auto known = table->find(name);
1287-
if (known == table->end()) {
1287+
auto known = table.find(name);
1288+
if (known == table.end()) {
12881289
return None;
12891290
}
12901291

@@ -1293,36 +1294,40 @@ NominalTypeDecl::lookupDirect(DeclName name,
12931294
includeAttrImplements);
12941295
};
12951296

1296-
auto updateLookupTable = [this](MemberLookupTable *table) {
1297+
auto updateLookupTable = [&decl](MemberLookupTable &table,
1298+
bool noExtensions) {
12971299
// Make sure we have the complete list of members (in this nominal and in
12981300
// all extensions).
1299-
(void)getMembers();
1301+
(void)decl->getMembers();
1302+
1303+
if (noExtensions)
1304+
return;
13001305

1301-
for (auto E : getExtensions())
1306+
for (auto E : decl->getExtensions())
13021307
(void)E->getMembers();
13031308

1304-
LookupTable->updateLookupTable(this);
1309+
table.updateLookupTable(decl);
13051310
};
13061311

1312+
auto &Table = *decl->LookupTable;
13071313
if (!useNamedLazyMemberLoading) {
1308-
updateLookupTable(LookupTable);
1309-
} else if (!LookupTable->isLazilyComplete(name.getBaseName())) {
1314+
updateLookupTable(Table, disableAdditionalExtensionLoading);
1315+
} else if (!Table.isLazilyComplete(name.getBaseName())) {
13101316
// The lookup table believes it doesn't have a complete accounting of this
13111317
// name - either because we're never seen it before, or another extension
13121318
// was registered since the last time we searched. Ask the loaders to give
13131319
// us a hand.
1314-
auto &Table = *LookupTable;
13151320
DeclBaseName baseName(name.getBaseName());
1316-
if (populateLookupTableEntryFromLazyIDCLoader(ctx, Table, baseName, this)) {
1317-
updateLookupTable(LookupTable);
1318-
} else {
1319-
populateLookupTableEntryFromExtensions(ctx, Table, this, baseName);
1321+
if (populateLookupTableEntryFromLazyIDCLoader(ctx, Table, baseName, decl)) {
1322+
updateLookupTable(Table, disableAdditionalExtensionLoading);
1323+
} else if (!disableAdditionalExtensionLoading) {
1324+
populateLookupTableEntryFromExtensions(ctx, Table, decl, baseName);
13201325
}
13211326
Table.markLazilyComplete(baseName);
13221327
}
13231328

13241329
// Look for a declaration with this name.
1325-
return tryCacheLookup(LookupTable, name)
1330+
return tryCacheLookup(Table, name)
13261331
.getValueOr(TinyPtrVector<ValueDecl *>());
13271332
}
13281333

lib/AST/NameLookupRequests.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,24 @@ swift::extractNearestSourceLoc(const UnqualifiedLookupDescriptor &desc) {
188188
return extractNearestSourceLoc(desc.DC);
189189
}
190190

191+
//----------------------------------------------------------------------------//
192+
// DirectLookupRequest computation.
193+
//----------------------------------------------------------------------------//
194+
195+
void swift::simple_display(llvm::raw_ostream &out,
196+
const DirectLookupDescriptor &desc) {
197+
out << "directly looking up ";
198+
simple_display(out, desc.Name);
199+
out << " on ";
200+
simple_display(out, desc.DC);
201+
out << " with options ";
202+
simple_display(out, desc.Options);
203+
}
204+
205+
SourceLoc swift::extractNearestSourceLoc(const DirectLookupDescriptor &desc) {
206+
return extractNearestSourceLoc(desc.DC);
207+
}
208+
191209
// Define request evaluation functions for each of the name lookup requests.
192210
static AbstractRequestFunction *nameLookupRequestFunctions[] = {
193211
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions) \

0 commit comments

Comments
 (0)