mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Make deserialization of known protocol adopters lazy.
...by adding a new callback to ModuleLoader: loadDeclsConformingTo. This is used only when the type checker doesn't have enough contextual information to resolve an expression involving a literal, so it's possible many *LiteralConvertible types will never be loaded. Deserialization of types with conversion methods is still eager, since there's no easy hook to tell when they're needed, but the list has been renamed to refer to any decls that need to be eagerly deserialized, in case we need it for other purposes in the future. This probably won't help much in a real program, but it cuts the test run time by about 5-10% in my build. Swift SVN r7268
This commit is contained in:
@@ -2004,8 +2004,8 @@ static Optional<KnownProtocolKind> getActualKnownProtocol(unsigned rawKind) {
|
||||
#define PROTOCOL(Id) \
|
||||
case index_block::Id: return KnownProtocolKind::Id;
|
||||
#include "swift/AST/KnownProtocols.def"
|
||||
case index_block::CONVERSION:
|
||||
llvm_unreachable("must handle CONVERSION explicitly");
|
||||
case index_block::FORCE_DESERIALIZATION:
|
||||
llvm_unreachable("must handle FORCE_DESERIALIZATION explicitly");
|
||||
}
|
||||
|
||||
// If there's a new case value in the module file, ignore it.
|
||||
@@ -2032,17 +2032,19 @@ bool ModuleFile::readKnownProtocolsBlock(llvm::BitstreamCursor &cursor) {
|
||||
case llvm::BitstreamEntry::Record: {
|
||||
scratch.clear();
|
||||
unsigned rawKind = cursor.readRecord(next.ID, scratch);
|
||||
unsigned index;
|
||||
|
||||
if (rawKind == index_block::CONVERSION)
|
||||
index = NumKnownProtocols;
|
||||
else if (auto actualKind = getActualKnownProtocol(rawKind))
|
||||
index = static_cast<unsigned>(actualKind.getValue());
|
||||
else
|
||||
break; // ignore this record
|
||||
DeclIDVector *list;
|
||||
if (rawKind == index_block::FORCE_DESERIALIZATION) {
|
||||
list = &EagerDeserializationDecls;
|
||||
} else if (auto actualKind = getActualKnownProtocol(rawKind)) {
|
||||
auto index = static_cast<unsigned>(actualKind.getValue());
|
||||
list = &KnownProtocolAdopters[index];
|
||||
} else {
|
||||
// Ignore this record.
|
||||
break;
|
||||
}
|
||||
|
||||
auto &adopterList = KnownProtocolAdopters[index];
|
||||
adopterList.append(scratch.begin(), scratch.end());
|
||||
list->append(scratch.begin(), scratch.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2265,6 +2267,12 @@ ModuleFile::ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input)
|
||||
return error();
|
||||
}
|
||||
|
||||
static NominalTypeDecl *getAnyNominal(Decl *D) {
|
||||
if (auto extension = dyn_cast<ExtensionDecl>(D))
|
||||
D = extension->getExtendedType()->getAnyNominal();
|
||||
return dyn_cast_or_null<NominalTypeDecl>(D);
|
||||
}
|
||||
|
||||
bool ModuleFile::associateWithModule(Module *module) {
|
||||
assert(Status == ModuleStatus::Valid && "invalid module file");
|
||||
assert(!ModuleContext && "already associated with an AST module");
|
||||
@@ -2303,21 +2311,11 @@ bool ModuleFile::associateWithModule(Module *module) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Eagerly deserialize decls conforming to special protocols.
|
||||
for (unsigned i = 0; i < NumKnownProtocols+1; ++i) {
|
||||
for (DeclID DID : KnownProtocolAdopters[i]) {
|
||||
Decl *decl = getDecl(DID);
|
||||
|
||||
// Don't record any conformance for the plain "force deserialization"
|
||||
// decls.
|
||||
if (i < NumKnownProtocols)
|
||||
ctx.recordConformance(static_cast<KnownProtocolKind>(i), decl);
|
||||
|
||||
if (auto extension = dyn_cast<ExtensionDecl>(decl))
|
||||
decl = extension->getExtendedType()->getAnyNominal();
|
||||
if (auto nominal = dyn_cast_or_null<NominalTypeDecl>(decl))
|
||||
loadExtensions(nominal);
|
||||
}
|
||||
// Process decls we know we want to eagerly deserialize.
|
||||
for (DeclID DID : EagerDeserializationDecls) {
|
||||
Decl *decl = getDecl(DID);
|
||||
if (auto nominal = getAnyNominal(decl))
|
||||
loadExtensions(nominal);
|
||||
}
|
||||
|
||||
return Status == ModuleStatus::Valid;
|
||||
@@ -2408,3 +2406,13 @@ void ModuleFile::loadExtensions(NominalTypeDecl *nominal) {
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleFile::loadDeclsConformingTo(KnownProtocolKind kind) {
|
||||
auto index = static_cast<unsigned>(kind);
|
||||
for (DeclID DID : KnownProtocolAdopters[index]) {
|
||||
Decl *D = getDecl(DID);
|
||||
ModuleContext->Ctx.recordConformance(kind, D);
|
||||
if (auto nominal = getAnyNominal(D))
|
||||
loadExtensions(nominal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user