[vm] Remove TypeRef
TypeRef type wraps around another type and it was used to represent a graph of recursive types. After [0], the only use of TypeRef is for TypeParameter.bound which may indirectly reference the same TypeParameter. This change replaces TypeParameter.bound with TypeParameter.owner and removes TypeRef entirely. Various parts of the VM no longer need to handle and support TypeRefs. TypeParameter.owner can reference a FunctionType, Class, or, as an optimization, it can be set to null in order to share class type parameters among different classes. With the exception of the 'TypeParameter.owner' back pointer, VM types are now not recursive and can be visited without additional tracking. Caveats: * Generic FunctionType cannot be cloned in a shallow way: when copying a FunctionType, type parameters should be cloned too and their owners should be updated. For that reason, a mapping between 'from' and 'to' function types (FunctionTypeMapping) is maintained during type transformations such as InstantiateFrom. FunctionType::Clone is used instead of Object::Clone where appropriate. * When testing types for subtyping and equivalence, mapping between function types is passed to make sure type parameters belong to the equivalent function types. * IL serializer needs to serialize function types as a whole before serializing any types potentially pointing into the middle of a function type (such as return type 'List<Y0>' pointing into the middle of a function type 'List<Y0> Function<Y0>()'). [0] https://dart-review.googlesource.com/c/sdk/+/296300 TEST=ci Change-Id: I67c2fd0117c6183a45e183919a7847fd1af70b3e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294165 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
Commit Queue
parent
709ba7aa24
commit
2ee6fcf514
+11
-18
@@ -27,7 +27,8 @@ A parameter type in the signature can be either a `Type`, a `FunctionType`, or a
|
||||
|
||||
## AbstractType
|
||||
|
||||
The VM declares the class `AbstractType` as a placeholder to store a concrete type. The following classes extend `AbstractType`: `Type`, `FunctionType`, `TypeParameter`, and `TypeRef`. The latter one, `TypeRef` is used to break cycles in recursive type graphs. More on it later. `AbstractType` declares several virtual methods that may be overridden by concrete types. See its declaration in [object.h](https://github.com/dart-lang/sdk/blob/main/runtime/vm/object.h).
|
||||
The VM declares the class `AbstractType` as a placeholder to store a concrete type. The following classes extend `AbstractType`: `Type`, `FunctionType`, `TypeParameter`, and `RecordType`.
|
||||
`AbstractType` declares several virtual methods that may be overridden by concrete types. See its declaration in [object.h](https://github.com/dart-lang/sdk/blob/main/runtime/vm/object.h).
|
||||
|
||||
## TypeArguments
|
||||
|
||||
@@ -123,14 +124,14 @@ The *function type arguments* are the concatenation of the type argument vectors
|
||||
A `TypeParameter` object specifies whether it is declared by a class (it is then a *class type parameter*) or by a function (it is then a *function type parameter*), thereby selecting the vector to use for its instantiation. The index value then identifies the type argument from that specific vector to be used to substitute the type parameter. To complete the instantiation, a normalization step is applied after the substitution.
|
||||
|
||||
The virtual method to instantiate an `AbstractType` is declared as follows:
|
||||
```dart
|
||||
```c++
|
||||
virtual AbstractTypePtr InstantiateFrom(
|
||||
const TypeArguments& instantiator_type_arguments,
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
```
|
||||
Note how both instantiators explained above are passed in, `instantiator_type_arguments` and `function_type_arguments`. Note also that an integer `num_free_fun_type_params` is provided. Its value indicates how many type arguments in the `function_type_arguments` vector are considered to be free variables and are therefore available to substitute type parameters with an index below this value. Type parameters with an index equal or above that value remain uninstantiated.
|
||||
Here is an example:
|
||||
@@ -143,27 +144,20 @@ class C<T> {
|
||||
```
|
||||
Although method `foo` is not generic, it takes a generic function `bar<B>()` as argument and its function type refers to class type parameter `T` and function type parameter `B`. When instantiating the function type of `foo` for a particular value of `T`, the function type parameter `B` must remain uninstantiated, because only `T` is a free variable in this function type. An instantiation in the context of `C<int>` would yield `int foo(bar<B>(int t, B b))`. In this case, the `InstantiateFrom` method would be called with `num_free_fun_type_params = 0`, as no function type parameters are free in this example.
|
||||
|
||||
## Trail
|
||||
|
||||
Another argument passed to the `InstantiateFrom` method above is `trail`. The trail prevents infinite recursion when traversing cyclic type graphs. When building type graphs, the VM makes sure that back references to the graph creating a cycle are represented by a `TypeRef` object. During graph traversal, when a `TypeRef` node is encountered, the implementation checks that the `TypeRef` is not already in the trail, in which case a repeated traversal of the same cycle is avoided. If not yet present, the `TypeRef` node is inserted in the trail, and the trail is passed down to recursive traversal calls.
|
||||
|
||||
There are different type graph traversal methods in the VM performing various operations. Each one of these traversals requires a trail to avoid divergence. Some take a single type graph as input, such as type instantiation and type instantiation check (whether a type is instantiated), but others take two type graphs as input, such as subtype test (whether a type is a subtype of another type) and type equivalence (whether two types are equivalent).
|
||||
|
||||
The traversals that take two type graphs as input use the trail differently. When a `TypeRef` is encountered on the left hand side, it is inserted in the trail in association with the right hand side type node being currently traversed. The implementation calls the right hand side type node the `buddy` of the `TypeRef` node. The trail consists of pairs of nodes. The implementation checks that a particular pair is already present before inserting it.
|
||||
|
||||
## Type Equivalence
|
||||
|
||||
The same virtual method `IsEquivalent` of `AbstractType` is used to traverse a pair of type graphs and decide whether they are canonically equal, syntactically equal, or equal in the context of subtype tests:
|
||||
```dart
|
||||
```c++
|
||||
enum class TypeEquality {
|
||||
kCanonical = 0,
|
||||
kSyntactical = 1,
|
||||
kInSubtypeTest = 2,
|
||||
};
|
||||
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(
|
||||
const Instance& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
```
|
||||
Instead of implementing three different traversals, the kind of type equality is passed as an argument to a single traversal method.
|
||||
|
||||
@@ -178,8 +172,7 @@ As a last step of finalization, types and type argument vectors get canonicalize
|
||||
## Canonicalization and Hash
|
||||
|
||||
The VM keeps global tables of canonical types and type arguments. Canonicalizing a type or a type argument vector consists in a table look up using a hash code to find a candidate, and then comparing the type with the candidate using the `IsEquivalent` method mentioned above (passing `kind = kCanonical`).
|
||||
|
||||
It is therefore imperative that two canonically equal types share the same hash code. `TypeRef` objects pose a problem in this regard. Namely, the hash of a `TypeRef` node cannot depend on the hash of the referenced type graph, otherwise, the hash code would depend on the location in the cycle where hash computation started and ended. Instead, the hash of a `TypeRef` node can only depend on information obtainable by “peeking” at the referenced type node, but not at the whole referenced type graph. See the comments in the [implementation](https://github.com/dart-lang/sdk/blob/main/runtime/vm/object.cc) of `TypeRef::Hash()` for details.
|
||||
It is therefore imperative that two canonically equal types share the same hash code.
|
||||
|
||||
## Cached Instantiations of TypeArguments
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ DEFINE_NATIVE_ENTRY(SuspendState_instantiateClosureWithFutureTypeArgument,
|
||||
}
|
||||
auto& type_args = TypeArguments::Handle(zone, type.arguments());
|
||||
ASSERT(type_args.IsNull() || type_args.Length() == 1);
|
||||
type_args = type_args.Canonicalize(thread, nullptr);
|
||||
type_args = type_args.Canonicalize(thread);
|
||||
|
||||
ASSERT(closure.delayed_type_arguments() ==
|
||||
Object::empty_type_arguments().ptr());
|
||||
|
||||
+10
-22
@@ -302,12 +302,6 @@ static InstancePtr CreateClassMirror(const Class& cls,
|
||||
const AbstractType& type,
|
||||
const Bool& is_declaration,
|
||||
const Instance& owner_mirror) {
|
||||
if (type.IsTypeRef()) {
|
||||
AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
|
||||
ASSERT(!ref_type.IsTypeRef());
|
||||
ASSERT(ref_type.IsCanonical());
|
||||
return CreateClassMirror(cls, ref_type, is_declaration, owner_mirror);
|
||||
}
|
||||
ASSERT(!cls.IsDynamicClass());
|
||||
ASSERT(!cls.IsVoidClass());
|
||||
ASSERT(!cls.IsNeverClass());
|
||||
@@ -518,12 +512,6 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_libraryDependencies, 0, 2) {
|
||||
}
|
||||
|
||||
static InstancePtr CreateTypeMirror(const AbstractType& type) {
|
||||
if (type.IsTypeRef()) {
|
||||
AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type());
|
||||
ASSERT(!ref_type.IsTypeRef());
|
||||
ASSERT(ref_type.IsCanonical());
|
||||
return CreateTypeMirror(ref_type);
|
||||
}
|
||||
ASSERT(type.IsFinalized());
|
||||
ASSERT(type.IsCanonical());
|
||||
|
||||
@@ -557,7 +545,7 @@ static InstancePtr CreateTypeMirror(const AbstractType& type) {
|
||||
if (!type.IsNullType()) {
|
||||
Type& legacy_type = Type::Handle(
|
||||
Type::Cast(type).ToNullability(Nullability::kLegacy, Heap::kOld));
|
||||
legacy_type ^= legacy_type.Canonicalize(Thread::Current(), nullptr);
|
||||
legacy_type ^= legacy_type.Canonicalize(Thread::Current());
|
||||
return CreateClassMirror(cls, legacy_type, Bool::False(),
|
||||
Object::null_instance());
|
||||
}
|
||||
@@ -567,7 +555,7 @@ static InstancePtr CreateTypeMirror(const AbstractType& type) {
|
||||
TypeParameter& legacy_type =
|
||||
TypeParameter::Handle(TypeParameter::Cast(type).ToNullability(
|
||||
Nullability::kLegacy, Heap::kOld));
|
||||
legacy_type ^= legacy_type.Canonicalize(Thread::Current(), nullptr);
|
||||
legacy_type ^= legacy_type.Canonicalize(Thread::Current());
|
||||
return CreateTypeVariableMirror(legacy_type, Object::null_instance());
|
||||
}
|
||||
UNREACHABLE();
|
||||
@@ -628,7 +616,7 @@ static AbstractTypePtr InstantiateType(const AbstractType& type,
|
||||
Thread* thread = Thread::Current();
|
||||
|
||||
if (type.IsInstantiated()) {
|
||||
return type.Canonicalize(thread, nullptr);
|
||||
return type.Canonicalize(thread);
|
||||
}
|
||||
TypeArguments& instantiator_type_args = TypeArguments::Handle();
|
||||
if (!instantiator.IsNull() && instantiator.IsType()) {
|
||||
@@ -646,7 +634,7 @@ static AbstractTypePtr InstantiateType(const AbstractType& type,
|
||||
instantiator_type_args, Object::null_type_arguments(), kAllFree,
|
||||
Heap::kOld));
|
||||
ASSERT(result.IsFinalized());
|
||||
return result.Canonicalize(thread, nullptr);
|
||||
return result.Canonicalize(thread);
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0, 0) {
|
||||
@@ -915,7 +903,7 @@ DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 0, 1) {
|
||||
ASSERT(!sig.IsNull());
|
||||
AbstractType& type = AbstractType::Handle(sig.result_type());
|
||||
// Signatures of function types are instantiated, but not canonical.
|
||||
return type.Canonicalize(thread, nullptr);
|
||||
return type.Canonicalize(thread);
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(ClassMirror_libraryUri, 0, 1) {
|
||||
@@ -1265,7 +1253,7 @@ DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 0, 1) {
|
||||
const AbstractType& type = AbstractType::Handle(instance.GetType(Heap::kNew));
|
||||
// The static type of null is specified to be the bottom type, however, the
|
||||
// runtime type of null is the Null type, which we correctly return here.
|
||||
return type.Canonicalize(thread, nullptr);
|
||||
return type.Canonicalize(thread);
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(ClosureMirror_function, 0, 1) {
|
||||
@@ -1551,8 +1539,8 @@ DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 0, 2) {
|
||||
// We handle constructors in Dart code.
|
||||
ASSERT(!func.IsGenerativeConstructor());
|
||||
AbstractType& type = AbstractType::Handle(func.result_type());
|
||||
type = type.Canonicalize(
|
||||
thread, nullptr); // Instantiated signatures are not canonical.
|
||||
type =
|
||||
type.Canonicalize(thread); // Instantiated signatures are not canonical.
|
||||
return InstantiateType(type, instantiator);
|
||||
}
|
||||
|
||||
@@ -1642,8 +1630,8 @@ DEFINE_NATIVE_ENTRY(ParameterMirror_type, 0, 3) {
|
||||
FunctionType::Handle(ref.GetFunctionTypeReferent());
|
||||
AbstractType& type = AbstractType::Handle(signature.ParameterTypeAt(
|
||||
signature.num_implicit_parameters() + pos.Value()));
|
||||
type = type.Canonicalize(
|
||||
thread, nullptr); // Instantiated signatures are not canonical.
|
||||
type =
|
||||
type.Canonicalize(thread); // Instantiated signatures are not canonical.
|
||||
return InstantiateType(type, instantiator);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ DEFINE_NATIVE_ENTRY(Object_runtimeType, 0, 1) {
|
||||
zone,
|
||||
Type::New(cls, type_arguments, Nullability::kNonNullable, Heap::kNew));
|
||||
type.SetIsFinalized();
|
||||
return type.Canonicalize(thread, nullptr);
|
||||
return type.Canonicalize(thread);
|
||||
}
|
||||
|
||||
return instance.GetType(Heap::kNew);
|
||||
@@ -462,7 +462,7 @@ DEFINE_NATIVE_ENTRY(Internal_extractTypeArguments, 0, 2) {
|
||||
extracted_type_args.SetTypeAt(i, type_arg);
|
||||
}
|
||||
extracted_type_args =
|
||||
extracted_type_args.Canonicalize(thread, nullptr); // Can be null.
|
||||
extracted_type_args.Canonicalize(thread); // Can be null.
|
||||
}
|
||||
}
|
||||
// Call the closure 'extract'.
|
||||
|
||||
@@ -123,7 +123,6 @@ class InstanceRefElement extends CustomElement implements Renderable {
|
||||
];
|
||||
case M.InstanceKind.type:
|
||||
case M.InstanceKind.functionType:
|
||||
case M.InstanceKind.typeRef:
|
||||
case M.InstanceKind.typeParameter:
|
||||
case M.InstanceKind.recordType:
|
||||
return [
|
||||
|
||||
@@ -236,9 +236,6 @@ class InstanceViewElement extends CustomElement implements Renderable {
|
||||
if (_instance.parameterIndex != null) {
|
||||
members.add(member('parameter index', '${_instance.parameterIndex}'));
|
||||
}
|
||||
if (_instance.targetType != null) {
|
||||
members.add(member('target type', _instance.targetType));
|
||||
}
|
||||
if (_instance.bound != null) {
|
||||
members.add(member('bound', _instance.bound));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ abstract class FieldRef extends ObjectRef {
|
||||
/// The declared type of this field.
|
||||
///
|
||||
/// The value will always be of one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
/// Type, FunctionType, RecordType, TypeParameter.
|
||||
InstanceRef? get declaredType;
|
||||
|
||||
/// Is this field const?
|
||||
|
||||
@@ -125,9 +125,6 @@ enum InstanceKind {
|
||||
/// An instance of the Dart class TypeParameter.
|
||||
typeParameter,
|
||||
|
||||
/// An instance of the Dart class TypeRef.
|
||||
typeRef,
|
||||
|
||||
/// An instance of the Dart class RawReceivePort
|
||||
receivePort,
|
||||
|
||||
@@ -190,7 +187,7 @@ bool isAbstractType(InstanceKind? kind) {
|
||||
switch (kind) {
|
||||
case InstanceKind.type:
|
||||
case InstanceKind.functionType:
|
||||
case InstanceKind.typeRef:
|
||||
case InstanceKind.recordType:
|
||||
case InstanceKind.typeParameter:
|
||||
return true;
|
||||
default:
|
||||
@@ -410,19 +407,10 @@ abstract class Instance extends Object implements InstanceRef {
|
||||
/// TypeParameter
|
||||
int? get parameterIndex;
|
||||
|
||||
/// [optional] The referent of a TypeRef instance.
|
||||
///
|
||||
/// The value will always be of one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
///
|
||||
/// Provided for instance kinds:
|
||||
/// TypeRef
|
||||
InstanceRef? get targetType;
|
||||
|
||||
/// [optional] The bound of a TypeParameter.
|
||||
///
|
||||
/// The value will always be of one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
/// Type, FunctionType, RecordType, TypeParameter.
|
||||
///
|
||||
/// Provided for instance kinds:
|
||||
/// TypeParameter
|
||||
|
||||
@@ -13,6 +13,6 @@ abstract class TypeArguments extends Object implements TypeArgumentsRef {
|
||||
/// A list of types.
|
||||
///
|
||||
/// The value will always be one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
/// Type, FunctionType, RecordType, TypeParameter.
|
||||
Iterable<InstanceRef>? get types;
|
||||
}
|
||||
|
||||
@@ -2778,8 +2778,6 @@ M.InstanceKind stringToInstanceKind(String s) {
|
||||
return M.InstanceKind.functionType;
|
||||
case 'TypeParameter':
|
||||
return M.InstanceKind.typeParameter;
|
||||
case 'TypeRef':
|
||||
return M.InstanceKind.typeRef;
|
||||
case 'ReceivePort':
|
||||
return M.InstanceKind.receivePort;
|
||||
case 'RecordType':
|
||||
@@ -2852,7 +2850,6 @@ class Instance extends HeapObject implements M.Instance {
|
||||
Class? parameterizedClass;
|
||||
TypeArguments? typeArguments;
|
||||
int? parameterIndex;
|
||||
Instance? targetType;
|
||||
Instance? bound;
|
||||
|
||||
Iterable<BoundField>? fields;
|
||||
@@ -3046,7 +3043,6 @@ class Instance extends HeapObject implements M.Instance {
|
||||
parameterizedClass = map['parameterizedClass'];
|
||||
typeArguments = map['typeArguments'];
|
||||
parameterIndex = map['parameterIndex'];
|
||||
targetType = map['targetType'];
|
||||
bound = map['bound'];
|
||||
|
||||
referent = map['mirrorReferent'];
|
||||
|
||||
@@ -125,7 +125,6 @@ class InstanceRefElement extends CustomElement implements Renderable {
|
||||
];
|
||||
case M.InstanceKind.type:
|
||||
case M.InstanceKind.functionType:
|
||||
case M.InstanceKind.typeRef:
|
||||
case M.InstanceKind.typeParameter:
|
||||
case M.InstanceKind.recordType:
|
||||
return [
|
||||
|
||||
@@ -251,9 +251,6 @@ class InstanceViewElement extends CustomElement implements Renderable {
|
||||
if (_instance.parameterIndex != null) {
|
||||
members.add(member('parameter index', '${_instance.parameterIndex}'));
|
||||
}
|
||||
if (_instance.targetType != null) {
|
||||
members.add(member('target type', _instance.targetType));
|
||||
}
|
||||
if (_instance.bound != null) {
|
||||
members.add(member('bound', _instance.bound));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ abstract class FieldRef extends ObjectRef {
|
||||
/// The declared type of this field.
|
||||
///
|
||||
/// The value will always be of one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
/// Type, FunctionType, RecordType, TypeParameter.
|
||||
InstanceRef get declaredType;
|
||||
|
||||
/// Is this field const?
|
||||
|
||||
@@ -125,9 +125,6 @@ enum InstanceKind {
|
||||
/// An instance of the Dart class TypeParameter.
|
||||
typeParameter,
|
||||
|
||||
/// An instance of the Dart class TypeRef.
|
||||
typeRef,
|
||||
|
||||
/// An instance of the Dart class RawReceivePort
|
||||
receivePort,
|
||||
|
||||
@@ -181,7 +178,7 @@ bool isAbstractType(InstanceKind kind) {
|
||||
switch (kind) {
|
||||
case InstanceKind.type:
|
||||
case InstanceKind.functionType:
|
||||
case InstanceKind.typeRef:
|
||||
case InstanceKind.recordType:
|
||||
case InstanceKind.typeParameter:
|
||||
return true;
|
||||
default:
|
||||
@@ -401,19 +398,10 @@ abstract class Instance extends Object implements InstanceRef {
|
||||
/// TypeParameter
|
||||
int get parameterIndex;
|
||||
|
||||
/// [optional] The referent of a TypeRef instance.
|
||||
///
|
||||
/// The value will always be of one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
///
|
||||
/// Provided for instance kinds:
|
||||
/// TypeRef
|
||||
InstanceRef get targetType;
|
||||
|
||||
/// [optional] The bound of a TypeParameter.
|
||||
///
|
||||
/// The value will always be of one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
/// Type, FunctionType, RecordType, TypeParameter.
|
||||
///
|
||||
/// Provided for instance kinds:
|
||||
/// TypeParameter
|
||||
|
||||
@@ -13,6 +13,6 @@ abstract class TypeArguments extends Object implements TypeArgumentsRef {
|
||||
/// A list of types.
|
||||
///
|
||||
/// The value will always be one of the kinds:
|
||||
/// Type, FunctionType, TypeRef, TypeParameter.
|
||||
/// Type, FunctionType, RecordType, TypeParameter.
|
||||
Iterable<InstanceRef> get types;
|
||||
}
|
||||
|
||||
@@ -2793,8 +2793,6 @@ M.InstanceKind stringToInstanceKind(String s) {
|
||||
return M.InstanceKind.functionType;
|
||||
case 'TypeParameter':
|
||||
return M.InstanceKind.typeParameter;
|
||||
case 'TypeRef':
|
||||
return M.InstanceKind.typeRef;
|
||||
case 'ReceivePort':
|
||||
return M.InstanceKind.receivePort;
|
||||
case 'Record':
|
||||
@@ -2867,7 +2865,6 @@ class Instance extends HeapObject implements M.Instance {
|
||||
Class parameterizedClass;
|
||||
TypeArguments typeArguments;
|
||||
int parameterIndex;
|
||||
Instance targetType;
|
||||
Instance bound;
|
||||
|
||||
Iterable<BoundField> fields;
|
||||
@@ -3065,7 +3062,6 @@ class Instance extends HeapObject implements M.Instance {
|
||||
parameterizedClass = map['parameterizedClass'];
|
||||
typeArguments = map['typeArguments'];
|
||||
parameterIndex = map['parameterIndex'];
|
||||
targetType = map['targetType'];
|
||||
bound = map['bound'];
|
||||
|
||||
referent = map['mirrorReferent'];
|
||||
|
||||
+7
-109
@@ -562,14 +562,8 @@ class CanonicalSetSerializationCluster : public SerializationCluster {
|
||||
element ^= ptr;
|
||||
intptr_t entry = -1;
|
||||
const bool present = table.FindKeyOrDeletedOrUnused(element, &entry);
|
||||
if (!present) {
|
||||
table.InsertKey(entry, element);
|
||||
} else {
|
||||
// Two recursive types with different topology (and hashes)
|
||||
// may be equal.
|
||||
ASSERT(element.IsRecursive());
|
||||
objects_[num_occupied++] = ptr;
|
||||
}
|
||||
ASSERT(!present);
|
||||
table.InsertKey(entry, element);
|
||||
} else {
|
||||
objects_[num_occupied++] = ptr;
|
||||
}
|
||||
@@ -901,7 +895,7 @@ class TypeArgumentsDeserializationCluster
|
||||
TypeArguments& type_arg = TypeArguments::Handle(d->zone());
|
||||
for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
|
||||
type_arg ^= refs.At(i);
|
||||
type_arg = type_arg.Canonicalize(d->thread(), nullptr);
|
||||
type_arg = type_arg.Canonicalize(d->thread());
|
||||
refs.SetAt(i, type_arg);
|
||||
}
|
||||
}
|
||||
@@ -4186,7 +4180,7 @@ class TypeDeserializationCluster
|
||||
AbstractType& type = AbstractType::Handle(d->zone());
|
||||
for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
|
||||
type ^= refs.At(i);
|
||||
type = type.Canonicalize(d->thread(), nullptr);
|
||||
type = type.Canonicalize(d->thread());
|
||||
refs.SetAt(i, type);
|
||||
}
|
||||
}
|
||||
@@ -4302,7 +4296,7 @@ class FunctionTypeDeserializationCluster
|
||||
AbstractType& type = AbstractType::Handle(d->zone());
|
||||
for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
|
||||
type ^= refs.At(i);
|
||||
type = type.Canonicalize(d->thread(), nullptr);
|
||||
type = type.Canonicalize(d->thread());
|
||||
refs.SetAt(i, type);
|
||||
}
|
||||
}
|
||||
@@ -4413,7 +4407,7 @@ class RecordTypeDeserializationCluster
|
||||
AbstractType& type = AbstractType::Handle(d->zone());
|
||||
for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
|
||||
type ^= refs.At(i);
|
||||
type = type.Canonicalize(d->thread(), nullptr);
|
||||
type = type.Canonicalize(d->thread());
|
||||
refs.SetAt(i, type);
|
||||
}
|
||||
}
|
||||
@@ -4436,97 +4430,6 @@ class RecordTypeDeserializationCluster
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
class TypeRefSerializationCluster : public SerializationCluster {
|
||||
public:
|
||||
TypeRefSerializationCluster()
|
||||
: SerializationCluster("TypeRef",
|
||||
kTypeRefCid,
|
||||
compiler::target::TypeRef::InstanceSize()) {}
|
||||
~TypeRefSerializationCluster() {}
|
||||
|
||||
void Trace(Serializer* s, ObjectPtr object) {
|
||||
TypeRefPtr type = TypeRef::RawCast(object);
|
||||
objects_.Add(type);
|
||||
PushFromTo(type);
|
||||
}
|
||||
|
||||
void WriteAlloc(Serializer* s) {
|
||||
const intptr_t count = objects_.length();
|
||||
s->WriteUnsigned(count);
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
TypeRefPtr type = objects_[i];
|
||||
s->AssignRef(type);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFill(Serializer* s) {
|
||||
const intptr_t count = objects_.length();
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
TypeRefPtr type = objects_[i];
|
||||
AutoTraceObject(type);
|
||||
WriteFromTo(type);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GrowableArray<TypeRefPtr> objects_;
|
||||
};
|
||||
#endif // !DART_PRECOMPILED_RUNTIME
|
||||
|
||||
class TypeRefDeserializationCluster : public DeserializationCluster {
|
||||
public:
|
||||
TypeRefDeserializationCluster() : DeserializationCluster("TypeRef") {}
|
||||
~TypeRefDeserializationCluster() {}
|
||||
|
||||
void ReadAlloc(Deserializer* d) {
|
||||
ReadAllocFixedSize(d, TypeRef::InstanceSize());
|
||||
}
|
||||
|
||||
void ReadFill(Deserializer* d_, bool primary) {
|
||||
Deserializer::Local d(d_);
|
||||
|
||||
const bool mark_canonical = primary && is_canonical();
|
||||
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
|
||||
TypeRefPtr type = static_cast<TypeRefPtr>(d.Ref(id));
|
||||
Deserializer::InitializeHeader(type, kTypeRefCid, TypeRef::InstanceSize(),
|
||||
mark_canonical);
|
||||
d.ReadFromTo(type);
|
||||
}
|
||||
}
|
||||
|
||||
void PostLoad(Deserializer* d, const Array& refs, bool primary) {
|
||||
if (!primary && is_canonical()) {
|
||||
AbstractType& type = AbstractType::Handle(d->zone());
|
||||
for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
|
||||
type ^= refs.At(i);
|
||||
type = type.Canonicalize(d->thread(), nullptr);
|
||||
refs.SetAt(i, type);
|
||||
}
|
||||
}
|
||||
|
||||
TypeRef& type_ref = TypeRef::Handle(d->zone());
|
||||
AbstractType& type = AbstractType::Handle(d->zone());
|
||||
Code& stub = Code::Handle(d->zone());
|
||||
const bool includes_code = Snapshot::IncludesCode(d->kind());
|
||||
|
||||
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
|
||||
type_ref ^= refs.At(id);
|
||||
|
||||
// Refresh finalization state and nullability.
|
||||
type = type_ref.type();
|
||||
type_ref.set_type(type);
|
||||
|
||||
if (includes_code) {
|
||||
type_ref.UpdateTypeTestingStubEntryPoint();
|
||||
} else {
|
||||
stub = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
|
||||
type_ref.InitializeTypeTestingStubNonAtomic(stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
class TypeParameterSerializationCluster
|
||||
: public CanonicalSetSerializationCluster<CanonicalTypeParameterSet,
|
||||
@@ -4623,7 +4526,7 @@ class TypeParameterDeserializationCluster
|
||||
TypeParameter& type_param = TypeParameter::Handle(d->zone());
|
||||
for (intptr_t i = start_index_, n = stop_index_; i < n; i++) {
|
||||
type_param ^= refs.At(i);
|
||||
type_param ^= type_param.Canonicalize(d->thread(), nullptr);
|
||||
type_param ^= type_param.Canonicalize(d->thread());
|
||||
refs.SetAt(i, type_param);
|
||||
}
|
||||
}
|
||||
@@ -7263,8 +7166,6 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid,
|
||||
case kRecordTypeCid:
|
||||
return new (Z) RecordTypeSerializationCluster(
|
||||
is_canonical, cluster_represents_canonical_set);
|
||||
case kTypeRefCid:
|
||||
return new (Z) TypeRefSerializationCluster();
|
||||
case kTypeParameterCid:
|
||||
return new (Z) TypeParameterSerializationCluster(
|
||||
is_canonical, cluster_represents_canonical_set);
|
||||
@@ -8442,9 +8343,6 @@ DeserializationCluster* Deserializer::ReadCluster() {
|
||||
case kRecordTypeCid:
|
||||
return new (Z)
|
||||
RecordTypeDeserializationCluster(is_canonical, !is_non_root_unit_);
|
||||
case kTypeRefCid:
|
||||
ASSERT(!is_canonical);
|
||||
return new (Z) TypeRefDeserializationCluster();
|
||||
case kTypeParameterCid:
|
||||
return new (Z)
|
||||
TypeParameterDeserializationCluster(is_canonical, !is_non_root_unit_);
|
||||
|
||||
@@ -364,7 +364,7 @@ TypeArgumentsPtr ClassFinalizer::FinalizeTypeArguments(
|
||||
}
|
||||
}
|
||||
if (finalization >= kCanonicalize) {
|
||||
return type_args.Canonicalize(Thread::Current(), nullptr);
|
||||
return type_args.Canonicalize(Thread::Current());
|
||||
}
|
||||
return type_args.ptr();
|
||||
}
|
||||
@@ -375,7 +375,7 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
|
||||
// Ensure type is canonical if canonicalization is requested.
|
||||
if ((finalization >= kCanonicalize) && !type.IsCanonical() &&
|
||||
!type.IsBeingFinalized()) {
|
||||
return type.Canonicalize(Thread::Current(), nullptr);
|
||||
return type.Canonicalize(Thread::Current());
|
||||
}
|
||||
return type.ptr();
|
||||
}
|
||||
@@ -383,22 +383,6 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
|
||||
if (type.IsTypeRef()) {
|
||||
if (type.IsBeingFinalized()) {
|
||||
// The referenced type will be finalized later by the code that set the
|
||||
// is_being_finalized mark bit.
|
||||
return type.ptr();
|
||||
}
|
||||
type.SetIsBeingFinalized();
|
||||
AbstractType& ref_type =
|
||||
AbstractType::Handle(zone, TypeRef::Cast(type).type());
|
||||
ref_type = FinalizeType(ref_type, finalization);
|
||||
ASSERT(ref_type.IsFinalized());
|
||||
TypeRef::Cast(type).set_type(ref_type);
|
||||
ASSERT(type.IsFinalized());
|
||||
return type.ptr();
|
||||
}
|
||||
|
||||
ASSERT(!type.IsBeingFinalized());
|
||||
|
||||
// Mark the type as being finalized in order to detect self reference.
|
||||
@@ -411,11 +395,12 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
|
||||
|
||||
if (type.IsTypeParameter()) {
|
||||
const TypeParameter& type_parameter = TypeParameter::Cast(type);
|
||||
const Class& parameterized_class =
|
||||
Class::Handle(zone, type_parameter.parameterized_class());
|
||||
// The base and index of a function type parameter are eagerly calculated
|
||||
// upon loading and do not require adjustment here.
|
||||
if (!parameterized_class.IsNull()) {
|
||||
if (type_parameter.IsClassTypeParameter()) {
|
||||
const Class& parameterized_class =
|
||||
Class::Cast(Object::Handle(zone, type_parameter.owner()));
|
||||
ASSERT(!parameterized_class.IsNull());
|
||||
// The index must reflect the position of this type parameter in the type
|
||||
// arguments vector of its parameterized class. The offset to add is the
|
||||
// number of type arguments in the super type, which is equal to the
|
||||
@@ -431,17 +416,17 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
|
||||
type_parameter.set_base(offset); // Informative, but not needed.
|
||||
type_parameter.set_index(index);
|
||||
|
||||
// Remove the reference to the parameterized class.
|
||||
type_parameter.set_parameterized_class_id(kClassCid);
|
||||
if (AbstractType::Handle(zone, type_parameter.bound())
|
||||
.IsNullableObjectType()) {
|
||||
// Remove the reference to the parameterized class to
|
||||
// canonicalize common class type parameters
|
||||
// with 'Object?' bound and same indices to the same
|
||||
// instances.
|
||||
type_parameter.set_owner(Object::null_object());
|
||||
}
|
||||
}
|
||||
|
||||
type_parameter.SetIsFinalized();
|
||||
AbstractType& upper_bound = AbstractType::Handle(zone);
|
||||
upper_bound = type_parameter.bound();
|
||||
if (!upper_bound.IsBeingFinalized()) {
|
||||
upper_bound = FinalizeType(upper_bound, kFinalize);
|
||||
type_parameter.set_bound(upper_bound);
|
||||
}
|
||||
|
||||
if (FLAG_trace_type_finalization) {
|
||||
THR_Print("Done finalizing type parameter at index %" Pd "\n",
|
||||
@@ -449,7 +434,7 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
|
||||
}
|
||||
|
||||
if (finalization >= kCanonicalize) {
|
||||
return type_parameter.Canonicalize(thread, nullptr);
|
||||
return type_parameter.Canonicalize(thread);
|
||||
}
|
||||
return type_parameter.ptr();
|
||||
}
|
||||
@@ -497,12 +482,12 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
|
||||
THR_Print("Canonicalizing type '%s'\n",
|
||||
String::Handle(zone, type.Name()).ToCString());
|
||||
AbstractType& canonical_type =
|
||||
AbstractType::Handle(zone, type.Canonicalize(thread, nullptr));
|
||||
AbstractType::Handle(zone, type.Canonicalize(thread));
|
||||
THR_Print("Done canonicalizing type '%s'\n",
|
||||
String::Handle(zone, canonical_type.Name()).ToCString());
|
||||
return canonical_type.ptr();
|
||||
}
|
||||
return type.Canonicalize(thread, nullptr);
|
||||
return type.Canonicalize(thread);
|
||||
} else {
|
||||
return type.ptr();
|
||||
}
|
||||
@@ -540,7 +525,7 @@ AbstractTypePtr ClassFinalizer::FinalizeSignature(
|
||||
signature.SetIsFinalized();
|
||||
|
||||
if (finalization >= kCanonicalize) {
|
||||
return signature.Canonicalize(Thread::Current(), nullptr);
|
||||
return signature.Canonicalize(Thread::Current());
|
||||
}
|
||||
return signature.ptr();
|
||||
}
|
||||
@@ -568,7 +553,7 @@ AbstractTypePtr ClassFinalizer::FinalizeRecordType(
|
||||
record.SetIsFinalized();
|
||||
|
||||
if (finalization >= kCanonicalize) {
|
||||
return record.Canonicalize(Thread::Current(), nullptr);
|
||||
return record.Canonicalize(Thread::Current());
|
||||
}
|
||||
return record.ptr();
|
||||
}
|
||||
@@ -1198,9 +1183,9 @@ void ClassFinalizer::RemapClassIds(intptr_t* old_to_new_cid) {
|
||||
// The following instances use cids for the computation of canonical hash codes
|
||||
// indirectly:
|
||||
//
|
||||
// * TypeRefPtr (due to UntaggedTypeRef::type_->type_class_id)
|
||||
// * TypePtr (due to type arguments)
|
||||
// * FunctionTypePtr (due to the result and parameter types)
|
||||
// * RecordTypePtr (due to field types)
|
||||
// * TypeArgumentsPtr (due to type references)
|
||||
// * InstancePtr (due to instance fields)
|
||||
// * ArrayPtr (due to type arguments & array entries)
|
||||
@@ -1215,11 +1200,6 @@ void ClassFinalizer::RemapClassIds(intptr_t* old_to_new_cid) {
|
||||
// * InstancePtr (weak table)
|
||||
// * ArrayPtr (weak table)
|
||||
//
|
||||
// No caching of canonical hash codes (i.e. it gets re-computed every time)
|
||||
// happens for:
|
||||
//
|
||||
// * TypeRefPtr (computed via UntaggedTypeRef::type_->type_class_id)
|
||||
//
|
||||
// Usages of canonical hash codes are:
|
||||
//
|
||||
// * ObjectStore::canonical_types()
|
||||
@@ -1293,8 +1273,7 @@ void ClassFinalizer::RehashTypes() {
|
||||
for (intptr_t i = 0; i < types.Length(); i++) {
|
||||
type ^= types.At(i);
|
||||
bool present = types_table.Insert(type);
|
||||
// Two recursive types with different topology (and hashes) may be equal.
|
||||
ASSERT(!present || type.IsRecursive());
|
||||
ASSERT(!present);
|
||||
}
|
||||
object_store->set_canonical_types(types_table.Release());
|
||||
|
||||
@@ -1314,8 +1293,7 @@ void ClassFinalizer::RehashTypes() {
|
||||
for (intptr_t i = 0; i < function_types.Length(); i++) {
|
||||
function_type ^= function_types.At(i);
|
||||
bool present = function_types_table.Insert(function_type);
|
||||
// Two recursive types with different topology (and hashes) may be equal.
|
||||
ASSERT(!present || function_type.IsRecursive());
|
||||
ASSERT(!present);
|
||||
}
|
||||
object_store->set_canonical_function_types(function_types_table.Release());
|
||||
|
||||
@@ -1335,8 +1313,7 @@ void ClassFinalizer::RehashTypes() {
|
||||
for (intptr_t i = 0; i < record_types.Length(); i++) {
|
||||
record_type ^= record_types.At(i);
|
||||
bool present = record_types_table.Insert(record_type);
|
||||
// Two recursive types with different topology (and hashes) may be equal.
|
||||
ASSERT(!present || record_type.IsRecursive());
|
||||
ASSERT(!present);
|
||||
}
|
||||
object_store->set_canonical_record_types(record_types_table.Release());
|
||||
|
||||
@@ -1356,8 +1333,7 @@ void ClassFinalizer::RehashTypes() {
|
||||
for (intptr_t i = 0; i < typeparams.Length(); i++) {
|
||||
typeparam ^= typeparams.At(i);
|
||||
bool present = typeparams_table.Insert(typeparam);
|
||||
// Two recursive types with different topology (and hashes) may be equal.
|
||||
ASSERT(!present || typeparam.IsRecursive());
|
||||
ASSERT(!present);
|
||||
}
|
||||
object_store->set_canonical_type_parameters(typeparams_table.Release());
|
||||
|
||||
@@ -1381,8 +1357,7 @@ void ClassFinalizer::RehashTypes() {
|
||||
for (intptr_t i = 0; i < typeargs.Length(); i++) {
|
||||
typearg ^= typeargs.At(i);
|
||||
bool present = typeargs_table.Insert(typearg);
|
||||
// Two recursive types with different topology (and hashes) may be equal.
|
||||
ASSERT(!present || typearg.IsRecursive());
|
||||
ASSERT(!present);
|
||||
}
|
||||
object_store->set_canonical_type_arguments(typeargs_table.Release());
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@ static constexpr intptr_t kClassIdTagMax = (1 << 20) - 1;
|
||||
V(Type) \
|
||||
V(FunctionType) \
|
||||
V(RecordType) \
|
||||
V(TypeRef) \
|
||||
V(TypeParameter) \
|
||||
V(FinalizerBase) \
|
||||
V(Finalizer) \
|
||||
|
||||
@@ -1161,8 +1161,14 @@ void Precompiler::AddType(const AbstractType& abstype) {
|
||||
if (typeparams_to_retain_.HasKey(¶m)) return;
|
||||
typeparams_to_retain_.Insert(&TypeParameter::ZoneHandle(Z, param.ptr()));
|
||||
|
||||
auto& bound = AbstractType::Handle(Z, param.bound());
|
||||
AddType(bound);
|
||||
Object& owner = Object::Handle(Z, param.owner());
|
||||
if (owner.IsClass()) {
|
||||
AddTypesOf(Class::Cast(owner));
|
||||
} else if (owner.IsFunctionType()) {
|
||||
AddType(FunctionType::Cast(owner));
|
||||
} else {
|
||||
RELEASE_ASSERT(owner.IsNull());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1193,10 +1199,6 @@ void Precompiler::AddType(const AbstractType& abstype) {
|
||||
AddTypesOf(cls);
|
||||
const TypeArguments& vector = TypeArguments::Handle(Z, type.arguments());
|
||||
AddTypeArguments(vector);
|
||||
} else if (abstype.IsTypeRef()) {
|
||||
AbstractType& type = AbstractType::Handle(Z);
|
||||
type = TypeRef::Cast(abstype).type();
|
||||
AddType(type);
|
||||
} else if (abstype.IsRecordType()) {
|
||||
const auto& rec = RecordType::Cast(abstype);
|
||||
AbstractType& type = AbstractType::Handle(Z);
|
||||
@@ -2404,8 +2406,7 @@ void Precompiler::AttachOptimizedTypeTestingStub() {
|
||||
void VisitObject(ObjectPtr obj) override {
|
||||
if (obj->GetClassId() == kTypeCid ||
|
||||
obj->GetClassId() == kFunctionTypeCid ||
|
||||
obj->GetClassId() == kRecordTypeCid ||
|
||||
obj->GetClassId() == kTypeRefCid) {
|
||||
obj->GetClassId() == kRecordTypeCid) {
|
||||
type_ ^= obj;
|
||||
types_->Add(type_);
|
||||
}
|
||||
|
||||
@@ -1055,11 +1055,8 @@ void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) {
|
||||
AbstractType& result = AbstractType::Handle(
|
||||
Z, instr->type().InstantiateFrom(
|
||||
instantiator_type_args, function_type_args, kAllFree, Heap::kOld));
|
||||
if (result.IsTypeRef()) {
|
||||
result = TypeRef::Cast(result).type();
|
||||
}
|
||||
ASSERT(result.IsInstantiated());
|
||||
result = result.Canonicalize(T, nullptr);
|
||||
result = result.Canonicalize(T);
|
||||
SetValue(instr, result);
|
||||
}
|
||||
|
||||
@@ -1126,7 +1123,7 @@ void ConstantPropagator::VisitInstantiateTypeArguments(
|
||||
Z, type_arguments.InstantiateFrom(
|
||||
instantiator_type_args, function_type_args, kAllFree, Heap::kOld));
|
||||
ASSERT(result.IsInstantiated());
|
||||
result = result.Canonicalize(T, nullptr);
|
||||
result = result.Canonicalize(T);
|
||||
SetValue(instr, result);
|
||||
}
|
||||
|
||||
|
||||
@@ -1027,9 +1027,6 @@ Instruction* AssertSubtypeInstr::Canonicalize(FlowGraph* flow_graph) {
|
||||
auto& constant_super_type = AbstractType::Handle(
|
||||
Z, AbstractType::Cast(super_type()->BoundConstant()).ptr());
|
||||
|
||||
ASSERT(!constant_super_type.IsTypeRef());
|
||||
ASSERT(!constant_sub_type.IsTypeRef());
|
||||
|
||||
if (AbstractType::InstantiateAndTestSubtype(
|
||||
&constant_sub_type, &constant_super_type,
|
||||
constant_instantiator_type_args, constant_function_type_args)) {
|
||||
@@ -3025,10 +3022,7 @@ Definition* AssertAssignableInstr::Canonicalize(FlowGraph* flow_graph) {
|
||||
// Failed instantiation in dead code.
|
||||
return this;
|
||||
}
|
||||
if (new_dst_type.IsTypeRef()) {
|
||||
new_dst_type = TypeRef::Cast(new_dst_type).type();
|
||||
}
|
||||
new_dst_type = new_dst_type.Canonicalize(Thread::Current(), nullptr);
|
||||
new_dst_type = new_dst_type.Canonicalize(Thread::Current());
|
||||
|
||||
// Successfully instantiated destination type: update the type attached
|
||||
// to this instruction and set type arguments to null because we no
|
||||
|
||||
@@ -1425,7 +1425,7 @@ void FlowGraphSerializer::WriteTrait<const Object&>::Write(
|
||||
ASSERT(cid != kIllegalCid);
|
||||
// Do not write objects repeatedly.
|
||||
const intptr_t object_id = s->heap()->GetObjectId(x.ptr());
|
||||
if (object_id != 0) {
|
||||
if (object_id > 0) {
|
||||
const intptr_t object_index = object_id - 1;
|
||||
s->Write<intptr_t>(kIllegalCid);
|
||||
s->Write<intptr_t>(object_index);
|
||||
@@ -1458,6 +1458,109 @@ void FlowGraphDeserializer::SetObjectAt(intptr_t object_index,
|
||||
objects_[object_index] = &object;
|
||||
}
|
||||
|
||||
bool FlowGraphSerializer::IsWritten(const Object& obj) {
|
||||
const intptr_t object_id = heap()->GetObjectId(obj.ptr());
|
||||
return (object_id != 0);
|
||||
}
|
||||
|
||||
bool FlowGraphSerializer::HasEnclosingTypes(const Object& obj) {
|
||||
if (num_free_fun_type_params_ == 0) return false;
|
||||
if (obj.IsAbstractType()) {
|
||||
return !AbstractType::Cast(obj).IsInstantiated(kFunctions,
|
||||
num_free_fun_type_params_);
|
||||
} else if (obj.IsTypeArguments()) {
|
||||
return !TypeArguments::Cast(obj).IsInstantiated(kFunctions,
|
||||
num_free_fun_type_params_);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
bool FlowGraphSerializer::WriteObjectWithEnclosingTypes(const Object& obj) {
|
||||
if (HasEnclosingTypes(obj)) {
|
||||
Write<bool>(true);
|
||||
// Reset assigned object id so it could be written
|
||||
// while writing enclosing types.
|
||||
heap()->SetObjectId(obj.ptr(), -1);
|
||||
WriteEnclosingTypes(obj, num_free_fun_type_params_);
|
||||
Write<bool>(false);
|
||||
// Can write any type parameters after all enclosing types are written.
|
||||
const intptr_t saved_num_free_fun_type_params = num_free_fun_type_params_;
|
||||
num_free_fun_type_params_ = 0;
|
||||
Write<const Object&>(obj);
|
||||
num_free_fun_type_params_ = saved_num_free_fun_type_params;
|
||||
return true;
|
||||
} else {
|
||||
Write<bool>(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FlowGraphSerializer::WriteEnclosingTypes(
|
||||
const Object& obj,
|
||||
intptr_t num_free_fun_type_params) {
|
||||
if (obj.IsType()) {
|
||||
const auto& type = Type::Cast(obj);
|
||||
if (type.arguments() != TypeArguments::null()) {
|
||||
const auto& type_args = TypeArguments::Handle(Z, type.arguments());
|
||||
WriteEnclosingTypes(type_args, num_free_fun_type_params);
|
||||
}
|
||||
} else if (obj.IsRecordType()) {
|
||||
const auto& rec = RecordType::Cast(obj);
|
||||
auto& elem = AbstractType::Handle(Z);
|
||||
for (intptr_t i = 0, n = rec.NumFields(); i < n; ++i) {
|
||||
elem = rec.FieldTypeAt(i);
|
||||
WriteEnclosingTypes(elem, num_free_fun_type_params);
|
||||
}
|
||||
} else if (obj.IsFunctionType()) {
|
||||
const auto& sig = FunctionType::Cast(obj);
|
||||
const intptr_t num_parent_type_args = sig.NumParentTypeArguments();
|
||||
if (num_free_fun_type_params > num_parent_type_args) {
|
||||
num_free_fun_type_params = num_parent_type_args;
|
||||
}
|
||||
AbstractType& elem = AbstractType::Handle(Z, sig.result_type());
|
||||
WriteEnclosingTypes(elem, num_free_fun_type_params);
|
||||
for (intptr_t i = 0, n = sig.NumParameters(); i < n; ++i) {
|
||||
elem = sig.ParameterTypeAt(i);
|
||||
WriteEnclosingTypes(elem, num_free_fun_type_params);
|
||||
}
|
||||
if (sig.IsGeneric()) {
|
||||
const TypeParameters& type_params =
|
||||
TypeParameters::Handle(Z, sig.type_parameters());
|
||||
WriteEnclosingTypes(TypeArguments::Handle(Z, type_params.bounds()),
|
||||
num_free_fun_type_params);
|
||||
}
|
||||
} else if (obj.IsTypeParameter()) {
|
||||
const auto& tp = TypeParameter::Cast(obj);
|
||||
if (tp.IsFunctionTypeParameter() &&
|
||||
(tp.index() < num_free_fun_type_params)) {
|
||||
const auto& owner = FunctionType::Cast(Object::Handle(Z, tp.owner()));
|
||||
if (!IsWritten(owner)) {
|
||||
Write<bool>(true);
|
||||
Write<const Object&>(owner);
|
||||
}
|
||||
}
|
||||
} else if (obj.IsTypeArguments()) {
|
||||
const auto& type_args = TypeArguments::Cast(obj);
|
||||
auto& elem = AbstractType::Handle(Z);
|
||||
for (intptr_t i = 0, n = type_args.Length(); i < n; ++i) {
|
||||
elem = type_args.TypeAt(i);
|
||||
WriteEnclosingTypes(elem, num_free_fun_type_params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Object& FlowGraphDeserializer::ReadObjectWithEnclosingTypes() {
|
||||
if (Read<bool>()) {
|
||||
while (Read<bool>()) {
|
||||
Read<const Object&>();
|
||||
}
|
||||
return Read<const Object&>();
|
||||
} else {
|
||||
return Object::null_object();
|
||||
}
|
||||
}
|
||||
|
||||
void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
||||
intptr_t cid,
|
||||
intptr_t object_index) {
|
||||
@@ -1519,24 +1622,23 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
||||
case kFunctionTypeCid: {
|
||||
const auto& type = FunctionType::Cast(x);
|
||||
ASSERT(type.IsFinalized());
|
||||
TypeScope type_scope(this, type.IsRecursive());
|
||||
if (WriteObjectWithEnclosingTypes(type)) {
|
||||
break;
|
||||
}
|
||||
const intptr_t saved_num_free_fun_type_params = num_free_fun_type_params_;
|
||||
const intptr_t num_parent_type_args = type.NumParentTypeArguments();
|
||||
if (num_free_fun_type_params_ > num_parent_type_args) {
|
||||
num_free_fun_type_params_ = num_parent_type_args;
|
||||
}
|
||||
Write<int8_t>(static_cast<int8_t>(type.nullability()));
|
||||
Write<uint32_t>(type.packed_parameter_counts());
|
||||
Write<uint16_t>(type.packed_type_parameter_counts());
|
||||
Write<const TypeParameters&>(
|
||||
TypeParameters::Handle(Z, type.type_parameters()));
|
||||
AbstractType& t = AbstractType::Handle(Z, type.result_type());
|
||||
Write<const AbstractType&>(t);
|
||||
// Do not write parameter types as Array to avoid eager canonicalization
|
||||
// when reading.
|
||||
const Array& param_types = Array::Handle(Z, type.parameter_types());
|
||||
ASSERT(param_types.Length() == type.NumParameters());
|
||||
for (intptr_t i = 0, n = type.NumParameters(); i < n; ++i) {
|
||||
t ^= param_types.At(i);
|
||||
Write<const AbstractType&>(t);
|
||||
}
|
||||
Write<const AbstractType&>(AbstractType::Handle(Z, type.result_type()));
|
||||
Write<const Array&>(Array::Handle(Z, type.parameter_types()));
|
||||
Write<const Array&>(Array::Handle(Z, type.named_parameter_names()));
|
||||
Write<bool>(type_scope.CanBeCanonicalized());
|
||||
num_free_fun_type_params_ = saved_num_free_fun_type_params;
|
||||
break;
|
||||
}
|
||||
case kICDataCid: {
|
||||
@@ -1618,11 +1720,12 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
||||
case kRecordTypeCid: {
|
||||
const auto& rec = RecordType::Cast(x);
|
||||
ASSERT(rec.IsFinalized());
|
||||
TypeScope type_scope(this, rec.IsRecursive());
|
||||
if (WriteObjectWithEnclosingTypes(rec)) {
|
||||
break;
|
||||
}
|
||||
Write<int8_t>(static_cast<int8_t>(rec.nullability()));
|
||||
Write<RecordShape>(rec.shape());
|
||||
Write<const Array&>(Array::Handle(Z, rec.field_types()));
|
||||
Write<bool>(type_scope.CanBeCanonicalized());
|
||||
break;
|
||||
}
|
||||
case kSentinelCid:
|
||||
@@ -1653,21 +1756,24 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
||||
case kTypeCid: {
|
||||
const auto& type = Type::Cast(x);
|
||||
ASSERT(type.IsFinalized());
|
||||
if (WriteObjectWithEnclosingTypes(type)) {
|
||||
break;
|
||||
}
|
||||
const auto& cls = Class::Handle(Z, type.type_class());
|
||||
TypeScope type_scope(this, type.IsRecursive() && cls.IsGeneric());
|
||||
Write<int8_t>(static_cast<int8_t>(type.nullability()));
|
||||
Write<classid_t>(type.type_class_id());
|
||||
if (cls.IsGeneric()) {
|
||||
const auto& type_args = TypeArguments::Handle(Z, type.arguments());
|
||||
Write<const TypeArguments&>(type_args);
|
||||
}
|
||||
Write<bool>(type_scope.CanBeCanonicalized());
|
||||
break;
|
||||
}
|
||||
case kTypeArgumentsCid: {
|
||||
const auto& type_args = TypeArguments::Cast(x);
|
||||
ASSERT(type_args.IsFinalized());
|
||||
TypeScope type_scope(this, type_args.IsRecursive());
|
||||
if (WriteObjectWithEnclosingTypes(type_args)) {
|
||||
break;
|
||||
}
|
||||
const intptr_t len = type_args.Length();
|
||||
Write<intptr_t>(len);
|
||||
auto& type = AbstractType::Handle(Z);
|
||||
@@ -1675,19 +1781,21 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
||||
type = type_args.TypeAt(i);
|
||||
Write<const AbstractType&>(type);
|
||||
}
|
||||
Write<bool>(type_scope.CanBeCanonicalized());
|
||||
break;
|
||||
}
|
||||
case kTypeParameterCid: {
|
||||
const auto& tp = TypeParameter::Cast(x);
|
||||
ASSERT(tp.IsFinalized());
|
||||
TypeScope type_scope(this, tp.IsRecursive());
|
||||
Write<classid_t>(tp.parameterized_class_id());
|
||||
if (WriteObjectWithEnclosingTypes(tp)) {
|
||||
break;
|
||||
}
|
||||
Write<intptr_t>(tp.base());
|
||||
Write<intptr_t>(tp.index());
|
||||
Write<int8_t>(static_cast<int8_t>(tp.nullability()));
|
||||
Write<const AbstractType&>(AbstractType::Handle(Z, tp.bound()));
|
||||
Write<bool>(type_scope.CanBeCanonicalized());
|
||||
Write<classid_t>(tp.parameterized_class_id());
|
||||
if (tp.IsFunctionTypeParameter()) {
|
||||
Write<const Object&>(Object::Handle(Z, tp.owner()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kTypeParametersCid: {
|
||||
@@ -1698,14 +1806,6 @@ void FlowGraphSerializer::WriteObjectImpl(const Object& x,
|
||||
Write<const TypeArguments&>(TypeArguments::Handle(Z, tps.defaults()));
|
||||
break;
|
||||
}
|
||||
case kTypeRefCid: {
|
||||
const auto& tr = TypeRef::Cast(x);
|
||||
ASSERT(tr.IsFinalized());
|
||||
TypeScope type_scope(this, tr.IsRecursive());
|
||||
Write<const AbstractType&>(AbstractType::Handle(Z, tr.type()));
|
||||
Write<bool>(type_scope.CanBeCanonicalized());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const classid_t cid = x.GetClassId();
|
||||
if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid)) {
|
||||
@@ -1793,6 +1893,10 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
case kFunctionCid:
|
||||
return Read<const Function&>();
|
||||
case kFunctionTypeCid: {
|
||||
const auto& enc_type = ReadObjectWithEnclosingTypes();
|
||||
if (!enc_type.IsNull()) {
|
||||
return enc_type;
|
||||
}
|
||||
const Nullability nullability = static_cast<Nullability>(Read<int8_t>());
|
||||
auto& result =
|
||||
FunctionType::ZoneHandle(Z, FunctionType::New(0, nullability));
|
||||
@@ -1801,15 +1905,10 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
result.set_packed_type_parameter_counts(Read<uint16_t>());
|
||||
result.SetTypeParameters(Read<const TypeParameters&>());
|
||||
result.set_result_type(Read<const AbstractType&>());
|
||||
const Array& param_types =
|
||||
Array::Handle(Z, Array::New(result.NumParameters(), Heap::kOld));
|
||||
for (intptr_t i = 0, n = result.NumParameters(); i < n; ++i) {
|
||||
param_types.SetAt(i, Read<const AbstractType&>());
|
||||
}
|
||||
result.set_parameter_types(param_types);
|
||||
result.set_parameter_types(Read<const Array&>());
|
||||
result.set_named_parameter_names(Read<const Array&>());
|
||||
result.SetIsFinalized();
|
||||
result ^= MaybeCanonicalize(result, object_index, Read<bool>());
|
||||
result ^= result.Canonicalize(thread());
|
||||
return result;
|
||||
}
|
||||
case kICDataCid: {
|
||||
@@ -1897,13 +1996,17 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
return record;
|
||||
}
|
||||
case kRecordTypeCid: {
|
||||
const auto& enc_type = ReadObjectWithEnclosingTypes();
|
||||
if (!enc_type.IsNull()) {
|
||||
return enc_type;
|
||||
}
|
||||
const Nullability nullability = static_cast<Nullability>(Read<int8_t>());
|
||||
const RecordShape shape = Read<RecordShape>();
|
||||
const Array& field_types = Read<const Array&>();
|
||||
RecordType& rec = RecordType::ZoneHandle(
|
||||
Z, RecordType::New(shape, field_types, nullability));
|
||||
rec.SetIsFinalized();
|
||||
rec ^= MaybeCanonicalize(rec, object_index, Read<bool>());
|
||||
rec ^= rec.Canonicalize(thread());
|
||||
return rec;
|
||||
}
|
||||
case kSentinelCid:
|
||||
@@ -1927,6 +2030,10 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
return String::ZoneHandle(Z, Symbols::FromUTF16(thread(), utf16, length));
|
||||
}
|
||||
case kTypeCid: {
|
||||
const auto& enc_type = ReadObjectWithEnclosingTypes();
|
||||
if (!enc_type.IsNull()) {
|
||||
return enc_type;
|
||||
}
|
||||
const Nullability nullability = static_cast<Nullability>(Read<int8_t>());
|
||||
const classid_t type_class_id = Read<classid_t>();
|
||||
const auto& cls = Class::Handle(Z, GetClassById(type_class_id));
|
||||
@@ -1941,37 +2048,43 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
result = cls.DeclarationType();
|
||||
result = result.ToNullability(nullability, Heap::kOld);
|
||||
}
|
||||
result ^= MaybeCanonicalize(result, object_index, Read<bool>());
|
||||
result ^= result.Canonicalize(thread());
|
||||
return result;
|
||||
}
|
||||
case kTypeArgumentsCid: {
|
||||
const auto& enc_type_args = ReadObjectWithEnclosingTypes();
|
||||
if (!enc_type_args.IsNull()) {
|
||||
return enc_type_args;
|
||||
}
|
||||
const intptr_t len = Read<intptr_t>();
|
||||
auto& type_args = TypeArguments::ZoneHandle(Z, TypeArguments::New(len));
|
||||
SetObjectAt(object_index, type_args);
|
||||
for (intptr_t i = 0; i < len; ++i) {
|
||||
type_args.SetTypeAt(i, Read<const AbstractType&>());
|
||||
}
|
||||
type_args ^= MaybeCanonicalize(type_args, object_index, Read<bool>());
|
||||
type_args ^= type_args.Canonicalize(thread());
|
||||
return type_args;
|
||||
}
|
||||
case kTypeParameterCid: {
|
||||
const classid_t parameterized_class_id = Read<classid_t>();
|
||||
const auto& enc_type = ReadObjectWithEnclosingTypes();
|
||||
if (!enc_type.IsNull()) {
|
||||
return enc_type;
|
||||
}
|
||||
const intptr_t base = Read<intptr_t>();
|
||||
const intptr_t index = Read<intptr_t>();
|
||||
const Nullability nullability = static_cast<Nullability>(Read<int8_t>());
|
||||
const auto& parameterized_class =
|
||||
Class::Handle(Z, (parameterized_class_id == kFunctionCid)
|
||||
? Class::null()
|
||||
: GetClassById(parameterized_class_id));
|
||||
const classid_t parameterized_class_id = Read<classid_t>();
|
||||
const Object& owner =
|
||||
(parameterized_class_id == kObjectCid)
|
||||
? Object::null_object()
|
||||
: ((parameterized_class_id == kFunctionCid)
|
||||
? Read<const Object&>()
|
||||
: Class::Handle(Z, GetClassById(parameterized_class_id)));
|
||||
auto& tp = TypeParameter::ZoneHandle(
|
||||
Z, TypeParameter::New(parameterized_class, base, index,
|
||||
/*bound=*/Object::null_abstract_type(),
|
||||
nullability));
|
||||
Z, TypeParameter::New(owner, base, index, nullability));
|
||||
SetObjectAt(object_index, tp);
|
||||
const auto& bound = Read<const AbstractType&>();
|
||||
tp.set_bound(bound);
|
||||
tp.SetIsFinalized();
|
||||
tp ^= MaybeCanonicalize(tp, object_index, Read<bool>());
|
||||
tp ^= tp.Canonicalize(thread());
|
||||
return tp;
|
||||
}
|
||||
case kTypeParametersCid: {
|
||||
@@ -1982,16 +2095,6 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
tps.set_defaults(Read<const TypeArguments&>());
|
||||
return tps;
|
||||
}
|
||||
case kTypeRefCid: {
|
||||
auto& tr =
|
||||
TypeRef::ZoneHandle(Z, TypeRef::New(Object::null_abstract_type()));
|
||||
SetObjectAt(object_index, tr);
|
||||
const auto& type = Read<const AbstractType&>();
|
||||
ASSERT(!type.IsNull());
|
||||
tr.set_type(type);
|
||||
tr ^= MaybeCanonicalize(tr, object_index, Read<bool>());
|
||||
return tr;
|
||||
}
|
||||
default:
|
||||
if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid)) {
|
||||
const auto& cls = Class::Handle(Z, GetClassById(cid));
|
||||
@@ -2024,29 +2127,6 @@ const Object& FlowGraphDeserializer::ReadObjectImpl(intptr_t cid,
|
||||
return Object::null_object();
|
||||
}
|
||||
|
||||
InstancePtr FlowGraphDeserializer::MaybeCanonicalize(
|
||||
const Instance& obj,
|
||||
intptr_t object_index,
|
||||
bool can_be_canonicalized) {
|
||||
if (can_be_canonicalized) {
|
||||
intptr_t remaining = 0;
|
||||
for (intptr_t idx : pending_canonicalization_) {
|
||||
if (idx < object_index) {
|
||||
pending_canonicalization_[remaining++] = idx;
|
||||
} else {
|
||||
objects_[idx] = &Instance::ZoneHandle(
|
||||
Z, Instance::Cast(*objects_[idx]).Canonicalize(thread()));
|
||||
}
|
||||
}
|
||||
pending_canonicalization_.TruncateTo(remaining);
|
||||
return obj.Canonicalize(thread());
|
||||
} else {
|
||||
ASSERT(objects_[object_index]->ptr() == obj.ptr());
|
||||
pending_canonicalization_.Add(object_index);
|
||||
return obj.ptr();
|
||||
}
|
||||
}
|
||||
|
||||
#define HANDLES_SERIALIZABLE_AS_OBJECT(V) \
|
||||
V(AbstractType, Object::null_abstract_type()) \
|
||||
V(Array, Object::null_array()) \
|
||||
|
||||
@@ -306,31 +306,11 @@ class FlowGraphSerializer : public ValueObject {
|
||||
|
||||
private:
|
||||
void WriteObjectImpl(const Object& x, intptr_t cid, intptr_t object_index);
|
||||
|
||||
// Used to track scopes of recursive types during serialization.
|
||||
struct TypeScope {
|
||||
TypeScope(FlowGraphSerializer* serializer, bool is_recursive)
|
||||
: serializer_(serializer),
|
||||
is_recursive_(is_recursive),
|
||||
was_writing_recursive_type_(serializer->writing_recursive_type_) {
|
||||
serializer->writing_recursive_type_ = is_recursive;
|
||||
}
|
||||
|
||||
~TypeScope() {
|
||||
serializer_->writing_recursive_type_ = was_writing_recursive_type_;
|
||||
}
|
||||
|
||||
// Returns true if type of the current scope can be canonicalized
|
||||
// during deserialization. Recursive types which were not
|
||||
// fully deserialized should not be canonicalized.
|
||||
bool CanBeCanonicalized() const {
|
||||
return !is_recursive_ || !was_writing_recursive_type_;
|
||||
}
|
||||
|
||||
FlowGraphSerializer* const serializer_;
|
||||
const bool is_recursive_;
|
||||
const bool was_writing_recursive_type_;
|
||||
};
|
||||
bool IsWritten(const Object& obj);
|
||||
bool HasEnclosingTypes(const Object& obj);
|
||||
bool WriteObjectWithEnclosingTypes(const Object& type);
|
||||
void WriteEnclosingTypes(const Object& type,
|
||||
intptr_t num_free_fun_type_params);
|
||||
|
||||
NonStreamingWriteStream* stream_;
|
||||
Zone* zone_;
|
||||
@@ -339,7 +319,7 @@ class FlowGraphSerializer : public ValueObject {
|
||||
Heap* heap_;
|
||||
intptr_t object_counter_ = 0;
|
||||
bool can_write_refs_ = false;
|
||||
bool writing_recursive_type_ = false;
|
||||
intptr_t num_free_fun_type_params_ = kMaxInt;
|
||||
};
|
||||
|
||||
// Deserializes flow graph.
|
||||
@@ -521,10 +501,7 @@ class FlowGraphDeserializer : public ValueObject {
|
||||
ClassPtr GetClassById(classid_t id) const;
|
||||
const Object& ReadObjectImpl(intptr_t cid, intptr_t object_index);
|
||||
void SetObjectAt(intptr_t object_index, const Object& object);
|
||||
|
||||
InstancePtr MaybeCanonicalize(const Instance& obj,
|
||||
intptr_t object_index,
|
||||
bool can_be_canonicalized);
|
||||
const Object& ReadObjectWithEnclosingTypes();
|
||||
|
||||
const ParsedFunction& parsed_function_;
|
||||
ReadStream* stream_;
|
||||
@@ -539,7 +516,6 @@ class FlowGraphDeserializer : public ValueObject {
|
||||
GrowableArray<Definition*> definitions_;
|
||||
GrowableArray<const Object*> objects_;
|
||||
intptr_t object_counter_ = 0;
|
||||
GrowableArray<intptr_t> pending_canonicalization_;
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
||||
@@ -2834,7 +2834,6 @@ void LoadFieldInstr::InferRange(RangeAnalysis* analysis, Range* range) {
|
||||
case Slot::Kind::kTypeParameters_flags:
|
||||
case Slot::Kind::kTypeParameters_bounds:
|
||||
case Slot::Kind::kTypeParameters_defaults:
|
||||
case Slot::Kind::kTypeParameter_bound:
|
||||
case Slot::Kind::kUnhandledException_exception:
|
||||
case Slot::Kind::kUnhandledException_stacktrace:
|
||||
case Slot::Kind::kWeakProperty_key:
|
||||
|
||||
@@ -201,7 +201,6 @@ bool Slot::IsImmutableLengthSlot() const {
|
||||
case Slot::Kind::kTypeParameters_flags:
|
||||
case Slot::Kind::kTypeParameters_bounds:
|
||||
case Slot::Kind::kTypeParameters_defaults:
|
||||
case Slot::Kind::kTypeParameter_bound:
|
||||
case Slot::Kind::kUnhandledException_exception:
|
||||
case Slot::Kind::kUnhandledException_stacktrace:
|
||||
case Slot::Kind::kWeakProperty_key:
|
||||
|
||||
@@ -130,7 +130,6 @@ class ParsedFunction;
|
||||
V(TypeArguments, UntaggedTypeArguments, hash, Smi, VAR) \
|
||||
V(TypeArguments, UntaggedTypeArguments, length, Smi, FINAL) \
|
||||
V(TypeParameters, UntaggedTypeParameters, names, Array, FINAL) \
|
||||
V(TypeParameter, UntaggedTypeParameter, bound, Dynamic, FINAL) \
|
||||
V(UnhandledException, UntaggedUnhandledException, exception, Dynamic, FINAL) \
|
||||
V(UnhandledException, UntaggedUnhandledException, stacktrace, Dynamic, FINAL)
|
||||
|
||||
|
||||
@@ -931,7 +931,6 @@ static bool CanPotentiallyBeSmi(const AbstractType& type, bool recurse) {
|
||||
// Comparable<int>).
|
||||
if (type.IsFutureOrType() ||
|
||||
type.type_class() == CompilerState::Current().ComparableClass().ptr()) {
|
||||
// Type may be a TypeRef.
|
||||
const auto& args = TypeArguments::Handle(type.arguments());
|
||||
const auto& arg0 = AbstractType::Handle(args.TypeAt(0));
|
||||
return !recurse || CanPotentiallyBeSmi(arg0, /*recurse=*/true);
|
||||
|
||||
@@ -541,7 +541,7 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_index) {
|
||||
for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
|
||||
type_arguments.SetTypeAt(j, type_translator.BuildType());
|
||||
}
|
||||
type_arguments = type_arguments.Canonicalize(Thread::Current(), nullptr);
|
||||
type_arguments = type_arguments.Canonicalize(Thread::Current());
|
||||
// Make a copy of the old closure, and set delayed type arguments.
|
||||
Closure& closure = Closure::Handle(Z, Closure::RawCast(constant.ptr()));
|
||||
Function& function = Function::Handle(Z, closure.function());
|
||||
|
||||
@@ -1993,9 +1993,6 @@ void FlowGraphBuilder::BuildTypeArgumentTypeChecks(TypeChecksToBuild mode,
|
||||
type_param = dart_function.TypeParameterAt(i);
|
||||
}
|
||||
ASSERT(type_param.IsFinalized());
|
||||
if (bound.IsTypeRef()) {
|
||||
bound = TypeRef::Cast(bound).type();
|
||||
}
|
||||
check_bounds +=
|
||||
AssertSubtype(TokenPosition::kNoSource, type_param, bound, name);
|
||||
}
|
||||
@@ -4313,7 +4310,7 @@ Fragment FlowGraphBuilder::FfiPointerFromAddress() {
|
||||
// do not appear in the type arguments to a any Pointer classes in an FFI
|
||||
// signature.
|
||||
ASSERT(args.IsNull() || args.IsInstantiated());
|
||||
args = args.Canonicalize(thread_, nullptr);
|
||||
args = args.Canonicalize(thread_);
|
||||
|
||||
Fragment code;
|
||||
code += Constant(args);
|
||||
|
||||
@@ -789,7 +789,6 @@ Type& TranslationHelper::GetDeclarationType(const Class& klass) {
|
||||
TypeParameter& type_param = TypeParameter::Handle();
|
||||
for (intptr_t i = 0; i < num_type_params; i++) {
|
||||
type_param = klass.TypeParameterAt(i);
|
||||
ASSERT(type_param.bound() != AbstractType::null());
|
||||
type_args.SetTypeAt(i, type_param);
|
||||
}
|
||||
}
|
||||
@@ -3103,7 +3102,6 @@ ActiveTypeParametersScope::ActiveTypeParametersScope(
|
||||
for (intptr_t j = f.NumTypeParameters() - 1; j >= 0; --j) {
|
||||
const auto& type_param = TypeParameter::Handle(Z, f.TypeParameterAt(j));
|
||||
params.SetTypeAt(--index, type_param);
|
||||
active_class_->RecordDerivedTypeParameter(Z, type_param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3139,27 +3137,13 @@ ActiveTypeParametersScope::ActiveTypeParametersScope(
|
||||
? active_class->klass->TypeParameterAt(i)
|
||||
: innermost_signature->TypeParameterAt(i));
|
||||
extended_params.SetTypeAt(index++, type_param);
|
||||
active_class->RecordDerivedTypeParameter(Z, type_param);
|
||||
}
|
||||
|
||||
active_class_->local_type_parameters = &extended_params;
|
||||
}
|
||||
|
||||
ActiveTypeParametersScope::~ActiveTypeParametersScope() {
|
||||
GrowableObjectArray* dropped = active_class_->derived_type_parameters;
|
||||
const bool preserve_unpatched =
|
||||
dropped != nullptr && saved_.derived_type_parameters == nullptr;
|
||||
*active_class_ = saved_;
|
||||
if (preserve_unpatched) {
|
||||
// Preserve still unpatched derived type parameters that would be dropped.
|
||||
auto& derived = TypeParameter::Handle(Z);
|
||||
for (intptr_t i = 0, n = dropped->Length(); i < n; ++i) {
|
||||
derived ^= dropped->At(i);
|
||||
if (derived.bound() == AbstractType::null()) {
|
||||
active_class_->RecordDerivedTypeParameter(Z, derived);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TypeTranslator::TypeTranslator(KernelReaderHelper* helper,
|
||||
@@ -3178,7 +3162,6 @@ TypeTranslator::TypeTranslator(KernelReaderHelper* helper,
|
||||
zone_(translation_helper_.zone()),
|
||||
result_(AbstractType::Handle(translation_helper_.zone())),
|
||||
finalize_(finalize),
|
||||
refers_to_derived_type_param_(false),
|
||||
apply_canonical_type_erasure_(apply_canonical_type_erasure),
|
||||
in_constant_context_(in_constant_context) {}
|
||||
|
||||
@@ -3238,10 +3221,6 @@ void TypeTranslator::BuildTypeInternal() {
|
||||
break;
|
||||
case kTypeParameterType:
|
||||
BuildTypeParameterType();
|
||||
if (result_.IsTypeParameter() &&
|
||||
TypeParameter::Cast(result_).bound() == AbstractType::null()) {
|
||||
refers_to_derived_type_param_ = true;
|
||||
}
|
||||
break;
|
||||
case kIntersectionType:
|
||||
BuildIntersectionType();
|
||||
@@ -3467,8 +3446,6 @@ void TypeTranslator::BuildTypeParameterType() {
|
||||
if (class_type_parameter_count > parameter_index) {
|
||||
result_ =
|
||||
active_class_->klass->TypeParameterAt(parameter_index, nullability);
|
||||
active_class_->RecordDerivedTypeParameter(Z,
|
||||
TypeParameter::Cast(result_));
|
||||
return;
|
||||
}
|
||||
parameter_index -= class_type_parameter_count;
|
||||
@@ -3495,8 +3472,6 @@ void TypeTranslator::BuildTypeParameterType() {
|
||||
if (class_type_parameter_count > parameter_index) {
|
||||
result_ = active_class_->klass->TypeParameterAt(parameter_index,
|
||||
nullability);
|
||||
active_class_->RecordDerivedTypeParameter(
|
||||
Z, TypeParameter::Cast(result_));
|
||||
return;
|
||||
}
|
||||
parameter_index -= class_type_parameter_count;
|
||||
@@ -3512,12 +3487,7 @@ void TypeTranslator::BuildTypeParameterType() {
|
||||
result_ = active_class_->member->TypeParameterAt(parameter_index,
|
||||
nullability);
|
||||
if (finalize_) {
|
||||
ASSERT(TypeParameter::Cast(result_).bound() !=
|
||||
AbstractType::null());
|
||||
result_ = ClassFinalizer::FinalizeType(result_);
|
||||
} else {
|
||||
active_class_->RecordDerivedTypeParameter(
|
||||
Z, TypeParameter::Cast(result_));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3531,11 +3501,7 @@ void TypeTranslator::BuildTypeParameterType() {
|
||||
Z, active_class_->local_type_parameters->TypeAt(parameter_index));
|
||||
result_ = type_param.ToNullability(nullability, Heap::kOld);
|
||||
if (finalize_) {
|
||||
ASSERT(TypeParameter::Cast(result_).bound() != AbstractType::null());
|
||||
result_ = ClassFinalizer::FinalizeType(result_);
|
||||
} else {
|
||||
active_class_->RecordDerivedTypeParameter(Z,
|
||||
TypeParameter::Cast(result_));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3587,7 +3553,7 @@ const TypeArguments& TypeTranslator::BuildTypeArguments(intptr_t length) {
|
||||
}
|
||||
|
||||
if (finalize_) {
|
||||
type_arguments = type_arguments.Canonicalize(Thread::Current(), nullptr);
|
||||
type_arguments = type_arguments.Canonicalize(Thread::Current());
|
||||
}
|
||||
}
|
||||
return type_arguments;
|
||||
@@ -3688,14 +3654,8 @@ void TypeTranslator::LoadAndSetupBounds(
|
||||
TypeParameterHelper helper(helper_);
|
||||
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
|
||||
|
||||
bool saved_refers_to_derived_type_param = refers_to_derived_type_param_;
|
||||
refers_to_derived_type_param_ = false;
|
||||
AbstractType& bound = BuildTypeWithoutFinalization(); // read ith bound.
|
||||
ASSERT(!bound.IsNull());
|
||||
if (refers_to_derived_type_param_) {
|
||||
bound = TypeRef::New(bound);
|
||||
}
|
||||
refers_to_derived_type_param_ = saved_refers_to_derived_type_param;
|
||||
type_parameters.SetBoundAt(i, bound);
|
||||
helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kDefaultType);
|
||||
AbstractType& default_arg = BuildTypeWithoutFinalization();
|
||||
@@ -3703,30 +3663,6 @@ void TypeTranslator::LoadAndSetupBounds(
|
||||
type_parameters.SetDefaultAt(i, default_arg);
|
||||
helper.Finish();
|
||||
}
|
||||
|
||||
// Fix bounds in all derived type parameters.
|
||||
const intptr_t offset = !parameterized_signature.IsNull()
|
||||
? parameterized_signature.NumParentTypeArguments()
|
||||
: 0;
|
||||
if (active_class->derived_type_parameters != nullptr) {
|
||||
auto& derived = TypeParameter::Handle(Z);
|
||||
auto& bound = AbstractType::Handle(Z);
|
||||
for (intptr_t i = 0, n = active_class->derived_type_parameters->Length();
|
||||
i < n; ++i) {
|
||||
derived ^= active_class->derived_type_parameters->At(i);
|
||||
if (derived.bound() == AbstractType::null() &&
|
||||
((!parameterized_class.IsNull() &&
|
||||
derived.parameterized_class_id() == parameterized_class.id()) ||
|
||||
(!parameterized_signature.IsNull() &&
|
||||
derived.parameterized_class_id() == kFunctionCid &&
|
||||
derived.index() >= offset &&
|
||||
derived.index() < offset + type_parameter_count))) {
|
||||
bound = type_parameters.BoundAt(derived.index() - offset);
|
||||
ASSERT(!bound.IsNull());
|
||||
derived.set_bound(bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Type& TypeTranslator::ReceiverType(const Class& klass) {
|
||||
@@ -3752,7 +3688,6 @@ const Type& TypeTranslator::ReceiverType(const Class& klass) {
|
||||
TypeParameter& type_param = TypeParameter::Handle();
|
||||
for (intptr_t i = 0; i < num_type_params; i++) {
|
||||
type_param = klass.TypeParameterAt(i);
|
||||
ASSERT(type_param.bound() != AbstractType::null());
|
||||
type_args.SetTypeAt(i, type_param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1429,16 +1429,6 @@ class ActiveClass {
|
||||
return klass->NumTypeArguments();
|
||||
}
|
||||
|
||||
void RecordDerivedTypeParameter(Zone* zone, const TypeParameter& derived) {
|
||||
if (derived.bound() == AbstractType::null()) {
|
||||
if (derived_type_parameters == nullptr) {
|
||||
derived_type_parameters = &GrowableObjectArray::Handle(
|
||||
zone, GrowableObjectArray::New(Heap::kOld));
|
||||
}
|
||||
derived_type_parameters->Add(derived);
|
||||
}
|
||||
}
|
||||
|
||||
const char* ToCString() {
|
||||
return member != nullptr ? member->ToCString() : klass->ToCString();
|
||||
}
|
||||
@@ -1453,8 +1443,6 @@ class ActiveClass {
|
||||
const FunctionType* enclosing;
|
||||
|
||||
const TypeArguments* local_type_parameters;
|
||||
|
||||
GrowableObjectArray* derived_type_parameters = nullptr;
|
||||
};
|
||||
|
||||
class ActiveClassScope {
|
||||
@@ -1625,7 +1613,6 @@ class TypeTranslator {
|
||||
Zone* zone_;
|
||||
AbstractType& result_;
|
||||
bool finalize_;
|
||||
bool refers_to_derived_type_param_;
|
||||
const bool apply_canonical_type_erasure_;
|
||||
const bool in_constant_context_;
|
||||
|
||||
|
||||
@@ -743,13 +743,6 @@ class RecordType : public AllStatic {
|
||||
FINAL_CLASS();
|
||||
};
|
||||
|
||||
class TypeRef : public AllStatic {
|
||||
public:
|
||||
static word type_offset();
|
||||
static word InstanceSize();
|
||||
FINAL_CLASS();
|
||||
};
|
||||
|
||||
class Nullability : public AllStatic {
|
||||
public:
|
||||
static const uint8_t kNullable;
|
||||
@@ -977,7 +970,6 @@ class Bool : public AllStatic {
|
||||
|
||||
class TypeParameter : public AllStatic {
|
||||
public:
|
||||
static word bound_offset();
|
||||
static word InstanceSize();
|
||||
FINAL_CLASS();
|
||||
static word parameterized_class_id_offset();
|
||||
|
||||
@@ -570,8 +570,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
12;
|
||||
@@ -680,7 +678,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
|
||||
@@ -1257,8 +1254,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -1369,7 +1364,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 48;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
|
||||
@@ -1937,8 +1931,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
12;
|
||||
@@ -2047,7 +2039,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
|
||||
@@ -2624,8 +2615,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -2737,7 +2726,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 48;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
|
||||
@@ -3312,8 +3300,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -3424,7 +3410,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
|
||||
@@ -3999,8 +3984,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -4112,7 +4095,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
|
||||
@@ -4680,8 +4662,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
12;
|
||||
@@ -4792,7 +4772,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
|
||||
@@ -5369,8 +5348,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -5482,7 +5459,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 48;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
|
||||
@@ -6044,8 +6020,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
12;
|
||||
@@ -6154,7 +6128,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
|
||||
@@ -6723,8 +6696,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -6835,7 +6806,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 48;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
|
||||
@@ -7395,8 +7365,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
12;
|
||||
@@ -7505,7 +7473,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
|
||||
@@ -8074,8 +8041,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -8187,7 +8152,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 48;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
|
||||
@@ -8754,8 +8718,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -8866,7 +8828,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
|
||||
@@ -9433,8 +9394,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 28;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -9546,7 +9505,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 32;
|
||||
@@ -10106,8 +10064,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 12;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
12;
|
||||
@@ -10218,7 +10174,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 20;
|
||||
@@ -10787,8 +10742,6 @@ static constexpr dart::compiler::target::word TypeParameters_flags_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypeParameters_bounds_offset = 24;
|
||||
static constexpr dart::compiler::target::word TypeParameters_defaults_offset =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word TypeParameter_bound_offset = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
|
||||
static constexpr dart::compiler::target::word TypedDataView_typed_data_offset =
|
||||
24;
|
||||
@@ -10900,7 +10853,6 @@ static constexpr dart::compiler::target::word
|
||||
static constexpr dart::compiler::target::word Type_InstanceSize = 48;
|
||||
static constexpr dart::compiler::target::word TypeParameter_InstanceSize = 56;
|
||||
static constexpr dart::compiler::target::word TypeParameters_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
|
||||
@@ -11529,9 +11481,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
12;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
8;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -11655,7 +11604,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
12;
|
||||
@@ -12288,9 +12236,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -12416,7 +12361,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
56;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -13052,9 +12996,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -13181,7 +13122,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
56;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -13815,9 +13755,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
28;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -13943,7 +13880,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -14577,9 +14513,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
28;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -14706,7 +14639,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -15336,9 +15268,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
12;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
8;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -15464,7 +15393,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
12;
|
||||
@@ -16097,9 +16025,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -16226,7 +16151,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
56;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -16849,9 +16773,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
12;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
8;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -16975,7 +16896,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
12;
|
||||
@@ -17599,9 +17519,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -17727,7 +17644,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
56;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -18354,9 +18270,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -18483,7 +18396,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
56;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -19108,9 +19020,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
28;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -19236,7 +19145,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -19861,9 +19769,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
28;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -19990,7 +19895,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
@@ -20611,9 +20515,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
12;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
8;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -20739,7 +20640,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
20;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 20;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 12;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
12;
|
||||
@@ -21363,9 +21263,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameters_bounds_offset =
|
||||
24;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_TypeParameters_defaults_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameter_bound_offset =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
|
||||
16;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -21492,7 +21389,6 @@ static constexpr dart::compiler::target::word AOT_TypeParameter_InstanceSize =
|
||||
56;
|
||||
static constexpr dart::compiler::target::word AOT_TypeParameters_InstanceSize =
|
||||
40;
|
||||
static constexpr dart::compiler::target::word AOT_TypeRef_InstanceSize = 40;
|
||||
static constexpr dart::compiler::target::word AOT_TypedData_HeaderSize = 24;
|
||||
static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
|
||||
24;
|
||||
|
||||
@@ -385,8 +385,6 @@
|
||||
FIELD(TypeParameters, flags_offset) \
|
||||
FIELD(TypeParameters, bounds_offset) \
|
||||
FIELD(TypeParameters, defaults_offset) \
|
||||
FIELD(TypeParameter, bound_offset) \
|
||||
FIELD(TypeRef, type_offset) \
|
||||
FIELD(TypedDataBase, length_offset) \
|
||||
FIELD(TypedDataView, typed_data_offset) \
|
||||
FIELD(TypedDataView, offset_in_bytes_offset) \
|
||||
@@ -478,7 +476,6 @@
|
||||
SIZEOF(Type, InstanceSize, UntaggedType) \
|
||||
SIZEOF(TypeParameter, InstanceSize, UntaggedTypeParameter) \
|
||||
SIZEOF(TypeParameters, InstanceSize, UntaggedTypeParameters) \
|
||||
SIZEOF(TypeRef, InstanceSize, UntaggedTypeRef) \
|
||||
SIZEOF(TypedData, HeaderSize, UntaggedTypedData) \
|
||||
SIZEOF(TypedDataBase, InstanceSize, UntaggedTypedDataBase) \
|
||||
SIZEOF(TypedDataView, InstanceSize, UntaggedTypedDataView) \
|
||||
|
||||
@@ -586,10 +586,6 @@ static void BuildInstantiateTypeParameterStub(Assembler* assembler,
|
||||
__ LoadClassId(InstantiateTypeABI::kScratchReg,
|
||||
InstantiateTypeABI::kResultTypeReg);
|
||||
|
||||
// Handle/unwrap TypeRefs in runtime.
|
||||
__ CompareImmediate(InstantiateTypeABI::kScratchReg, kTypeRefCid);
|
||||
__ BranchIf(EQUAL, &runtime_call);
|
||||
|
||||
switch (nullability) {
|
||||
case Nullability::kNonNullable:
|
||||
__ Ret();
|
||||
@@ -689,15 +685,6 @@ static void EnsureIsTypeOrFunctionTypeOrTypeParameter(Assembler* assembler,
|
||||
__ CompareImmediate(scratch_reg, kFunctionTypeCid);
|
||||
__ BranchIf(EQUAL, &is_type_param_or_type_or_function_type,
|
||||
compiler::Assembler::kNearJump);
|
||||
// Type references show up in F-bounded polymorphism, which is limited
|
||||
// to classes. Thus, TypeRefs only appear in places like class type
|
||||
// arguments or the bounds of uninstantiated class type parameters.
|
||||
//
|
||||
// Since this stub is currently used only by the dynamic versions of
|
||||
// AssertSubtype and AssertAssignable, where kDstType is either the bound of
|
||||
// a function type parameter or the type of a function parameter
|
||||
// (respectively), we should never see a TypeRef here. This check is here
|
||||
// in case this changes and we need to update this stub.
|
||||
__ Stop("not a type or function type or type parameter");
|
||||
__ Bind(&is_type_param_or_type_or_function_type);
|
||||
#endif
|
||||
|
||||
@@ -2571,7 +2571,7 @@ DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) {
|
||||
}
|
||||
const AbstractType& type =
|
||||
AbstractType::Handle(Instance::Cast(obj).GetType(Heap::kNew));
|
||||
return Api::NewHandle(T, type.Canonicalize(T, nullptr));
|
||||
return Api::NewHandle(T, type.Canonicalize(T));
|
||||
}
|
||||
|
||||
DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) {
|
||||
|
||||
@@ -220,6 +220,8 @@ constexpr bool FLAG_support_il_printer = false;
|
||||
P(trace_strong_mode_types, bool, false, \
|
||||
"Trace optimizations based on strong mode types.") \
|
||||
D(trace_type_checks, bool, false, "Trace runtime type checks.") \
|
||||
D(trace_type_checks_verbose, bool, false, \
|
||||
"Enable verbose trace of runtime type checks.") \
|
||||
D(trace_patching, bool, false, "Trace patching of code.") \
|
||||
D(trace_optimized_ic_calls, bool, false, \
|
||||
"Trace IC calls in optimized code.") \
|
||||
|
||||
@@ -796,95 +796,6 @@ class TypeMessageDeserializationCluster : public MessageDeserializationCluster {
|
||||
}
|
||||
};
|
||||
|
||||
class TypeRefMessageSerializationCluster : public MessageSerializationCluster {
|
||||
public:
|
||||
explicit TypeRefMessageSerializationCluster(bool is_canonical)
|
||||
: MessageSerializationCluster("TypeRef",
|
||||
MessagePhase::kTypes,
|
||||
kTypeRefCid,
|
||||
is_canonical) {}
|
||||
~TypeRefMessageSerializationCluster() {}
|
||||
|
||||
void Trace(MessageSerializer* s, Object* object) {
|
||||
TypeRef* type = static_cast<TypeRef*>(object);
|
||||
objects_.Add(type);
|
||||
|
||||
s->Push(type->type());
|
||||
}
|
||||
|
||||
void WriteNodes(MessageSerializer* s) {
|
||||
const intptr_t count = objects_.length();
|
||||
s->WriteUnsigned(count);
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
TypeRef* type = objects_[i];
|
||||
s->AssignRef(type);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteEdges(MessageSerializer* s) {
|
||||
const intptr_t count = objects_.length();
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
TypeRef* type = objects_[i];
|
||||
s->WriteRef(type->type());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GrowableArray<TypeRef*> objects_;
|
||||
};
|
||||
|
||||
class TypeRefMessageDeserializationCluster
|
||||
: public MessageDeserializationCluster {
|
||||
public:
|
||||
explicit TypeRefMessageDeserializationCluster(bool is_canonical)
|
||||
: MessageDeserializationCluster("TypeRef", is_canonical) {}
|
||||
~TypeRefMessageDeserializationCluster() {}
|
||||
|
||||
void ReadNodes(MessageDeserializer* d) {
|
||||
const intptr_t count = d->ReadUnsigned();
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
d->AssignRef(TypeRef::New());
|
||||
}
|
||||
}
|
||||
|
||||
void ReadEdges(MessageDeserializer* d) {
|
||||
for (intptr_t id = start_index_; id < stop_index_; id++) {
|
||||
TypeRefPtr type = static_cast<TypeRefPtr>(d->Ref(id));
|
||||
type->untag()->set_type(static_cast<AbstractTypePtr>(d->ReadRef()));
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPtr PostLoad(MessageDeserializer* d) {
|
||||
ClassFinalizer::FinalizationKind finalization =
|
||||
is_canonical() ? ClassFinalizer::kCanonicalize
|
||||
: ClassFinalizer::kFinalize;
|
||||
Code& code = Code::Handle(d->zone());
|
||||
TypeRef& type = TypeRef::Handle(d->zone());
|
||||
for (intptr_t id = start_index_; id < stop_index_; id++) {
|
||||
type ^= d->Ref(id);
|
||||
type ^= ClassFinalizer::FinalizeType(type, finalization);
|
||||
d->UpdateRef(id, type);
|
||||
|
||||
code = TypeTestingStubGenerator::DefaultCodeForType(type);
|
||||
type.InitializeTypeTestingStubNonAtomic(code);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ReadNodesApi(ApiMessageDeserializer* d) {
|
||||
intptr_t count = d->ReadUnsigned();
|
||||
for (intptr_t i = 0; i < count; i++) {
|
||||
d->AssignRef(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadEdgesApi(ApiMessageDeserializer* d) {
|
||||
for (intptr_t id = start_index_; id < stop_index_; id++) {
|
||||
d->ReadRef(); // Type.
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SmiMessageSerializationCluster : public MessageSerializationCluster {
|
||||
public:
|
||||
explicit SmiMessageSerializationCluster(Zone* zone)
|
||||
@@ -3159,8 +3070,6 @@ MessageSerializationCluster* BaseSerializer::NewClusterForClass(
|
||||
return new (Z) TypeArgumentsMessageSerializationCluster(is_canonical);
|
||||
case kTypeCid:
|
||||
return new (Z) TypeMessageSerializationCluster(is_canonical);
|
||||
case kTypeRefCid:
|
||||
return new (Z) TypeRefMessageSerializationCluster(is_canonical);
|
||||
case kSmiCid:
|
||||
return new (Z) SmiMessageSerializationCluster(Z);
|
||||
case kMintCid:
|
||||
@@ -3238,8 +3147,6 @@ MessageDeserializationCluster* BaseDeserializer::ReadCluster() {
|
||||
return new (Z) TypeArgumentsMessageDeserializationCluster(is_canonical);
|
||||
case kTypeCid:
|
||||
return new (Z) TypeMessageDeserializationCluster(is_canonical);
|
||||
case kTypeRefCid:
|
||||
return new (Z) TypeRefMessageDeserializationCluster(is_canonical);
|
||||
case kSmiCid:
|
||||
ASSERT(is_canonical);
|
||||
return new (Z) SmiMessageDeserializationCluster();
|
||||
|
||||
+591
-981
File diff suppressed because it is too large
Load Diff
+140
-231
@@ -67,6 +67,7 @@ class CallSiteResetter;
|
||||
class CodeStatistics;
|
||||
class IsolateGroupReloadContext;
|
||||
class ObjectGraphCopier;
|
||||
class FunctionTypeMapping;
|
||||
class NativeArguments;
|
||||
|
||||
#define REUSABLE_FORWARD_DECLARATION(name) class Reusable##name##HandleScope;
|
||||
@@ -984,9 +985,6 @@ class PassiveObject : public Object {
|
||||
DISALLOW_COPY_AND_ASSIGN(PassiveObject);
|
||||
};
|
||||
|
||||
typedef ZoneGrowableHandlePtrArray<const AbstractType> Trail;
|
||||
typedef ZoneGrowableHandlePtrArray<const AbstractType>* TrailPtr;
|
||||
|
||||
// A URIs array contains triplets of strings.
|
||||
// The first string in the triplet is a type name (usually a class).
|
||||
// The second string in the triplet is the URI of the type.
|
||||
@@ -1485,12 +1483,13 @@ class Class : public Object {
|
||||
|
||||
// Returns true if the type specified by cls, type_arguments, and nullability
|
||||
// is a subtype of the other type.
|
||||
static bool IsSubtypeOf(const Class& cls,
|
||||
const TypeArguments& type_arguments,
|
||||
Nullability nullability,
|
||||
const AbstractType& other,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr);
|
||||
static bool IsSubtypeOf(
|
||||
const Class& cls,
|
||||
const TypeArguments& type_arguments,
|
||||
Nullability nullability,
|
||||
const AbstractType& other,
|
||||
Heap::Space space,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr);
|
||||
|
||||
// Check if this is the top level class.
|
||||
bool IsTopLevel() const;
|
||||
@@ -2887,9 +2886,9 @@ class Function : public Object {
|
||||
// Note that function type parameters declared by this function do not make
|
||||
// its signature uninstantiated, only type parameters declared by parent
|
||||
// generic functions or class type parameters.
|
||||
bool HasInstantiatedSignature(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
bool HasInstantiatedSignature(
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
|
||||
bool IsPrivate() const;
|
||||
|
||||
@@ -8148,14 +8147,10 @@ class TypeArguments : public Instance {
|
||||
return IsDynamicTypes(true, 0, len);
|
||||
}
|
||||
|
||||
// Return true if this vector contains a TypeRef.
|
||||
bool IsRecursive(TrailPtr trail = nullptr) const;
|
||||
|
||||
// Return true if this vector contains a non-nullable type.
|
||||
bool RequireConstCanonicalTypeErasure(Zone* zone,
|
||||
intptr_t from_index,
|
||||
intptr_t len,
|
||||
TrailPtr trail = nullptr) const;
|
||||
intptr_t len) const;
|
||||
|
||||
TypeArgumentsPtr Prepend(Zone* zone,
|
||||
const TypeArguments& other,
|
||||
@@ -8172,31 +8167,32 @@ class TypeArguments : public Instance {
|
||||
TypeEquality::kCanonical);
|
||||
}
|
||||
|
||||
bool IsEquivalent(const TypeArguments& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const {
|
||||
bool IsEquivalent(
|
||||
const TypeArguments& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const {
|
||||
// Make a null vector a vector of dynamic as long as the other vector.
|
||||
return IsSubvectorEquivalent(other, 0, IsNull() ? other.Length() : Length(),
|
||||
kind, trail);
|
||||
kind, function_type_equivalence);
|
||||
}
|
||||
bool IsSubvectorEquivalent(const TypeArguments& other,
|
||||
intptr_t from_index,
|
||||
intptr_t len,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
bool IsSubvectorEquivalent(
|
||||
const TypeArguments& other,
|
||||
intptr_t from_index,
|
||||
intptr_t len,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
|
||||
// Check if the vector is instantiated (it must not be null).
|
||||
bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const {
|
||||
intptr_t num_free_fun_type_params = kAllFree) const {
|
||||
return IsSubvectorInstantiated(0, Length(), genericity,
|
||||
num_free_fun_type_params, trail);
|
||||
num_free_fun_type_params);
|
||||
}
|
||||
bool IsSubvectorInstantiated(intptr_t from_index,
|
||||
intptr_t len,
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
bool IsSubvectorInstantiated(
|
||||
intptr_t from_index,
|
||||
intptr_t len,
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
bool IsUninstantiatedIdentity() const;
|
||||
|
||||
// Determine whether this uninstantiated type argument vector can share its
|
||||
@@ -8218,11 +8214,11 @@ class TypeArguments : public Instance {
|
||||
|
||||
// Caller must hold IsolateGroup::constant_canonicalization_mutex_.
|
||||
virtual InstancePtr CanonicalizeLocked(Thread* thread) const {
|
||||
return Canonicalize(thread, nullptr);
|
||||
return Canonicalize(thread);
|
||||
}
|
||||
|
||||
// Canonicalize only if instantiated, otherwise returns 'this'.
|
||||
TypeArgumentsPtr Canonicalize(Thread* thread, TrailPtr trail = nullptr) const;
|
||||
TypeArgumentsPtr Canonicalize(Thread* thread) const;
|
||||
|
||||
// Shrinks flattened instance type arguments to ordinary type arguments.
|
||||
TypeArgumentsPtr FromInstanceTypeArguments(Thread* thread,
|
||||
@@ -8252,16 +8248,16 @@ class TypeArguments : public Instance {
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
// Update number of parent function type arguments for
|
||||
// all elements of this vector.
|
||||
TypeArgumentsPtr UpdateParentFunctionType(
|
||||
TypeArgumentsPtr UpdateFunctionTypes(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
FunctionTypeMapping* function_type_mapping) const;
|
||||
|
||||
// Runtime instantiation with canonicalization. Not to be used during type
|
||||
// finalization at compile time.
|
||||
@@ -8574,9 +8570,9 @@ class AbstractType : public Instance {
|
||||
virtual classid_t type_class_id() const;
|
||||
virtual ClassPtr type_class() const;
|
||||
virtual TypeArgumentsPtr arguments() const;
|
||||
virtual bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsInstantiated(
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
virtual bool CanonicalizeEquals(const Instance& other) const {
|
||||
return Equals(other);
|
||||
}
|
||||
@@ -8584,12 +8580,11 @@ class AbstractType : public Instance {
|
||||
virtual bool Equals(const Instance& other) const {
|
||||
return IsEquivalent(other, TypeEquality::kCanonical);
|
||||
}
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(
|
||||
const Instance& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone) const;
|
||||
|
||||
// Instantiate this type using the given type argument vectors.
|
||||
//
|
||||
@@ -8607,30 +8602,32 @@ class AbstractType : public Instance {
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
// Update number of parent function type arguments for the
|
||||
// nested function types and their type parameters.
|
||||
//
|
||||
// This adjustment is needed when nesting one generic function type
|
||||
// inside another.
|
||||
// inside another. It is also needed when function type is copied
|
||||
// and owners of type parameters need to be adjusted.
|
||||
//
|
||||
// Number of parent function type arguments is adjusted by
|
||||
// [num_parent_type_args_adjustment].
|
||||
// Type parameters up to [num_free_fun_type_params] are not adjusted.
|
||||
virtual AbstractTypePtr UpdateParentFunctionType(
|
||||
virtual AbstractTypePtr UpdateFunctionTypes(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
FunctionTypeMapping* function_type_mapping) const;
|
||||
|
||||
// Caller must hold IsolateGroup::constant_canonicalization_mutex_.
|
||||
virtual InstancePtr CanonicalizeLocked(Thread* thread) const {
|
||||
return Canonicalize(thread, nullptr);
|
||||
return Canonicalize(thread);
|
||||
}
|
||||
|
||||
// Return the canonical version of this type.
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread) const;
|
||||
|
||||
#if defined(DEBUG)
|
||||
// Check if abstract type is canonical.
|
||||
@@ -8640,25 +8637,6 @@ class AbstractType : public Instance {
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
// Return the object associated with the receiver in the trail or
|
||||
// AbstractType::null() if the receiver is not contained in the trail.
|
||||
AbstractTypePtr OnlyBuddyInTrail(TrailPtr trail) const;
|
||||
|
||||
// If the trail is null, allocate a trail, add the pair <receiver, buddy> to
|
||||
// the trail. The receiver may only be added once with its only buddy.
|
||||
void AddOnlyBuddyToTrail(TrailPtr* trail, const AbstractType& buddy) const;
|
||||
|
||||
// Return true if the receiver is contained in the trail.
|
||||
// Otherwise, if the trail is null, allocate a trail, then add the receiver to
|
||||
// the trail and return false.
|
||||
bool TestAndAddToTrail(TrailPtr* trail) const;
|
||||
|
||||
// Return true if the pair <receiver, buddy> is contained in the trail.
|
||||
// Otherwise, if the trail is null, allocate a trail, add the pair <receiver,
|
||||
// buddy> to the trail and return false.
|
||||
// The receiver may be added several times, each time with a different buddy.
|
||||
bool TestAndAddBuddyToTrail(TrailPtr* trail, const AbstractType& buddy) const;
|
||||
|
||||
// Add the pair <name, uri> to the list, if not already present.
|
||||
static void AddURI(URIs* uris, const String& name, const String& uri);
|
||||
|
||||
@@ -8695,9 +8673,6 @@ class AbstractType : public Instance {
|
||||
// type.
|
||||
StringPtr ClassName() const;
|
||||
|
||||
// Check if this type is a still uninitialized TypeRef.
|
||||
bool IsNullTypeRef() const;
|
||||
|
||||
// Check if this type represents the 'dynamic' type.
|
||||
bool IsDynamicType() const { return type_class_id() == kDynamicCid; }
|
||||
|
||||
@@ -8716,6 +8691,11 @@ class AbstractType : public Instance {
|
||||
// Check if this type represents the 'Object' type.
|
||||
bool IsObjectType() const { return type_class_id() == kInstanceCid; }
|
||||
|
||||
// Check if this type represents the 'Object?' type.
|
||||
bool IsNullableObjectType() const {
|
||||
return IsObjectType() && (nullability() == Nullability::kNullable);
|
||||
}
|
||||
|
||||
// Check if this type represents a top type for subtyping,
|
||||
// assignability and 'as' type tests.
|
||||
//
|
||||
@@ -8796,9 +8776,10 @@ class AbstractType : public Instance {
|
||||
bool IsTypeClassAllowedBySpawnUri() const;
|
||||
|
||||
// Check the subtype relationship.
|
||||
bool IsSubtypeOf(const AbstractType& other,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
bool IsSubtypeOf(
|
||||
const AbstractType& other,
|
||||
Heap::Space space,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
|
||||
// Returns true iff subtype is a subtype of supertype, false otherwise or if
|
||||
// an error occurred.
|
||||
@@ -8849,10 +8830,11 @@ class AbstractType : public Instance {
|
||||
private:
|
||||
// Returns true if this type is a subtype of FutureOr<T> specified by 'other'.
|
||||
// Returns false if other type is not a FutureOr.
|
||||
bool IsSubtypeOfFutureOr(Zone* zone,
|
||||
const AbstractType& other,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
bool IsSubtypeOfFutureOr(
|
||||
Zone* zone,
|
||||
const AbstractType& other,
|
||||
Heap::Space space,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
|
||||
protected:
|
||||
bool IsNullabilityEquivalent(Thread* thread,
|
||||
@@ -8871,7 +8853,6 @@ class AbstractType : public Instance {
|
||||
friend class Class;
|
||||
friend class Function;
|
||||
friend class TypeArguments;
|
||||
friend class TypeRef;
|
||||
};
|
||||
|
||||
// A Type consists of a class, possibly parameterized with type
|
||||
@@ -8898,15 +8879,14 @@ class Type : public AbstractType {
|
||||
TypeArgumentsPtr GetInstanceTypeArguments(Thread* thread,
|
||||
bool canonicalize = true) const;
|
||||
|
||||
virtual bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsInstantiated(
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
virtual bool IsEquivalent(
|
||||
const Instance& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone) const;
|
||||
|
||||
// Return true if this type can be used as the declaration type of cls after
|
||||
// canonicalization (passed-in cls must match type_class()).
|
||||
@@ -8917,16 +8897,16 @@ class Type : public AbstractType {
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
virtual AbstractTypePtr UpdateParentFunctionType(
|
||||
virtual AbstractTypePtr UpdateFunctionTypes(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
FunctionTypeMapping* function_type_mapping) const;
|
||||
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread) const;
|
||||
#if defined(DEBUG)
|
||||
// Check if type is canonical.
|
||||
virtual bool CheckIsCanonical(Thread* thread) const;
|
||||
@@ -9050,31 +9030,30 @@ class FunctionType : public AbstractType {
|
||||
virtual bool HasTypeClass() const { return false; }
|
||||
FunctionTypePtr ToNullability(Nullability value, Heap::Space space) const;
|
||||
virtual classid_t type_class_id() const { return kIllegalCid; }
|
||||
virtual bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsInstantiated(
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
virtual bool IsEquivalent(
|
||||
const Instance& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone) const;
|
||||
|
||||
virtual AbstractTypePtr InstantiateFrom(
|
||||
const TypeArguments& instantiator_type_arguments,
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
virtual AbstractTypePtr UpdateParentFunctionType(
|
||||
virtual AbstractTypePtr UpdateFunctionTypes(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
FunctionTypeMapping* function_type_mapping) const;
|
||||
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread) const;
|
||||
#if defined(DEBUG)
|
||||
// Check if type is canonical.
|
||||
virtual bool CheckIsCanonical(Thread* thread) const;
|
||||
@@ -9086,7 +9065,10 @@ class FunctionType : public AbstractType {
|
||||
virtual uword Hash() const;
|
||||
uword ComputeHash() const;
|
||||
|
||||
bool IsSubtypeOf(const FunctionType& other, Heap::Space space) const;
|
||||
bool IsSubtypeOf(
|
||||
const FunctionType& other,
|
||||
Heap::Space space,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
|
||||
static intptr_t NumParentTypeArgumentsOf(FunctionTypePtr ptr) {
|
||||
return ptr->untag()
|
||||
@@ -9261,9 +9243,10 @@ class FunctionType : public AbstractType {
|
||||
// Returns true if this function type has the same number of type parameters
|
||||
// with equal bounds as the other function type. Type parameter names and
|
||||
// parameter names (unless optional named) are ignored.
|
||||
bool HasSameTypeParametersAndBounds(const FunctionType& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
bool HasSameTypeParametersAndBounds(
|
||||
const FunctionType& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
|
||||
// Return true if this function type declares type parameters.
|
||||
static bool IsGeneric(FunctionTypePtr ptr) {
|
||||
@@ -9277,10 +9260,12 @@ class FunctionType : public AbstractType {
|
||||
// Returns true if the type of the formal parameter at the given position in
|
||||
// this function type is contravariant with the type of the other formal
|
||||
// parameter at the given position in the other function type.
|
||||
bool IsContravariantParameter(intptr_t parameter_position,
|
||||
const FunctionType& other,
|
||||
intptr_t other_parameter_position,
|
||||
Heap::Space space) const;
|
||||
bool IsContravariantParameter(
|
||||
intptr_t parameter_position,
|
||||
const FunctionType& other,
|
||||
intptr_t other_parameter_position,
|
||||
Heap::Space space,
|
||||
FunctionTypeMapping* function_type_equivalence) const;
|
||||
|
||||
// Returns the index in the parameter names array of the corresponding flag
|
||||
// for the given parameter index. Also returns (via flag_mask) the
|
||||
@@ -9304,6 +9289,8 @@ class FunctionType : public AbstractType {
|
||||
Nullability nullability = Nullability::kLegacy,
|
||||
Heap::Space space = Heap::kOld);
|
||||
|
||||
static FunctionTypePtr Clone(const FunctionType& orig, Heap::Space space);
|
||||
|
||||
private:
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
@@ -9315,76 +9302,6 @@ class FunctionType : public AbstractType {
|
||||
friend class Function;
|
||||
};
|
||||
|
||||
// A TypeRef is used to break cycles in the representation of recursive types.
|
||||
// Its only field is the recursive AbstractType it refers to, which can
|
||||
// temporarily be null during finalization.
|
||||
// Note that the cycle always involves type arguments.
|
||||
class TypeRef : public AbstractType {
|
||||
public:
|
||||
static intptr_t type_offset() { return OFFSET_OF(UntaggedTypeRef, type_); }
|
||||
|
||||
virtual bool HasTypeClass() const {
|
||||
return (type() != AbstractType::null()) &&
|
||||
AbstractType::Handle(type()).HasTypeClass();
|
||||
}
|
||||
AbstractTypePtr type() const { return untag()->type(); }
|
||||
void set_type(const AbstractType& value) const;
|
||||
virtual classid_t type_class_id() const {
|
||||
return AbstractType::Handle(type()).type_class_id();
|
||||
}
|
||||
virtual ClassPtr type_class() const {
|
||||
return AbstractType::Handle(type()).type_class();
|
||||
}
|
||||
virtual TypeArgumentsPtr arguments() const {
|
||||
return AbstractType::Handle(type()).arguments();
|
||||
}
|
||||
virtual bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsRecursive(TrailPtr trail = nullptr) const { return true; }
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual AbstractTypePtr InstantiateFrom(
|
||||
const TypeArguments& instantiator_type_arguments,
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
virtual AbstractTypePtr UpdateParentFunctionType(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
|
||||
#if defined(DEBUG)
|
||||
// Check if typeref is canonical.
|
||||
virtual bool CheckIsCanonical(Thread* thread) const;
|
||||
#endif // DEBUG
|
||||
virtual void EnumerateURIs(URIs* uris) const;
|
||||
virtual void PrintName(NameVisibility visibility,
|
||||
BaseTextBuffer* printer) const;
|
||||
|
||||
virtual uword Hash() const;
|
||||
|
||||
static intptr_t InstanceSize() {
|
||||
return RoundedAllocationSize(sizeof(UntaggedTypeRef));
|
||||
}
|
||||
|
||||
static TypeRefPtr New(const AbstractType& type);
|
||||
|
||||
private:
|
||||
static TypeRefPtr New();
|
||||
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeRef, AbstractType);
|
||||
friend class Class;
|
||||
};
|
||||
|
||||
// A TypeParameter represents a type parameter of a parameterized class.
|
||||
// It specifies its index (and its name for debugging purposes), as well as its
|
||||
// upper bound.
|
||||
@@ -9402,7 +9319,6 @@ class TypeParameter : public AbstractType {
|
||||
virtual classid_t type_class_id() const { return kIllegalCid; }
|
||||
classid_t parameterized_class_id() const;
|
||||
void set_parameterized_class_id(classid_t value) const;
|
||||
ClassPtr parameterized_class() const;
|
||||
bool IsClassTypeParameter() const {
|
||||
return parameterized_class_id() != kFunctionCid;
|
||||
}
|
||||
@@ -9422,22 +9338,19 @@ class TypeParameter : public AbstractType {
|
||||
return OFFSET_OF(UntaggedTypeParameter, index_);
|
||||
}
|
||||
|
||||
AbstractTypePtr bound() const { return untag()->bound(); }
|
||||
void set_bound(const AbstractType& value) const;
|
||||
static intptr_t bound_offset() {
|
||||
return OFFSET_OF(UntaggedTypeParameter, bound_);
|
||||
}
|
||||
ObjectPtr owner() const { return untag()->owner(); }
|
||||
void set_owner(const Object& value) const;
|
||||
|
||||
virtual bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(
|
||||
Zone* zone,
|
||||
TrailPtr trail = nullptr) const {
|
||||
AbstractTypePtr bound() const;
|
||||
|
||||
virtual bool IsInstantiated(
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
virtual bool IsEquivalent(
|
||||
const Instance& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone) const {
|
||||
return IsNonNullable();
|
||||
}
|
||||
virtual AbstractTypePtr InstantiateFrom(
|
||||
@@ -9445,16 +9358,16 @@ class TypeParameter : public AbstractType {
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
virtual AbstractTypePtr UpdateParentFunctionType(
|
||||
virtual AbstractTypePtr UpdateFunctionTypes(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
FunctionTypeMapping* function_type_mapping) const;
|
||||
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread) const;
|
||||
#if defined(DEBUG)
|
||||
// Check if type parameter is canonical.
|
||||
virtual bool CheckIsCanonical(Thread* thread) const;
|
||||
@@ -9486,20 +9399,16 @@ class TypeParameter : public AbstractType {
|
||||
return RoundedAllocationSize(sizeof(UntaggedTypeParameter));
|
||||
}
|
||||
|
||||
// 'parameterized_class' is null for a function type parameter.
|
||||
static TypeParameterPtr New(const Class& parameterized_class,
|
||||
// 'owner' is a Class or FunctionType.
|
||||
static TypeParameterPtr New(const Object& owner,
|
||||
intptr_t base,
|
||||
intptr_t index,
|
||||
const AbstractType& bound,
|
||||
Nullability nullability);
|
||||
|
||||
private:
|
||||
uword ComputeHash() const;
|
||||
void SetHash(intptr_t value) const;
|
||||
|
||||
void set_parameterized_class(const Class& value) const;
|
||||
void set_name(const String& value) const;
|
||||
|
||||
static TypeParameterPtr New();
|
||||
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
|
||||
@@ -9843,8 +9752,6 @@ class String : public Instance {
|
||||
return GetCachedHash(ptr()) != 0;
|
||||
}
|
||||
|
||||
bool IsRecursive() const { return false; } // Required by HashSet templates.
|
||||
|
||||
static intptr_t hash_offset() {
|
||||
#if defined(HASH_IN_OBJECT_HEADER)
|
||||
COMPILE_ASSERT(UntaggedObject::kHashTagPos % kBitsPerByte == 0);
|
||||
@@ -11149,31 +11056,30 @@ class RecordType : public AbstractType {
|
||||
virtual bool HasTypeClass() const { return false; }
|
||||
RecordTypePtr ToNullability(Nullability value, Heap::Space space) const;
|
||||
virtual classid_t type_class_id() const { return kIllegalCid; }
|
||||
virtual bool IsInstantiated(Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsEquivalent(const Instance& other,
|
||||
TypeEquality kind,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsRecursive(TrailPtr trail = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone,
|
||||
TrailPtr trail = nullptr) const;
|
||||
virtual bool IsInstantiated(
|
||||
Genericity genericity = kAny,
|
||||
intptr_t num_free_fun_type_params = kAllFree) const;
|
||||
virtual bool IsEquivalent(
|
||||
const Instance& other,
|
||||
TypeEquality kind,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
virtual bool RequireConstCanonicalTypeErasure(Zone* zone) const;
|
||||
|
||||
virtual AbstractTypePtr InstantiateFrom(
|
||||
const TypeArguments& instantiator_type_arguments,
|
||||
const TypeArguments& function_type_arguments,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr,
|
||||
FunctionTypeMapping* function_type_mapping = nullptr,
|
||||
intptr_t num_parent_type_args_adjustment = 0) const;
|
||||
|
||||
virtual AbstractTypePtr UpdateParentFunctionType(
|
||||
virtual AbstractTypePtr UpdateFunctionTypes(
|
||||
intptr_t num_parent_type_args_adjustment,
|
||||
intptr_t num_free_fun_type_params,
|
||||
Heap::Space space,
|
||||
TrailPtr trail = nullptr) const;
|
||||
FunctionTypeMapping* function_type_mapping) const;
|
||||
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread, TrailPtr trail) const;
|
||||
virtual AbstractTypePtr Canonicalize(Thread* thread) const;
|
||||
#if defined(DEBUG)
|
||||
// Check if type is canonical.
|
||||
virtual bool CheckIsCanonical(Thread* thread) const;
|
||||
@@ -11185,7 +11091,10 @@ class RecordType : public AbstractType {
|
||||
virtual uword Hash() const;
|
||||
uword ComputeHash() const;
|
||||
|
||||
bool IsSubtypeOf(const RecordType& other, Heap::Space space) const;
|
||||
bool IsSubtypeOf(
|
||||
const RecordType& other,
|
||||
Heap::Space space,
|
||||
FunctionTypeMapping* function_type_equivalence = nullptr) const;
|
||||
|
||||
RecordShape shape() const { return RecordShape(untag()->shape()); }
|
||||
|
||||
@@ -13200,7 +13109,7 @@ inline intptr_t RecordType::NumFields() const {
|
||||
}
|
||||
|
||||
inline uword TypeParameter::Hash() const {
|
||||
ASSERT(IsFinalized() || IsBeingFinalized()); // Bound may not be finalized.
|
||||
ASSERT(IsFinalized());
|
||||
intptr_t result = Smi::Value(untag()->hash());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
V(TypeArguments) \
|
||||
V(TypeParameter) \
|
||||
V(TypeParameters) \
|
||||
V(TypeRef) \
|
||||
V(TypedDataBase) \
|
||||
V(UnhandledException) \
|
||||
V(UnlinkedCall) \
|
||||
|
||||
@@ -1464,22 +1464,6 @@ void RecordType::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
void RecordType::PrintImplementationFieldsImpl(
|
||||
const JSONArray& jsarr_fields) const {}
|
||||
|
||||
void TypeRef::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
JSONObject jsobj(stream);
|
||||
PrintSharedInstanceJSON(&jsobj, ref);
|
||||
jsobj.AddProperty("kind", "TypeRef");
|
||||
const String& user_name = String::Handle(UserVisibleName());
|
||||
const String& vm_name = String::Handle(Name());
|
||||
AddNameProperties(&jsobj, user_name.ToCString(), vm_name.ToCString());
|
||||
if (ref) {
|
||||
return;
|
||||
}
|
||||
jsobj.AddProperty("targetType", AbstractType::Handle(type()));
|
||||
}
|
||||
|
||||
void TypeRef::PrintImplementationFieldsImpl(
|
||||
const JSONArray& jsarr_fields) const {}
|
||||
|
||||
void TypeParameter::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
JSONObject jsobj(stream);
|
||||
PrintSharedInstanceJSON(&jsobj, ref);
|
||||
@@ -1488,8 +1472,7 @@ void TypeParameter::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
const String& vm_name = String::Handle(Name());
|
||||
AddNameProperties(&jsobj, user_name.ToCString(), vm_name.ToCString());
|
||||
// TODO(regis): parameterizedClass is meaningless and always null.
|
||||
const Class& param_cls = Class::Handle(parameterized_class());
|
||||
jsobj.AddProperty("parameterizedClass", param_cls);
|
||||
jsobj.AddProperty("parameterizedClass", Object::null_class());
|
||||
if (ref) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ void ObjectStore::LazyInitAsyncMembers() {
|
||||
type_args.SetTypeAt(0, type);
|
||||
type = Type::New(cls, type_args, Nullability::kNonNullable);
|
||||
type.SetIsFinalized();
|
||||
type ^= type.Canonicalize(thread, nullptr);
|
||||
type ^= type.Canonicalize(thread);
|
||||
non_nullable_future_never_type_.store(type.ptr());
|
||||
|
||||
type = null_type();
|
||||
@@ -519,7 +519,7 @@ void ObjectStore::LazyInitAsyncMembers() {
|
||||
type_args.SetTypeAt(0, type);
|
||||
type = Type::New(cls, type_args, Nullability::kNullable);
|
||||
type.SetIsFinalized();
|
||||
type ^= type.Canonicalize(thread, nullptr);
|
||||
type ^= type.Canonicalize(thread);
|
||||
nullable_future_null_type_.store(type.ptr());
|
||||
|
||||
type = cls.RareType();
|
||||
|
||||
+13
-14
@@ -275,8 +275,8 @@ ISOLATE_UNIT_TEST_CASE(TypeArguments) {
|
||||
OS::PrintErr("2: %s\n", type_arguments2.ToCString());
|
||||
EXPECT(type_arguments1.Equals(type_arguments2));
|
||||
TypeArguments& type_arguments3 = TypeArguments::Handle();
|
||||
type_arguments1.Canonicalize(thread, nullptr);
|
||||
type_arguments3 ^= type_arguments2.Canonicalize(thread, nullptr);
|
||||
type_arguments1.Canonicalize(thread);
|
||||
type_arguments3 ^= type_arguments2.Canonicalize(thread);
|
||||
EXPECT_EQ(type_arguments1.ptr(), type_arguments3.ptr());
|
||||
}
|
||||
|
||||
@@ -7660,14 +7660,13 @@ ISOLATE_UNIT_TEST_CASE(ClosureType_SubtypeOfFunctionType) {
|
||||
Class::Handle(async_lib.LookupClass(Symbols::FutureOr()));
|
||||
auto& tav_function_nullable = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_function_nullable.SetTypeAt(0, function_type_nullable);
|
||||
tav_function_nullable = tav_function_nullable.Canonicalize(thread, nullptr);
|
||||
tav_function_nullable = tav_function_nullable.Canonicalize(thread);
|
||||
auto& tav_function_legacy = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_function_legacy.SetTypeAt(0, function_type_legacy);
|
||||
tav_function_legacy = tav_function_legacy.Canonicalize(thread, nullptr);
|
||||
tav_function_legacy = tav_function_legacy.Canonicalize(thread);
|
||||
auto& tav_function_nonnullable = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_function_nonnullable.SetTypeAt(0, function_type_nonnullable);
|
||||
tav_function_nonnullable =
|
||||
tav_function_nonnullable.Canonicalize(thread, nullptr);
|
||||
tav_function_nonnullable = tav_function_nonnullable.Canonicalize(thread);
|
||||
|
||||
auto& future_or_function_type_nullable =
|
||||
Type::Handle(Type::New(future_or_class, tav_function_nullable));
|
||||
@@ -7772,18 +7771,18 @@ TEST_CASE(Class_GetInstantiationOf) {
|
||||
TypeParameter::CheckedHandle(zone, decl_type_args_a1.TypeAt(1));
|
||||
auto& tav_a1_y = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_a1_y.SetTypeAt(0, type_arg_a1_y);
|
||||
tav_a1_y = tav_a1_y.Canonicalize(thread, nullptr);
|
||||
tav_a1_y = tav_a1_y.Canonicalize(thread);
|
||||
auto& type_list_a1_y = Type::CheckedHandle(
|
||||
zone, decl_type_list.InstantiateFrom(tav_a1_y, null_tav, kAllFree,
|
||||
Heap::kNew));
|
||||
type_list_a1_y ^= type_list_a1_y.Canonicalize(thread, nullptr);
|
||||
type_list_a1_y ^= type_list_a1_y.Canonicalize(thread);
|
||||
auto& tav_list_a1_y = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_list_a1_y.SetTypeAt(0, type_list_a1_y);
|
||||
tav_list_a1_y = tav_list_a1_y.Canonicalize(thread, nullptr);
|
||||
tav_list_a1_y = tav_list_a1_y.Canonicalize(thread);
|
||||
auto& type_b_list_a1_y = Type::CheckedHandle(
|
||||
zone, decl_type_b.InstantiateFrom(tav_list_a1_y, null_tav, kAllFree,
|
||||
Heap::kNew));
|
||||
type_b_list_a1_y ^= type_b_list_a1_y.Canonicalize(thread, nullptr);
|
||||
type_b_list_a1_y ^= type_b_list_a1_y.Canonicalize(thread);
|
||||
|
||||
const auto& inst_b_a1 =
|
||||
Type::Handle(zone, class_a1.GetInstantiationOf(zone, class_b));
|
||||
@@ -7800,18 +7799,18 @@ TEST_CASE(Class_GetInstantiationOf) {
|
||||
TypeParameter::CheckedHandle(zone, decl_type_args_a2.TypeAt(0));
|
||||
auto& tav_a2_x = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_a2_x.SetTypeAt(0, type_arg_a2_x);
|
||||
tav_a2_x = tav_a2_x.Canonicalize(thread, nullptr);
|
||||
tav_a2_x = tav_a2_x.Canonicalize(thread);
|
||||
auto& type_list_a2_x = Type::CheckedHandle(
|
||||
zone, decl_type_list.InstantiateFrom(tav_a2_x, null_tav, kAllFree,
|
||||
Heap::kNew));
|
||||
type_list_a2_x ^= type_list_a2_x.Canonicalize(thread, nullptr);
|
||||
type_list_a2_x ^= type_list_a2_x.Canonicalize(thread);
|
||||
auto& tav_list_a2_x = TypeArguments::Handle(TypeArguments::New(1));
|
||||
tav_list_a2_x.SetTypeAt(0, type_list_a2_x);
|
||||
tav_list_a2_x = tav_list_a2_x.Canonicalize(thread, nullptr);
|
||||
tav_list_a2_x = tav_list_a2_x.Canonicalize(thread);
|
||||
auto& type_b_list_a2_x = Type::CheckedHandle(
|
||||
zone, decl_type_b.InstantiateFrom(tav_list_a2_x, null_tav, kAllFree,
|
||||
Heap::kNew));
|
||||
type_b_list_a2_x ^= type_b_list_a2_x.Canonicalize(thread, nullptr);
|
||||
type_b_list_a2_x ^= type_b_list_a2_x.Canonicalize(thread);
|
||||
|
||||
const auto& inst_b_a2 =
|
||||
Type::Handle(zone, class_a2.GetInstantiationOf(zone, class_b));
|
||||
|
||||
@@ -534,7 +534,6 @@ VARIABLE_COMPRESSED_VISITOR(WeakArray, Smi::Value(raw_obj->untag()->length()))
|
||||
COMPRESSED_VISITOR(Type)
|
||||
COMPRESSED_VISITOR(FunctionType)
|
||||
COMPRESSED_VISITOR(RecordType)
|
||||
COMPRESSED_VISITOR(TypeRef)
|
||||
COMPRESSED_VISITOR(TypeParameter)
|
||||
COMPRESSED_VISITOR(Function)
|
||||
COMPRESSED_VISITOR(Closure)
|
||||
|
||||
+3
-12
@@ -2763,23 +2763,14 @@ class UntaggedRecordType : public UntaggedAbstractType {
|
||||
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
|
||||
};
|
||||
|
||||
class UntaggedTypeRef : public UntaggedAbstractType {
|
||||
private:
|
||||
RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
|
||||
|
||||
COMPRESSED_POINTER_FIELD(AbstractTypePtr, type) // The referenced type.
|
||||
VISIT_TO(type)
|
||||
CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
|
||||
};
|
||||
|
||||
class UntaggedTypeParameter : public UntaggedAbstractType {
|
||||
private:
|
||||
RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
|
||||
|
||||
COMPRESSED_POINTER_FIELD(SmiPtr, hash)
|
||||
// ObjectType if no explicit bound specified.
|
||||
COMPRESSED_POINTER_FIELD(AbstractTypePtr, bound)
|
||||
VISIT_TO(bound)
|
||||
// Class or FunctionType.
|
||||
COMPRESSED_POINTER_FIELD(ObjectPtr, owner)
|
||||
VISIT_TO(owner)
|
||||
ClassIdTagType parameterized_class_id_; // Or kFunctionCid for function tp.
|
||||
uint16_t base_; // Number of enclosing function type parameters.
|
||||
uint16_t index_; // Keep size in sync with BuildTypeParameterTypeTestStub.
|
||||
|
||||
@@ -142,11 +142,9 @@ namespace dart {
|
||||
F(FunctionType, parameter_types_) \
|
||||
F(FunctionType, named_parameter_names_) \
|
||||
F(FunctionType, type_parameters_) \
|
||||
F(TypeRef, type_test_stub_) \
|
||||
F(TypeRef, type_) \
|
||||
F(TypeParameter, type_test_stub_) \
|
||||
F(TypeParameter, hash_) \
|
||||
F(TypeParameter, bound_) \
|
||||
F(TypeParameter, owner_) \
|
||||
F(TypeParameters, names_) \
|
||||
F(TypeParameters, flags_) \
|
||||
F(TypeParameters, bounds_) \
|
||||
|
||||
@@ -562,11 +562,6 @@ DEFINE_RUNTIME_ENTRY(InstantiateType, 3) {
|
||||
function_type_arguments.IsInstantiated());
|
||||
type = type.InstantiateFrom(instantiator_type_arguments,
|
||||
function_type_arguments, kAllFree, Heap::kOld);
|
||||
if (type.IsTypeRef()) {
|
||||
type = TypeRef::Cast(type).type();
|
||||
ASSERT(!type.IsTypeRef());
|
||||
ASSERT(type.IsCanonical());
|
||||
}
|
||||
ASSERT(!type.IsNull() && type.IsInstantiated());
|
||||
arguments.SetReturn(type);
|
||||
}
|
||||
@@ -642,20 +637,13 @@ DEFINE_RUNTIME_ENTRY(SubtypeCheck, 5) {
|
||||
AbstractType::CheckedHandle(zone, arguments.ArgAt(3));
|
||||
const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(4));
|
||||
|
||||
if (supertype.IsTypeRef()) {
|
||||
supertype = TypeRef::Cast(supertype).type();
|
||||
}
|
||||
ASSERT(!supertype.IsNull() && !supertype.IsTypeRef());
|
||||
ASSERT(!supertype.IsNull());
|
||||
ASSERT(!subtype.IsNull());
|
||||
|
||||
// Now that AssertSubtype may be checking types only available at runtime,
|
||||
// we can't guarantee the supertype isn't the top type.
|
||||
if (supertype.IsTopTypeForSubtyping()) return;
|
||||
|
||||
if (subtype.IsTypeRef()) {
|
||||
subtype = TypeRef::Cast(subtype).type();
|
||||
}
|
||||
ASSERT(!subtype.IsNull() && !subtype.IsTypeRef());
|
||||
|
||||
// The supertype or subtype may not be instantiated.
|
||||
if (AbstractType::InstantiateAndTestSubtype(
|
||||
&subtype, &supertype, instantiator_type_args, function_type_args)) {
|
||||
|
||||
@@ -2916,13 +2916,6 @@ static void CollectStringifiedType(Zone* zone,
|
||||
output.Add(instance);
|
||||
return;
|
||||
}
|
||||
if (type.IsTypeRef()) {
|
||||
// A TypeRef is used to break cycles in the representation of types
|
||||
// calling type class on it will cause an infinite recursion.
|
||||
// We use null instead.
|
||||
output.Add(instance);
|
||||
return;
|
||||
}
|
||||
ASSERT(type.IsType());
|
||||
|
||||
const Class& cls = Class::Handle(type.type_class());
|
||||
|
||||
@@ -2570,7 +2570,7 @@ class @Field extends @Object {
|
||||
// The declared type of this field.
|
||||
//
|
||||
// The value will always be of one of the kinds:
|
||||
// Type, TypeRef, TypeParameter, BoundedType.
|
||||
// Type, TypeParameter, RecordType, FunctionType, BoundedType.
|
||||
@Instance declaredType;
|
||||
|
||||
// Is this field const?
|
||||
@@ -2607,7 +2607,7 @@ class Field extends Object {
|
||||
// The declared type of this field.
|
||||
//
|
||||
// The value will always be of one of the kinds:
|
||||
// Type, TypeRef, TypeParameter, BoundedType.
|
||||
// Type, TypeParameter, RecordType, FunctionType, BoundedType.
|
||||
@Instance declaredType;
|
||||
|
||||
// Is this field const?
|
||||
@@ -3151,22 +3151,19 @@ class Instance extends Object {
|
||||
// TypeParameter
|
||||
int parameterIndex [optional];
|
||||
|
||||
// The type bounded by a BoundedType instance
|
||||
// - or -
|
||||
// the referent of a TypeRef instance.
|
||||
// The type bounded by a BoundedType instance.
|
||||
//
|
||||
// The value will always be of one of the kinds:
|
||||
// Type, TypeRef, TypeParameter, BoundedType.
|
||||
// Type, TypeParameter, RecordType, FunctionType, BoundedType.
|
||||
//
|
||||
// Provided for instance kinds:
|
||||
// BoundedType
|
||||
// TypeRef
|
||||
@Instance targetType [optional];
|
||||
|
||||
// The bound of a TypeParameter or BoundedType.
|
||||
//
|
||||
// The value will always be of one of the kinds:
|
||||
// Type, TypeRef, TypeParameter, BoundedType.
|
||||
// Type, TypeParameter, RecordType, FunctionType, BoundedType.
|
||||
//
|
||||
// Provided for instance kinds:
|
||||
// BoundedType
|
||||
@@ -3285,9 +3282,6 @@ enum InstanceKind {
|
||||
// An instance of the Dart class TypeParameter.
|
||||
TypeParameter,
|
||||
|
||||
// An instance of the Dart class TypeRef.
|
||||
TypeRef,
|
||||
|
||||
// An instance of the Dart class FunctionType.
|
||||
FunctionType,
|
||||
|
||||
@@ -4369,7 +4363,7 @@ class TypeArguments extends Object {
|
||||
// A list of types.
|
||||
//
|
||||
// The value will always be one of the kinds:
|
||||
// Type, TypeRef, TypeParameter, BoundedType.
|
||||
// Type, TypeParameter, RecordType, FunctionType, BoundedType.
|
||||
@Instance[] types;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -379,7 +379,6 @@ class ObjectPointerVisitor;
|
||||
V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl") \
|
||||
V(_Type, "_Type") \
|
||||
V(_TypeParameter, "_TypeParameter") \
|
||||
V(_TypeRef, "_TypeRef") \
|
||||
V(_TypeVariableMirror, "_TypeVariableMirror") \
|
||||
V(_Uint16ArrayFactory, "Uint16List.") \
|
||||
V(_Uint16ArrayView, "_Uint16ArrayView") \
|
||||
|
||||
@@ -397,7 +397,6 @@ DEFINE_TAGGED_POINTER(AbstractType, Instance)
|
||||
DEFINE_TAGGED_POINTER(Type, AbstractType)
|
||||
DEFINE_TAGGED_POINTER(FunctionType, AbstractType)
|
||||
DEFINE_TAGGED_POINTER(RecordType, AbstractType)
|
||||
DEFINE_TAGGED_POINTER(TypeRef, AbstractType)
|
||||
DEFINE_TAGGED_POINTER(TypeParameter, AbstractType)
|
||||
DEFINE_TAGGED_POINTER(Closure, Instance)
|
||||
DEFINE_TAGGED_POINTER(Number, Instance)
|
||||
|
||||
@@ -114,14 +114,6 @@ void TypeTestingStubNamer::MakeNameAssemblerSafe(BaseTextBuffer* buffer) {
|
||||
CodePtr TypeTestingStubGenerator::DefaultCodeForType(
|
||||
const AbstractType& type,
|
||||
bool lazy_specialize /* = true */) {
|
||||
auto isolate_group = IsolateGroup::Current();
|
||||
|
||||
if (type.IsTypeRef()) {
|
||||
return isolate_group->use_strict_null_safety_checks()
|
||||
? StubCode::DefaultTypeTest().ptr()
|
||||
: StubCode::DefaultNullableTypeTest().ptr();
|
||||
}
|
||||
|
||||
// During bootstrapping we have no access to stubs yet, so we'll just return
|
||||
// `null` and patch these later in `Object::FinishInit()`.
|
||||
if (!StubCode::HasBeenInitialized()) {
|
||||
@@ -181,7 +173,7 @@ CodePtr TypeTestingStubGenerator::OptimizedCodeForType(
|
||||
#if !defined(TARGET_ARCH_IA32)
|
||||
ASSERT(StubCode::HasBeenInitialized());
|
||||
|
||||
if (type.IsTypeRef() || type.IsTypeParameter()) {
|
||||
if (type.IsTypeParameter()) {
|
||||
return TypeTestingStubGenerator::DefaultCodeForType(
|
||||
type, /*lazy_specialize=*/false);
|
||||
}
|
||||
@@ -1054,26 +1046,6 @@ bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
|
||||
return !type_argument_checks.is_empty();
|
||||
}
|
||||
|
||||
// Unwraps TypeRef in [type_reg] and loads class id of the unwrapped type to
|
||||
// [class_id_reg].
|
||||
//
|
||||
// [type_reg] must contain an AbstractType. Unwrapped TypeRef is written
|
||||
// back to [type_reg]. [class_id_reg] must be distinct from [type_reg].
|
||||
static void UnwrapTypeRefAndLoadClassId(compiler::Assembler* assembler,
|
||||
Register type_reg,
|
||||
Register class_id_reg) {
|
||||
ASSERT(class_id_reg != type_reg);
|
||||
compiler::Label done;
|
||||
// TypeRefs never wrap other TypeRefs, so we only need to unwrap once.
|
||||
__ LoadClassId(class_id_reg, type_reg);
|
||||
__ CompareImmediate(class_id_reg, kTypeRefCid);
|
||||
__ BranchIf(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
|
||||
__ LoadCompressedFieldFromOffset(type_reg, type_reg,
|
||||
compiler::target::TypeRef::type_offset());
|
||||
__ LoadClassId(class_id_reg, type_reg);
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
||||
void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
|
||||
compiler::Assembler* assembler,
|
||||
HierarchyInfo* hi,
|
||||
@@ -1115,8 +1087,8 @@ void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
|
||||
|
||||
__ Comment("Checking instantiated type parameter for possible top types");
|
||||
compiler::Label check_subtype_type_class_ids;
|
||||
UnwrapTypeRefAndLoadClassId(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
|
||||
TTSInternalRegs::kScratchReg);
|
||||
__ LoadClassId(TTSInternalRegs::kScratchReg,
|
||||
TTSInternalRegs::kSuperTypeArgumentReg);
|
||||
__ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
|
||||
__ BranchIf(NOT_EQUAL, &check_subtype_type_class_ids);
|
||||
__ LoadTypeClassId(TTSInternalRegs::kScratchReg,
|
||||
@@ -1148,8 +1120,8 @@ void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
|
||||
__ Bind(&check_subtype_type_class_ids);
|
||||
__ Comment("Checking instance type argument for possible bottom types");
|
||||
// Nothing else to check for non-Types, so fall back to the slow stub.
|
||||
UnwrapTypeRefAndLoadClassId(assembler, TTSInternalRegs::kSubTypeArgumentReg,
|
||||
TTSInternalRegs::kScratchReg);
|
||||
__ LoadClassId(TTSInternalRegs::kScratchReg,
|
||||
TTSInternalRegs::kSubTypeArgumentReg);
|
||||
__ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
|
||||
__ BranchIf(NOT_EQUAL, check_failed);
|
||||
__ LoadTypeClassId(TTSInternalRegs::kScratchReg,
|
||||
@@ -1203,8 +1175,8 @@ void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
|
||||
TTSInternalRegs::kInstanceTypeArgumentsReg,
|
||||
compiler::target::TypeArguments::type_at_offset(
|
||||
type_param_value_offset_i));
|
||||
UnwrapTypeRefAndLoadClassId(assembler, TTSInternalRegs::kSubTypeArgumentReg,
|
||||
TTSInternalRegs::kScratchReg);
|
||||
__ LoadClassId(TTSInternalRegs::kScratchReg,
|
||||
TTSInternalRegs::kSubTypeArgumentReg);
|
||||
if (type.IsObjectType() || type.IsDartFunctionType() ||
|
||||
type.IsDartRecordType()) {
|
||||
__ CompareImmediate(TTSInternalRegs::kScratchReg, kTypeCid);
|
||||
@@ -1537,12 +1509,8 @@ void TypeUsageInfo::AddTypeToSet(TypeSet* set, const AbstractType* type) {
|
||||
}
|
||||
|
||||
bool TypeUsageInfo::IsUsedInTypeTest(const AbstractType& type) {
|
||||
const AbstractType* dereferenced_type = &type;
|
||||
if (type.IsTypeRef()) {
|
||||
dereferenced_type = &AbstractType::Handle(TypeRef::Cast(type).type());
|
||||
}
|
||||
if (dereferenced_type->IsFinalized()) {
|
||||
return assert_assignable_types_.HasKey(dereferenced_type);
|
||||
if (type.IsFinalized()) {
|
||||
return assert_assignable_types_.HasKey(&type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ static void FinalizeAndCanonicalize(AbstractType* type) {
|
||||
}
|
||||
|
||||
static void CanonicalizeTAV(TypeArguments* tav) {
|
||||
*tav = tav->Canonicalize(Thread::Current(), nullptr);
|
||||
*tav = tav->Canonicalize(Thread::Current());
|
||||
}
|
||||
|
||||
struct TTSTestCase {
|
||||
|
||||
Reference in New Issue
Block a user