Reland "[vm] Avoid expanding/flattening type arguments vectors in Type objects"

This is a reland of commit 135443706b

Original change's description:
> [vm] Avoid expanding/flattening type arguments vectors in Type objects
>
> Previously, vectors of type arguments were expanded to include type
> arguments corresponding to superclasses both in the instances of
> generic classes and in Type objects (after type finalization).
> As a result, Type objects after finalization could be recursive and
> need to use extra TypeRef objects to break loops. The finalization of
> types was very complex and sometimes slow.
>
> This change simplifies the representation of Type objects: now they
> always have short type argument vectors, corresponding only to
> the type parameters of their own classes (both before and after
> finalization). Vectors of type arguments in the instances of generic
> classes are still expanded/flattened.
>
> This greatly simplifies type finalization, makes Type objects
> non-recursive and removes the need to create and handle excessive
> TypeRefs for type arguments corresponding to superclasses,
> as those type arguments are no longer included into types.
> The only remaining use of TypeRefs is for bounds of type parameters.
>
> In order to expand/flatten type arguments, new methods Type::GetInstanceTypeArguments / Class::GetInstanceTypeArguments
> are introduced. They build canonical declaration type arguments
> once (for each class), and then instantiate them as needed.
>
> There are also simple helper methods to shrink type arguments (TypeArguments::FromInstanceTypeArguments) and expand type arguments without filling type arguments corresponding to superclasses (TypeArguments::ToInstantiatorTypeArguments).
>
> Time of edge case 'regress_51960_test' 15min -> 300ms.
>
> TEST=ci, runtime/tests/vm/dart/regress_51960_test.dart
>
> Fixes https://github.com/dart-lang/sdk/issues/52022
> Fixes https://github.com/dart-lang/sdk/issues/51960
>
> Change-Id: I75b466b74698a33c0bb5e1dcbd29542e413812a1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295060
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>

TEST=runtime/tests/vm/dart/regress_b_278841863_test.dart
Fixes b/278841863.

Change-Id: Ib1e20055bfb26e1df0a077300c69f0bec7152480
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/296300
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2023-04-19 17:25:31 +00:00 committed by Commit Queue
parent ac1bdebff7
commit 7247a1b3b7
33 changed files with 651 additions and 937 deletions

View file

@ -100,53 +100,6 @@ Instead of using `[List[T], T, T]`, the last overlapping `T` is collapsed and th
Class `B` has 2 type parameters and 2 type arguments, whereas class `C` has 1 type parameter and 2 type arguments.
## TypeRef
Consider the following example:
```dart
class B<T> { }
class D extends B<D> { }
```
Flattening the type argument vector of instances of class `D` poses a problem. Indeed, the type argument at index 0 must represent type `D`, which is the type argument of class `B`. Therefore, type `D` would need to be represented by `D[D[D[D[...]]]]` ad infinitum. To solve this problem, the `TypeRef` object extending `AbstractType` is introduced. It contains a single field `type`, which points to an `AbstractType`. Basically, `TypeRef` references another type and it is used to break cycles in type graphs. In this example, type `D` is represented as `D[TypeRef -> D]`, or graphically:
```
D: D[TypeRef]
^ |
| |
+----+
```
Another example:
```dart
class D1 extends B<D2> { }
class D2 extends B<D1> { }
```
Corresponding types and their internal representation:
```
D1: D1[TypeRef -> D2]
D2: D2[TypeRef -> D1]
```
Note that not all declarations of types can be represented this way, but only what is called *contractive* types:
```dart
class D<T> extends B<D<D<int>> { }
```
```
D<T>: D[D<D<int>>, T]
D<D<int>>: D[TypeRef -> D<D<int>>, D<int>]
D<int>: D[D<D<int>>, int]
```
Here however is the example of a *non-contractive* type:
```dart
class D<T> extends B<D<D<T>> { }
```
```
D<T>: D[D<D<T>>, T]
D<D<T>>: D[D<D<D<T>>>, D<T>]
D<D<D<T>>>: D[D<D<D<D<T>>>>, D<D<T>>]
...
```
The representation is divergent and therefore not possible. The VM detects non-contractive types (search for `ClassFinalizer::CheckRecursiveType` in the [class finalizer](https://github.com/dart-lang/sdk/blob/main/runtime/vm/class_finalizer.cc)) and reports an error. These non-contractive types make no sense in real programs and rejecting them is not an issue at all.
## Compile Time Type
The VM classes described so far are not only used to represent the runtime type of instances in the heap, but they are also used to describe types at compile time. For example, the right handside of an *instance of* type test is represented by a concrete instance of `AbstractType`. Note that the type may still be *uninstantiated* at compile time, e.g. `List<T>` still contains the `TypeParameter` `T` of a generic class in its type argument vector:
@ -216,7 +169,7 @@ Instead of implementing three different traversals, the kind of type equality is
## Finalization
Types read from kernel files (produced by the Common Front End) need finalization before being used in the VM runtime. Finalization consists in flattening type argument vectors and in assigning indices to type parameters. A generic type provided by CFE will always have as many type arguments as the number of type parameters declared by the types class. As explained above, type arguments get prepended to the type argument vector, so that the vector can be used unchanged in any super class of the types class. This is done by methods of the [class finalizer](https://github.com/dart-lang/sdk/blob/main/runtime/vm/class_finalizer.h) called `ExpandAndFinalizeTypeArguments` and `FillAndFinalizeTypeArguments`.
Types read from kernel files (produced by the Common Front End) need finalization before being used in the VM runtime. Finalization currently assigns indices to type parameters.
The index of function type parameters can be assigned immediately upon loading of the type parameter from the kernel file. This is possible because enclosing generic functions are always loaded prior to inner generic functions. Therefore the number of type parameters declared in the enclosing scope is known. The picture is more complicated with class type parameters. Classes can reference each other and a clear order is not defined in the kernel file. Clusters of classes must be fully loaded before type arguments can be flattened, which in turn determines the indices of class type parameters.

View file

@ -37,23 +37,17 @@ DEFINE_NATIVE_ENTRY(SuspendState_instantiateClosureWithFutureTypeArgument,
ASSERT(future_class.NumTypeArguments() == 1);
const auto& cls = Class::Handle(zone, future.clazz());
auto& type =
AbstractType::Handle(zone, cls.GetInstantiationOf(zone, future_class));
auto& type = Type::Handle(zone, cls.GetInstantiationOf(zone, future_class));
ASSERT(!type.IsNull());
if (!type.IsInstantiated()) {
const auto& instance_type_args =
TypeArguments::Handle(zone, future.GetTypeArguments());
type =
type ^=
type.InstantiateFrom(instance_type_args, Object::null_type_arguments(),
kNoneFree, Heap::kNew);
kNoneFree, Heap::kOld);
}
auto& type_args = TypeArguments::Handle(zone, type.arguments());
if (type_args.Length() != 1) {
// Create a new TypeArguments vector of length 1.
type = type_args.TypeAtNullSafe(0);
type_args = TypeArguments::New(1);
type_args.SetTypeAt(0, type);
}
ASSERT(type_args.IsNull() || type_args.Length() == 1);
type_args = type_args.Canonicalize(thread, nullptr);
ASSERT(closure.delayed_type_arguments() ==

View file

@ -625,20 +625,28 @@ static AbstractTypePtr InstantiateType(const AbstractType& type,
// i.e. all function type parameters are free with a null vector.
ASSERT(type.IsFinalized());
ASSERT(type.IsCanonical());
Thread* thread = Thread::Current();
if (type.IsInstantiated()) {
return type.Canonicalize(Thread::Current(), nullptr);
return type.Canonicalize(thread, nullptr);
}
TypeArguments& instantiator_type_args = TypeArguments::Handle();
if (!instantiator.IsNull() && instantiator.IsType()) {
ASSERT(instantiator.IsFinalized());
instantiator_type_args = instantiator.arguments();
if (instantiator.type_class_id() == kInstanceCid) {
// Handle types created in ClosureMirror_function.
instantiator_type_args = instantiator.arguments();
} else {
instantiator_type_args =
Type::Cast(instantiator)
.GetInstanceTypeArguments(thread, /*canonicalize=*/false);
}
}
AbstractType& result = AbstractType::Handle(type.InstantiateFrom(
instantiator_type_args, Object::null_type_arguments(), kAllFree,
Heap::kOld));
ASSERT(result.IsFinalized());
return result.Canonicalize(Thread::Current(), nullptr);
return result.Canonicalize(thread, nullptr);
}
DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0, 0) {
@ -1183,7 +1191,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 0, 1) {
const Array& result = Array::Handle(Array::New(num_params));
AbstractType& arg_type = AbstractType::Handle();
Instance& type_mirror = Instance::Handle();
const TypeArguments& args = TypeArguments::Handle(type.arguments());
const TypeArguments& args =
TypeArguments::Handle(Type::Cast(type).arguments());
// Handle argument lists that have been optimized away, because either no
// arguments have been provided, or all arguments are dynamic. Return a list
@ -1197,10 +1206,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 0, 1) {
return result.ptr();
}
ASSERT(args.Length() >= num_params);
const intptr_t num_inherited_args = args.Length() - num_params;
ASSERT(args.Length() == num_params);
for (intptr_t i = 0; i < num_params; i++) {
arg_type = args.TypeAt(i + num_inherited_args);
arg_type = args.TypeAt(i);
type_mirror = CreateTypeMirror(arg_type);
result.SetAt(i, type_mirror);
}
@ -1391,12 +1399,14 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 0, 5) {
}
ASSERT(!type.IsNull());
TypeArguments& type_arguments = TypeArguments::Handle(type.arguments());
TypeArguments& type_arguments = TypeArguments::Handle();
if (!type.IsInstantiated()) {
// Must have been a declaration type.
AbstractType& rare_type = AbstractType::Handle(klass.RareType());
const Type& rare_type = Type::Handle(klass.RareType());
ASSERT(rare_type.IsInstantiated());
type_arguments = rare_type.arguments();
type_arguments = rare_type.GetInstanceTypeArguments(thread);
} else {
type_arguments = type.GetInstanceTypeArguments(thread);
}
Class& redirected_klass = Class::Handle(klass.ptr());

View file

@ -85,8 +85,9 @@ DEFINE_NATIVE_ENTRY(Object_runtimeType, 0, 1) {
} else if (IsArrayClassId(instance.GetClassId())) {
const auto& cls = Class::Handle(
zone, thread->isolate_group()->object_store()->list_class());
const auto& type_arguments =
auto& type_arguments =
TypeArguments::Handle(zone, instance.GetTypeArguments());
type_arguments = type_arguments.FromInstanceTypeArguments(thread, cls);
const auto& type = Type::Handle(
zone,
Type::New(cls, type_arguments, Nullability::kNonNullable, Heap::kNew));
@ -359,10 +360,11 @@ static bool ExtractInterfaceTypeArgs(Zone* zone,
const TypeArguments& instance_type_args,
const Class& interface_cls,
TypeArguments* interface_type_args) {
Thread* thread = Thread::Current();
Class& cur_cls = Class::Handle(zone, instance_cls.ptr());
// The following code is a specialization of Class::IsSubtypeOf().
Array& interfaces = Array::Handle(zone);
AbstractType& interface = AbstractType::Handle(zone);
Type& interface = Type::Handle(zone);
Class& cur_interface_cls = Class::Handle(zone);
TypeArguments& cur_interface_type_args = TypeArguments::Handle(zone);
while (true) {
@ -376,7 +378,8 @@ static bool ExtractInterfaceTypeArgs(Zone* zone,
interface ^= interfaces.At(i);
ASSERT(interface.IsFinalized());
cur_interface_cls = interface.type_class();
cur_interface_type_args = interface.arguments();
cur_interface_type_args =
interface.GetInstanceTypeArguments(thread, /*canonicalize=*/false);
if (!cur_interface_type_args.IsNull() &&
!cur_interface_type_args.IsInstantiated()) {
cur_interface_type_args = cur_interface_type_args.InstantiateFrom(
@ -409,7 +412,7 @@ DEFINE_NATIVE_ENTRY(Internal_extractTypeArguments, 0, 2) {
const AbstractType& function_type_arg =
AbstractType::Handle(zone, arguments->NativeTypeArgAt(0));
if (function_type_arg.IsType() &&
(function_type_arg.arguments() == TypeArguments::null())) {
(Type::Cast(function_type_arg).arguments() == TypeArguments::null())) {
interface_cls = function_type_arg.type_class();
num_type_args = interface_cls.NumTypeParameters();
}

View file

@ -0,0 +1,54 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Verifies that VM doesn't time out on loading of highly recursive types.
// Regression test for https://github.com/dart-lang/sdk/issues/51960.
class A<A1 extends A<A1, B1, C1, D1>, B1 extends B<A1, B1, C1, D1>,
C1 extends C<A1, B1, C1, D1>, D1 extends D<A1, B1, C1, D1>> {}
class B<A1 extends A<A1, B1, C1, D1>, B1 extends B<A1, B1, C1, D1>,
C1 extends C<A1, B1, C1, D1>, D1 extends D<A1, B1, C1, D1>> {}
class C<A1 extends A<A1, B1, C1, D1>, B1 extends B<A1, B1, C1, D1>,
C1 extends C<A1, B1, C1, D1>, D1 extends D<A1, B1, C1, D1>> {}
class D<A1 extends A<A1, B1, C1, D1>, B1 extends B<A1, B1, C1, D1>,
C1 extends C<A1, B1, C1, D1>, D1 extends D<A1, B1, C1, D1>> {}
/* -= Mixins =- */
mixin MixinA<
A1 extends MixinA<A1, B1, C1, D1>,
B1 extends MixinB<A1, B1, C1, D1>,
C1 extends MixinC<A1, B1, C1, D1>,
D1 extends MixinD<A1, B1, C1, D1>>
on A<MixinA<A1, B1, C1, D1>, MixinB<A1, B1, C1, D1>, MixinC<A1, B1, C1, D1>,
MixinD<A1, B1, C1, D1>> {}
mixin MixinB<
A1 extends MixinA<A1, B1, C1, D1>,
B1 extends MixinB<A1, B1, C1, D1>,
C1 extends MixinC<A1, B1, C1, D1>,
D1 extends MixinD<A1, B1, C1, D1>>
on B<MixinA<A1, B1, C1, D1>, MixinB<A1, B1, C1, D1>, MixinC<A1, B1, C1, D1>,
MixinD<A1, B1, C1, D1>> {}
mixin MixinC<
A1 extends MixinA<A1, B1, C1, D1>,
B1 extends MixinB<A1, B1, C1, D1>,
C1 extends MixinC<A1, B1, C1, D1>,
D1 extends MixinD<A1, B1, C1, D1>>
on C<MixinA<A1, B1, C1, D1>, MixinB<A1, B1, C1, D1>, MixinC<A1, B1, C1, D1>,
MixinD<A1, B1, C1, D1>> {}
mixin MixinD<
A1 extends MixinA<A1, B1, C1, D1>,
B1 extends MixinB<A1, B1, C1, D1>,
C1 extends MixinC<A1, B1, C1, D1>,
D1 extends MixinD<A1, B1, C1, D1>>
on D<MixinA<A1, B1, C1, D1>, MixinB<A1, B1, C1, D1>, MixinC<A1, B1, C1, D1>,
MixinD<A1, B1, C1, D1>> {}
void main() {}

View file

@ -0,0 +1,28 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Regression test for b/278841863.
//
// Verifies that generic type literal correctly compares to a runtime type.
import "package:expect/expect.dart";
class A<T> {}
class B<T> extends A {}
dynamic getTypeA<T>() => A<T>;
dynamic getTypeB<T>() => B<T>;
void main() {
Expect.isTrue(A().runtimeType == getTypeA());
Expect.isTrue(A<int>().runtimeType == getTypeA<int>());
Expect.isFalse(A<int>().runtimeType == getTypeA());
Expect.isFalse(A().runtimeType == getTypeA<int>());
Expect.isTrue(B().runtimeType == getTypeB());
Expect.isTrue(B<int>().runtimeType == getTypeB<int>());
Expect.isFalse(B<int>().runtimeType == getTypeB());
Expect.isFalse(B().runtimeType == getTypeB<int>());
}

View file

@ -316,8 +316,7 @@ void ClassFinalizer::VerifyBootstrapClasses() {
void ClassFinalizer::FinalizeTypeParameters(Zone* zone,
const Class& cls,
const FunctionType& signature,
FinalizationKind finalization,
PendingTypes* pending_types) {
FinalizationKind finalization) {
if (FLAG_trace_type_finalization) {
THR_Print(
"%s type parameters of %s '%s'\n",
@ -333,390 +332,21 @@ void ClassFinalizer::FinalizeTypeParameters(Zone* zone,
TypeArguments& type_args = TypeArguments::Handle(zone);
type_args = type_params.bounds();
type_args =
FinalizeTypeArguments(zone, type_args, finalization, pending_types);
type_args = FinalizeTypeArguments(zone, type_args, finalization);
type_params.set_bounds(type_args);
type_args = type_params.defaults();
type_args =
FinalizeTypeArguments(zone, type_args, finalization, pending_types);
type_args = FinalizeTypeArguments(zone, type_args, finalization);
type_params.set_defaults(type_args);
type_params.OptimizeFlags();
}
}
// This function reports a compilation error if the recursive 'type' T being
// finalized is a non-contractive type, i.e. if the induced type set S of P is
// not finite, where P is the instantiation of T with its own type parameters.
// The induced type set S consists of the super types of any type in S as well
// as the type arguments of any parameterized type in S.
// The Dart Language Specification does not disallow the declaration and use of
// non-contractive types (this may change). They are nevertheless disallowed
// as an implementation restriction in the VM since they cause divergence.
// A non-contractive type can be detected by looking at the queue of types
// pending finalization that are mutually recursive with the checked type.
void ClassFinalizer::CheckRecursiveType(const AbstractType& type,
PendingTypes* pending_types) {
ASSERT(!type.IsFunctionType());
ASSERT(pending_types != nullptr);
Zone* zone = Thread::Current()->zone();
if (FLAG_trace_type_finalization) {
THR_Print("Checking recursive type '%s': %s\n",
String::Handle(type.Name()).ToCString(), type.ToCString());
}
const Class& type_cls = Class::Handle(zone, type.type_class());
const TypeArguments& arguments =
TypeArguments::Handle(zone, type.arguments());
// A type can only be recursive via its type arguments.
ASSERT(!arguments.IsNull());
const intptr_t num_type_args = arguments.Length();
ASSERT(num_type_args > 0);
ASSERT(num_type_args == type_cls.NumTypeArguments());
const intptr_t num_type_params = type_cls.NumTypeParameters();
const intptr_t first_type_param = num_type_args - num_type_params;
// If the type is not generic (num_type_params == 0) or if its type parameters
// are instantiated, no divergence can occur. Note that if the type parameters
// are null, i.e. if the generic type is raw, they are considered
// instantiated and no divergence can occur.
if ((num_type_params == 0) ||
arguments.IsSubvectorInstantiated(first_type_param, num_type_params)) {
return;
}
// Consider mutually recursive and uninstantiated types pending finalization
// with the same type class and report an error if they are not equal in their
// raw form, i.e. where each class type parameter is substituted with dynamic.
// This test eliminates divergent types without restricting recursive types
// typically found in the wild.
TypeArguments& pending_arguments = TypeArguments::Handle(zone);
const intptr_t num_pending_types = pending_types->length();
for (intptr_t i = num_pending_types - 1; i >= 0; i--) {
const AbstractType& pending_type = pending_types->At(i);
if (FLAG_trace_type_finalization) {
THR_Print(" Comparing with pending type '%s': %s\n",
String::Handle(pending_type.Name()).ToCString(),
pending_type.ToCString());
}
if ((pending_type.ptr() != type.ptr()) && pending_type.IsType() &&
(pending_type.type_class() == type_cls.ptr())) {
pending_arguments = pending_type.arguments();
// By using TypeEquality::kInSubtypeTest, we throw a wider net than
// using canonical or syntactical equality and may reject more
// problematic declarations.
if (!pending_arguments.IsSubvectorEquivalent(
arguments, first_type_param, num_type_params,
TypeEquality::kInSubtypeTest) &&
!pending_arguments.IsSubvectorInstantiated(first_type_param,
num_type_params)) {
const TypeArguments& instantiated_arguments = TypeArguments::Handle(
zone, arguments.InstantiateFrom(Object::null_type_arguments(),
Object::null_type_arguments(),
kNoneFree, Heap::kNew));
const TypeArguments& instantiated_pending_arguments =
TypeArguments::Handle(zone, pending_arguments.InstantiateFrom(
Object::null_type_arguments(),
Object::null_type_arguments(),
kNoneFree, Heap::kNew));
// By using TypeEquality::kInSubtypeTest, we throw a wider net than
// using canonical or syntactical equality and may reject more
// problematic declarations.
if (!instantiated_pending_arguments.IsSubvectorEquivalent(
instantiated_arguments, first_type_param, num_type_params,
TypeEquality::kInSubtypeTest)) {
const String& type_name = String::Handle(zone, type.Name());
ReportError("illegal recursive type '%s'", type_name.ToCString());
}
}
}
}
}
// Expand the type arguments of the given type and finalize its full type
// argument vector. Return the number of type arguments (0 for a raw type).
intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments(
Zone* zone,
const AbstractType& type,
PendingTypes* pending_types) {
// The type class does not need to be finalized in order to finalize the type.
// Also, the type parameters of the type class must be finalized.
Class& type_class = Class::Handle(zone, type.type_class());
type_class.EnsureDeclarationLoaded();
// The finalized type argument vector needs num_type_arguments types.
const intptr_t num_type_arguments = type_class.NumTypeArguments();
// The class has num_type_parameters type parameters.
const intptr_t num_type_parameters = type_class.NumTypeParameters();
// Initialize the type argument vector.
// A null type argument vector indicates a raw type.
TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments());
ASSERT(arguments.IsNull() || (arguments.Length() == num_type_parameters));
// The full type argument vector consists of the type arguments of the
// super types of type_class, which are initialized from the parsed
// type arguments, followed by the parsed type arguments.
TypeArguments& full_arguments = TypeArguments::Handle(zone);
if (num_type_arguments > 0) {
// If no type arguments were parsed and if the super types do not prepend
// type arguments to the vector, we can leave the vector as null.
if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) {
full_arguments = TypeArguments::New(num_type_arguments);
// Copy the parsed type arguments at the correct offset in the full type
// argument vector.
const intptr_t offset = num_type_arguments - num_type_parameters;
AbstractType& type_arg = AbstractType::Handle(zone, Type::DynamicType());
// Leave the temporary type arguments at indices [0..offset[ as null.
for (intptr_t i = 0; i < num_type_parameters; i++) {
// If no type parameters were provided, a raw type is desired, so we
// create a vector of dynamic.
if (!arguments.IsNull()) {
type_arg = arguments.TypeAt(i);
// The parsed type_arg may or may not be finalized.
if (type_arg.IsTypeRef()) {
// Dereferencing the TypeRef 'rotates' the cycle in the recursive
// type argument, so that the top level type arguments of the type
// do not start with a TypeRef, for better readability and possibly
// fewer later dereferences in various type traversal routines.
// This rotation is not required for correctness.
// The cycle containing TypeRefs always involves type arguments of
// the super class in the flatten argument vector, so it is safe to
// remove TypeRefs from type arguments corresponding to the type
// parameters of the type class.
// Such TypeRefs may appear after instantiation of types at runtime.
type_arg = TypeRef::Cast(type_arg).type();
}
}
full_arguments.SetTypeAt(offset + i, type_arg);
}
// Replace the compile-time argument vector (of length zero or
// num_type_parameters) of this type being finalized with the still
// unfinalized run-time argument vector (of length num_type_arguments).
// This type being finalized may be recursively reached via bounds
// checking or type arguments of its super type.
type.set_arguments(full_arguments);
// Finalize the current type arguments of the type, which are still the
// parsed type arguments.
if (!arguments.IsNull()) {
for (intptr_t i = 0; i < num_type_parameters; i++) {
type_arg = full_arguments.TypeAt(offset + i);
if (!type_arg.IsBeingFinalized()) {
type_arg = FinalizeType(type_arg, kFinalize, pending_types);
} else {
ASSERT(type_arg.IsTypeParameter());
// The bound of the type parameter is still being finalized.
}
full_arguments.SetTypeAt(offset + i, type_arg);
}
}
if (offset > 0) {
TrailPtr trail = new Trail(zone, 4);
FillAndFinalizeTypeArguments(zone, type_class, full_arguments, offset,
pending_types, trail);
}
if (full_arguments.IsRaw(0, num_type_arguments)) {
// The parameterized_type is raw. Set its argument vector to null, which
// is more efficient in type tests.
full_arguments = TypeArguments::null();
}
type.set_arguments(full_arguments);
} else {
ASSERT(full_arguments.IsNull()); // Use null vector for raw type.
}
}
ASSERT(full_arguments.IsNull() ||
!full_arguments.IsRaw(0, num_type_arguments));
return full_arguments.IsNull() ? 0 : full_arguments.Length();
}
// Finalize the type argument vector 'arguments' of the type defined by the
// class 'cls' parameterized with the type arguments 'cls_args'.
// The vector 'cls_args' is already initialized as a subvector at the correct
// position in the passed in 'arguments' vector.
// The subvector 'cls_args' has length cls.NumTypeParameters() and starts at
// offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments'
// vector.
// The type argument vector of cls may overlap the type argument vector of its
// super class. In case of an overlap, the overlapped type arguments of the
// super class are already initialized. The still uninitialized ones have an
// offset smaller than 'num_uninitialized_arguments'.
// Example 1 (without overlap):
// Declared: class C<K, V> extends B<V> { ... }
// class B<T> extends A<int> { ... }
// Input: C<String, double> expressed as
// cls = C, arguments = [dynamic, dynamic, String, double],
// num_uninitialized_arguments = 2,
// i.e. cls_args = [String, double], offset = 2, length = 2.
// Output: arguments = [int, double, String, double]
// Example 2 (with overlap):
// Declared: class C<K, V> extends B<K> { ... }
// class B<T> extends A<int> { ... }
// Input: C<String, double> expressed as
// cls = C, arguments = [dynamic, String, double],
// num_uninitialized_arguments = 1,
// i.e. cls_args = [String, double], offset = 1, length = 2.
// Output: arguments = [int, String, double]
//
// It is too early to canonicalize the type arguments of the vector, because
// several type argument vectors may be mutually recursive and finalized at the
// same time. Canonicalization happens when pending types are processed.
// The trail is required to correctly instantiate a recursive type argument
// of the super type.
void ClassFinalizer::FillAndFinalizeTypeArguments(
Zone* zone,
const Class& cls,
const TypeArguments& arguments,
intptr_t num_uninitialized_arguments,
PendingTypes* pending_types,
TrailPtr trail) {
ASSERT(arguments.Length() >= cls.NumTypeArguments());
if (!cls.is_type_finalized()) {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
FinalizeTypeParameters(zone, cls, Object::null_function_type(), kFinalize);
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
AbstractType& super_type = AbstractType::Handle(zone, cls.super_type());
if (!super_type.IsNull()) {
const Class& super_class = Class::Handle(zone, super_type.type_class());
const intptr_t num_super_type_params = super_class.NumTypeParameters();
const intptr_t num_super_type_args = super_class.NumTypeArguments();
if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) {
super_type = FinalizeType(super_type, kFinalize, pending_types);
cls.set_super_type(super_type);
}
TypeArguments& super_type_args =
TypeArguments::Handle(zone, super_type.arguments());
// Offset of super type's type parameters in cls' type argument vector.
const intptr_t super_offset = num_super_type_args - num_super_type_params;
// If the super type is raw (i.e. super_type_args is null), set to dynamic.
AbstractType& super_type_arg =
AbstractType::Handle(zone, Type::DynamicType());
for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) {
if (!super_type_args.IsNull()) {
super_type_arg = super_type_args.TypeAt(i);
if (!super_type_arg.IsTypeRef()) {
if (super_type_arg.IsBeingFinalized()) {
// A type parameter being finalized indicates an unfinalized bound,
// but the bound is not relevant here. Its index is finalized.
if (!super_type_arg.IsTypeParameter()) {
if (super_type_arg.IsType()) {
CheckRecursiveType(super_type_arg, pending_types);
} else {
// The spec prohibits a typedef-declared function type to refer
// to itself. However, self-reference can occur via type
// arguments of the base class,
// e.g. `class Derived extends Base<TypeDef<Derived>> {}`.
ASSERT(super_type_arg.IsFunctionType());
}
if (FLAG_trace_type_finalization) {
THR_Print(
"Creating TypeRef '%s': '%s'\n",
String::Handle(zone, super_type_arg.Name()).ToCString(),
super_type_arg.ToCString());
}
super_type_arg = TypeRef::New(super_type_arg);
}
super_type_args.SetTypeAt(i, super_type_arg);
} else {
if (!super_type_arg.IsFinalized()) {
super_type_arg =
FinalizeType(super_type_arg, kFinalize, pending_types);
super_type_args.SetTypeAt(i, super_type_arg);
// Note that super_type_arg may still not be finalized here, in
// which case it is a TypeRef to a legal recursive type.
}
}
}
// Instantiate super_type_arg with the current argument vector.
if (!super_type_arg.IsInstantiated()) {
if (FLAG_trace_type_finalization && super_type_arg.IsTypeRef()) {
AbstractType& ref_type = AbstractType::Handle(
zone, TypeRef::Cast(super_type_arg).type());
THR_Print(
"Instantiating TypeRef '%s': '%s'\n"
" instantiator: '%s'\n",
String::Handle(zone, super_type_arg.Name()).ToCString(),
ref_type.ToCString(), arguments.ToCString());
}
// In the typical case of an F-bounded type, the instantiation of the
// super_type_arg from arguments is a fixpoint. Take the shortcut.
// Example: class B<T>; class D<T> extends B<D<T>>;
// While finalizing D<T>, the super type arg D<T> (a typeref) gets
// instantiated from vector [T], yielding itself.
if (super_type_arg.IsTypeRef() &&
(super_type_arg.arguments() == arguments.ptr())) {
ASSERT(super_type_arg.IsBeingFinalized());
arguments.SetTypeAt(i, super_type_arg);
continue;
}
super_type_arg = super_type_arg.InstantiateFrom(
arguments, Object::null_type_arguments(), kNoneFree, Heap::kOld,
trail);
if (super_type_arg.IsBeingFinalized() &&
!super_type_arg.IsTypeParameter()) {
// The super_type_arg was instantiated from a type being finalized.
// We need to finish finalizing its type arguments, unless it is a
// type parameter, in which case there is nothing more to do.
AbstractType& unfinalized_type = AbstractType::Handle(zone);
if (super_type_arg.IsTypeRef()) {
unfinalized_type = TypeRef::Cast(super_type_arg).type();
if (unfinalized_type.IsFinalized()) {
super_type_arg.SetIsFinalized();
arguments.SetTypeAt(i, super_type_arg);
continue;
}
} else {
ASSERT(super_type_arg.IsType());
unfinalized_type = super_type_arg.ptr();
}
if (FLAG_trace_type_finalization) {
THR_Print(
"Instantiated unfinalized '%s': '%s'\n",
String::Handle(zone, unfinalized_type.Name()).ToCString(),
unfinalized_type.ToCString());
}
if (unfinalized_type.IsType()) {
CheckRecursiveType(unfinalized_type, pending_types);
pending_types->Add(unfinalized_type);
}
const Class& super_cls =
Class::Handle(zone, unfinalized_type.type_class());
const TypeArguments& super_args =
TypeArguments::Handle(zone, unfinalized_type.arguments());
// Mark as finalized before finalizing to avoid cycles.
unfinalized_type.SetIsFinalized();
// Although the instantiator is different between cls and super_cls,
// we still need to pass the current instantiation trail as to avoid
// divergence. Finalizing the type arguments of super_cls may indeed
// recursively require instantiating the same type_refs already
// present in the trail (see issue #29949).
FillAndFinalizeTypeArguments(
zone, super_cls, super_args,
super_cls.NumTypeArguments() - super_cls.NumTypeParameters(),
pending_types, trail);
if (FLAG_trace_type_finalization) {
THR_Print(
"Finalized instantiated '%s': '%s'\n",
String::Handle(zone, unfinalized_type.Name()).ToCString(),
unfinalized_type.ToCString());
}
}
}
}
arguments.SetTypeAt(i, super_type_arg);
}
FillAndFinalizeTypeArguments(zone, super_class, arguments, super_offset,
pending_types, trail);
}
}
TypeArgumentsPtr ClassFinalizer::FinalizeTypeArguments(
Zone* zone,
const TypeArguments& type_args,
FinalizationKind finalization,
PendingTypes* pending_types) {
FinalizationKind finalization) {
if (type_args.IsNull()) return TypeArguments::null();
ASSERT(type_args.ptr() != Object::empty_type_arguments().ptr());
const intptr_t len = type_args.Length();
@ -728,7 +358,7 @@ TypeArgumentsPtr ClassFinalizer::FinalizeTypeArguments(
ASSERT(finalization < kCanonicalize);
continue;
}
finalized_type = FinalizeType(type, kFinalize, pending_types);
finalized_type = FinalizeType(type, kFinalize);
if (type.ptr() != finalized_type.ptr()) {
type_args.SetTypeAt(i, finalized_type);
}
@ -740,11 +370,7 @@ TypeArgumentsPtr ClassFinalizer::FinalizeTypeArguments(
}
AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
FinalizationKind finalization,
PendingTypes* pending_types) {
// Only the 'root' type of the graph can be canonicalized, after all depending
// types have been bound checked.
ASSERT((pending_types == nullptr) || (finalization < kCanonicalize));
FinalizationKind finalization) {
if (type.IsFinalized()) {
// Ensure type is canonical if canonicalization is requested.
if ((finalization >= kCanonicalize) && !type.IsCanonical() &&
@ -766,15 +392,13 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
type.SetIsBeingFinalized();
AbstractType& ref_type =
AbstractType::Handle(zone, TypeRef::Cast(type).type());
ref_type = FinalizeType(ref_type, finalization, pending_types);
ref_type = FinalizeType(ref_type, finalization);
ASSERT(ref_type.IsFinalized());
TypeRef::Cast(type).set_type(ref_type);
ASSERT(type.IsFinalized());
return type.ptr();
}
// Recursive types must be processed in FillAndFinalizeTypeArguments() and
// cannot be encountered here.
ASSERT(!type.IsBeingFinalized());
// Mark the type as being finalized in order to detect self reference.
@ -834,28 +458,24 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
// signature, i.e. finalize the result type and parameter types of the
// signature function of this function type.
if (type.IsFunctionType()) {
return FinalizeSignature(zone, FunctionType::Cast(type), finalization,
pending_types);
return FinalizeSignature(zone, FunctionType::Cast(type), finalization);
}
if (type.IsRecordType()) {
return FinalizeRecordType(zone, RecordType::Cast(type), finalization,
pending_types);
}
// This type is the root type of the type graph if no pending types queue is
// allocated yet. A function type is a collection of types, but not a root.
const bool is_root_type = pending_types == nullptr;
if (is_root_type) {
pending_types = new PendingTypes(zone, 4);
return FinalizeRecordType(zone, RecordType::Cast(type), finalization);
}
// At this point, we can only have a Type.
ASSERT(type.IsType());
pending_types->Add(type);
const intptr_t num_expanded_type_arguments =
ExpandAndFinalizeTypeArguments(zone, type, pending_types);
TypeArguments& type_args =
TypeArguments::Handle(zone, Type::Cast(type).arguments());
ASSERT(type_args.IsNull() ||
type_args.Length() ==
Class::Handle(zone, type.type_class()).NumTypeParameters(thread));
type_args = FinalizeTypeArguments(zone, type_args, finalization);
Type::Cast(type).set_arguments(type_args);
// Self referencing types may get finalized indirectly.
if (!type.IsFinalized()) {
@ -868,9 +488,8 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
}
if (FLAG_trace_type_finalization) {
THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n",
String::Handle(zone, type.Name()).ToCString(),
num_expanded_type_arguments, type.ToCString());
THR_Print("Done finalizing type '%s': %s\n",
String::Handle(zone, type.Name()).ToCString(), type.ToCString());
}
if (finalization >= kCanonicalize) {
@ -889,19 +508,18 @@ AbstractTypePtr ClassFinalizer::FinalizeType(const AbstractType& type,
}
}
AbstractTypePtr ClassFinalizer::FinalizeSignature(Zone* zone,
const FunctionType& signature,
FinalizationKind finalization,
PendingTypes* pending_types) {
AbstractTypePtr ClassFinalizer::FinalizeSignature(
Zone* zone,
const FunctionType& signature,
FinalizationKind finalization) {
// Finalize signature type parameter upper bounds and default args.
FinalizeTypeParameters(zone, Object::null_class(), signature, finalization,
pending_types);
FinalizeTypeParameters(zone, Object::null_class(), signature, finalization);
AbstractType& type = AbstractType::Handle(zone);
AbstractType& finalized_type = AbstractType::Handle(zone);
// Finalize result type.
type = signature.result_type();
finalized_type = FinalizeType(type, kFinalize, pending_types);
finalized_type = FinalizeType(type, kFinalize);
if (finalized_type.ptr() != type.ptr()) {
signature.set_result_type(finalized_type);
}
@ -909,7 +527,7 @@ AbstractTypePtr ClassFinalizer::FinalizeSignature(Zone* zone,
const intptr_t num_parameters = signature.NumParameters();
for (intptr_t i = 0; i < num_parameters; i++) {
type = signature.ParameterTypeAt(i);
finalized_type = FinalizeType(type, kFinalize, pending_types);
finalized_type = FinalizeType(type, kFinalize);
if (type.ptr() != finalized_type.ptr()) {
signature.SetParameterTypeAt(i, finalized_type);
}
@ -930,15 +548,14 @@ AbstractTypePtr ClassFinalizer::FinalizeSignature(Zone* zone,
AbstractTypePtr ClassFinalizer::FinalizeRecordType(
Zone* zone,
const RecordType& record,
FinalizationKind finalization,
PendingTypes* pending_types) {
FinalizationKind finalization) {
AbstractType& type = AbstractType::Handle(zone);
AbstractType& finalized_type = AbstractType::Handle(zone);
// Finalize record field types.
const intptr_t num_fields = record.NumFields();
for (intptr_t i = 0; i < num_fields; ++i) {
type = record.FieldTypeAt(i);
finalized_type = FinalizeType(type, kFinalize, pending_types);
finalized_type = FinalizeType(type, kFinalize);
if (type.ptr() != finalized_type.ptr()) {
record.SetFieldTypeAt(i, finalized_type);
}
@ -1100,9 +717,9 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
ASSERT(super_class.ptr() == cls.SuperClass()); // Not modified.
ASSERT(super_class.IsNull() || super_class.is_type_finalized());
// Finalize super type.
AbstractType& super_type = AbstractType::Handle(zone, cls.super_type());
Type& super_type = Type::Handle(zone, cls.super_type());
if (!super_type.IsNull()) {
super_type = FinalizeType(super_type);
super_type ^= FinalizeType(super_type);
cls.set_super_type(super_type);
has_isolate_unsendable_pragma |=
Class::IsIsolateUnsendableDueToPragma(super_type.type_class());

View file

@ -17,8 +17,6 @@ namespace dart {
// finalized.
class ClassFinalizer : public AllStatic {
public:
typedef ZoneGrowableHandlePtrArray<const AbstractType> PendingTypes;
// Modes for finalization. The ordering is relevant.
enum FinalizationKind {
kFinalize, // Finalize type and type arguments.
@ -28,8 +26,7 @@ class ClassFinalizer : public AllStatic {
// Finalize given type.
static AbstractTypePtr FinalizeType(
const AbstractType& type,
FinalizationKind finalization = kCanonicalize,
PendingTypes* pending_types = nullptr);
FinalizationKind finalization = kCanonicalize);
// Return false if we still have classes pending to be finalized.
static bool AllClassesFinalized();
@ -83,40 +80,24 @@ class ClassFinalizer : public AllStatic {
static TypeArgumentsPtr FinalizeTypeArguments(
Zone* zone,
const TypeArguments& type_args,
FinalizationKind finalization = kCanonicalize,
PendingTypes* pending_types = nullptr);
FinalizationKind finalization = kCanonicalize);
// Finalize the types in the signature and the signature itself.
static AbstractTypePtr FinalizeSignature(
Zone* zone,
const FunctionType& signature,
FinalizationKind finalization = kCanonicalize,
PendingTypes* pending_types = nullptr);
FinalizationKind finalization = kCanonicalize);
static AbstractTypePtr FinalizeRecordType(
Zone* zone,
const RecordType& record,
FinalizationKind finalization = kCanonicalize,
PendingTypes* pending_types = nullptr);
FinalizationKind finalization = kCanonicalize);
static void FinalizeTypeParameters(
Zone* zone,
const Class& cls,
const FunctionType& signature,
FinalizationKind finalization = kCanonicalize,
PendingTypes* pending_types = nullptr);
static intptr_t ExpandAndFinalizeTypeArguments(Zone* zone,
const AbstractType& type,
PendingTypes* pending_types);
static void FillAndFinalizeTypeArguments(Zone* zone,
const Class& cls,
const TypeArguments& arguments,
intptr_t num_uninitialized_arguments,
PendingTypes* pending_types,
TrailPtr trail);
static void CheckRecursiveType(const AbstractType& type,
PendingTypes* pending_types);
FinalizationKind finalization = kCanonicalize);
#if !defined(DART_PRECOMPILED_RUNTIME)
static void FinalizeMemberTypes(const Class& cls);

View file

@ -1191,7 +1191,7 @@ void Precompiler::AddType(const AbstractType& abstype) {
const Type& type = Type::Cast(abstype);
const Class& cls = Class::Handle(Z, type.type_class());
AddTypesOf(cls);
const TypeArguments& vector = TypeArguments::Handle(Z, abstype.arguments());
const TypeArguments& vector = TypeArguments::Handle(Z, type.arguments());
AddTypeArguments(vector);
} else if (abstype.IsTypeRef()) {
AbstractType& type = AbstractType::Handle(Z);

View file

@ -631,7 +631,8 @@ void FlowGraph::AddExactnessGuard(InstanceCallInstr* call,
const AbstractType& type =
AbstractType::Handle(zone(), call->ic_data()->receivers_static_type());
ASSERT(!type.IsNull());
const TypeArguments& args = TypeArguments::Handle(zone(), type.arguments());
const TypeArguments& args = TypeArguments::Handle(
zone(), Type::Cast(type).GetInstanceTypeArguments(thread()));
Instruction* guard = new (zone()) CheckConditionInstr(
new StrictCompareInstr(call->source(), Token::kEQ_STRICT,
new (zone()) Value(load_type_args),

View file

@ -2492,6 +2492,7 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
ASSERT(type.IsInstantiated());
ASSERT(!type.IsFunctionType());
ASSERT(!type.IsRecordType());
ASSERT(type.IsType());
const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
ASSERT(type_class.NumTypeArguments() > 0);
const Type& smi_type = Type::Handle(zone(), Type::SmiType());
@ -2499,13 +2500,10 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
__ BranchIfSmi(TypeTestABI::kInstanceReg,
smi_is_ok ? is_instance_lbl : is_not_instance_lbl);
const intptr_t num_type_args = type_class.NumTypeArguments();
const intptr_t num_type_params = type_class.NumTypeParameters();
const intptr_t from_index = num_type_args - num_type_params;
const TypeArguments& type_arguments =
TypeArguments::ZoneHandle(zone(), type.arguments());
TypeArguments::ZoneHandle(zone(), Type::Cast(type).arguments());
const bool is_raw_type = type_arguments.IsNull() ||
type_arguments.IsRaw(from_index, num_type_params);
type_arguments.IsRaw(0, type_arguments.Length());
// We don't use TypeTestABI::kScratchReg as it is not defined on IA32.
// Instead, we use the subtype test cache register, as it is clobbered by the
// subtype test cache stub call anyway.

View file

@ -329,10 +329,9 @@ bool HierarchyInfo::CanUseSubtypeRangeCheckFor(const AbstractType& type) {
if (type_class.IsGeneric()) {
// TODO(kustermann): We might want to consider extending this when the type
// arguments are not "dynamic" but instantiated-to-bounds.
const Type& rare_type =
Type::Handle(zone, Type::RawCast(type_class.RareType()));
const Type& rare_type = Type::Handle(zone, type_class.RareType());
if (!rare_type.IsSubtypeOf(type, Heap::kNew)) {
ASSERT(type.arguments() != TypeArguments::null());
ASSERT(Type::Cast(type).arguments() != TypeArguments::null());
return false;
}
}
@ -367,22 +366,20 @@ bool HierarchyInfo::CanUseGenericSubtypeRangeCheckFor(
Zone* zone = thread()->zone();
const Class& type_class = Class::Handle(zone, type.type_class());
const intptr_t num_type_parameters = type_class.NumTypeParameters();
const intptr_t num_type_arguments = type_class.NumTypeArguments();
// This function should only be called for generic classes.
ASSERT(type_class.NumTypeParameters() > 0 &&
type.arguments() != TypeArguments::null());
Type::Cast(type).arguments() != TypeArguments::null());
const TypeArguments& ta =
TypeArguments::Handle(zone, Type::Cast(type).arguments());
ASSERT(ta.Length() == num_type_arguments);
ASSERT(ta.Length() == num_type_parameters);
// The last [num_type_parameters] entries in the [TypeArguments] vector [ta]
// are the values we have to check against. Ensure we can handle all of them
// Ensure we can handle all type arguments
// via [CidRange]-based checks or that it is a type parameter.
AbstractType& type_arg = AbstractType::Handle(zone);
for (intptr_t i = 0; i < num_type_parameters; ++i) {
type_arg = ta.TypeAt(num_type_arguments - num_type_parameters + i);
type_arg = ta.TypeAt(i);
if (!CanUseSubtypeRangeCheckFor(type_arg) && !type_arg.IsTypeParameter()) {
return false;
}
@ -2875,7 +2872,8 @@ Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
const Field& field = slot.field();
if (field.static_type_exactness_state().IsTriviallyExact()) {
return flow_graph->GetConstant(TypeArguments::Handle(
AbstractType::Handle(field.type()).arguments()));
Type::Cast(AbstractType::Handle(field.type()))
.GetInstanceTypeArguments(flow_graph->thread())));
}
break;
}
@ -2967,7 +2965,8 @@ Definition* AssertAssignableInstr::Canonicalize(FlowGraph* flow_graph) {
// be located in the unreachable part of the graph (e.g.
// it might be dominated by CheckClass that always fails).
// This means that the code below must guard against such possibility.
Zone* Z = Thread::Current()->zone();
Thread* thread = Thread::Current();
Zone* Z = thread->zone();
const TypeArguments* instantiator_type_args = nullptr;
const TypeArguments* function_type_args = nullptr;
@ -3009,8 +3008,9 @@ Definition* AssertAssignableInstr::Canonicalize(FlowGraph* flow_graph) {
.static_type_exactness_state()
.IsHasExactSuperClass()) {
instantiator_type_args = &TypeArguments::Handle(
Z, AbstractType::Handle(Z, load_field->slot().field().type())
.arguments());
Z, Type::Cast(AbstractType::Handle(
Z, load_field->slot().field().type()))
.GetInstanceTypeArguments(thread));
}
}
}

View file

@ -2572,9 +2572,11 @@ void GuardFieldTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// At this point temp is known to be type arguments offset in words.
__ movq(temp, compiler::FieldAddress(value_reg, temp,
TIMES_COMPRESSED_WORD_SIZE, 0));
__ CompareObject(temp, TypeArguments::ZoneHandle(
compiler->zone(),
AbstractType::Handle(field().type()).arguments()));
__ CompareObject(
temp,
TypeArguments::ZoneHandle(
compiler->zone(), Type::Cast(AbstractType::Handle(field().type()))
.GetInstanceTypeArguments(compiler->thread())));
if (deopt != nullptr) {
__ j(NOT_EQUAL, deopt);
} else {

View file

@ -2829,7 +2829,6 @@ void LoadFieldInstr::InferRange(RangeAnalysis* analysis, Range* range) {
case Slot::Kind::kSuspendState_then_callback:
case Slot::Kind::kSuspendState_error_callback:
case Slot::Kind::kTypedDataView_typed_data:
case Slot::Kind::kType_arguments:
case Slot::Kind::kTypeArgumentsIndex:
case Slot::Kind::kTypeParameters_names:
case Slot::Kind::kTypeParameters_flags:

View file

@ -196,7 +196,6 @@ bool Slot::IsImmutableLengthSlot() const {
case Slot::Kind::kSuspendState_function_data:
case Slot::Kind::kSuspendState_then_callback:
case Slot::Kind::kSuspendState_error_callback:
case Slot::Kind::kType_arguments:
case Slot::Kind::kTypeArgumentsIndex:
case Slot::Kind::kTypeParameters_names:
case Slot::Kind::kTypeParameters_flags:

View file

@ -78,7 +78,6 @@ class ParsedFunction;
V(SuspendState, UntaggedSuspendState, function_data, Dynamic, VAR) \
V(SuspendState, UntaggedSuspendState, then_callback, Closure, VAR) \
V(SuspendState, UntaggedSuspendState, error_callback, Closure, VAR) \
V(Type, UntaggedType, arguments, TypeArguments, FINAL) \
V(TypeParameters, UntaggedTypeParameters, flags, Array, FINAL) \
V(TypeParameters, UntaggedTypeParameters, bounds, TypeArguments, FINAL) \
V(TypeParameters, UntaggedTypeParameters, defaults, TypeArguments, FINAL) \

View file

@ -1520,14 +1520,18 @@ static CompileType ComputeListFactoryType(CompileType* inferred_type,
if ((cid == kGrowableObjectArrayCid || cid == kArrayCid ||
cid == kImmutableArrayCid) &&
type_args_value->BindsToConstant()) {
const auto& type_args =
type_args_value->BoundConstant().IsNull()
? TypeArguments::null_type_arguments()
: TypeArguments::Cast(type_args_value->BoundConstant());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Class& cls =
Class::Handle(IsolateGroup::Current()->class_table()->At(cid));
Type& type =
Type::ZoneHandle(Type::New(cls, type_args, Nullability::kNonNullable));
Class::Handle(zone, thread->isolate_group()->class_table()->At(cid));
auto& type_args = TypeArguments::Handle(zone);
if (!type_args_value->BoundConstant().IsNull()) {
type_args ^= type_args_value->BoundConstant().ptr();
ASSERT(type_args.Length() >= cls.NumTypeArguments());
type_args = type_args.FromInstanceTypeArguments(thread, cls);
}
Type& type = Type::ZoneHandle(
zone, Type::New(cls, type_args, Nullability::kNonNullable));
ASSERT(type.IsInstantiated());
type.SetIsFinalized();
return CompileType(CompileType::kCannotBeNull,
@ -1927,7 +1931,8 @@ static AbstractTypePtr ExtractElementTypeFromArrayType(
cid == kImmutableArrayCid ||
array_type.type_class() ==
IsolateGroup::Current()->object_store()->list_class()) {
const auto& type_args = TypeArguments::Handle(array_type.arguments());
const auto& type_args =
TypeArguments::Handle(Type::Cast(array_type).arguments());
return type_args.TypeAtNullSafe(Array::kElementTypeTypeArgPos);
}
return Object::dynamic_type().ptr();

View file

@ -1049,12 +1049,10 @@ BoolPtr CallSpecializer::InstanceOfAsBool(
if (num_type_args > 0) {
// Only raw types can be directly compared, thus disregarding type
// arguments.
const intptr_t num_type_params = type_class.NumTypeParameters();
const intptr_t from_index = num_type_args - num_type_params;
const TypeArguments& type_arguments =
TypeArguments::Handle(Z, type.arguments());
TypeArguments::Handle(Z, Type::Cast(type).arguments());
const bool is_raw_type = type_arguments.IsNull() ||
type_arguments.IsRaw(from_index, num_type_params);
type_arguments.IsRaw(0, type_arguments.Length());
if (!is_raw_type) {
// Unknown result.
return Bool::null();
@ -1120,12 +1118,10 @@ bool CallSpecializer::TypeCheckAsClassEquality(const AbstractType& type,
if (num_type_args > 0) {
// Only raw types can be directly compared, thus disregarding type
// arguments.
const intptr_t num_type_params = type_class.NumTypeParameters();
const intptr_t from_index = num_type_args - num_type_params;
const TypeArguments& type_arguments =
TypeArguments::Handle(type.arguments());
TypeArguments::Handle(Type::Cast(type).arguments());
const bool is_raw_type = type_arguments.IsNull() ||
type_arguments.IsRaw(from_index, num_type_params);
type_arguments.IsRaw(0, type_arguments.Length());
if (!is_raw_type) {
return false;
}

View file

@ -46,7 +46,8 @@ const NativeFunctionType* NativeFunctionTypeFromFunctionType(
arg_type = c_signature.ParameterTypeAt(i + kNativeParamsStartAt);
const bool varargs = arg_type.type_class() == object_store->varargs_class();
if (varargs) {
arg_type = TypeArguments::Handle(zone, arg_type.arguments()).TypeAt(0);
arg_type = TypeArguments::Handle(zone, Type::Cast(arg_type).arguments())
.TypeAt(0);
variadic_arguments_index = i;
ASSERT(arg_type.IsRecordType());
const auto& record_type = RecordType::Cast(arg_type);
@ -122,7 +123,8 @@ AbstractTypePtr BaseMarshaller::CType(intptr_t arg_index) const {
if (has_varargs && real_arg_index >= last_param_index) {
// The C-type is nested in a VarArgs.
const auto& var_args_type_arg = AbstractType::Handle(
zone, TypeArguments::Handle(zone, last_arg_type.arguments()).TypeAt(0));
zone, TypeArguments::Handle(zone, Type::Cast(last_arg_type).arguments())
.TypeAt(0));
if (var_args_type_arg.IsRecordType()) {
const intptr_t index_in_record = real_arg_index - last_param_index;
const auto& record_type = RecordType::Cast(var_args_type_arg);

View file

@ -315,9 +315,8 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_index) {
AbstractType& type = type_translator.BuildType();
type_arguments.SetTypeAt(0, type);
// Instantiate class.
type = Type::New(list_class, type_arguments);
type = ClassFinalizer::FinalizeType(type, ClassFinalizer::kCanonicalize);
type_arguments = type.arguments();
type_arguments =
list_class.GetInstanceTypeArguments(H.thread(), type_arguments);
// Fill array with constant elements.
const intptr_t length = reader.ReadUInt();
const Array& array =
@ -354,9 +353,8 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_index) {
type_arguments.SetTypeAt(1, type);
// Instantiate class.
type = Type::New(map_class, type_arguments);
type = ClassFinalizer::FinalizeType(type, ClassFinalizer::kCanonicalize);
type_arguments = type.arguments();
type_arguments =
map_class.GetInstanceTypeArguments(H.thread(), type_arguments);
// Fill map with constant elements.
const auto& map = Map::Handle(Z, ConstMap::NewUninitialized(Heap::kOld));
@ -445,9 +443,8 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_index) {
type_arguments.SetTypeAt(0, type);
// Instantiate class.
type = Type::New(set_class, type_arguments);
type = ClassFinalizer::FinalizeType(type, ClassFinalizer::kCanonicalize);
type_arguments = type.arguments();
type_arguments =
set_class.GetInstanceTypeArguments(H.thread(), type_arguments);
// Fill set with constant elements.
const auto& set = Set::Handle(Z, ConstSet::NewUninitialized(Heap::kOld));
@ -503,10 +500,8 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_index) {
type_arguments.SetTypeAt(j, type_translator.BuildType());
}
// Instantiate class.
auto& type = AbstractType::Handle(Z, Type::New(klass, type_arguments));
type =
ClassFinalizer::FinalizeType(type, ClassFinalizer::kCanonicalize);
type_arguments = type.arguments();
type_arguments =
klass.GetInstanceTypeArguments(H.thread(), type_arguments);
instance.SetTypeArguments(type_arguments);
} else {
ASSERT(number_of_type_arguments == 0);

View file

@ -567,7 +567,7 @@ Fragment StreamingFlowGraphBuilder::InitSuspendableFunction(
(Class::Handle(Z, result_type.type_class()).IsFutureClass() ||
result_type.IsFutureOrType())) {
ASSERT(result_type.IsFinalized());
type_args = result_type.arguments();
type_args = Type::Cast(result_type).GetInstanceTypeArguments(H.thread());
}
body += TranslateInstantiatedTypeArguments(type_args);
@ -581,7 +581,7 @@ Fragment StreamingFlowGraphBuilder::InitSuspendableFunction(
if (result_type.IsType() &&
(result_type.type_class() == IG->object_store()->stream_class())) {
ASSERT(result_type.IsFinalized());
type_args = result_type.arguments();
type_args = Type::Cast(result_type).GetInstanceTypeArguments(H.thread());
}
body += TranslateInstantiatedTypeArguments(type_args);
@ -599,7 +599,7 @@ Fragment StreamingFlowGraphBuilder::InitSuspendableFunction(
if (result_type.IsType() &&
(result_type.type_class() == IG->object_store()->iterable_class())) {
ASSERT(result_type.IsFinalized());
type_args = result_type.arguments();
type_args = Type::Cast(result_type).GetInstanceTypeArguments(H.thread());
}
body += TranslateInstantiatedTypeArguments(type_args);
@ -3496,15 +3496,9 @@ Fragment StreamingFlowGraphBuilder::BuildConstructorInvocation(
if (klass.NumTypeArguments() > 0) {
if (!klass.IsGeneric()) {
Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).ptr());
// TODO(27590): Can we move this code into [ReceiverType]?
type ^= ClassFinalizer::FinalizeType(type, ClassFinalizer::kFinalize);
TypeArguments& canonicalized_type_arguments =
TypeArguments::ZoneHandle(Z, type.arguments());
canonicalized_type_arguments =
canonicalized_type_arguments.Canonicalize(thread(), nullptr);
instructions += Constant(canonicalized_type_arguments);
const TypeArguments& type_arguments = TypeArguments::ZoneHandle(
Z, klass.GetDeclarationInstanceTypeArguments());
instructions += Constant(type_arguments);
} else {
const TypeArguments& type_arguments =
PeekArgumentsInstantiatedType(klass);
@ -4471,7 +4465,8 @@ Fragment StreamingFlowGraphBuilder::BuildAwaitExpression(
FATAL("Unexpected type for runtime check in await: %s", type.ToCString());
}
ASSERT(type.IsFinalized());
const auto& type_args = TypeArguments::ZoneHandle(Z, type.arguments());
const auto& type_args =
TypeArguments::ZoneHandle(Z, Type::Cast(type).arguments());
if (!type_args.IsNull()) {
const auto& type_arg = AbstractType::Handle(Z, type_args.TypeAt(0));
if (!type_arg.IsTopTypeForSubtyping()) {

View file

@ -3483,7 +3483,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodForwarder(
Function::ZoneHandle(Z, function.parent_function());
const Class& owner = Class::ZoneHandle(Z, parent.Owner());
AbstractType& type = AbstractType::ZoneHandle(Z);
type = Type::New(owner, TypeArguments::Handle(Z));
type = Type::New(owner, Object::null_type_arguments());
type = ClassFinalizer::FinalizeType(type);
body += Constant(type);
} else {
@ -3740,8 +3740,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
// TranslateInstantiatedTypeArguments is smart enough to
// avoid instantiation and reuse passed function type arguments
// if there are no extra type arguments in the flattened vector.
const auto& instantiated_type_arguments =
TypeArguments::ZoneHandle(Z, result_type.arguments());
const auto& instantiated_type_arguments = TypeArguments::ZoneHandle(
Z, Type::Cast(result_type).GetInstanceTypeArguments(H.thread()));
closure +=
TranslateInstantiatedTypeArguments(instantiated_type_arguments);
} else {
@ -3760,8 +3760,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
const Class& cls = Class::ZoneHandle(Z, target.Owner());
if (cls.NumTypeArguments() > 0) {
if (!function.IsGeneric()) {
Type& cls_type = Type::Handle(Z, cls.DeclarationType());
closure += Constant(TypeArguments::ZoneHandle(Z, cls_type.arguments()));
closure += Constant(TypeArguments::ZoneHandle(
Z, cls.GetDeclarationInstanceTypeArguments()));
}
closure += AllocateObject(function.token_pos(), cls, 1);
} else {

View file

@ -3606,16 +3606,8 @@ const TypeArguments& TypeTranslator::BuildInstantiatedTypeArguments(
return type_arguments;
}
// We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
// finalize the argument types.
// (This can for example make the [type_arguments] vector larger)
Type& type = Type::Handle(Z, Type::New(receiver_class, type_arguments));
if (finalize_) {
type ^= ClassFinalizer::FinalizeType(type);
}
const TypeArguments& instantiated_type_arguments =
TypeArguments::ZoneHandle(Z, type.arguments());
const TypeArguments& instantiated_type_arguments = TypeArguments::ZoneHandle(
Z, receiver_class.GetInstanceTypeArguments(H.thread(), type_arguments));
return instantiated_type_arguments;
}

View file

@ -135,10 +135,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
92;
96;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 104;
Class_host_type_arguments_field_offset_in_words_offset = 108;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 4;
static constexpr dart::compiler::target::word Closure_context_offset = 20;
@ -602,7 +602,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_header_size = 12;
static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 116;
static constexpr dart::compiler::target::word Class_InstanceSize = 120;
static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@ -816,10 +816,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
168;
176;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 180;
Class_host_type_arguments_field_offset_in_words_offset = 188;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
@ -1290,7 +1290,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 192;
static constexpr dart::compiler::target::word Class_InstanceSize = 200;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -1502,10 +1502,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
92;
96;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 104;
Class_host_type_arguments_field_offset_in_words_offset = 108;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 4;
static constexpr dart::compiler::target::word Closure_context_offset = 20;
@ -1969,7 +1969,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_header_size = 12;
static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 116;
static constexpr dart::compiler::target::word Class_InstanceSize = 120;
static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@ -2183,10 +2183,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
168;
176;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 180;
Class_host_type_arguments_field_offset_in_words_offset = 188;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
@ -2658,7 +2658,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 192;
static constexpr dart::compiler::target::word Class_InstanceSize = 200;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -2870,10 +2870,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
96;
100;
static constexpr dart::compiler::target::word Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 108;
Class_host_type_arguments_field_offset_in_words_offset = 112;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word Closure_context_offset = 24;
@ -3345,7 +3345,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 16;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 120;
static constexpr dart::compiler::target::word Class_InstanceSize = 128;
static constexpr dart::compiler::target::word Closure_InstanceSize = 32;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 24;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -3557,10 +3557,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
96;
100;
static constexpr dart::compiler::target::word Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 108;
Class_host_type_arguments_field_offset_in_words_offset = 112;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word Closure_context_offset = 24;
@ -4033,7 +4033,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 16;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 120;
static constexpr dart::compiler::target::word Class_InstanceSize = 128;
static constexpr dart::compiler::target::word Closure_InstanceSize = 32;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 24;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -4245,10 +4245,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
92;
96;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 104;
Class_host_type_arguments_field_offset_in_words_offset = 108;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 4;
static constexpr dart::compiler::target::word Closure_context_offset = 20;
@ -4714,7 +4714,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_header_size = 12;
static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 116;
static constexpr dart::compiler::target::word Class_InstanceSize = 120;
static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@ -4928,10 +4928,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
104;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
168;
176;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 180;
Class_host_type_arguments_field_offset_in_words_offset = 188;
static constexpr dart::compiler::target::word
ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
@ -5403,7 +5403,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 192;
static constexpr dart::compiler::target::word Class_InstanceSize = 200;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -5614,10 +5614,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
48;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
92;
static constexpr dart::compiler::target::word Class_super_type_offset = 40;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 100;
Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word Closure_context_offset = 20;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 12;
@ -6076,7 +6076,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_header_size = 12;
static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 112;
static constexpr dart::compiler::target::word Class_InstanceSize = 116;
static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@ -6287,10 +6287,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
96;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
160;
168;
static constexpr dart::compiler::target::word Class_super_type_offset = 80;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 172;
Class_host_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 24;
@ -6756,7 +6756,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 184;
static constexpr dart::compiler::target::word Class_InstanceSize = 192;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -6965,10 +6965,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
48;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
92;
static constexpr dart::compiler::target::word Class_super_type_offset = 40;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 100;
Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word Closure_context_offset = 20;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 12;
@ -7427,7 +7427,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_header_size = 12;
static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 112;
static constexpr dart::compiler::target::word Class_InstanceSize = 116;
static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@ -7638,10 +7638,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
96;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
160;
168;
static constexpr dart::compiler::target::word Class_super_type_offset = 80;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 172;
Class_host_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 24;
@ -8108,7 +8108,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 184;
static constexpr dart::compiler::target::word Class_InstanceSize = 192;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -8317,10 +8317,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
92;
96;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 104;
Class_host_type_arguments_field_offset_in_words_offset = 108;
static constexpr dart::compiler::target::word Closure_context_offset = 24;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 16;
@ -8996,10 +8996,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
52;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
92;
96;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 104;
Class_host_type_arguments_field_offset_in_words_offset = 108;
static constexpr dart::compiler::target::word Closure_context_offset = 24;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 16;
@ -9676,10 +9676,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
48;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
88;
92;
static constexpr dart::compiler::target::word Class_super_type_offset = 40;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 100;
Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word Closure_context_offset = 20;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 12;
@ -10140,7 +10140,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_header_size = 12;
static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 112;
static constexpr dart::compiler::target::word Class_InstanceSize = 116;
static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@ -10351,10 +10351,10 @@ static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
96;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
160;
168;
static constexpr dart::compiler::target::word Class_super_type_offset = 80;
static constexpr dart::compiler::target::word
Class_host_type_arguments_field_offset_in_words_offset = 172;
Class_host_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 24;
@ -10821,7 +10821,7 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word Class_InstanceSize = 184;
static constexpr dart::compiler::target::word Class_InstanceSize = 192;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
static constexpr dart::compiler::target::word ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@ -11044,10 +11044,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 52;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 72;
AOT_Class_num_type_arguments_offset = 76;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 84;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 88;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 4;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
@ -11565,7 +11565,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 92;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 8;
@ -11801,10 +11801,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 140;
AOT_Class_num_type_arguments_offset = 148;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 152;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 160;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@ -12326,7 +12326,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 160;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 168;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -12565,10 +12565,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 140;
AOT_Class_num_type_arguments_offset = 148;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 152;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 160;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@ -13091,7 +13091,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 160;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 168;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -13327,10 +13327,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 56;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 76;
AOT_Class_num_type_arguments_offset = 80;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 88;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 92;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 24;
@ -13853,7 +13853,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 16;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 104;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -14089,10 +14089,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 56;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 76;
AOT_Class_num_type_arguments_offset = 80;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 88;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 92;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 24;
@ -14616,7 +14616,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 16;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 104;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -14851,10 +14851,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 52;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 72;
AOT_Class_num_type_arguments_offset = 76;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 84;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 88;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 4;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
@ -15374,7 +15374,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 92;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 8;
@ -15610,10 +15610,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 104;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 140;
AOT_Class_num_type_arguments_offset = 148;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 152;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 160;
static constexpr dart::compiler::target::word
AOT_ClassTable_allocation_tracing_state_table_offset = 8;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@ -16136,7 +16136,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 160;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 168;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -16370,10 +16370,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 48;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 60;
AOT_Class_num_type_arguments_offset = 64;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 40;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 72;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 76;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 12;
@ -16885,7 +16885,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 80;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 84;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 8;
@ -17118,10 +17118,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 96;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 116;
AOT_Class_num_type_arguments_offset = 124;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 80;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 128;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 136;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 24;
@ -17637,7 +17637,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 136;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 144;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -17873,10 +17873,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 96;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 116;
AOT_Class_num_type_arguments_offset = 124;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 80;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 128;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 136;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 24;
@ -18393,7 +18393,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 136;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 144;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
@ -18626,10 +18626,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 52;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 64;
AOT_Class_num_type_arguments_offset = 68;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 76;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 80;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 24;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 16;
@ -19379,10 +19379,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 52;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 64;
AOT_Class_num_type_arguments_offset = 68;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 76;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 80;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 24;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 16;
@ -20132,10 +20132,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 48;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 60;
AOT_Class_num_type_arguments_offset = 64;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 40;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 72;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 76;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 12;
@ -20649,7 +20649,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 80;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 84;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 20;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 8;
@ -20882,10 +20882,10 @@ static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
static constexpr dart::compiler::target::word
AOT_Class_declaration_type_offset = 96;
static constexpr dart::compiler::target::word
AOT_Class_num_type_arguments_offset = 116;
AOT_Class_num_type_arguments_offset = 124;
static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 80;
static constexpr dart::compiler::target::word
AOT_Class_host_type_arguments_field_offset_in_words_offset = 128;
AOT_Class_host_type_arguments_field_offset_in_words_offset = 136;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 24;
@ -21402,7 +21402,7 @@ static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 136;
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 144;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;

View file

@ -4362,7 +4362,7 @@ DART_EXPORT Dart_Handle Dart_New(Dart_Handle type,
CHECK_ERROR_HANDLE(cls.EnsureIsAllocateFinalized(T));
TypeArguments& type_arguments =
TypeArguments::Handle(Z, type_obj.arguments());
TypeArguments::Handle(Z, type_obj.GetInstanceTypeArguments(T));
const String& base_constructor_name = String::Handle(Z, cls.Name());
@ -4508,7 +4508,7 @@ DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type) {
const Class& cls = Class::Handle(Z, type_obj.type_class());
const TypeArguments& type_arguments =
TypeArguments::Handle(Z, type_obj.arguments());
TypeArguments::Handle(Z, type_obj.GetInstanceTypeArguments(T));
CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
#if defined(DEBUG)
@ -4621,8 +4621,10 @@ DART_EXPORT Dart_Handle Dart_InvokeConstructor(Dart_Handle object,
strings.SetAt(2, constructor_name);
}
const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
const TypeArguments& type_arguments =
TypeArguments::Handle(Z, type_obj.arguments());
TypeArguments& type_arguments = TypeArguments::Handle(Z);
if (type_obj.IsType()) {
type_arguments = Type::Cast(type_obj).GetInstanceTypeArguments(T);
}
const Function& constructor =
Function::Handle(Z, cls.LookupFunctionAllowPrivate(dot_name));
const int kTypeArgsLen = 0;

View file

@ -1275,7 +1275,7 @@ void KernelLoader::LoadPreliminaryClass(ClassHelper* class_helper,
if (type_tag == kSomething) {
AbstractType& super_type =
T.BuildTypeWithoutFinalization(); // read super class type (part 2).
klass->set_super_type(super_type);
klass->set_super_type(Type::Cast(super_type));
}
class_helper->SetJustRead(ClassHelper::kSuperClass);

View file

@ -1850,7 +1850,7 @@ ErrorPtr Object::Init(IsolateGroup* isolate_group,
// patching. The array type allocated below represents the raw type _List
// and not _List<E> as we could expect. Use with caution.
type = Type::New(Class::Handle(zone, cls.ptr()),
TypeArguments::Handle(zone), Nullability::kNonNullable);
Object::null_type_arguments(), Nullability::kNonNullable);
type.SetIsFinalized();
type ^= type.Canonicalize(thread, nullptr);
object_store->set_array_type(type);
@ -3055,14 +3055,15 @@ bool Class::IsInFullSnapshot() const {
untag()->library()->untag()->flags_);
}
AbstractTypePtr Class::RareType() const {
TypePtr Class::RareType() const {
if (!IsGeneric() && !IsClosureClass()) {
return DeclarationType();
}
ASSERT(is_declaration_loaded());
const Type& type = Type::Handle(Type::New(
*this, Object::null_type_arguments(), Nullability::kNonNullable));
return ClassFinalizer::FinalizeType(type);
Type& type = Type::Handle(Type::New(*this, Object::null_type_arguments(),
Nullability::kNonNullable));
type ^= ClassFinalizer::FinalizeType(type);
return type.ptr();
}
template <class FakeObject, class TargetFakeObject>
@ -3457,6 +3458,94 @@ void Class::set_invocation_dispatcher_cache(const Array& cache) const {
cache.ptr());
}
void Class::set_declaration_instance_type_arguments(
const TypeArguments& value) const {
ASSERT(value.IsNull() || (value.IsCanonical() && value.IsOld()));
ASSERT((declaration_instance_type_arguments() == TypeArguments::null()) ||
(declaration_instance_type_arguments() == value.ptr()));
untag()->set_declaration_instance_type_arguments<std::memory_order_release>(
value.ptr());
}
TypeArgumentsPtr Class::GetDeclarationInstanceTypeArguments() const {
const intptr_t num_type_arguments = NumTypeArguments();
if (num_type_arguments == 0) {
return TypeArguments::null();
}
if (declaration_instance_type_arguments() != TypeArguments::null()) {
return declaration_instance_type_arguments();
}
Thread* thread = Thread::Current();
SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
if (declaration_instance_type_arguments() != TypeArguments::null()) {
return declaration_instance_type_arguments();
}
Zone* zone = thread->zone();
auto& args = TypeArguments::Handle(zone);
auto& type = AbstractType::Handle(zone);
const intptr_t num_type_parameters = NumTypeParameters(thread);
if (num_type_arguments == num_type_parameters) {
type = DeclarationType();
args = Type::Cast(type).arguments();
} else {
type = super_type();
const auto& super_args = TypeArguments::Handle(
zone, Type::Cast(type).GetInstanceTypeArguments(thread));
if ((num_type_parameters == 0) ||
(!super_args.IsNull() && (super_args.Length() == num_type_arguments))) {
args = super_args.ptr();
} else {
args = TypeArguments::New(num_type_arguments);
const intptr_t offset = num_type_arguments - num_type_parameters;
for (intptr_t i = 0; i < offset; ++i) {
type = super_args.TypeAtNullSafe(i);
args.SetTypeAt(i, type);
}
type = DeclarationType();
const auto& decl_args =
TypeArguments::Handle(zone, Type::Cast(type).arguments());
for (intptr_t i = 0; i < num_type_parameters; ++i) {
type = decl_args.TypeAt(i);
args.SetTypeAt(offset + i, type);
}
}
}
args = args.Canonicalize(thread, nullptr);
set_declaration_instance_type_arguments(args);
return args.ptr();
}
TypeArgumentsPtr Class::GetInstanceTypeArguments(
Thread* thread,
const TypeArguments& type_arguments,
bool canonicalize) const {
const intptr_t num_type_arguments = NumTypeArguments();
if (num_type_arguments == 0) {
return TypeArguments::null();
}
Zone* zone = thread->zone();
auto& args = TypeArguments::Handle(zone);
const intptr_t num_type_parameters = NumTypeParameters(thread);
ASSERT(type_arguments.IsNull() ||
type_arguments.Length() == num_type_parameters);
if (num_type_arguments == num_type_parameters) {
args = type_arguments.ptr();
} else {
args = GetDeclarationInstanceTypeArguments();
if (num_type_parameters == 0) {
return args.ptr();
}
args = args.InstantiateFrom(
TypeArguments::Handle(
zone, type_arguments.ToInstantiatorTypeArguments(thread, *this)),
Object::null_type_arguments(), kAllFree, Heap::kOld);
}
if (canonicalize) {
args = args.Canonicalize(thread, nullptr);
}
return args.ptr();
}
intptr_t Class::NumTypeParameters(Thread* thread) const {
if (!is_declaration_loaded()) {
ASSERT(is_prefinalized());
@ -3488,9 +3577,7 @@ intptr_t Class::ComputeNumTypeArguments() const {
return num_type_params;
}
const auto& sup_type = AbstractType::Handle(zone, super_type());
ASSERT(sup_type.IsType());
const auto& sup_type = Type::Handle(zone, super_type());
const auto& sup_class = Class::Handle(zone, sup_type.type_class());
const intptr_t sup_class_num_type_args = sup_class.NumTypeArguments();
if (num_type_params == 0) {
@ -3505,13 +3592,6 @@ intptr_t Class::ComputeNumTypeArguments() const {
}
const intptr_t sup_type_args_length = sup_type_args.Length();
// At this point, the super type may or may not be finalized. In either case,
// the result of this function must remain the same.
// The value of num_sup_type_args may increase when the super type is
// finalized, but the last [sup_type_args_length] type arguments will not be
// modified by finalization, only shifted to higher indices in the vector.
// The super type may not even be resolved yet. This is not necessary, since
// we only check for matching type parameters, which are resolved by default.
// Determine the maximum overlap of a prefix of the vector consisting of the
// type parameters of this class with a suffix of the vector consisting of the
// type arguments of the super type of this class.
@ -3529,11 +3609,8 @@ intptr_t Class::ComputeNumTypeArguments() const {
for (; i < num_overlapping_type_args; i++) {
sup_type_arg = sup_type_args.TypeAt(sup_type_args_length -
num_overlapping_type_args + i);
// 'sup_type_arg' can be null if type arguments are currently being
// finalized in ClassFinalizer::ExpandAndFinalizeTypeArguments.
// Type arguments which are not filled yet do not correspond to
// the type parameters and cannot be reused.
if (sup_type_arg.IsNull() || !sup_type_arg.IsTypeParameter()) break;
ASSERT(!sup_type_arg.IsNull());
if (!sup_type_arg.IsTypeParameter()) break;
// The only type parameters appearing in the type arguments of the super
// type are those declared by this class. Their finalized indices depend
// on the number of type arguments being computed here. Therefore, they
@ -3600,8 +3677,8 @@ ClassPtr Class::SuperClass(ClassTable* class_table /* = nullptr */) const {
return class_table->At(type_class_id);
}
void Class::set_super_type(const AbstractType& value) const {
ASSERT(value.IsNull() || (value.IsType() && !value.IsDynamicType()));
void Class::set_super_type(const Type& value) const {
ASSERT(value.IsNull() || !value.IsDynamicType());
untag()->set_super_type(value.ptr());
}
@ -5697,6 +5774,7 @@ bool Class::IsFutureClass() const {
// Type T0 is specified by class 'cls' parameterized with 'type_arguments' and
// by 'nullability', and type T1 is specified by 'other' and must have a type
// class.
// [type_arguments] should be a flattened instance type arguments vector.
bool Class::IsSubtypeOf(const Class& cls,
const TypeArguments& type_arguments,
Nullability nullability,
@ -5707,6 +5785,8 @@ bool Class::IsSubtypeOf(const Class& cls,
classid_t this_cid = cls.id();
ASSERT(this_cid != kNullCid && this_cid != kNeverCid &&
this_cid != kDynamicCid && this_cid != kVoidCid);
ASSERT(type_arguments.IsNull() ||
(type_arguments.Length() >= cls.NumTypeArguments()));
// Type T1 must have a type class (e.g. not a type param or a function type).
ASSERT(other.HasTypeClass());
const classid_t other_cid = other.type_class_id();
@ -5804,19 +5884,18 @@ bool Class::IsSubtypeOf(const Class& cls,
if (num_type_params == 0) {
return true;
}
const intptr_t num_type_args = this_class.NumTypeArguments();
const intptr_t from_index = num_type_args - num_type_params;
// Since we do not truncate the type argument vector of a subclass (see
// below), we only check a subvector of the proper length.
// Check for covariance.
if (other_type_arguments.IsNull()) {
return true;
}
const intptr_t num_type_args = this_class.NumTypeArguments();
const intptr_t from_index = num_type_args - num_type_params;
ASSERT(other_type_arguments.Length() == num_type_params);
AbstractType& type = AbstractType::Handle(zone);
AbstractType& other_type = AbstractType::Handle(zone);
for (intptr_t i = 0; i < num_type_params; ++i) {
type = type_arguments.TypeAtNullSafe(from_index + i);
other_type = other_type_arguments.TypeAt(from_index + i);
other_type = other_type_arguments.TypeAt(i);
ASSERT(!type.IsNull() && !other_type.IsNull());
if (!type.IsSubtypeOf(other_type, space, trail)) {
return false;
@ -5833,7 +5912,7 @@ bool Class::IsSubtypeOf(const Class& cls,
// Check for 'direct super type' specified in the implements clause
// and check for transitivity at the same time.
Array& interfaces = Array::Handle(zone, this_class.interfaces());
AbstractType& interface = AbstractType::Handle(zone);
Type& interface = Type::Handle(zone);
Class& interface_class = Class::Handle(zone);
TypeArguments& interface_args = TypeArguments::Handle(zone);
for (intptr_t i = 0; i < interfaces.Length(); i++) {
@ -5853,6 +5932,8 @@ bool Class::IsSubtypeOf(const Class& cls,
interface_args = interface_args.InstantiateFrom(
type_arguments, Object::null_type_arguments(), kNoneFree, space);
}
interface_args = interface_class.GetInstanceTypeArguments(
thread, interface_args, /*canonicalize=*/false);
// In Dart 2, implementing Function has no meaning.
// TODO(regis): Can we encounter and skip Object as well?
if (interface_class.IsDartFunctionClass()) {
@ -7238,10 +7319,10 @@ bool TypeArguments::CanShareInstantiatorTypeArguments(
if (first_type_param_offset == 0) {
return true;
}
AbstractType& super_type =
AbstractType::Handle(instantiator_class.super_type());
Type& super_type = Type::Handle(instantiator_class.super_type());
const TypeArguments& super_type_args =
TypeArguments::Handle(super_type.arguments());
TypeArguments::Handle(super_type.GetInstanceTypeArguments(
Thread::Current(), /*canonicalize=*/false));
if (super_type_args.IsNull()) {
ASSERT(!IsUninstantiatedIdentity());
return false;
@ -7571,6 +7652,57 @@ TypeArgumentsPtr TypeArguments::Canonicalize(Thread* thread,
return result.ptr();
}
TypeArgumentsPtr TypeArguments::FromInstanceTypeArguments(
Thread* thread,
const Class& cls) const {
if (IsNull()) {
return ptr();
}
const intptr_t num_type_arguments = cls.NumTypeArguments();
const intptr_t num_type_parameters = cls.NumTypeParameters(thread);
ASSERT(Length() >= num_type_arguments);
if (Length() == num_type_parameters) {
return ptr();
}
if (num_type_parameters == 0) {
return TypeArguments::null();
}
Zone* zone = thread->zone();
const auto& args =
TypeArguments::Handle(zone, TypeArguments::New(num_type_parameters));
const intptr_t offset = num_type_arguments - num_type_parameters;
auto& type = AbstractType::Handle(zone);
for (intptr_t i = 0; i < num_type_parameters; ++i) {
type = TypeAt(offset + i);
args.SetTypeAt(i, type);
}
return args.ptr();
}
TypeArgumentsPtr TypeArguments::ToInstantiatorTypeArguments(
Thread* thread,
const Class& cls) const {
if (IsNull()) {
return ptr();
}
const intptr_t num_type_arguments = cls.NumTypeArguments();
const intptr_t num_type_parameters = cls.NumTypeParameters(thread);
ASSERT(Length() == num_type_parameters);
if (num_type_arguments == num_type_parameters) {
return ptr();
}
Zone* zone = thread->zone();
const auto& args =
TypeArguments::Handle(zone, TypeArguments::New(num_type_arguments));
const intptr_t offset = num_type_arguments - num_type_parameters;
auto& type = AbstractType::Handle(zone);
for (intptr_t i = 0; i < num_type_parameters; ++i) {
type = TypeAt(i);
args.SetTypeAt(offset + i, type);
}
return args.ptr();
}
void TypeArguments::EnumerateURIs(URIs* uris) const {
if (IsNull()) {
return;
@ -10024,9 +10156,12 @@ FunctionPtr Function::ImplicitClosureFunction() const {
} else if (IsConstructor() && closure_signature.IsGeneric()) {
// Instantiate types of parameters as they may reference
// class type parameters.
const auto& instantiator_type_args = TypeArguments::Handle(
zone, AbstractType::Handle(zone, closure_signature.result_type())
.arguments());
const auto& result_type =
Type::Cast(AbstractType::Handle(zone, closure_signature.result_type()));
auto& instantiator_type_args =
TypeArguments::Handle(zone, result_type.arguments());
instantiator_type_args = instantiator_type_args.ToInstantiatorTypeArguments(
thread, Class::Handle(zone, result_type.type_class()));
const intptr_t num_type_args = closure_signature.NumTypeArguments();
auto& param_type = AbstractType::Handle(zone);
for (intptr_t i = kClosure; i < num_params; ++i) {
@ -12100,7 +12235,7 @@ void FieldGuardUpdater::ReviewGuards() {
bool Class::FindInstantiationOf(Zone* zone,
const Class& cls,
GrowableArray<const AbstractType*>* path,
GrowableArray<const Type*>* path,
bool consider_only_super_classes) const {
ASSERT(cls.is_type_finalized());
if (cls.ptr() == ptr()) {
@ -12108,7 +12243,7 @@ bool Class::FindInstantiationOf(Zone* zone,
}
Class& cls2 = Class::Handle(zone);
AbstractType& super = AbstractType::Handle(zone, super_type());
Type& super = Type::Handle(zone, super_type());
if (!super.IsNull() && !super.IsObjectType()) {
cls2 = super.type_class();
if (path != nullptr) {
@ -12145,7 +12280,7 @@ bool Class::FindInstantiationOf(Zone* zone,
bool Class::FindInstantiationOf(Zone* zone,
const Type& type,
GrowableArray<const AbstractType*>* path,
GrowableArray<const Type*>* path,
bool consider_only_super_classes) const {
return FindInstantiationOf(zone, Class::Handle(zone, type.type_class()), path,
consider_only_super_classes);
@ -12160,14 +12295,19 @@ TypePtr Class::GetInstantiationOf(Zone* zone, const Class& cls) const {
return cls.DeclarationType();
}
const auto& decl_type = Type::Handle(zone, DeclarationType());
GrowableArray<const AbstractType*> path(zone, 0);
GrowableArray<const Type*> path(zone, 0);
if (!FindInstantiationOf(zone, cls, &path)) {
return Type::null();
}
Thread* thread = Thread::Current();
ASSERT(!path.is_empty());
auto& calculated_type = Type::Handle(zone, decl_type.ptr());
auto& calculated_type_class =
Class::Handle(zone, calculated_type.type_class());
auto& calculated_type_args =
TypeArguments::Handle(zone, calculated_type.arguments());
calculated_type_args = calculated_type_args.ToInstantiatorTypeArguments(
thread, calculated_type_class);
for (auto* const type : path) {
calculated_type ^= type->ptr();
if (!calculated_type.IsInstantiated()) {
@ -12175,7 +12315,10 @@ TypePtr Class::GetInstantiationOf(Zone* zone, const Class& cls) const {
calculated_type_args, Object::null_type_arguments(), kAllFree,
Heap::kNew);
}
calculated_type_class = calculated_type.type_class();
calculated_type_args = calculated_type.arguments();
calculated_type_args = calculated_type_args.ToInstantiatorTypeArguments(
thread, calculated_type_class);
}
ASSERT_EQUAL(calculated_type.type_class_id(), cls.id());
return calculated_type.ptr();
@ -12222,15 +12365,16 @@ StaticTypeExactnessState StaticTypeExactnessState::Compute(
ASSERT(value.ptr() != Object::sentinel().ptr());
ASSERT(value.ptr() != Object::transition_sentinel().ptr());
Zone* const zone = Thread::Current()->zone();
Thread* thread = Thread::Current();
Zone* const zone = thread->zone();
const TypeArguments& static_type_args =
TypeArguments::Handle(zone, static_type.arguments());
TypeArguments::Handle(zone, static_type.GetInstanceTypeArguments(thread));
TypeArguments& args = TypeArguments::Handle(zone);
ASSERT(static_type.IsFinalized());
const Class& cls = Class::Handle(zone, value.clazz());
GrowableArray<const AbstractType*> path(10);
GrowableArray<const Type*> path(10);
bool is_super_class = true;
if (!cls.FindInstantiationOf(zone, static_type, &path,
@ -12269,18 +12413,18 @@ StaticTypeExactnessState StaticTypeExactnessState::Compute(
// To compute C<X0, ..., Xn> at G we walk the chain backwards and
// instantiate Si using type parameters of S{i-1} which gives us a type
// depending on type parameters of S{i-2}.
AbstractType& type = AbstractType::Handle(zone, path.Last()->ptr());
Type& type = Type::Handle(zone, path.Last()->ptr());
for (intptr_t i = path.length() - 2; (i >= 0) && !type.IsInstantiated();
i--) {
args = path[i]->arguments();
type = type.InstantiateFrom(args, TypeArguments::null_type_arguments(),
kAllFree, Heap::kNew);
args = path[i]->GetInstanceTypeArguments(thread, /*canonicalize=*/false);
type ^= type.InstantiateFrom(args, TypeArguments::null_type_arguments(),
kAllFree, Heap::kNew);
}
if (type.IsInstantiated()) {
// C<X0, ..., Xn> at G is fully instantiated and does not depend on
// Xi. In this case just check if type arguments match.
args = type.arguments();
args = type.GetInstanceTypeArguments(thread, /*canonicalize=*/false);
if (args.Equals(static_type_args)) {
return is_super_class ? StaticTypeExactnessState::HasExactSuperClass()
: StaticTypeExactnessState::HasExactSuperType();
@ -12308,7 +12452,7 @@ StaticTypeExactnessState StaticTypeExactnessState::Compute(
bool trivial_case =
(num_type_params ==
Class::Handle(zone, static_type.type_class()).NumTypeParameters()) &&
(value.GetTypeArguments() == static_type.arguments());
(value.GetTypeArguments() == static_type_args.ptr());
if (!trivial_case && FLAG_trace_field_guards) {
THR_Print("Not a simple case: %" Pd " vs %" Pd
" type parameters, %s vs %s type arguments\n",
@ -12320,7 +12464,7 @@ StaticTypeExactnessState StaticTypeExactnessState::Compute(
}
AbstractType& type_arg = AbstractType::Handle(zone);
args = type.arguments();
args = type.GetInstanceTypeArguments(thread, /*canonicalize=*/false);
for (intptr_t i = 0; (i < num_type_params) && trivial_case; i++) {
type_arg = args.TypeAt(i);
if (!type_arg.IsTypeParameter() ||
@ -12384,13 +12528,13 @@ void FieldGuardUpdater::ReviewExactnessState() {
ASSERT(guarded_cid() != kNullCid);
const Type& field_type = Type::Cast(AbstractType::Handle(field_->type()));
const TypeArguments& field_type_args =
TypeArguments::Handle(field_type.arguments());
const Instance& instance = Instance::Cast(value_);
TypeArguments& args = TypeArguments::Handle();
if (static_type_exactness_state().IsTriviallyExact()) {
args = instance.GetTypeArguments();
const TypeArguments& args =
TypeArguments::Handle(instance.GetTypeArguments());
const TypeArguments& field_type_args = TypeArguments::Handle(
field_type.GetInstanceTypeArguments(Thread::Current()));
if (args.ptr() == field_type_args.ptr()) {
return;
}
@ -20145,8 +20289,12 @@ AbstractTypePtr Instance::GetType(Heap::Space space) const {
}
if (type.IsNull()) {
TypeArguments& type_arguments = TypeArguments::Handle(zone);
if (cls.NumTypeArguments() > 0) {
const intptr_t num_type_arguments = cls.NumTypeArguments();
if (num_type_arguments > 0) {
type_arguments = GetTypeArguments();
if (!type_arguments.IsNull()) {
type_arguments = type_arguments.FromInstanceTypeArguments(thread, cls);
}
}
type = Type::New(cls, type_arguments, Nullability::kNonNullable, space);
type.SetIsFinalized();
@ -20399,7 +20547,8 @@ bool Instance::RuntimeTypeIsSubtypeOf(
return true;
}
TypeArguments& type_arguments = TypeArguments::Handle(zone);
if (cls.NumTypeArguments() > 0) {
const intptr_t num_type_arguments = cls.NumTypeArguments();
if (num_type_arguments > 0) {
type_arguments = GetTypeArguments();
ASSERT(type_arguments.IsNull() || type_arguments.IsCanonical());
// The number of type arguments in the instance must be greater or equal to
@ -20411,7 +20560,7 @@ bool Instance::RuntimeTypeIsSubtypeOf(
// Also, an optimization reuses the type argument vector of the instantiator
// of generic instances when its layout is compatible.
ASSERT(type_arguments.IsNull() ||
(type_arguments.Length() >= cls.NumTypeArguments()));
(type_arguments.Length() >= num_type_arguments));
}
AbstractType& instantiated_other = AbstractType::Handle(zone, other.ptr());
if (!other.IsInstantiated()) {
@ -20676,14 +20825,6 @@ TypeArgumentsPtr AbstractType::arguments() const {
return nullptr;
}
void AbstractType::set_arguments(const TypeArguments& value) const {
// All subclasses should implement this appropriately, so the only value that
// should reach this implementation should be the null value.
ASSERT(IsNull());
// AbstractType is an abstract class.
UNREACHABLE();
}
bool AbstractType::IsStrictlyNonNullable() const {
// Null can be assigned to legacy and nullable types.
if (!IsNonNullable()) {
@ -21440,9 +21581,13 @@ bool AbstractType::IsSubtypeOf(const AbstractType& other,
// fall through to class-based type tests.
return false;
}
ASSERT(IsType());
const Class& type_cls = Class::Handle(zone, type_class());
return Class::IsSubtypeOf(type_cls, TypeArguments::Handle(zone, arguments()),
nullability(), other, space, trail);
return Class::IsSubtypeOf(
type_cls,
TypeArguments::Handle(zone, Type::Cast(*this).GetInstanceTypeArguments(
thread, /*canonicalize=*/false)),
nullability(), other, space, trail);
}
bool AbstractType::IsSubtypeOfFutureOr(Zone* zone,
@ -21708,20 +21853,7 @@ bool Type::IsInstantiated(Genericity genericity,
return true;
}
const TypeArguments& args = TypeArguments::Handle(arguments());
intptr_t num_type_args = args.Length();
intptr_t len = num_type_args; // Check the full vector of type args.
ASSERT(num_type_args > 0);
// This type is not instantiated if it refers to type parameters.
const Class& cls = Class::Handle(type_class());
len = cls.NumTypeParameters(); // Check the type parameters only.
if (len > num_type_args) {
// This type has the wrong number of arguments and is not finalized yet.
// Type arguments are reset to null when finalizing such a type.
ASSERT(!IsFinalized());
len = num_type_args;
}
return (len == 0) ||
args.IsSubvectorInstantiated(num_type_args - len, len, genericity,
return args.IsSubvectorInstantiated(0, args.Length(), genericity,
num_free_fun_type_params, trail);
}
@ -21740,7 +21872,7 @@ AbstractTypePtr Type::InstantiateFrom(
// finalizing the type argument vector of a recursive type.
const Class& cls = Class::Handle(zone, type_class());
TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments());
ASSERT(type_arguments.Length() == cls.NumTypeArguments());
ASSERT(type_arguments.Length() == cls.NumTypeParameters());
type_arguments = type_arguments.InstantiateFrom(
instantiator_type_arguments, function_type_arguments,
num_free_fun_type_params, space, trail, num_parent_type_args_adjustment);
@ -21836,6 +21968,10 @@ bool Type::IsEquivalent(const Instance& other,
}
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
ASSERT(
Class::Handle(zone, type_class()).NumTypeParameters(thread) ==
Class::Handle(zone, other_type.type_class()).NumTypeParameters(thread));
if (!IsNullabilityEquivalent(thread, other_type, kind)) {
return false;
}
@ -21846,51 +21982,11 @@ bool Type::IsEquivalent(const Instance& other,
if (arguments() == other_type.arguments()) {
return true;
}
if (arguments() != other_type.arguments()) {
const Class& cls = Class::Handle(zone, type_class());
const intptr_t num_type_params = cls.NumTypeParameters(thread);
// Shortcut unnecessary handle allocation below if non-generic.
if (num_type_params > 0) {
const intptr_t num_type_args = cls.NumTypeArguments();
const intptr_t from_index = num_type_args - num_type_params;
const TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
const TypeArguments& other_type_args =
TypeArguments::Handle(zone, other_type.arguments());
if (type_args.IsNull()) {
// Ignore from_index.
if (!other_type_args.IsRaw(0, num_type_args)) {
return false;
}
} else if (other_type_args.IsNull()) {
// Ignore from_index.
if (!type_args.IsRaw(0, num_type_args)) {
return false;
}
} else if (!type_args.IsSubvectorEquivalent(other_type_args, from_index,
num_type_params, kind,
trail)) {
return false;
}
#ifdef DEBUG
if ((from_index > 0) && !type_args.IsNull() &&
!other_type_args.IsNull()) {
// Verify that the type arguments of the super class match, since they
// depend solely on the type parameters that were just verified to
// match.
ASSERT(type_args.Length() >= (from_index + num_type_params));
ASSERT(other_type_args.Length() >= (from_index + num_type_params));
AbstractType& type_arg = AbstractType::Handle(zone);
AbstractType& other_type_arg = AbstractType::Handle(zone);
for (intptr_t i = 0; i < from_index; i++) {
type_arg = type_args.TypeAt(i);
other_type_arg = other_type_args.TypeAt(i);
ASSERT(type_arg.IsEquivalent(other_type_arg, kind, trail));
}
}
#endif
}
}
return true;
const TypeArguments& type_args =
TypeArguments::Handle(zone, this->arguments());
const TypeArguments& other_type_args =
TypeArguments::Handle(zone, other_type.arguments());
return type_args.IsEquivalent(other_type_args, kind, trail);
}
bool FunctionType::IsEquivalent(const Instance& other,
@ -21980,13 +22076,9 @@ bool Type::RequireConstCanonicalTypeErasure(Zone* zone, TrailPtr trail) const {
// bound or non-nullable default argument.
return false;
}
const Class& cls = Class::Handle(zone, type_class());
const intptr_t num_type_params = cls.NumTypeParameters();
const intptr_t num_type_args = cls.NumTypeArguments();
const intptr_t from_index = num_type_args - num_type_params;
return TypeArguments::Handle(zone, arguments())
.RequireConstCanonicalTypeErasure(zone, from_index, num_type_params,
trail);
const auto& type_args = TypeArguments::Handle(zone, this->arguments());
return type_args.RequireConstCanonicalTypeErasure(zone, 0, type_args.Length(),
trail);
}
bool Type::IsDeclarationTypeOf(const Class& cls) const {
@ -22082,25 +22174,8 @@ AbstractTypePtr Type::Canonicalize(Thread* thread, TrailPtr trail) const {
// Canonicalize the type arguments.
TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
// In case the type is first canonicalized at runtime, its type argument
// vector may be longer than necessary. If so, reallocate a vector of the
// exact size to prevent multiple "canonical" types.
if (!type_args.IsNull()) {
const intptr_t num_type_args = cls.NumTypeArguments();
ASSERT(type_args.Length() >= num_type_args);
if (type_args.Length() > num_type_args) {
TypeArguments& new_type_args =
TypeArguments::Handle(zone, TypeArguments::New(num_type_args));
AbstractType& type_arg = AbstractType::Handle(zone);
for (intptr_t i = 0; i < num_type_args; i++) {
type_arg = type_args.TypeAt(i);
new_type_args.SetTypeAt(i, type_arg);
}
type_args = new_type_args.ptr();
set_arguments(type_args);
SetHash(0); // Flush cached hash value.
}
}
ASSERT(type_args.IsNull() ||
(type_args.Length() == cls.NumTypeParameters()));
type_args = type_args.Canonicalize(thread, trail);
if (IsCanonical()) {
// Canonicalizing type_args canonicalized this type as a side effect.
@ -22189,38 +22264,19 @@ void Type::PrintName(NameVisibility name_visibility,
BaseTextBuffer* printer) const {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const TypeArguments& args = TypeArguments::Handle(zone, arguments());
const intptr_t num_args = args.IsNull() ? 0 : args.Length();
intptr_t first_type_param_index;
intptr_t num_type_params = num_args; // Number of type parameters to print.
const Class& cls = Class::Handle(zone, type_class());
if (cls.is_declaration_loaded()) {
// Do not print the full vector, but only the declared type parameters.
num_type_params = cls.NumTypeParameters();
}
printer->AddString(cls.NameCString(name_visibility));
if (num_type_params > num_args) {
first_type_param_index = 0;
if (!IsFinalized() || IsBeingFinalized()) {
// TODO(regis): Check if this is dead code.
num_type_params = num_args;
} else {
ASSERT(num_args == 0); // Type is raw.
}
} else {
// The actual type argument vector can be longer than necessary, because
// of type optimizations.
if (IsFinalized() && cls.is_type_finalized()) {
first_type_param_index = cls.NumTypeArguments() - num_type_params;
} else {
first_type_param_index = num_args - num_type_params;
}
const TypeArguments& args = TypeArguments::Handle(zone, arguments());
intptr_t num_type_params = 0;
if (cls.is_declaration_loaded()) {
num_type_params = cls.NumTypeParameters(thread);
} else if (!args.IsNull()) {
num_type_params = args.Length();
}
if (num_type_params == 0) {
// Do nothing.
} else {
args.PrintSubvectorName(first_type_param_index, num_type_params,
name_visibility, printer);
args.PrintSubvectorName(0, num_type_params, name_visibility, printer);
}
printer->AddString(NullabilitySuffix(name_visibility));
// The name is only used for type checking and debugging purposes.
@ -22240,20 +22296,8 @@ uword Type::ComputeHash() const {
result = CombineHashes(result, static_cast<uint32_t>(type_nullability));
uint32_t type_args_hash = TypeArguments::kAllDynamicHash;
if (arguments() != TypeArguments::null()) {
// Only include hashes of type arguments corresponding to type parameters.
// This prevents obtaining different hashes depending on the location of
// TypeRefs in the super class type argument vector.
// Note that TypeRefs can also appear as type arguments corresponding to
// type parameters, typically after an instantiation at runtime.
// These are dealt with in TypeArguments::HashForRange, which is also called
// to compute the hash of a full standalone TypeArguments.
const TypeArguments& type_args = TypeArguments::Handle(arguments());
const Class& cls = Class::Handle(type_class());
const intptr_t num_type_params = cls.NumTypeParameters();
if (num_type_params > 0) {
const intptr_t from_index = cls.NumTypeArguments() - num_type_params;
type_args_hash = type_args.HashForRange(from_index, num_type_params);
}
const TypeArguments& args = TypeArguments::Handle(arguments());
type_args_hash = args.HashForRange(0, args.Length());
}
result = CombineHashes(result, type_args_hash);
result = FinalizeHash(result, kHashBits);
@ -22314,9 +22358,25 @@ void Type::set_type_class(const Class& value) const {
void Type::set_arguments(const TypeArguments& value) const {
ASSERT(!IsCanonical());
ASSERT(value.IsNull() ||
// Do not attempt to query number of type parameters
// before class declaration is fully loaded.
!Class::Handle(type_class()).is_declaration_loaded() ||
// Relax assertion in order to support invalid generic types
// created in ClosureMirror_function.
(type_class_id() == kInstanceCid) ||
value.Length() == Class::Handle(type_class()).NumTypeParameters());
untag()->set_arguments(value.ptr());
}
TypeArgumentsPtr Type::GetInstanceTypeArguments(Thread* thread,
bool canonicalize) const {
Zone* zone = thread->zone();
const auto& cls = Class::Handle(zone, type_class());
const auto& args = TypeArguments::Handle(zone, arguments());
return cls.GetInstanceTypeArguments(thread, args, canonicalize);
}
TypePtr Type::New(Heap::Space space) {
ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space,
Type::ContainsCompressedPointers());
@ -22329,12 +22389,12 @@ TypePtr Type::New(const Class& clazz,
Heap::Space space) {
Zone* Z = Thread::Current()->zone();
const Type& result = Type::Handle(Z, Type::New(space));
result.set_arguments(arguments);
result.SetHash(0);
result.set_flags(0);
result.set_nullability(nullability);
result.set_type_state(UntaggedAbstractType::kAllocated);
result.set_type_class(clazz);
result.set_arguments(arguments);
result.InitializeTypeTestingStubNonAtomic(
Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));

View file

@ -1196,25 +1196,31 @@ class Class : public Object {
uint32_t Hash() const;
int32_t SourceFingerprint() const;
// Return the Type with type parameters declared by this class filled in with
// dynamic and type parameters declared in superclasses filled in as declared
// in superclass clauses.
AbstractTypePtr RareType() const;
// Return the Type with type arguments filled in with dynamic.
TypePtr RareType() const;
// Return the Type whose arguments are the type parameters declared by this
// class preceded by the type arguments declared for superclasses, etc.
// e.g. given
// class B<T, S>
// class C<R> extends B<R, int>
// C.DeclarationType() --> C [R, int, R]
// The declaration type's nullability is either legacy or non-nullable when
// the non-nullable experiment is enabled.
// Return the non-nullable Type whose arguments are the type parameters
// declared by this class.
TypePtr DeclarationType() const;
static intptr_t declaration_type_offset() {
return OFFSET_OF(UntaggedClass, declaration_type_);
}
// Returns flattened instance type arguments vector for
// instance of this class, parameterized with declared
// type parameters of this class.
TypeArgumentsPtr GetDeclarationInstanceTypeArguments() const;
// Returns flattened instance type arguments vector for
// instance of this type, parameterized with given type arguments.
//
// Length of [type_arguments] should match number of type parameters
// returned by [NumTypeParameters].
TypeArgumentsPtr GetInstanceTypeArguments(Thread* thread,
const TypeArguments& type_arguments,
bool canonicalize = true) const;
LibraryPtr library() const { return untag()->library(); }
void set_library(const Library& value) const;
@ -1235,8 +1241,8 @@ class Class : public Object {
intptr_t index,
Nullability nullability = Nullability::kNonNullable) const;
// The type argument vector is flattened and includes the type arguments of
// the super class.
// Length of the flattened instance type arguments vector.
// Includes type arguments of the super class.
intptr_t NumTypeArguments() const;
// Return true if this class declares type parameters.
@ -1310,11 +1316,11 @@ class Class : public Object {
}
// The super type of this class, Object type if not explicitly specified.
AbstractTypePtr super_type() const {
TypePtr super_type() const {
ASSERT(is_declaration_loaded());
return untag()->super_type();
}
void set_super_type(const AbstractType& value) const;
void set_super_type(const Type& value) const;
static intptr_t super_type_offset() {
return OFFSET_OF(UntaggedClass, super_type_);
}
@ -1345,7 +1351,7 @@ class Class : public Object {
// path must be equal to the other results.
bool FindInstantiationOf(Zone* zone,
const Class& cls,
GrowableArray<const AbstractType*>* path,
GrowableArray<const Type*>* path,
bool consider_only_super_classes = false) const;
bool FindInstantiationOf(Zone* zone,
const Class& cls,
@ -1368,7 +1374,7 @@ class Class : public Object {
// applying each path must be equal to the other results.
bool FindInstantiationOf(Zone* zone,
const Type& type,
GrowableArray<const AbstractType*>* path,
GrowableArray<const Type*>* path,
bool consider_only_super_classes = false) const;
bool FindInstantiationOf(Zone* zone,
const Type& type,
@ -1884,6 +1890,13 @@ class Class : public Object {
// Caches the declaration type of this class.
void set_declaration_type(const Type& type) const;
TypeArgumentsPtr declaration_instance_type_arguments() const {
return untag()
->declaration_instance_type_arguments<std::memory_order_acquire>();
}
void set_declaration_instance_type_arguments(
const TypeArguments& value) const;
bool CanReloadFinalized(const Class& replacement,
ProgramReloadContext* context) const;
bool CanReloadPreFinalized(const Class& replacement,
@ -7745,9 +7758,9 @@ class Instance : public Object {
AbstractTypePtr GetType(Heap::Space space) const;
// Access the arguments of the [Type] of this [Instance].
// Note: for [Type]s instead of [Instance]s with a [Type] attached, use
// [arguments()] and [set_arguments()]
// Access the type arguments vector of this [Instance].
// This vector includes type arguments corresponding to type parameters of
// instance's class and all its superclasses.
virtual TypeArgumentsPtr GetTypeArguments() const;
virtual void SetTypeArguments(const TypeArguments& value) const;
@ -8227,6 +8240,20 @@ class TypeArguments : public Instance {
// Canonicalize only if instantiated, otherwise returns 'this'.
TypeArgumentsPtr Canonicalize(Thread* thread, TrailPtr trail = nullptr) const;
// Shrinks flattened instance type arguments to ordinary type arguments.
TypeArgumentsPtr FromInstanceTypeArguments(Thread* thread,
const Class& cls) const;
// Expands type arguments to a vector suitable as instantiator type
// arguments.
//
// Only fills positions corresponding to type parameters of [cls], leave
// all positions of superclass type parameters blank.
// Use [GetInstanceTypeArguments] on a class or a type if full vector is
// needed.
TypeArgumentsPtr ToInstantiatorTypeArguments(Thread* thread,
const Class& cls) const;
// Add the class name and URI of each type argument of this vector to the uris
// list and mark ambiguous triplets to be printed.
void EnumerateURIs(URIs* uris) const;
@ -8563,7 +8590,6 @@ class AbstractType : public Instance {
virtual classid_t type_class_id() const;
virtual ClassPtr type_class() const;
virtual TypeArgumentsPtr arguments() const;
virtual void set_arguments(const TypeArguments& value) const;
virtual bool IsInstantiated(Genericity genericity = kAny,
intptr_t num_free_fun_type_params = kAllFree,
TrailPtr trail = nullptr) const;
@ -8881,7 +8907,13 @@ class Type : public AbstractType {
virtual ClassPtr type_class() const;
void set_type_class(const Class& value) const;
virtual TypeArgumentsPtr arguments() const { return untag()->arguments(); }
virtual void set_arguments(const TypeArguments& value) const;
void set_arguments(const TypeArguments& value) const;
// Returns flattened instance type arguments vector for
// instance of this type.
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;

View file

@ -445,14 +445,14 @@ void ObjectStore::LazyInitCoreMembers() {
list_class_.store(cls.ptr());
auto& type = Type::Handle(zone);
type ^= cls.RareType();
type = cls.RareType();
non_nullable_list_rare_type_.store(type.ptr());
cls = core_lib.LookupClass(Symbols::Map());
ASSERT(!cls.IsNull());
map_class_.store(cls.ptr());
type ^= cls.RareType();
type = cls.RareType();
non_nullable_map_rare_type_.store(type.ptr());
cls = core_lib.LookupClass(Symbols::Set());
@ -522,7 +522,7 @@ void ObjectStore::LazyInitAsyncMembers() {
type ^= type.Canonicalize(thread, nullptr);
nullable_future_null_type_.store(type.ptr());
type ^= cls.RareType();
type = cls.RareType();
non_nullable_future_rare_type_.store(type.ptr());
}
}

View file

@ -7797,7 +7797,7 @@ TEST_CASE(Class_GetInstantiationOf) {
const auto& decl_type_args_a2 =
TypeArguments::Handle(zone, decl_type_a2.arguments());
const auto& type_arg_a2_x =
TypeParameter::CheckedHandle(zone, decl_type_args_a2.TypeAt(1));
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);

View file

@ -993,7 +993,7 @@ class UntaggedClass : public UntaggedObject {
COMPRESSED_POINTER_FIELD(ScriptPtr, script)
COMPRESSED_POINTER_FIELD(LibraryPtr, library)
COMPRESSED_POINTER_FIELD(TypeParametersPtr, type_parameters)
COMPRESSED_POINTER_FIELD(AbstractTypePtr, super_type)
COMPRESSED_POINTER_FIELD(TypePtr, super_type)
// Canonicalized const instances of this class.
COMPRESSED_POINTER_FIELD(ArrayPtr, constants)
// Declaration type for this class.
@ -1008,6 +1008,11 @@ class UntaggedClass : public UntaggedObject {
COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, direct_subclasses)
#endif // !defined(PRODUCT) || !defined(DART_PRECOMPILED_RUNTIME)
// Cached declaration instance type arguments for this class.
// Not preserved in AOT snapshots.
COMPRESSED_POINTER_FIELD(TypeArgumentsPtr,
declaration_instance_type_arguments)
#if !defined(DART_PRECOMPILED_RUNTIME)
// Stub code for allocation of instances.
COMPRESSED_POINTER_FIELD(CodePtr, allocation_stub)
@ -1016,11 +1021,7 @@ class UntaggedClass : public UntaggedObject {
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#if defined(DART_PRECOMPILED_RUNTIME)
#if defined(PRODUCT)
VISIT_TO(invocation_dispatcher_cache)
#else
VISIT_TO(direct_subclasses)
#endif // defined(PRODUCT)
VISIT_TO(declaration_instance_type_arguments)
#else
VISIT_TO(dependent_code)
#endif // defined(DART_PRECOMPILED_RUNTIME)

View file

@ -2910,8 +2910,8 @@ static void CollectStringifiedType(Zone* zone,
output.Add(instance);
return;
}
if (type.IsTypeParameter() && type.IsAbstractType()) {
// Calling type_class on an abstract type parameter will crash the VM.
if (type.IsTypeParameter()) {
// Calling type_class on a type parameter will crash the VM.
// We use null instead.
output.Add(instance);
return;
@ -2923,6 +2923,8 @@ static void CollectStringifiedType(Zone* zone,
output.Add(instance);
return;
}
ASSERT(type.IsType());
const Class& cls = Class::Handle(type.type_class());
const Library& lib = Library::Handle(zone, cls.library());
@ -2935,7 +2937,8 @@ static void CollectStringifiedType(Zone* zone,
instance ^= Smi::New((intptr_t)type.nullability());
output.Add(instance);
const TypeArguments& srcArguments = TypeArguments::Handle(type.arguments());
const TypeArguments& srcArguments =
TypeArguments::Handle(Type::Cast(type).arguments());
instance ^= Smi::New(srcArguments.Length());
output.Add(instance);
for (int i = 0; i < srcArguments.Length(); i++) {

View file

@ -65,14 +65,10 @@ void TypeTestingStubNamer::StringifyTypeTo(BaseTextBuffer* buffer,
buffer->AddString("_");
buffer->AddString(klass_.ScrubbedNameCString());
const intptr_t type_parameters = klass_.NumTypeParameters();
auto& type_arguments = TypeArguments::Handle(type.arguments());
if (!type_arguments.IsNull() && type_parameters > 0) {
type_arguments = type.arguments();
ASSERT(type_arguments.Length() >= type_parameters);
const intptr_t length = type_arguments.Length();
for (intptr_t i = 0; i < type_parameters; ++i) {
type_ = type_arguments.TypeAt(length - type_parameters + i);
auto& type_arguments = TypeArguments::Handle(Type::Cast(type).arguments());
if (!type_arguments.IsNull()) {
for (intptr_t i = 0, n = type_arguments.Length(); i < n; ++i) {
type_ = type_arguments.TypeAt(i);
buffer->AddString("__");
StringifyTypeTo(buffer, type_);
}
@ -503,7 +499,7 @@ static CheckType SubtypeChecksForClass(Zone* zone,
: CheckType::kCannotBeChecked;
}
auto& calculated_type =
AbstractType::Handle(zone, to_check.GetInstantiationOf(zone, type_class));
Type::Handle(zone, to_check.GetInstantiationOf(zone, type_class));
if (calculated_type.IsInstantiated()) {
if (type.IsInstantiated()) {
return calculated_type.IsSubtypeOf(type, Heap::kNew)
@ -526,9 +522,10 @@ static CheckType SubtypeChecksForClass(Zone* zone,
// arguments, then we can just treat the instance type arguments as if they
// were used to instantiate the type class during checking.
const auto& decl_type_args = TypeArguments::Handle(
zone, Type::Handle(zone, to_check.DeclarationType()).arguments());
const auto& calculated_type_args =
TypeArguments::Handle(zone, calculated_type.arguments());
zone, to_check.GetDeclarationInstanceTypeArguments());
const auto& calculated_type_args = TypeArguments::Handle(
zone, calculated_type.GetInstanceTypeArguments(Thread::Current(),
/*canonicalize=*/false));
const bool type_args_consistent = calculated_type_args.IsSubvectorEquivalent(
decl_type_args, 0, type_class.NumTypeArguments(),
TypeEquality::kCanonical);
@ -639,7 +636,7 @@ void TypeTestingStubGenerator::
// uncommon because most Dart code in 2.0 will be strongly typed)!
__ CompareObject(TTSInternalRegs::kInstanceTypeArgumentsReg,
Object::null_object());
const Type& rare_type = Type::Handle(Type::RawCast(type_class.RareType()));
const Type& rare_type = Type::Handle(type_class.RareType());
if (rare_type.IsSubtypeOf(type, Heap::kNew)) {
compiler::Label process_done;
__ BranchIf(NOT_EQUAL, &process_done, compiler::Assembler::kNearJump);
@ -659,12 +656,12 @@ void TypeTestingStubGenerator::
const TypeArguments& ta = TypeArguments::Handle(type.arguments());
const intptr_t num_type_parameters = type_class.NumTypeParameters();
const intptr_t num_type_arguments = type_class.NumTypeArguments();
ASSERT(ta.Length() >= num_type_arguments);
ASSERT(ta.Length() == num_type_parameters);
for (intptr_t i = 0; i < num_type_parameters; ++i) {
const intptr_t type_param_value_offset_i =
num_type_arguments - num_type_parameters + i;
type_arg = ta.TypeAt(type_param_value_offset_i);
type_arg = ta.TypeAt(i);
ASSERT(type_arg.IsTypeParameter() ||
hi->CanUseSubtypeRangeCheckFor(type_arg));
@ -1347,10 +1344,8 @@ void RegisterTypeArgumentsUse(const Function& function,
//
// We use the declaration type arguments for the instance creation,
// which is a non-instantiated, expanded, type arguments vector.
const Type& declaration_type =
Type::Handle(instance_klass.DeclarationType());
TypeArguments& declaration_type_args =
TypeArguments::Handle(declaration_type.arguments());
TypeArguments& declaration_type_args = TypeArguments::Handle(
instance_klass.GetDeclarationInstanceTypeArguments());
type_usage_info->UseTypeArgumentsInInstanceCreation(
klass, declaration_type_args);
}
@ -1365,10 +1360,8 @@ void RegisterTypeArgumentsUse(const Function& function,
// vector passed in by the caller.
if (function.IsFactory()) {
const Class& enclosing_class = Class::Handle(function.Owner());
const Type& declaration_type =
Type::Handle(enclosing_class.DeclarationType());
TypeArguments& declaration_type_args =
TypeArguments::Handle(declaration_type.arguments());
TypeArguments& declaration_type_args = TypeArguments::Handle(
enclosing_class.GetDeclarationInstanceTypeArguments());
type_usage_info->UseTypeArgumentsInInstanceCreation(
klass, declaration_type_args);
}