[modular_aot] Serialization of type parameter declarations in module snapshots

TEST=ci

Issue: https://github.com/dart-lang/sdk/issues/61635
Change-Id: Ia5646ec6e2133a2232ffbbdb4926d94296bcd690
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505522
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
Alexander Markov
2026-05-22 10:10:19 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 7d93f44c17
commit d7d723327f
3 changed files with 115 additions and 40 deletions
+87 -37
View File
@@ -360,6 +360,7 @@ class SnapshotSerializer {
ast.StructuralParameterType() => getPredefinedCluster(
PredefinedClusters.typeParameterTypes,
),
TypeParameters() => getPredefinedCluster(PredefinedClusters.typeParameters),
TypeArgumentsConstant() => getPredefinedCluster(
PredefinedClusters.typeArguments,
),
@@ -379,40 +380,39 @@ class SnapshotSerializer {
SerializationCluster getInstanceCluster(ast.Class cls) =>
(_instanceClusters[cls] ??= InstanceSerializationCluster(cls));
SerializationCluster _createPredefinedCluster(
PredefinedClusters clusterId,
) => switch (clusterId) {
.libraryRefs => LibraryRefSerializationCluster(),
.classRefs => ClassRefSerializationCluster(),
.fieldRefs => FieldRefSerializationCluster(),
.functionRefs => FunctionRefSerializationCluster(),
.closureFunctionRefs => ClosureFunctionRefSerializationCluster(),
.closureRefs => ClosureRefSerializationCluster(),
.argumentsDescriptorRefs => ArgumentsDescriptorRefSerializationCluster(),
.recordShapeRefs => RecordShapeRefSerializationCluster(),
.oneByteStrings => OneByteStringSerializationCluster(),
.twoByteStrings => TwoByteStringSerializationCluster(),
.privateNames => PrivateNameSerializationCluster(),
.ints => IntSerializationCluster(),
.doubles => DoubleSerializationCluster(),
.lists => ListSerializationCluster(),
.maps => MapSerializationCluster(),
.sets => SetSerializationCluster(),
.records => RecordSerializationCluster(),
.instantiatedClosures => throw 'Unimplemented cluster $clusterId',
.typeParameters =>
throw 'Unimplemented cluster $clusterId', // TypeParametersSerializationCluster(),
.typeArguments => TypeArgumentsSerializationCluster(),
.interfaceTypes => InterfaceTypeSerializationCluster(),
.functionTypes => FunctionTypeSerializationCluster(),
.recordTypes => RecordTypeSerializationCluster(),
.typeParameterTypes => TypeParameterTypeSerializationCluster(),
.codes => CodeSerializationCluster(),
.icDatas => ICDataSerializationCluster(),
.subtypeTestCaches => SubtypeTestCacheSerializationCluster(),
.objectPools => ObjectPoolSerializationCluster(),
.instances => throw 'Each class has a separate instance cluster',
};
SerializationCluster _createPredefinedCluster(PredefinedClusters clusterId) =>
switch (clusterId) {
.libraryRefs => LibraryRefSerializationCluster(),
.classRefs => ClassRefSerializationCluster(),
.fieldRefs => FieldRefSerializationCluster(),
.functionRefs => FunctionRefSerializationCluster(),
.closureFunctionRefs => ClosureFunctionRefSerializationCluster(),
.closureRefs => ClosureRefSerializationCluster(),
.argumentsDescriptorRefs =>
ArgumentsDescriptorRefSerializationCluster(),
.recordShapeRefs => RecordShapeRefSerializationCluster(),
.oneByteStrings => OneByteStringSerializationCluster(),
.twoByteStrings => TwoByteStringSerializationCluster(),
.privateNames => PrivateNameSerializationCluster(),
.ints => IntSerializationCluster(),
.doubles => DoubleSerializationCluster(),
.lists => ListSerializationCluster(),
.maps => MapSerializationCluster(),
.sets => SetSerializationCluster(),
.records => RecordSerializationCluster(),
.instantiatedClosures => throw 'Unimplemented cluster $clusterId',
.typeParameters => TypeParametersSerializationCluster(),
.typeArguments => TypeArgumentsSerializationCluster(),
.interfaceTypes => InterfaceTypeSerializationCluster(),
.functionTypes => FunctionTypeSerializationCluster(),
.recordTypes => RecordTypeSerializationCluster(),
.typeParameterTypes => TypeParameterTypeSerializationCluster(),
.codes => CodeSerializationCluster(),
.icDatas => ICDataSerializationCluster(),
.subtypeTestCaches => SubtypeTestCacheSerializationCluster(),
.objectPools => ObjectPoolSerializationCluster(),
.instances => throw 'Each class has a separate instance cluster',
};
}
/// AST Constant which wraps an arbitrary object.
@@ -1221,8 +1221,58 @@ final class InterfaceTypeSerializationCluster extends SerializationCluster {
/// Declaration of type parameters, corresponds to the VM TypeParameters object.
class TypeParameters {
final List<ast.StructuralParameter> params;
TypeParameters(this.params);
final ast.ListConstant names;
final TypeArgumentsConstant bounds;
final TypeArgumentsConstant defaultTypes;
TypeParameters._(this.names, this.bounds, this.defaultTypes);
factory TypeParameters.fromStructuralParameters(
List<ast.StructuralParameter> params,
) {
final names = getListConstant([for (final p in params) p.name!]);
final bounds = TypeArgumentsConstant([for (final p in params) p.bound]);
final defaultTypes = TypeArgumentsConstant([
for (final p in params) p.defaultType,
]);
return TypeParameters._(names, bounds, defaultTypes);
}
}
final class TypeParametersSerializationCluster extends SerializationCluster {
final List<TypeParameters> _objects = [];
@override
void trace(SnapshotSerializer serializer, Object object) {
final obj = object as TypeParameters;
_objects.add(obj);
serializer.push(obj.names);
serializer.push(obj.bounds);
serializer.push(obj.defaultTypes);
}
@override
void writePreLoad(SnapshotSerializer serializer) {
serializer.writeUint(PredefinedClusters.typeParameters.index);
}
@override
void writeAlloc(SnapshotSerializer serializer) {
serializer.writeUint(_objects.length);
for (final obj in _objects) {
serializer.assignRef(obj);
}
}
@override
void writeFill(SnapshotSerializer serializer) {
for (var i = 0; i < _objects.length; i++) {
final obj = _objects[i];
serializer.writeRefId(obj.names);
serializer.writeRefId(obj.bounds);
serializer.writeRefId(obj.defaultTypes);
}
}
}
final class FunctionTypeSerializationCluster extends SerializationCluster {
@@ -1250,7 +1300,7 @@ final class FunctionTypeSerializationCluster extends SerializationCluster {
}
}
final typeParameters = type.typeParameters.isNotEmpty
? TypeParameters(type.typeParameters)
? TypeParameters.fromStructuralParameters(type.typeParameters)
: null;
final parameterTypes = getListConstant([
const ast.DynamicType(), // implicit closure parameter
+26 -3
View File
@@ -931,6 +931,31 @@ class InstanceDeserializationCluster : public DeserializationCluster {
intptr_t instance_size_ = 0;
};
class TypeParametersDeserializationCluster : public DeserializationCluster {
public:
TypeParametersDeserializationCluster()
: DeserializationCluster("TypeParameters") {}
~TypeParametersDeserializationCluster() {}
void ReadAlloc(Deserializer* d) override {
ReadAllocFixedSize(d, TypeParameters::InstanceSize());
}
void ReadFill(Deserializer* d_) override {
Deserializer::Local d(d_);
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
TypeParametersPtr tps = static_cast<TypeParametersPtr>(d.Ref(id));
Deserializer::InitializeHeader(tps, kTypeParametersCid,
TypeParameters::InstanceSize());
tps->untag()->names_ = static_cast<ArrayPtr>(d.ReadRef());
tps->untag()->flags_ = static_cast<ArrayPtr>(d.null());
tps->untag()->bounds_ = static_cast<TypeArgumentsPtr>(d.ReadRef());
tps->untag()->defaults_ = static_cast<TypeArgumentsPtr>(d.ReadRef());
}
}
};
class TypeArgumentsDeserializationCluster : public DeserializationCluster {
public:
TypeArgumentsDeserializationCluster()
@@ -1544,9 +1569,7 @@ DeserializationCluster* Deserializer::ReadCluster() {
UNIMPLEMENTED();
return nullptr;
case ModuleSnapshot::kTypeParameters:
// return new (Z) TypeParametersDeserializationCluster();
UNIMPLEMENTED();
return nullptr;
return new (Z) TypeParametersDeserializationCluster();
case ModuleSnapshot::kInterfaceTypes:
return new (Z) InterfaceTypeDeserializationCluster();
case ModuleSnapshot::kFunctionTypes:
+2
View File
@@ -63,6 +63,7 @@ class SetDeserializationCluster;
class SubtypeTestCacheDeserializationCluster;
class TypeArgumentsDeserializationCluster;
class TypeParameterTypeDeserializationCluster;
class TypeParametersDeserializationCluster;
} // namespace module_snapshot
#define DEFINE_CONTAINS_COMPRESSED(type) \
@@ -2951,6 +2952,7 @@ class UntaggedTypeParameters : public UntaggedObject {
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
friend class Object;
friend class module_snapshot::TypeParametersDeserializationCluster;
};
class UntaggedAbstractType : public UntaggedInstance {