Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(625)

Side by Side Diff: runtime/vm/object.cc

Issue 109593003: Use a trail instead of a mark bit when processing recursive types in the VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 3383 matching lines...) Expand 10 before | Expand all | Expand 10 after
3394 } 3394 }
3395 3395
3396 3396
3397 bool AbstractTypeArguments::IsResolved() const { 3397 bool AbstractTypeArguments::IsResolved() const {
3398 // AbstractTypeArguments is an abstract class. 3398 // AbstractTypeArguments is an abstract class.
3399 UNREACHABLE(); 3399 UNREACHABLE();
3400 return false; 3400 return false;
3401 } 3401 }
3402 3402
3403 3403
3404 bool AbstractTypeArguments::IsInstantiated() const { 3404 bool AbstractTypeArguments::IsInstantiated(GrowableObjectArray* trail) const {
3405 // AbstractTypeArguments is an abstract class. 3405 // AbstractTypeArguments is an abstract class.
3406 UNREACHABLE(); 3406 UNREACHABLE();
3407 return false; 3407 return false;
3408 } 3408 }
3409 3409
3410 3410
3411 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { 3411 bool AbstractTypeArguments::IsUninstantiatedIdentity() const {
3412 // AbstractTypeArguments is an abstract class. 3412 // AbstractTypeArguments is an abstract class.
3413 UNREACHABLE(); 3413 UNREACHABLE();
3414 return false; 3414 return false;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3472 strings.SetAt(s++, Symbols::CommaSpace()); 3472 strings.SetAt(s++, Symbols::CommaSpace());
3473 } 3473 }
3474 } 3474 }
3475 strings.SetAt(s++, Symbols::RAngleBracket()); 3475 strings.SetAt(s++, Symbols::RAngleBracket());
3476 ASSERT(s == num_strings); 3476 ASSERT(s == num_strings);
3477 name = String::ConcatAll(strings); 3477 name = String::ConcatAll(strings);
3478 return Symbols::New(name); 3478 return Symbols::New(name);
3479 } 3479 }
3480 3480
3481 3481
3482 bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const { 3482 bool AbstractTypeArguments::IsEquivalent(const AbstractTypeArguments& other,
3483 GrowableObjectArray* trail) const {
3483 if (this->raw() == other.raw()) { 3484 if (this->raw() == other.raw()) {
3484 return true; 3485 return true;
3485 } 3486 }
3486 if (IsNull() || other.IsNull()) { 3487 if (IsNull() || other.IsNull()) {
3487 return false; 3488 return false;
3488 } 3489 }
3489 const intptr_t num_types = Length(); 3490 const intptr_t num_types = Length();
3490 if (num_types != other.Length()) { 3491 if (num_types != other.Length()) {
3491 return false; 3492 return false;
3492 } 3493 }
3493 AbstractType& type = AbstractType::Handle(); 3494 AbstractType& type = AbstractType::Handle();
3494 AbstractType& other_type = AbstractType::Handle(); 3495 AbstractType& other_type = AbstractType::Handle();
3495 for (intptr_t i = 0; i < num_types; i++) { 3496 for (intptr_t i = 0; i < num_types; i++) {
3496 type = TypeAt(i); 3497 type = TypeAt(i);
3497 other_type = other.TypeAt(i); 3498 other_type = other.TypeAt(i);
3498 if (!type.Equals(other_type)) { 3499 if (!type.IsEquivalent(other_type, trail)) {
3499 return false; 3500 return false;
3500 } 3501 }
3501 } 3502 }
3502 return true; 3503 return true;
3503 } 3504 }
3504 3505
3505 3506
3506 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( 3507 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
3507 const AbstractTypeArguments& instantiator_type_arguments, 3508 const AbstractTypeArguments& instantiator_type_arguments,
3508 Error* bound_error) const { 3509 Error* bound_error,
3510 GrowableObjectArray* trail) const {
3509 // AbstractTypeArguments is an abstract class. 3511 // AbstractTypeArguments is an abstract class.
3510 UNREACHABLE(); 3512 UNREACHABLE();
3511 return NULL; 3513 return NULL;
3512 } 3514 }
3513 3515
3514 3516
3515 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, 3517 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated,
3516 intptr_t from_index, 3518 intptr_t from_index,
3517 intptr_t len) const { 3519 intptr_t len) const {
3518 ASSERT(Length() >= (from_index + len)); 3520 ASSERT(Length() >= (from_index + len));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3607 for (intptr_t i = 0; i < num_types; i++) { 3609 for (intptr_t i = 0; i < num_types; i++) {
3608 type = TypeAt(i); 3610 type = TypeAt(i);
3609 if (!type.IsResolved()) { 3611 if (!type.IsResolved()) {
3610 return false; 3612 return false;
3611 } 3613 }
3612 } 3614 }
3613 return true; 3615 return true;
3614 } 3616 }
3615 3617
3616 3618
3617 bool TypeArguments::IsInstantiated() const { 3619 bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const {
3618 AbstractType& type = AbstractType::Handle(); 3620 AbstractType& type = AbstractType::Handle();
3619 const intptr_t num_types = Length(); 3621 const intptr_t num_types = Length();
3620 for (intptr_t i = 0; i < num_types; i++) { 3622 for (intptr_t i = 0; i < num_types; i++) {
3621 type = TypeAt(i); 3623 type = TypeAt(i);
3622 ASSERT(!type.IsNull()); 3624 ASSERT(!type.IsNull());
3623 if (!type.IsInstantiated()) { 3625 if (!type.IsInstantiated(trail)) {
3624 return false; 3626 return false;
3625 } 3627 }
3626 } 3628 }
3627 return true; 3629 return true;
3628 } 3630 }
3629 3631
3630 3632
3631 bool TypeArguments::IsUninstantiatedIdentity() const { 3633 bool TypeArguments::IsUninstantiatedIdentity() const {
3632 ASSERT(!IsInstantiated()); 3634 ASSERT(!IsInstantiated());
3633 AbstractType& type = AbstractType::Handle(); 3635 AbstractType& type = AbstractType::Handle();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3763 if (!type_args.IsNull() && type_args.IsBounded()) { 3765 if (!type_args.IsNull() && type_args.IsBounded()) {
3764 return true; 3766 return true;
3765 } 3767 }
3766 } 3768 }
3767 return false; 3769 return false;
3768 } 3770 }
3769 3771
3770 3772
3771 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( 3773 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
3772 const AbstractTypeArguments& instantiator_type_arguments, 3774 const AbstractTypeArguments& instantiator_type_arguments,
3773 Error* bound_error) const { 3775 Error* bound_error,
3776 GrowableObjectArray* trail) const {
3774 ASSERT(!IsInstantiated()); 3777 ASSERT(!IsInstantiated());
3775 if (!instantiator_type_arguments.IsNull() && 3778 if (!instantiator_type_arguments.IsNull() &&
3776 IsUninstantiatedIdentity() && 3779 IsUninstantiatedIdentity() &&
3777 (instantiator_type_arguments.Length() == Length())) { 3780 (instantiator_type_arguments.Length() == Length())) {
3778 return instantiator_type_arguments.raw(); 3781 return instantiator_type_arguments.raw();
3779 } 3782 }
3780 const intptr_t num_types = Length(); 3783 const intptr_t num_types = Length();
3781 TypeArguments& instantiated_array = 3784 TypeArguments& instantiated_array =
3782 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); 3785 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew));
3783 AbstractType& type = AbstractType::Handle(); 3786 AbstractType& type = AbstractType::Handle();
3784 for (intptr_t i = 0; i < num_types; i++) { 3787 for (intptr_t i = 0; i < num_types; i++) {
3785 type = TypeAt(i); 3788 type = TypeAt(i);
3786 if (!type.IsInstantiated()) { 3789 if (!type.IsInstantiated()) {
3787 type = type.InstantiateFrom(instantiator_type_arguments, bound_error); 3790 type = type.InstantiateFrom(instantiator_type_arguments,
3791 bound_error,
3792 trail);
3788 } 3793 }
3789 instantiated_array.SetTypeAt(i, type); 3794 instantiated_array.SetTypeAt(i, type);
3790 } 3795 }
3791 return instantiated_array.raw(); 3796 return instantiated_array.raw();
3792 } 3797 }
3793 3798
3794 3799
3795 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { 3800 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
3796 if (len < 0 || len > kMaxElements) { 3801 if (len < 0 || len > kMaxElements) {
3797 // This should be caught before we reach here. 3802 // This should be caught before we reach here.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3908 TypeArguments::New(num_types)); 3913 TypeArguments::New(num_types));
3909 for (intptr_t i = 0; i < num_types; i++) { 3914 for (intptr_t i = 0; i < num_types; i++) {
3910 type = TypeAt(i); 3915 type = TypeAt(i);
3911 type = type.CloneUnfinalized(); 3916 type = type.CloneUnfinalized();
3912 clone.SetTypeAt(i, type); 3917 clone.SetTypeAt(i, type);
3913 } 3918 }
3914 return clone.raw(); 3919 return clone.raw();
3915 } 3920 }
3916 3921
3917 3922
3918 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { 3923 RawAbstractTypeArguments* TypeArguments::Canonicalize(
3924 GrowableObjectArray* trail) const {
3919 if (IsNull() || IsCanonical()) { 3925 if (IsNull() || IsCanonical()) {
3920 ASSERT(IsOld()); 3926 ASSERT(IsOld());
3921 return this->raw(); 3927 return this->raw();
3922 } 3928 }
3923 Isolate* isolate = Isolate::Current(); 3929 Isolate* isolate = Isolate::Current();
3924 ObjectStore* object_store = isolate->object_store(); 3930 ObjectStore* object_store = isolate->object_store();
3925 const Array& table = Array::Handle(isolate, 3931 const Array& table = Array::Handle(isolate,
3926 object_store->canonical_type_arguments()); 3932 object_store->canonical_type_arguments());
3927 ASSERT(table.Length() > 0); 3933 ASSERT(table.Length() > 0);
3928 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, 3934 intptr_t index = FindIndexInCanonicalTypeArguments(isolate,
3929 table, 3935 table,
3930 *this, 3936 *this,
3931 Hash()); 3937 Hash());
3932 TypeArguments& result = TypeArguments::Handle(isolate); 3938 TypeArguments& result = TypeArguments::Handle(isolate);
3933 result ^= table.At(index); 3939 result ^= table.At(index);
3934 if (result.IsNull()) { 3940 if (result.IsNull()) {
3935 // Canonicalize each type argument. 3941 // Canonicalize each type argument.
3936 const intptr_t num_types = Length(); 3942 const intptr_t num_types = Length();
3937 AbstractType& type = AbstractType::Handle(isolate); 3943 AbstractType& type = AbstractType::Handle(isolate);
3938 for (intptr_t i = 0; i < num_types; i++) { 3944 for (intptr_t i = 0; i < num_types; i++) {
3939 type = TypeAt(i); 3945 type = TypeAt(i);
3940 type = type.Canonicalize(); 3946 type = type.Canonicalize(trail);
3941 SetTypeAt(i, type); 3947 SetTypeAt(i, type);
3942 } 3948 }
3943 // Make sure we have an old space object and add it to the table. 3949 // Make sure we have an old space object and add it to the table.
3944 if (this->IsNew()) { 3950 if (this->IsNew()) {
3945 result ^= Object::Clone(*this, Heap::kOld); 3951 result ^= Object::Clone(*this, Heap::kOld);
3946 } else { 3952 } else {
3947 result ^= this->raw(); 3953 result ^= this->raw();
3948 } 3954 }
3949 ASSERT(result.IsOld()); 3955 ASSERT(result.IsOld());
3950 InsertIntoCanonicalTypeArguments(isolate, table, result, index); 3956 InsertIntoCanonicalTypeArguments(isolate, table, result, index);
(...skipping 7596 matching lines...) Expand 10 before | Expand all | Expand 10 after
11547 } 11553 }
11548 11554
11549 11555
11550 intptr_t AbstractType::token_pos() const { 11556 intptr_t AbstractType::token_pos() const {
11551 // AbstractType is an abstract class. 11557 // AbstractType is an abstract class.
11552 UNREACHABLE(); 11558 UNREACHABLE();
11553 return -1; 11559 return -1;
11554 } 11560 }
11555 11561
11556 11562
11557 bool AbstractType::IsInstantiated() const { 11563 bool AbstractType::IsInstantiated(GrowableObjectArray* trail) const {
11558 // AbstractType is an abstract class. 11564 // AbstractType is an abstract class.
11559 UNREACHABLE(); 11565 UNREACHABLE();
11560 return false; 11566 return false;
11561 } 11567 }
11562 11568
11563 11569
11564 bool AbstractType::IsFinalized() const { 11570 bool AbstractType::IsFinalized() const {
11565 // AbstractType is an abstract class. 11571 // AbstractType is an abstract class.
11566 UNREACHABLE(); 11572 UNREACHABLE();
11567 return false; 11573 return false;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
11602 return LanguageError::null(); 11608 return LanguageError::null();
11603 } 11609 }
11604 11610
11605 11611
11606 void AbstractType::set_error(const LanguageError& value) const { 11612 void AbstractType::set_error(const LanguageError& value) const {
11607 // AbstractType is an abstract class. 11613 // AbstractType is an abstract class.
11608 UNREACHABLE(); 11614 UNREACHABLE();
11609 } 11615 }
11610 11616
11611 11617
11612 bool AbstractType::Equals(const Instance& other) const { 11618 bool AbstractType::IsEquivalent(const Instance& other,
11619 GrowableObjectArray* trail) const {
11613 // AbstractType is an abstract class. 11620 // AbstractType is an abstract class.
11614 UNREACHABLE(); 11621 UNREACHABLE();
11615 return false; 11622 return false;
11616 } 11623 }
11617 11624
11618 11625
11619 RawAbstractType* AbstractType::InstantiateFrom( 11626 RawAbstractType* AbstractType::InstantiateFrom(
11620 const AbstractTypeArguments& instantiator_type_arguments, 11627 const AbstractTypeArguments& instantiator_type_arguments,
11621 Error* bound_error) const { 11628 Error* bound_error,
11629 GrowableObjectArray* trail) const {
11622 // AbstractType is an abstract class. 11630 // AbstractType is an abstract class.
11623 UNREACHABLE(); 11631 UNREACHABLE();
11624 return NULL; 11632 return NULL;
11625 } 11633 }
11626 11634
11627 11635
11628 RawAbstractType* AbstractType::CloneUnfinalized() const { 11636 RawAbstractType* AbstractType::CloneUnfinalized() const {
11629 // AbstractType is an abstract class. 11637 // AbstractType is an abstract class.
11630 UNREACHABLE(); 11638 UNREACHABLE();
11631 return NULL; 11639 return NULL;
11632 } 11640 }
11633 11641
11634 11642
11635 RawAbstractType* AbstractType::Canonicalize() const { 11643 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const {
11636 // AbstractType is an abstract class. 11644 // AbstractType is an abstract class.
11637 UNREACHABLE(); 11645 UNREACHABLE();
11638 return NULL; 11646 return NULL;
11639 } 11647 }
11640 11648
11641 11649
11642 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { 11650 RawString* AbstractType::BuildName(NameVisibility name_visibility) const {
11643 if (IsBoundedType()) { 11651 if (IsBoundedType()) {
11644 const AbstractType& type = AbstractType::Handle( 11652 const AbstractType& type = AbstractType::Handle(
11645 BoundedType::Cast(*this).type()); 11653 BoundedType::Cast(*this).type());
11646 if (name_visibility == kUserVisibleName) { 11654 if (name_visibility == kUserVisibleName) {
11647 return type.BuildName(kUserVisibleName); 11655 return type.BuildName(kUserVisibleName);
11648 } 11656 }
11649 String& type_name = String::Handle(type.BuildName(kInternalName)); 11657 String& type_name = String::Handle(type.BuildName(kInternalName));
11650 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); 11658 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace());
11651 // Building the bound name may lead into cycles. 11659 // Build the bound name without causing divergence.
11652 const AbstractType& bound = AbstractType::Handle( 11660 const AbstractType& bound = AbstractType::Handle(
11653 BoundedType::Cast(*this).bound()); 11661 BoundedType::Cast(*this).bound());
11654 String& bound_name = String::Handle(); 11662 String& bound_name = String::Handle();
11655 if (bound.IsTypeParameter()) { 11663 if (bound.IsTypeParameter()) {
11656 bound_name = TypeParameter::Cast(bound).name(); 11664 bound_name = TypeParameter::Cast(bound).name();
11657 } else if (bound.IsType()) { 11665 } else if (bound.IsType()) {
11658 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); 11666 const Class& cls = Class::Handle(Type::Cast(bound).type_class());
11659 bound_name = cls.Name(); 11667 bound_name = cls.Name();
11660 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { 11668 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) {
11661 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); 11669 bound_name = String::Concat(bound_name, Symbols::OptimizedOut());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
11702 // The actual type argument vector can be longer than necessary, because 11710 // The actual type argument vector can be longer than necessary, because
11703 // of type optimizations. 11711 // of type optimizations.
11704 if (IsFinalized() && cls.is_type_finalized()) { 11712 if (IsFinalized() && cls.is_type_finalized()) {
11705 first_type_param_index = cls.NumTypeArguments() - num_type_params; 11713 first_type_param_index = cls.NumTypeArguments() - num_type_params;
11706 } else { 11714 } else {
11707 first_type_param_index = num_args - num_type_params; 11715 first_type_param_index = num_args - num_type_params;
11708 } 11716 }
11709 } 11717 }
11710 if (cls.IsSignatureClass()) { 11718 if (cls.IsSignatureClass()) {
11711 // We may be reporting an error about a malformed function type. In that 11719 // We may be reporting an error about a malformed function type. In that
11712 // case, avoid instantiating the signature, since it may lead to cycles. 11720 // case, avoid instantiating the signature, since it may cause divergence.
11713 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { 11721 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
11714 return class_name.raw(); 11722 return class_name.raw();
11715 } 11723 }
11716 // In order to avoid cycles, print the name of a typedef (non-canonical 11724 // To avoid divergence, print the name of a typedef (non-canonical
11717 // signature class) as a regular, possibly parameterized, class. 11725 // signature class) as a regular, possibly parameterized, class.
11718 if (cls.IsCanonicalSignatureClass()) { 11726 if (cls.IsCanonicalSignatureClass()) {
11719 const Function& signature_function = Function::Handle( 11727 const Function& signature_function = Function::Handle(
11720 cls.signature_function()); 11728 cls.signature_function());
11721 // Signature classes have no super type, however, they take as many 11729 // Signature classes have no super type, however, they take as many
11722 // type arguments as the owner class of their signature function (if it 11730 // type arguments as the owner class of their signature function (if it
11723 // is non static and generic, see Class::NumTypeArguments()). Therefore, 11731 // is non static and generic, see Class::NumTypeArguments()). Therefore,
11724 // first_type_param_index may be greater than 0 here. 11732 // first_type_param_index may be greater than 0 here.
11725 return signature_function.InstantiatedSignatureFrom(args, 11733 return signature_function.InstantiatedSignatureFrom(args,
11726 name_visibility); 11734 name_visibility);
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
12111 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); 12119 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_);
12112 #endif 12120 #endif
12113 } 12121 }
12114 12122
12115 12123
12116 RawAbstractTypeArguments* Type::arguments() const { 12124 RawAbstractTypeArguments* Type::arguments() const {
12117 return raw_ptr()->arguments_; 12125 return raw_ptr()->arguments_;
12118 } 12126 }
12119 12127
12120 12128
12121 bool Type::IsInstantiated() const { 12129 bool Type::IsInstantiated(GrowableObjectArray* trail) const {
12122 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { 12130 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
12123 return true; 12131 return true;
12124 } 12132 }
12125 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { 12133 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) {
12126 return false; 12134 return false;
12127 } 12135 }
12128 const AbstractTypeArguments& args = 12136 const AbstractTypeArguments& args =
12129 AbstractTypeArguments::Handle(arguments()); 12137 AbstractTypeArguments::Handle(arguments());
12130 return args.IsNull() || args.IsInstantiated(); 12138 return args.IsNull() || args.IsInstantiated(trail);
12131 } 12139 }
12132 12140
12133 12141
12134 RawAbstractType* Type::InstantiateFrom( 12142 RawAbstractType* Type::InstantiateFrom(
12135 const AbstractTypeArguments& instantiator_type_arguments, 12143 const AbstractTypeArguments& instantiator_type_arguments,
12136 Error* bound_error) const { 12144 Error* bound_error,
12145 GrowableObjectArray* trail) const {
12137 ASSERT(IsFinalized() || IsBeingFinalized()); 12146 ASSERT(IsFinalized() || IsBeingFinalized());
12138 ASSERT(!IsInstantiated()); 12147 ASSERT(!IsInstantiated());
12139 // Return the uninstantiated type unchanged if malformed. No copy needed. 12148 // Return the uninstantiated type unchanged if malformed. No copy needed.
12140 if (IsMalformed()) { 12149 if (IsMalformed()) {
12141 return raw(); 12150 return raw();
12142 } 12151 }
12143 AbstractTypeArguments& type_arguments = 12152 AbstractTypeArguments& type_arguments =
12144 AbstractTypeArguments::Handle(arguments()); 12153 AbstractTypeArguments::Handle(arguments());
12145 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, 12154 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
12146 bound_error); 12155 bound_error,
12156 trail);
12147 // Note that the type class has to be resolved at this time, but not 12157 // Note that the type class has to be resolved at this time, but not
12148 // necessarily finalized yet. We may be checking bounds at compile time. 12158 // necessarily finalized yet. We may be checking bounds at compile time.
12149 const Class& cls = Class::Handle(type_class()); 12159 const Class& cls = Class::Handle(type_class());
12150 // This uninstantiated type is not modified, as it can be instantiated 12160 // This uninstantiated type is not modified, as it can be instantiated
12151 // with different instantiators. 12161 // with different instantiators.
12152 Type& instantiated_type = Type::Handle( 12162 Type& instantiated_type = Type::Handle(
12153 Type::New(cls, type_arguments, token_pos())); 12163 Type::New(cls, type_arguments, token_pos()));
12154 ASSERT(type_arguments.IsNull() || 12164 ASSERT(type_arguments.IsNull() ||
12155 (type_arguments.Length() == cls.NumTypeArguments())); 12165 (type_arguments.Length() == cls.NumTypeArguments()));
12156 instantiated_type.SetIsFinalized(); 12166 instantiated_type.SetIsFinalized();
12157 return instantiated_type.raw(); 12167 return instantiated_type.raw();
12158 } 12168 }
12159 12169
12160 12170
12161 bool Type::Equals(const Instance& other) const { 12171 bool Type::IsEquivalent(const Instance& other,
12172 GrowableObjectArray* trail) const {
12162 ASSERT(!IsNull()); 12173 ASSERT(!IsNull());
12163 if (raw() == other.raw()) { 12174 if (raw() == other.raw()) {
12164 return true; 12175 return true;
12165 } 12176 }
12166 if (other.IsTypeRef()) { 12177 if (other.IsTypeRef()) {
12167 // TODO(regis): Use trail. For now, we "unfold" the right hand type. 12178 // Unfold right hand type. Divergence is controlled by left hand type.
12168 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); 12179 const AbstractType& other_ref_type = AbstractType::Handle(
12180 TypeRef::Cast(other).type());
12181 ASSERT(!other_ref_type.IsTypeRef());
12182 return IsEquivalent(other_ref_type, trail);
12169 } 12183 }
12170 if (!other.IsType()) { 12184 if (!other.IsType()) {
12171 return false; 12185 return false;
12172 } 12186 }
12173 const Type& other_type = Type::Cast(other); 12187 const Type& other_type = Type::Cast(other);
12174 ASSERT(IsResolved() && other_type.IsResolved()); 12188 ASSERT(IsResolved() && other_type.IsResolved());
12175 if (IsMalformed() || other_type.IsMalformed()) { 12189 if (IsMalformed() || other_type.IsMalformed()) {
12176 return false; 12190 return false;
12177 } 12191 }
12178 if (type_class() != other_type.type_class()) { 12192 if (type_class() != other_type.type_class()) {
(...skipping 23 matching lines...) Expand all
12202 if (other_type_args.IsNull()) { 12216 if (other_type_args.IsNull()) {
12203 return type_args.IsRaw(from_index, num_type_params); 12217 return type_args.IsRaw(from_index, num_type_params);
12204 } 12218 }
12205 ASSERT(type_args.Length() >= (from_index + num_type_params)); 12219 ASSERT(type_args.Length() >= (from_index + num_type_params));
12206 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); 12220 ASSERT(other_type_args.Length() >= (from_index + num_type_params));
12207 AbstractType& type_arg = AbstractType::Handle(); 12221 AbstractType& type_arg = AbstractType::Handle();
12208 AbstractType& other_type_arg = AbstractType::Handle(); 12222 AbstractType& other_type_arg = AbstractType::Handle();
12209 for (intptr_t i = 0; i < num_type_params; i++) { 12223 for (intptr_t i = 0; i < num_type_params; i++) {
12210 type_arg = type_args.TypeAt(from_index + i); 12224 type_arg = type_args.TypeAt(from_index + i);
12211 other_type_arg = other_type_args.TypeAt(from_index + i); 12225 other_type_arg = other_type_args.TypeAt(from_index + i);
12212 if (!type_arg.Equals(other_type_arg)) { 12226 if (!type_arg.IsEquivalent(other_type_arg, trail)) {
12213 return false; 12227 return false;
12214 } 12228 }
12215 } 12229 }
12216 return true; 12230 return true;
12217 } 12231 }
12218 12232
12219 12233
12220 RawAbstractType* Type::CloneUnfinalized() const { 12234 RawAbstractType* Type::CloneUnfinalized() const {
12221 ASSERT(IsResolved()); 12235 ASSERT(IsResolved());
12222 if (IsFinalized()) { 12236 if (IsFinalized()) {
12223 return raw(); 12237 return raw();
12224 } 12238 }
12225 ASSERT(!IsMalformed()); // Malformed types are finalized. 12239 ASSERT(!IsMalformed()); // Malformed types are finalized.
12226 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. 12240 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization.
12227 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); 12241 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments());
12228 type_args = type_args.CloneUnfinalized(); 12242 type_args = type_args.CloneUnfinalized();
12229 const Class& type_cls = Class::Handle(type_class()); 12243 const Class& type_cls = Class::Handle(type_class());
12230 return Type::New(type_cls, type_args, token_pos()); 12244 return Type::New(type_cls, type_args, token_pos());
12231 } 12245 }
12232 12246
12233 12247
12234 RawAbstractType* Type::Canonicalize() const { 12248 RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
12235 ASSERT(IsFinalized()); 12249 ASSERT(IsFinalized());
12236 if (IsCanonical() || IsMalformed()) { 12250 if (IsCanonical() || IsMalformed()) {
12237 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); 12251 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld());
12238 return this->raw(); 12252 return this->raw();
12239 } 12253 }
12240 Isolate* isolate = Isolate::Current(); 12254 Isolate* isolate = Isolate::Current();
12241 Type& type = Type::Handle(isolate); 12255 Type& type = Type::Handle(isolate);
12242 const Class& cls = Class::Handle(isolate, type_class()); 12256 const Class& cls = Class::Handle(isolate, type_class());
12243 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) { 12257 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
12244 return Object::dynamic_type(); 12258 return Object::dynamic_type();
(...skipping 30 matching lines...) Expand all
12275 ASSERT(type.IsFinalized()); 12289 ASSERT(type.IsFinalized());
12276 if (this->Equals(type)) { 12290 if (this->Equals(type)) {
12277 return type.raw(); 12291 return type.raw();
12278 } 12292 }
12279 index++; 12293 index++;
12280 } 12294 }
12281 // Canonicalize the type arguments. 12295 // Canonicalize the type arguments.
12282 AbstractTypeArguments& type_args = 12296 AbstractTypeArguments& type_args =
12283 AbstractTypeArguments::Handle(isolate, arguments()); 12297 AbstractTypeArguments::Handle(isolate, arguments());
12284 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); 12298 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments()));
12285 type_args = type_args.Canonicalize(); 12299 type_args = type_args.Canonicalize(trail);
12286 set_arguments(type_args); 12300 set_arguments(type_args);
12287 // The type needs to be added to the list. Grow the list if it is full. 12301 // The type needs to be added to the list. Grow the list if it is full.
12288 if (index == canonical_types_len) { 12302 if (index == canonical_types_len) {
12289 const intptr_t kLengthIncrement = 2; // Raw and parameterized. 12303 const intptr_t kLengthIncrement = 2; // Raw and parameterized.
12290 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; 12304 const intptr_t new_length = canonical_types.Length() + kLengthIncrement;
12291 const Array& new_canonical_types = Array::Handle( 12305 const Array& new_canonical_types = Array::Handle(
12292 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); 12306 isolate, Array::Grow(canonical_types, new_length, Heap::kOld));
12293 cls.set_canonical_types(new_canonical_types); 12307 cls.set_canonical_types(new_canonical_types);
12294 new_canonical_types.SetAt(index, *this); 12308 new_canonical_types.SetAt(index, *this);
12295 } else { 12309 } else {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
12413 return "Unresolved Type"; 12427 return "Unresolved Type";
12414 } 12428 }
12415 } 12429 }
12416 12430
12417 12431
12418 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { 12432 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const {
12419 JSONObject jsobj(stream); 12433 JSONObject jsobj(stream);
12420 } 12434 }
12421 12435
12422 12436
12423 bool TypeRef::IsInstantiated() const { 12437 bool TypeRef::IsInstantiated(GrowableObjectArray* trail) const {
12424 if (is_being_checked()) { 12438 if (TestAndAddToTrail(&trail)) {
12425 return true; 12439 return true;
12426 } 12440 }
12427 set_is_being_checked(true); 12441 return AbstractType::Handle(type()).IsInstantiated(trail);
12428 const bool result = AbstractType::Handle(type()).IsInstantiated();
12429 set_is_being_checked(false);
12430 return result;
12431 } 12442 }
12432 12443
12433 12444
12434 bool TypeRef::Equals(const Instance& other) const { 12445 bool TypeRef::IsEquivalent(const Instance& other,
12435 // TODO(regis): Use trail instead of mark bit. 12446 GrowableObjectArray* trail) const {
12436 if (raw() == other.raw()) { 12447 if (raw() == other.raw()) {
12437 return true; 12448 return true;
12438 } 12449 }
12439 if (is_being_checked()) { 12450 if (TestAndAddBuddyToTrail(&trail, other)) {
12440 return true; 12451 return true;
12441 } 12452 }
12442 set_is_being_checked(true); 12453 return AbstractType::Handle(type()).IsEquivalent(other, trail);
12443 const bool result = AbstractType::Handle(type()).Equals(other);
12444 set_is_being_checked(false);
12445 return result;
12446 } 12454 }
12447 12455
12448 12456
12449 RawAbstractType* TypeRef::InstantiateFrom( 12457 RawAbstractType* TypeRef::InstantiateFrom(
12450 const AbstractTypeArguments& instantiator_type_arguments, 12458 const AbstractTypeArguments& instantiator_type_arguments,
12451 Error* bound_error) const { 12459 Error* bound_error,
12460 GrowableObjectArray* trail) const {
12461 TypeRef& instantiated_type_ref = TypeRef::Handle();
12462 instantiated_type_ref ^= BuddyInTrail(trail);
12463 if (!instantiated_type_ref.IsNull()) {
12464 return instantiated_type_ref.raw();
12465 }
12466 instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType()));
12467 AddBuddyToTrail(&trail, instantiated_type_ref);
12452 const AbstractType& ref_type = AbstractType::Handle(type()); 12468 const AbstractType& ref_type = AbstractType::Handle(type());
12453 // TODO(regis): Use trail instead of mark bit plus temporary redirection,
12454 // because it could be marked for another reason.
12455 if (is_being_checked()) {
12456 ASSERT(ref_type.IsTypeRef());
12457 return ref_type.raw();
12458 }
12459 set_is_being_checked(true);
12460 ASSERT(!ref_type.IsTypeRef()); 12469 ASSERT(!ref_type.IsTypeRef());
12461 const TypeRef& instantiated_type_ref = TypeRef::Handle(
12462 TypeRef::New(ref_type));
12463 // TODO(regis): instantiated_type_ref should be stored in the trail instead.
12464 set_type(instantiated_type_ref);
12465 const AbstractType& instantiated_ref_type = AbstractType::Handle( 12470 const AbstractType& instantiated_ref_type = AbstractType::Handle(
12466 ref_type.InstantiateFrom(instantiator_type_arguments, bound_error)); 12471 ref_type.InstantiateFrom(instantiator_type_arguments,
12472 bound_error,
12473 trail));
12467 instantiated_type_ref.set_type(instantiated_ref_type); 12474 instantiated_type_ref.set_type(instantiated_ref_type);
12468 set_type(ref_type);
12469 set_is_being_checked(false);
12470 return instantiated_type_ref.raw(); 12475 return instantiated_type_ref.raw();
12471 } 12476 }
12472 12477
12473 12478
12474 void TypeRef::set_type(const AbstractType& value) const { 12479 void TypeRef::set_type(const AbstractType& value) const {
12475 ASSERT(value.HasResolvedTypeClass()); 12480 ASSERT(value.HasResolvedTypeClass());
12476 StorePointer(&raw_ptr()->type_, value.raw()); 12481 StorePointer(&raw_ptr()->type_, value.raw());
12477 } 12482 }
12478 12483
12479 12484
12480 void TypeRef::set_is_being_checked(bool value) const { 12485 // A TypeRef cannot be canonical by definition. Only its referenced type can be.
12481 raw_ptr()->is_being_checked_ = value;
12482 }
12483
12484
12485 // This function only canonicalizes the referenced type, but not the TypeRef
12486 // itself, since it cannot be canonical by definition.
12487 // Consider the type Derived, where class Derived extends Base<Derived>. 12486 // Consider the type Derived, where class Derived extends Base<Derived>.
12488 // The first type argument of its flattened type argument vector is Derived, 12487 // The first type argument of its flattened type argument vector is Derived,
12489 // i.e. itself, but pointer equality is not possible. 12488 // i.e. itself, but pointer equality is not possible.
12490 RawAbstractType* TypeRef::Canonicalize() const { 12489 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const {
12491 // TODO(regis): Use trail, not mark bit. 12490 if (TestAndAddToTrail(&trail)) {
12492 if (is_being_checked()) {
12493 return raw(); 12491 return raw();
12494 } 12492 }
12495 set_is_being_checked(true);
12496 AbstractType& ref_type = AbstractType::Handle(type()); 12493 AbstractType& ref_type = AbstractType::Handle(type());
12497 ASSERT(!ref_type.IsTypeRef()); 12494 ref_type = ref_type.Canonicalize(trail);
12498 ref_type = ref_type.Canonicalize();
12499 set_type(ref_type); 12495 set_type(ref_type);
12500 // No need to call SetCanonical(), since a TypeRef cannot be canonical by 12496 return raw();
12501 // definition.
12502 set_is_being_checked(false);
12503 // We return the referenced type instead of the TypeRef in order to provide
12504 // pointer equality in simple cases, e.g. in language/f_bounded_equality_test.
12505 return ref_type.raw();
12506 } 12497 }
12507 12498
12508 12499
12509 intptr_t TypeRef::Hash() const { 12500 intptr_t TypeRef::Hash() const {
12510 // TODO(regis): Use trail and hash of referenced type. 12501 // Do not calculate the hash of the referenced type to avoid divergence.
12511 // Do not calculate the hash of the referenced type to avoid cycles.
12512 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); 12502 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id();
12513 return FinalizeHash(result); 12503 return FinalizeHash(result);
12514 } 12504 }
12515 12505
12516 12506
12507 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const {
12508 if (*trail == NULL) {
12509 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12510 } else {
12511 const intptr_t len = (*trail)->Length();
12512 for (intptr_t i = 0; i < len; i++) {
12513 if ((*trail)->At(i) == this->raw()) {
12514 return true;
12515 }
12516 }
12517 }
12518 (*trail)->Add(*this);
12519 return false;
12520 }
12521
12522
12523 bool TypeRef::TestAndAddBuddyToTrail(GrowableObjectArray** trail,
12524 const Object& buddy) const {
12525 if (*trail == NULL) {
12526 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12527 } else {
12528 const intptr_t len = (*trail)->Length();
12529 ASSERT((len % 2) == 0);
12530 for (intptr_t i = 0; i < len; i += 2) {
12531 if (((*trail)->At(i) == this->raw()) &&
12532 ((*trail)->At(i + 1) == buddy.raw())) {
12533 return true;
12534 }
12535 }
12536 }
12537 (*trail)->Add(*this);
12538 (*trail)->Add(buddy);
siva 2013/12/20 19:35:10 The code in this function seems to imply that a re
regis 2014/01/07 20:26:27 I renamed the other function AddOnlyBuddyToTrail.
12539 return false;
12540 }
12541
12542
12543 RawObject* TypeRef::BuddyInTrail(GrowableObjectArray* trail) const {
12544 if (trail == NULL) {
12545 return Object::null();
12546 }
12547 const intptr_t len = trail->Length();
12548 ASSERT((len % 2) == 0);
12549 for (intptr_t i = 0; i < len; i += 2) {
12550 if (trail->At(i) == this->raw()) {
siva 2013/12/20 19:35:10 Should there be an assert here: ASSERT(trail->At(i
regis 2014/01/07 20:26:27 Done.
12551 return trail->At(i + 1);
12552 }
12553 }
12554 return Object::null();
12555 }
12556
12557
12558 void TypeRef::AddBuddyToTrail(GrowableObjectArray** trail,
12559 const Object& buddy) const {
12560 if (*trail == NULL) {
12561 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12562 } else {
12563 ASSERT(BuddyInTrail(*trail) == Object::null());
12564 }
12565 (*trail)->Add(*this);
12566 (*trail)->Add(buddy);
12567 }
12568
12569
12517 RawTypeRef* TypeRef::New() { 12570 RawTypeRef* TypeRef::New() {
12518 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); 12571 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null());
12519 RawObject* raw = Object::Allocate(TypeRef::kClassId, 12572 RawObject* raw = Object::Allocate(TypeRef::kClassId,
12520 TypeRef::InstanceSize(), 12573 TypeRef::InstanceSize(),
12521 Heap::kOld); 12574 Heap::kOld);
12522 return reinterpret_cast<RawTypeRef*>(raw); 12575 return reinterpret_cast<RawTypeRef*>(raw);
12523 } 12576 }
12524 12577
12525 12578
12526 RawTypeRef* TypeRef::New(const AbstractType& type) { 12579 RawTypeRef* TypeRef::New(const AbstractType& type) {
12527 const TypeRef& result = TypeRef::Handle(TypeRef::New()); 12580 const TypeRef& result = TypeRef::Handle(TypeRef::New());
12528 result.set_type(type); 12581 result.set_type(type);
12529 result.set_is_being_checked(false);
12530 return result.raw(); 12582 return result.raw();
12531 } 12583 }
12532 12584
12533 12585
12534 const char* TypeRef::ToCString() const { 12586 const char* TypeRef::ToCString() const {
12535 const char* format = "TypeRef: %s%s"; 12587 const char* format = "TypeRef: %s%s";
12536 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( 12588 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle(
12537 type()).type_class()).Name()).ToCString(); 12589 type()).type_class()).Name()).ToCString();
12538 const char* args_cstr = (AbstractType::Handle( 12590 const char* args_cstr = (AbstractType::Handle(
12539 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; 12591 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>";
12540 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; 12592 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1;
12541 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 12593 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
12542 OS::SNPrint(chars, len, format, type_cstr, args_cstr); 12594 OS::SNPrint(chars, len, format, type_cstr, args_cstr);
12543 return chars; 12595 return chars;
12544 } 12596 }
12545 12597
12546 12598
12547 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { 12599 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const {
12548 JSONObject jsobj(stream); 12600 JSONObject jsobj(stream);
12549 } 12601 }
12550 12602
12551 12603
12552 void TypeParameter::set_is_finalized() const { 12604 void TypeParameter::set_is_finalized() const {
12553 ASSERT(!IsFinalized()); 12605 ASSERT(!IsFinalized());
12554 set_type_state(RawTypeParameter::kFinalizedUninstantiated); 12606 set_type_state(RawTypeParameter::kFinalizedUninstantiated);
12555 } 12607 }
12556 12608
12557 12609
12558 bool TypeParameter::Equals(const Instance& other) const { 12610 bool TypeParameter::IsEquivalent(const Instance& other,
12611 GrowableObjectArray* trail) const {
12559 if (raw() == other.raw()) { 12612 if (raw() == other.raw()) {
12560 return true; 12613 return true;
12561 } 12614 }
12562 if (other.IsTypeRef()) { 12615 if (other.IsTypeRef()) {
12563 // TODO(regis): Use trail. For now, we "unfold" the right hand type. 12616 // Unfold right hand type. Divergence is controlled by left hand type.
12564 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); 12617 const AbstractType& other_ref_type = AbstractType::Handle(
12618 TypeRef::Cast(other).type());
12619 ASSERT(!other_ref_type.IsTypeRef());
12620 return IsEquivalent(other_ref_type, trail);
12565 } 12621 }
12566 if (!other.IsTypeParameter()) { 12622 if (!other.IsTypeParameter()) {
12567 return false; 12623 return false;
12568 } 12624 }
12569 const TypeParameter& other_type_param = TypeParameter::Cast(other); 12625 const TypeParameter& other_type_param = TypeParameter::Cast(other);
12570 if (parameterized_class() != other_type_param.parameterized_class()) { 12626 if (parameterized_class() != other_type_param.parameterized_class()) {
12571 return false; 12627 return false;
12572 } 12628 }
12573 if (IsFinalized() == other_type_param.IsFinalized()) { 12629 if (IsFinalized() == other_type_param.IsFinalized()) {
12574 return index() == other_type_param.index(); 12630 return index() == other_type_param.index();
(...skipping 20 matching lines...) Expand all
12595 } 12651 }
12596 12652
12597 12653
12598 void TypeParameter::set_bound(const AbstractType& value) const { 12654 void TypeParameter::set_bound(const AbstractType& value) const {
12599 StorePointer(&raw_ptr()->bound_, value.raw()); 12655 StorePointer(&raw_ptr()->bound_, value.raw());
12600 } 12656 }
12601 12657
12602 12658
12603 RawAbstractType* TypeParameter::InstantiateFrom( 12659 RawAbstractType* TypeParameter::InstantiateFrom(
12604 const AbstractTypeArguments& instantiator_type_arguments, 12660 const AbstractTypeArguments& instantiator_type_arguments,
12605 Error* bound_error) const { 12661 Error* bound_error,
12662 GrowableObjectArray* trail) const {
12606 ASSERT(IsFinalized()); 12663 ASSERT(IsFinalized());
12607 if (instantiator_type_arguments.IsNull()) { 12664 if (instantiator_type_arguments.IsNull()) {
12608 return Type::DynamicType(); 12665 return Type::DynamicType();
12609 } 12666 }
12610 const AbstractType& type_arg = AbstractType::Handle( 12667 const AbstractType& type_arg = AbstractType::Handle(
12611 instantiator_type_arguments.TypeAt(index())); 12668 instantiator_type_arguments.TypeAt(index()));
12612 // There is no need to canonicalize the instantiated type parameter, since all 12669 // There is no need to canonicalize the instantiated type parameter, since all
12613 // type arguments are canonicalized at type finalization time. It would be too 12670 // type arguments are canonicalized at type finalization time. It would be too
12614 // early to canonicalize the returned type argument here, since instantiation 12671 // early to canonicalize the returned type argument here, since instantiation
12615 // not only happens at run time, but also during type finalization. 12672 // not only happens at run time, but also during type finalization.
12616 // However, if the type argument is a reference to a canonical type, we
12617 // return the referenced canonical type instead of the type reference to
12618 // provide pointer equality in some simple cases, e.g. in
12619 // language/f_bounded_equality_test.
12620 if (type_arg.IsTypeRef()) {
12621 const AbstractType& ref_type = AbstractType::Handle(
12622 TypeRef::Cast(type_arg).type());
12623 if (ref_type.IsCanonical()) {
12624 return ref_type.raw();
12625 }
12626 }
12627 return type_arg.raw(); 12673 return type_arg.raw();
12628 } 12674 }
12629 12675
12630 12676
12631 bool TypeParameter::CheckBound(const AbstractType& bounded_type, 12677 bool TypeParameter::CheckBound(const AbstractType& bounded_type,
12632 const AbstractType& upper_bound, 12678 const AbstractType& upper_bound,
12633 Error* bound_error) const { 12679 Error* bound_error) const {
12634 ASSERT((bound_error != NULL) && bound_error->IsNull()); 12680 ASSERT((bound_error != NULL) && bound_error->IsNull());
12635 ASSERT(bounded_type.IsFinalized()); 12681 ASSERT(bounded_type.IsFinalized());
12636 ASSERT(upper_bound.IsFinalized()); 12682 ASSERT(upper_bound.IsFinalized());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
12683 index(), 12729 index(),
12684 String::Handle(name()), 12730 String::Handle(name()),
12685 AbstractType::Handle(bound()), 12731 AbstractType::Handle(bound()),
12686 token_pos()); 12732 token_pos());
12687 } 12733 }
12688 12734
12689 12735
12690 intptr_t TypeParameter::Hash() const { 12736 intptr_t TypeParameter::Hash() const {
12691 ASSERT(IsFinalized()); 12737 ASSERT(IsFinalized());
12692 uword result = Class::Handle(parameterized_class()).id(); 12738 uword result = Class::Handle(parameterized_class()).id();
12693 // Do not include the hash of the bound, which could lead to cycles. 12739 // No need to include the hash of the bound, since the type parameter is fully
12740 // identified by its class and index.
12694 result <<= index(); 12741 result <<= index();
12695 return FinalizeHash(result); 12742 return FinalizeHash(result);
12696 } 12743 }
12697 12744
12698 12745
12699 RawTypeParameter* TypeParameter::New() { 12746 RawTypeParameter* TypeParameter::New() {
12700 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != 12747 ASSERT(Isolate::Current()->object_store()->type_parameter_class() !=
12701 Class::null()); 12748 Class::null());
12702 RawObject* raw = Object::Allocate(TypeParameter::kClassId, 12749 RawObject* raw = Object::Allocate(TypeParameter::kClassId,
12703 TypeParameter::InstanceSize(), 12750 TypeParameter::InstanceSize(),
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
12767 bool BoundedType::IsMalformedOrMalbounded() const { 12814 bool BoundedType::IsMalformedOrMalbounded() const {
12768 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); 12815 return AbstractType::Handle(type()).IsMalformedOrMalbounded();
12769 } 12816 }
12770 12817
12771 12818
12772 RawLanguageError* BoundedType::error() const { 12819 RawLanguageError* BoundedType::error() const {
12773 return AbstractType::Handle(type()).error(); 12820 return AbstractType::Handle(type()).error();
12774 } 12821 }
12775 12822
12776 12823
12777 bool BoundedType::Equals(const Instance& other) const { 12824 bool BoundedType::IsEquivalent(const Instance& other,
12825 GrowableObjectArray* trail) const {
12778 // BoundedType are not canonicalized, because their bound may get finalized 12826 // BoundedType are not canonicalized, because their bound may get finalized
12779 // after the BoundedType is created and initialized. 12827 // after the BoundedType is created and initialized.
12780 if (raw() == other.raw()) { 12828 if (raw() == other.raw()) {
12781 return true; 12829 return true;
12782 } 12830 }
12783 if (other.IsTypeRef()) { 12831 if (other.IsTypeRef()) {
12784 // TODO(regis): Use trail. For now, we "unfold" the right hand type. 12832 // Unfold right hand type. Divergence is controlled by left hand type.
12785 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); 12833 const AbstractType& other_ref_type = AbstractType::Handle(
12834 TypeRef::Cast(other).type());
12835 ASSERT(!other_ref_type.IsTypeRef());
12836 return IsEquivalent(other_ref_type, trail);
12786 } 12837 }
12787 if (!other.IsBoundedType()) { 12838 if (!other.IsBoundedType()) {
12788 return false; 12839 return false;
12789 } 12840 }
12790 const BoundedType& other_bounded = BoundedType::Cast(other); 12841 const BoundedType& other_bounded = BoundedType::Cast(other);
12791 if (type_parameter() != other_bounded.type_parameter()) { 12842 if (type_parameter() != other_bounded.type_parameter()) {
12792 // Not a structural compare.
12793 // Note that a deep comparison of bounds could lead to cycles.
12794 return false; 12843 return false;
12795 } 12844 }
12796 const AbstractType& this_type = AbstractType::Handle(type()); 12845 const AbstractType& this_type = AbstractType::Handle(type());
12797 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); 12846 const AbstractType& other_type = AbstractType::Handle(other_bounded.type());
12798 if (!this_type.Equals(other_type)) { 12847 if (!this_type.IsEquivalent(other_type, trail)) {
12799 return false; 12848 return false;
12800 } 12849 }
12801 const AbstractType& this_bound = AbstractType::Handle(bound()); 12850 const AbstractType& this_bound = AbstractType::Handle(bound());
12802 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); 12851 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound());
12803 return this_bound.IsFinalized() && 12852 return this_bound.IsFinalized() &&
12804 other_bound.IsFinalized() && 12853 other_bound.IsFinalized() &&
12805 this_bound.Equals(other_bound); 12854 this_bound.Equals(other_bound); // Different graph, do not pass trail.
12806 } 12855 }
12807 12856
12808 12857
12809 void BoundedType::set_type(const AbstractType& value) const { 12858 void BoundedType::set_type(const AbstractType& value) const {
12810 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); 12859 ASSERT(value.IsFinalized() || value.IsBeingFinalized());
12811 ASSERT(!value.IsMalformed()); 12860 ASSERT(!value.IsMalformed());
12812 StorePointer(&raw_ptr()->type_, value.raw()); 12861 StorePointer(&raw_ptr()->type_, value.raw());
12813 } 12862 }
12814 12863
12815 12864
12816 void BoundedType::set_bound(const AbstractType& value) const { 12865 void BoundedType::set_bound(const AbstractType& value) const {
12817 // The bound may still be unfinalized because of legal cycles. 12866 // The bound may still be unfinalized because of legal cycles.
12818 // It must be finalized before it is checked at run time, though. 12867 // It must be finalized before it is checked at run time, though.
12819 StorePointer(&raw_ptr()->bound_, value.raw()); 12868 StorePointer(&raw_ptr()->bound_, value.raw());
12820 } 12869 }
12821 12870
12822 12871
12823 void BoundedType::set_type_parameter(const TypeParameter& value) const { 12872 void BoundedType::set_type_parameter(const TypeParameter& value) const {
12824 // A null type parameter is set when marking a type malformed because of a 12873 // A null type parameter is set when marking a type malformed because of a
12825 // bound error at compile time. 12874 // bound error at compile time.
12826 ASSERT(value.IsNull() || value.IsFinalized()); 12875 ASSERT(value.IsNull() || value.IsFinalized());
12827 StorePointer(&raw_ptr()->type_parameter_, value.raw()); 12876 StorePointer(&raw_ptr()->type_parameter_, value.raw());
12828 } 12877 }
12829 12878
12830 12879
12831 void BoundedType::set_is_being_checked(bool value) const {
12832 raw_ptr()->is_being_checked_ = value;
12833 }
12834
12835
12836 RawAbstractType* BoundedType::InstantiateFrom( 12880 RawAbstractType* BoundedType::InstantiateFrom(
12837 const AbstractTypeArguments& instantiator_type_arguments, 12881 const AbstractTypeArguments& instantiator_type_arguments,
12838 Error* bound_error) const { 12882 Error* bound_error,
12883 GrowableObjectArray* trail) const {
12839 ASSERT(IsFinalized()); 12884 ASSERT(IsFinalized());
12840 AbstractType& bounded_type = AbstractType::Handle(type()); 12885 AbstractType& bounded_type = AbstractType::Handle(type());
12841 if (!bounded_type.IsInstantiated()) { 12886 if (!bounded_type.IsInstantiated()) {
12842 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, 12887 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments,
12843 bound_error); 12888 bound_error,
12889 trail);
12844 } 12890 }
12845 if (FLAG_enable_type_checks && 12891 if (FLAG_enable_type_checks && bound_error->IsNull()) {
12846 bound_error->IsNull() &&
12847 !is_being_checked()) {
12848 // Avoid endless recursion while checking and instantiating bound.
12849 set_is_being_checked(true);
12850 AbstractType& upper_bound = AbstractType::Handle(bound()); 12892 AbstractType& upper_bound = AbstractType::Handle(bound());
12851 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); 12893 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
12852 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); 12894 const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
12853 if (!upper_bound.IsInstantiated()) { 12895 if (!upper_bound.IsInstantiated()) {
12854 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, 12896 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
12855 bound_error); 12897 bound_error,
12898 trail);
12856 } 12899 }
12857 if (bound_error->IsNull()) { 12900 if (bound_error->IsNull()) {
12858 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && 12901 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
12859 bound_error->IsNull()) { 12902 bound_error->IsNull()) {
12860 // We cannot determine yet whether the bounded_type is below the 12903 // We cannot determine yet whether the bounded_type is below the
12861 // upper_bound, because one or both of them is still uninstantiated. 12904 // upper_bound, because one or both of them is still uninstantiated.
12862 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); 12905 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated());
12863 // Postpone bound check by returning a new BoundedType with partially 12906 // Postpone bound check by returning a new BoundedType with partially
12864 // instantiated bounded_type and upper_bound, but keeping type_param. 12907 // instantiated bounded_type and upper_bound, but keeping type_param.
12865 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); 12908 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param);
12866 } 12909 }
12867 } 12910 }
12868 set_is_being_checked(false);
12869 } 12911 }
12870 return bounded_type.raw(); 12912 return bounded_type.raw();
12871 } 12913 }
12872 12914
12873 12915
12874 RawAbstractType* BoundedType::CloneUnfinalized() const { 12916 RawAbstractType* BoundedType::CloneUnfinalized() const {
12875 if (IsFinalized()) { 12917 if (IsFinalized()) {
12876 return raw(); 12918 return raw();
12877 } 12919 }
12878 AbstractType& bounded_type = AbstractType::Handle(type()); 12920 AbstractType& bounded_type = AbstractType::Handle(type());
12879 12921
12880 bounded_type = bounded_type.CloneUnfinalized(); 12922 bounded_type = bounded_type.CloneUnfinalized();
12881 // No need to clone bound or type parameter, as they are not part of the 12923 // No need to clone bound or type parameter, as they are not part of the
12882 // finalization state of this bounded type. 12924 // finalization state of this bounded type.
12883 return BoundedType::New(bounded_type, 12925 return BoundedType::New(bounded_type,
12884 AbstractType::Handle(bound()), 12926 AbstractType::Handle(bound()),
12885 TypeParameter::Handle(type_parameter())); 12927 TypeParameter::Handle(type_parameter()));
12886 } 12928 }
12887 12929
12888 12930
12889 intptr_t BoundedType::Hash() const { 12931 intptr_t BoundedType::Hash() const {
12890 uword result = AbstractType::Handle(type()).Hash(); 12932 uword result = AbstractType::Handle(type()).Hash();
12891 // Do not include the hash of the bound, which could lead to cycles. 12933 // No need to include the hash of the bound, since the bound is defined by the
12934 // type parameter (modulo instantiation state).
12892 result += TypeParameter::Handle(type_parameter()).Hash(); 12935 result += TypeParameter::Handle(type_parameter()).Hash();
12893 return FinalizeHash(result); 12936 return FinalizeHash(result);
12894 } 12937 }
12895 12938
12896 12939
12897 RawBoundedType* BoundedType::New() { 12940 RawBoundedType* BoundedType::New() {
12898 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != 12941 ASSERT(Isolate::Current()->object_store()->bounded_type_class() !=
12899 Class::null()); 12942 Class::null());
12900 RawObject* raw = Object::Allocate(BoundedType::kClassId, 12943 RawObject* raw = Object::Allocate(BoundedType::kClassId,
12901 BoundedType::InstanceSize(), 12944 BoundedType::InstanceSize(),
12902 Heap::kOld); 12945 Heap::kOld);
12903 return reinterpret_cast<RawBoundedType*>(raw); 12946 return reinterpret_cast<RawBoundedType*>(raw);
12904 } 12947 }
12905 12948
12906 12949
12907 RawBoundedType* BoundedType::New(const AbstractType& type, 12950 RawBoundedType* BoundedType::New(const AbstractType& type,
12908 const AbstractType& bound, 12951 const AbstractType& bound,
12909 const TypeParameter& type_parameter) { 12952 const TypeParameter& type_parameter) {
12910 const BoundedType& result = BoundedType::Handle(BoundedType::New()); 12953 const BoundedType& result = BoundedType::Handle(BoundedType::New());
12911 result.set_type(type); 12954 result.set_type(type);
12912 result.set_bound(bound); 12955 result.set_bound(bound);
12913 result.set_type_parameter(type_parameter); 12956 result.set_type_parameter(type_parameter);
12914 result.set_is_being_checked(false);
12915 return result.raw(); 12957 return result.raw();
12916 } 12958 }
12917 12959
12918 12960
12919 const char* BoundedType::ToCString() const { 12961 const char* BoundedType::ToCString() const {
12920 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; 12962 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s";
12921 const char* type_cstr = String::Handle(AbstractType::Handle( 12963 const char* type_cstr = String::Handle(AbstractType::Handle(
12922 type()).Name()).ToCString(); 12964 type()).Name()).ToCString();
12923 const char* bound_cstr = String::Handle(AbstractType::Handle( 12965 const char* bound_cstr = String::Handle(AbstractType::Handle(
12924 bound()).Name()).ToCString(); 12966 bound()).Name()).ToCString();
(...skipping 3587 matching lines...) Expand 10 before | Expand all | Expand 10 after
16512 return "_MirrorReference"; 16554 return "_MirrorReference";
16513 } 16555 }
16514 16556
16515 16557
16516 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 16558 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
16517 Instance::PrintToJSONStream(stream, ref); 16559 Instance::PrintToJSONStream(stream, ref);
16518 } 16560 }
16519 16561
16520 16562
16521 } // namespace dart 16563 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698