| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index cde637d134a1c78e8a7263414e85921f3f12e1ff..dddddfb9de4ed94c1d5d25cc1ce9f3cd62fe2a85 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -1868,30 +1868,17 @@ bool Class::IsInFullSnapshot() const {
|
|
|
| RawType* Class::SignatureType() const {
|
| ASSERT(IsSignatureClass());
|
| - const Function& function = Function::Handle(signature_function());
|
| + Zone* zone = Thread::Current()->zone();
|
| + const Function& function = Function::Handle(zone, signature_function());
|
| ASSERT(!function.IsNull());
|
| if (function.signature_class() != raw()) {
|
| // This class is a function type alias. Return the canonical signature type.
|
| - const Class& canonical_class = Class::Handle(function.signature_class());
|
| - return canonical_class.SignatureType();
|
| - }
|
| - // Return the first canonical signature type if already computed at class
|
| - // finalization time. The optimizer may canonicalize instantiated function
|
| - // types of the same signature class, but these will be added after the
|
| - // uninstantiated signature class at index 1.
|
| - Array& signature_types = Array::Handle();
|
| - signature_types ^= canonical_types();
|
| - if (signature_types.IsNull()) {
|
| - set_canonical_types(empty_array());
|
| - signature_types ^= canonical_types();
|
| - }
|
| - // The canonical_types array is initialized to the empty array.
|
| - ASSERT(!signature_types.IsNull());
|
| - if (signature_types.Length() > 0) {
|
| - ASSERT(signature_types.Length() > 1);
|
| - Type& signature_type = Type::Handle();
|
| - signature_type ^= signature_types.At(1);
|
| - ASSERT(!signature_type.IsNull());
|
| + const Class& canonical_signature_class =
|
| + Class::Handle(zone, function.signature_class());
|
| + return canonical_signature_class.SignatureType();
|
| + }
|
| + const Type& signature_type = Type::Handle(zone, CanonicalType());
|
| + if (!signature_type.IsNull()) {
|
| return signature_type.raw();
|
| }
|
| // A signature class extends class Instance and is parameterized in the same
|
| @@ -1903,13 +1890,9 @@ RawType* Class::SignatureType() const {
|
| // argument vector. Therefore, we only need to set the type arguments
|
| // matching the type parameters here.
|
| const TypeArguments& signature_type_arguments =
|
| - TypeArguments::Handle(type_parameters());
|
| - const Type& signature_type = Type::Handle(
|
| - Type::New(*this, signature_type_arguments, token_pos()));
|
| -
|
| + TypeArguments::Handle(zone, type_parameters());
|
| // Return the still unfinalized signature type.
|
| - ASSERT(!signature_type.IsFinalized());
|
| - return signature_type.raw();
|
| + return Type::New(*this, signature_type_arguments, token_pos());
|
| }
|
|
|
|
|
| @@ -3609,7 +3592,7 @@ void Class::set_canonical_types(const Object& value) const {
|
|
|
|
|
| RawType* Class::CanonicalType() const {
|
| - if ((NumTypeArguments() == 0) && !IsSignatureClass()) {
|
| + if (NumTypeArguments() == 0) {
|
| return reinterpret_cast<RawType*>(raw_ptr()->canonical_types_);
|
| }
|
| Array& types = Array::Handle();
|
| @@ -3623,9 +3606,9 @@ RawType* Class::CanonicalType() const {
|
|
|
| void Class::SetCanonicalType(const Type& type) const {
|
| ASSERT(type.IsCanonical());
|
| - if ((NumTypeArguments() == 0) && !IsSignatureClass()) {
|
| - ASSERT((canonical_types() == Object::null() ||
|
| - (canonical_types() == type.raw()))); // Set during own finalization.
|
| + if (NumTypeArguments() == 0) {
|
| + ASSERT((canonical_types() == Object::null()) ||
|
| + (canonical_types() == type.raw())); // Set during own finalization.
|
| set_canonical_types(type);
|
| } else {
|
| Array& types = Array::Handle();
|
| @@ -6478,6 +6461,9 @@ RawFunction* Function::ImplicitClosureFunction() const {
|
| } else {
|
| closure_function.set_signature_class(signature_class);
|
| }
|
| + // Finalize types in signature class here, so that the
|
| + // signature type is not computed twice.
|
| + ClassFinalizer::FinalizeTypesInClass(signature_class);
|
| const Type& signature_type = Type::Handle(signature_class.SignatureType());
|
| if (!signature_type.IsFinalized()) {
|
| ClassFinalizer::FinalizeType(
|
| @@ -15662,7 +15648,7 @@ RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
|
| return Object::dynamic_type();
|
| }
|
| // Fast canonical lookup/registry for simple types.
|
| - if ((cls.NumTypeArguments() == 0) && !cls.IsSignatureClass()) {
|
| + if (cls.NumTypeArguments() == 0) {
|
| type = cls.CanonicalType();
|
| if (type.IsNull()) {
|
| ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate()));
|
| @@ -15737,12 +15723,12 @@ RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
|
| const Array& new_canonical_types = Array::Handle(
|
| isolate, Array::Grow(canonical_types, new_length, Heap::kOld));
|
| cls.set_canonical_types(new_canonical_types);
|
| - new_canonical_types.SetAt(index, *this);
|
| - } else {
|
| - canonical_types.SetAt(index, *this);
|
| + canonical_types = new_canonical_types.raw();
|
| }
|
| -#ifdef DEBUG
|
| + canonical_types.SetAt(index, *this);
|
| if ((index == 1) && cls.IsCanonicalSignatureClass()) {
|
| + canonical_types.SetAt(0, *this); // Also set canonical signature type at 0.
|
| +#ifdef DEBUG
|
| // Verify that the first canonical type is the signature type by checking
|
| // that the type argument vector of the canonical type ends with the
|
| // uninstantiated type parameters of the signature class. Note that these
|
| @@ -15768,8 +15754,8 @@ RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
|
| type_param ^= type_params.TypeAt(i);
|
| ASSERT(type_arg.Equals(type_param));
|
| }
|
| - }
|
| #endif
|
| + }
|
| ASSERT(IsOld());
|
| ASSERT(type_args.IsNull() || type_args.IsOld());
|
| SetCanonical();
|
|
|