Skip to content

[Serialization] Do less work checking if a value can be deserialized. #9666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -855,12 +855,13 @@ namespace decls_block {
CtorInitializerKindField, // initializer kind
GenericEnvironmentIDField, // generic environment
TypeIDField, // interface type
TypeIDField, // canonical interface type
DeclIDField, // overridden decl
AccessibilityKindField, // accessibility
BCFixed<1>, // requires a new vtable slot
BCFixed<1>, // 'required' but overridden is not (used for recovery)
BCArray<IdentifierIDField> // argument names
BCVBR<5>, // number of parameter name components
BCArray<IdentifierIDField> // name components,
// followed by TypeID dependencies
// Trailed by its generic parameters, if any, followed by the parameter
// patterns.
>;
Expand All @@ -876,7 +877,6 @@ namespace decls_block {
BCFixed<1>, // HasNonPatternBindingInit?
StorageKindField, // StorageKind
TypeIDField, // interface type
TypeIDField, // canonical interface type
DeclIDField, // getter
DeclIDField, // setter
DeclIDField, // materializeForSet
Expand All @@ -886,7 +886,8 @@ namespace decls_block {
DeclIDField, // didset
DeclIDField, // overridden decl
AccessibilityKindField, // accessibility
AccessibilityKindField // setter accessibility, if applicable
AccessibilityKindField, // setter accessibility, if applicable
BCArray<TypeIDField> // dependencies
>;

using ParamLayout = BCRecordLayout<
Expand All @@ -911,15 +912,16 @@ namespace decls_block {
BCVBR<5>, // number of parameter patterns
GenericEnvironmentIDField, // generic environment
TypeIDField, // interface type
TypeIDField, // canonical interface type
DeclIDField, // operator decl
DeclIDField, // overridden function
DeclIDField, // AccessorStorageDecl
BCFixed<1>, // name is compound?
BCVBR<5>, // 0 for a simple name, otherwise the number of parameter name
// components plus one
AddressorKindField, // addressor kind
AccessibilityKindField, // accessibility
BCFixed<1>, // requires a new vtable slot
BCArray<IdentifierIDField> // name components
BCArray<IdentifierIDField> // name components,
// followed by TypeID dependencies
// The record is trailed by:
// - its _silgen_name, if any
// - its generic parameters, if any
Expand Down Expand Up @@ -984,7 +986,6 @@ namespace decls_block {
StorageKindField, // StorageKind
GenericEnvironmentIDField, // generic environment
TypeIDField, // interface type
TypeIDField, // canonical interface type
DeclIDField, // getter
DeclIDField, // setter
DeclIDField, // materializeForSet
Expand All @@ -995,7 +996,9 @@ namespace decls_block {
DeclIDField, // overridden decl
AccessibilityKindField, // accessibility
AccessibilityKindField, // setter accessibility, if applicable
BCArray<IdentifierIDField> // name components
BCVBR<5>, // number of parameter name components
BCArray<IdentifierIDField> // name components,
// followed by TypeID dependencies
// Trailed by:
// - generic parameters, if any
// - the indices pattern
Expand Down
123 changes: 74 additions & 49 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2574,25 +2574,27 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
bool isImplicit, isObjC, hasStubImplementation, throws;
GenericEnvironmentID genericEnvID;
uint8_t storedInitKind, rawAccessLevel;
TypeID interfaceID, canonicalTypeID;
TypeID interfaceID;
DeclID overriddenID;
bool needsNewVTableEntry, firstTimeRequired;
ArrayRef<uint64_t> argNameIDs;
unsigned numArgNames;
ArrayRef<uint64_t> argNameAndDependencyIDs;

decls_block::ConstructorLayout::readRecord(scratch, contextID,
rawFailability, isImplicit,
isObjC, hasStubImplementation,
throws, storedInitKind,
genericEnvID, interfaceID,
canonicalTypeID, overriddenID,
overriddenID,
rawAccessLevel,
needsNewVTableEntry,
firstTimeRequired,
argNameIDs);
numArgNames,
argNameAndDependencyIDs);

// Resolve the name ids.
SmallVector<Identifier, 2> argNames;
for (auto argNameID : argNameIDs)
for (auto argNameID : argNameAndDependencyIDs.slice(0, numArgNames))
argNames.push_back(getIdentifier(argNameID));
DeclName name(ctx, ctx.Id_init, argNames);

Expand All @@ -2618,10 +2620,12 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
return llvm::make_error<OverrideError>(name, errorFlags);
}

auto canonicalType = getTypeChecked(canonicalTypeID);
if (!canonicalType) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(canonicalType.takeError()), errorFlags);
for (auto dependencyID : argNameAndDependencyIDs.slice(numArgNames)) {
auto dependency = getTypeChecked(dependencyID);
if (!dependency) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(dependency.takeError()), errorFlags);
}
}

auto parent = getDeclContext(contextID);
Expand Down Expand Up @@ -2698,18 +2702,20 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclContextID contextID;
bool isImplicit, isObjC, isStatic, isLet, hasNonPatternBindingInit;
uint8_t storageKind, rawAccessLevel, rawSetterAccessLevel;
TypeID interfaceTypeID, canonicalTypeID;
TypeID interfaceTypeID;
DeclID getterID, setterID, materializeForSetID, willSetID, didSetID;
DeclID addressorID, mutableAddressorID, overriddenID;
ArrayRef<uint64_t> dependencyIDs;

decls_block::VarLayout::readRecord(scratch, nameID, contextID,
isImplicit, isObjC, isStatic, isLet,
hasNonPatternBindingInit, storageKind,
interfaceTypeID, canonicalTypeID,
interfaceTypeID,
getterID, setterID, materializeForSetID,
addressorID, mutableAddressorID,
willSetID, didSetID, overriddenID,
rawAccessLevel, rawSetterAccessLevel);
rawAccessLevel, rawSetterAccessLevel,
dependencyIDs);

Identifier name = getIdentifier(nameID);

Expand All @@ -2719,10 +2725,12 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
return llvm::make_error<OverrideError>(name);
}

auto canonicalType = getTypeChecked(canonicalTypeID);
if (!canonicalType) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(canonicalType.takeError()));
for (TypeID dependencyID : dependencyIDs) {
auto dependency = getTypeChecked(dependencyID);
if (!dependency) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(dependency.takeError()));
}
}

auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
Expand Down Expand Up @@ -2810,37 +2818,42 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
bool isStatic;
uint8_t rawStaticSpelling, rawAccessLevel, rawAddressorKind;
bool isObjC, isMutating, hasDynamicSelf, throws;
unsigned numParamPatterns;
unsigned numParamPatterns, numNameComponentsBiased;
GenericEnvironmentID genericEnvID;
TypeID interfaceTypeID, canonicalTypeID;
TypeID interfaceTypeID;
DeclID associatedDeclID;
DeclID overriddenID;
DeclID accessorStorageDeclID;
bool hasCompoundName, needsNewVTableEntry;
ArrayRef<uint64_t> nameIDs;
bool needsNewVTableEntry;
ArrayRef<uint64_t> nameAndDependencyIDs;

decls_block::FuncLayout::readRecord(scratch, contextID, isImplicit,
isStatic, rawStaticSpelling, isObjC,
isMutating, hasDynamicSelf, throws,
numParamPatterns, genericEnvID,
interfaceTypeID, canonicalTypeID,
interfaceTypeID,
associatedDeclID, overriddenID,
accessorStorageDeclID, hasCompoundName,
accessorStorageDeclID,
numNameComponentsBiased,
rawAddressorKind, rawAccessLevel,
needsNewVTableEntry, nameIDs);
needsNewVTableEntry,
nameAndDependencyIDs);

// Resolve the name ids.
SmallVector<Identifier, 2> names;
for (auto nameID : nameIDs)
names.push_back(getIdentifier(nameID));

Identifier baseName = getIdentifier(nameAndDependencyIDs.front());
DeclName name;
if (!names.empty()) {
if (hasCompoundName)
name = DeclName(ctx, names[0],
llvm::makeArrayRef(names.begin() + 1, names.end()));
else
name = DeclName(names[0]);
ArrayRef<uint64_t> dependencyIDs;
if (numNameComponentsBiased != 0) {
SmallVector<Identifier, 2> names;
for (auto nameID : nameAndDependencyIDs.slice(1,
numNameComponentsBiased-1)){
names.push_back(getIdentifier(nameID));
}
name = DeclName(ctx, baseName, names);
dependencyIDs = nameAndDependencyIDs.slice(numNameComponentsBiased);
} else {
name = baseName;
dependencyIDs = nameAndDependencyIDs.drop_front();
}

DeclDeserializationError::Flags errorFlags;
Expand All @@ -2853,10 +2866,12 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
return llvm::make_error<OverrideError>(name, errorFlags);
}

auto canonicalType = getTypeChecked(canonicalTypeID);
if (!canonicalType) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(canonicalType.takeError()), errorFlags);
for (TypeID dependencyID : dependencyIDs) {
auto dependency = getTypeChecked(dependencyID);
if (!dependency) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(dependency.takeError()), errorFlags);
}
}

auto DC = getDeclContext(contextID);
Expand Down Expand Up @@ -3363,28 +3378,29 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclContextID contextID;
bool isImplicit, isObjC;
GenericEnvironmentID genericEnvID;
TypeID interfaceTypeID, canonicalTypeID;
TypeID interfaceTypeID;
DeclID getterID, setterID, materializeForSetID;
DeclID addressorID, mutableAddressorID, willSetID, didSetID;
DeclID overriddenID;
uint8_t rawAccessLevel, rawSetterAccessLevel;
uint8_t rawStorageKind;
ArrayRef<uint64_t> argNameIDs;
unsigned numArgNames;
ArrayRef<uint64_t> argNameAndDependencyIDs;

decls_block::SubscriptLayout::readRecord(scratch, contextID,
isImplicit, isObjC, rawStorageKind,
genericEnvID,
interfaceTypeID, canonicalTypeID,
interfaceTypeID,
getterID, setterID,
materializeForSetID,
addressorID, mutableAddressorID,
willSetID, didSetID,
overriddenID, rawAccessLevel,
rawSetterAccessLevel,
argNameIDs);
rawSetterAccessLevel, numArgNames,
argNameAndDependencyIDs);
// Resolve the name ids.
SmallVector<Identifier, 2> argNames;
for (auto argNameID : argNameIDs)
for (auto argNameID : argNameAndDependencyIDs.slice(0, numArgNames))
argNames.push_back(getIdentifier(argNameID));
DeclName name(ctx, ctx.Id_subscript, argNames);

Expand All @@ -3394,10 +3410,12 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
return llvm::make_error<OverrideError>(name);
}

auto canonicalType = getTypeChecked(canonicalTypeID);
if (!canonicalType) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(canonicalType.takeError()));
for (TypeID dependencyID : argNameAndDependencyIDs.slice(numArgNames)) {
auto dependency = getTypeChecked(dependencyID);
if (!dependency) {
return llvm::make_error<TypeError>(
name, takeErrorInfo(dependency.takeError()));
}
}

auto parent = getDeclContext(contextID);
Expand Down Expand Up @@ -4387,8 +4405,15 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
decls_block::UnboundGenericTypeLayout::readRecord(scratch,
genericID, parentID);

auto genericDecl = cast<GenericTypeDecl>(getDecl(genericID));
typeOrOffset = UnboundGenericType::get(genericDecl, getType(parentID), ctx);
auto nominalOrError = getDeclChecked(genericID);
if (!nominalOrError)
return nominalOrError.takeError();
auto genericDecl = cast<GenericTypeDecl>(nominalOrError.get());

// FIXME: Check this?
auto parentTy = getType(parentID);

typeOrOffset = UnboundGenericType::get(genericDecl, parentTy, ctx);
break;
}

Expand Down
Loading