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

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 6 years, 11 months 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3577 matching lines...) Expand 10 before | Expand all | Expand 10 after
3588 } 3588 }
3589 3589
3590 3590
3591 bool AbstractTypeArguments::IsResolved() const { 3591 bool AbstractTypeArguments::IsResolved() const {
3592 // AbstractTypeArguments is an abstract class. 3592 // AbstractTypeArguments is an abstract class.
3593 UNREACHABLE(); 3593 UNREACHABLE();
3594 return false; 3594 return false;
3595 } 3595 }
3596 3596
3597 3597
3598 bool AbstractTypeArguments::IsInstantiated() const { 3598 bool AbstractTypeArguments::IsInstantiated(GrowableObjectArray* trail) const {
3599 // AbstractTypeArguments is an abstract class. 3599 // AbstractTypeArguments is an abstract class.
3600 UNREACHABLE(); 3600 UNREACHABLE();
3601 return false; 3601 return false;
3602 } 3602 }
3603 3603
3604 3604
3605 bool AbstractTypeArguments::IsUninstantiatedIdentity() const { 3605 bool AbstractTypeArguments::IsUninstantiatedIdentity() const {
3606 // AbstractTypeArguments is an abstract class. 3606 // AbstractTypeArguments is an abstract class.
3607 UNREACHABLE(); 3607 UNREACHABLE();
3608 return false; 3608 return false;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 strings.SetAt(s++, Symbols::CommaSpace()); 3666 strings.SetAt(s++, Symbols::CommaSpace());
3667 } 3667 }
3668 } 3668 }
3669 strings.SetAt(s++, Symbols::RAngleBracket()); 3669 strings.SetAt(s++, Symbols::RAngleBracket());
3670 ASSERT(s == num_strings); 3670 ASSERT(s == num_strings);
3671 name = String::ConcatAll(strings); 3671 name = String::ConcatAll(strings);
3672 return Symbols::New(name); 3672 return Symbols::New(name);
3673 } 3673 }
3674 3674
3675 3675
3676 bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const { 3676 bool AbstractTypeArguments::IsEquivalent(const AbstractTypeArguments& other,
3677 GrowableObjectArray* trail) const {
3677 if (this->raw() == other.raw()) { 3678 if (this->raw() == other.raw()) {
3678 return true; 3679 return true;
3679 } 3680 }
3680 if (IsNull() || other.IsNull()) { 3681 if (IsNull() || other.IsNull()) {
3681 return false; 3682 return false;
3682 } 3683 }
3683 const intptr_t num_types = Length(); 3684 const intptr_t num_types = Length();
3684 if (num_types != other.Length()) { 3685 if (num_types != other.Length()) {
3685 return false; 3686 return false;
3686 } 3687 }
3687 AbstractType& type = AbstractType::Handle(); 3688 AbstractType& type = AbstractType::Handle();
3688 AbstractType& other_type = AbstractType::Handle(); 3689 AbstractType& other_type = AbstractType::Handle();
3689 for (intptr_t i = 0; i < num_types; i++) { 3690 for (intptr_t i = 0; i < num_types; i++) {
3690 type = TypeAt(i); 3691 type = TypeAt(i);
3691 other_type = other.TypeAt(i); 3692 other_type = other.TypeAt(i);
3692 if (!type.Equals(other_type)) { 3693 if (!type.IsEquivalent(other_type, trail)) {
3693 return false; 3694 return false;
3694 } 3695 }
3695 } 3696 }
3696 return true; 3697 return true;
3697 } 3698 }
3698 3699
3699 3700
3700 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( 3701 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
3701 const AbstractTypeArguments& instantiator_type_arguments, 3702 const AbstractTypeArguments& instantiator_type_arguments,
3702 Error* bound_error) const { 3703 Error* bound_error,
3704 GrowableObjectArray* trail) const {
3703 // AbstractTypeArguments is an abstract class. 3705 // AbstractTypeArguments is an abstract class.
3704 UNREACHABLE(); 3706 UNREACHABLE();
3705 return NULL; 3707 return NULL;
3706 } 3708 }
3707 3709
3708 3710
3709 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, 3711 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated,
3710 intptr_t from_index, 3712 intptr_t from_index,
3711 intptr_t len) const { 3713 intptr_t len) const {
3712 ASSERT(Length() >= (from_index + len)); 3714 ASSERT(Length() >= (from_index + len));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3801 for (intptr_t i = 0; i < num_types; i++) { 3803 for (intptr_t i = 0; i < num_types; i++) {
3802 type = TypeAt(i); 3804 type = TypeAt(i);
3803 if (!type.IsResolved()) { 3805 if (!type.IsResolved()) {
3804 return false; 3806 return false;
3805 } 3807 }
3806 } 3808 }
3807 return true; 3809 return true;
3808 } 3810 }
3809 3811
3810 3812
3811 bool TypeArguments::IsInstantiated() const { 3813 bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const {
3812 AbstractType& type = AbstractType::Handle(); 3814 AbstractType& type = AbstractType::Handle();
3813 const intptr_t num_types = Length(); 3815 const intptr_t num_types = Length();
3814 for (intptr_t i = 0; i < num_types; i++) { 3816 for (intptr_t i = 0; i < num_types; i++) {
3815 type = TypeAt(i); 3817 type = TypeAt(i);
3816 ASSERT(!type.IsNull()); 3818 ASSERT(!type.IsNull());
3817 if (!type.IsInstantiated()) { 3819 if (!type.IsInstantiated(trail)) {
3818 return false; 3820 return false;
3819 } 3821 }
3820 } 3822 }
3821 return true; 3823 return true;
3822 } 3824 }
3823 3825
3824 3826
3825 bool TypeArguments::IsUninstantiatedIdentity() const { 3827 bool TypeArguments::IsUninstantiatedIdentity() const {
3826 ASSERT(!IsInstantiated()); 3828 ASSERT(!IsInstantiated());
3827 AbstractType& type = AbstractType::Handle(); 3829 AbstractType& type = AbstractType::Handle();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3957 if (!type_args.IsNull() && type_args.IsBounded()) { 3959 if (!type_args.IsNull() && type_args.IsBounded()) {
3958 return true; 3960 return true;
3959 } 3961 }
3960 } 3962 }
3961 return false; 3963 return false;
3962 } 3964 }
3963 3965
3964 3966
3965 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( 3967 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
3966 const AbstractTypeArguments& instantiator_type_arguments, 3968 const AbstractTypeArguments& instantiator_type_arguments,
3967 Error* bound_error) const { 3969 Error* bound_error,
3970 GrowableObjectArray* trail) const {
3968 ASSERT(!IsInstantiated()); 3971 ASSERT(!IsInstantiated());
3969 if (!instantiator_type_arguments.IsNull() && 3972 if (!instantiator_type_arguments.IsNull() &&
3970 IsUninstantiatedIdentity() && 3973 IsUninstantiatedIdentity() &&
3971 (instantiator_type_arguments.Length() == Length())) { 3974 (instantiator_type_arguments.Length() == Length())) {
3972 return instantiator_type_arguments.raw(); 3975 return instantiator_type_arguments.raw();
3973 } 3976 }
3974 const intptr_t num_types = Length(); 3977 const intptr_t num_types = Length();
3975 TypeArguments& instantiated_array = 3978 TypeArguments& instantiated_array =
3976 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); 3979 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew));
3977 AbstractType& type = AbstractType::Handle(); 3980 AbstractType& type = AbstractType::Handle();
3978 for (intptr_t i = 0; i < num_types; i++) { 3981 for (intptr_t i = 0; i < num_types; i++) {
3979 type = TypeAt(i); 3982 type = TypeAt(i);
3980 if (!type.IsInstantiated()) { 3983 if (!type.IsInstantiated()) {
3981 type = type.InstantiateFrom(instantiator_type_arguments, bound_error); 3984 type = type.InstantiateFrom(instantiator_type_arguments,
3985 bound_error,
3986 trail);
3982 } 3987 }
3983 instantiated_array.SetTypeAt(i, type); 3988 instantiated_array.SetTypeAt(i, type);
3984 } 3989 }
3985 return instantiated_array.raw(); 3990 return instantiated_array.raw();
3986 } 3991 }
3987 3992
3988 3993
3989 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { 3994 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
3990 if (len < 0 || len > kMaxElements) { 3995 if (len < 0 || len > kMaxElements) {
3991 // This should be caught before we reach here. 3996 // This should be caught before we reach here.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4102 TypeArguments::New(num_types)); 4107 TypeArguments::New(num_types));
4103 for (intptr_t i = 0; i < num_types; i++) { 4108 for (intptr_t i = 0; i < num_types; i++) {
4104 type = TypeAt(i); 4109 type = TypeAt(i);
4105 type = type.CloneUnfinalized(); 4110 type = type.CloneUnfinalized();
4106 clone.SetTypeAt(i, type); 4111 clone.SetTypeAt(i, type);
4107 } 4112 }
4108 return clone.raw(); 4113 return clone.raw();
4109 } 4114 }
4110 4115
4111 4116
4112 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { 4117 RawAbstractTypeArguments* TypeArguments::Canonicalize(
4118 GrowableObjectArray* trail) const {
4113 if (IsNull() || IsCanonical()) { 4119 if (IsNull() || IsCanonical()) {
4114 ASSERT(IsOld()); 4120 ASSERT(IsOld());
4115 return this->raw(); 4121 return this->raw();
4116 } 4122 }
4117 Isolate* isolate = Isolate::Current(); 4123 Isolate* isolate = Isolate::Current();
4118 ObjectStore* object_store = isolate->object_store(); 4124 ObjectStore* object_store = isolate->object_store();
4119 const Array& table = Array::Handle(isolate, 4125 const Array& table = Array::Handle(isolate,
4120 object_store->canonical_type_arguments()); 4126 object_store->canonical_type_arguments());
4121 ASSERT(table.Length() > 0); 4127 ASSERT(table.Length() > 0);
4122 intptr_t index = FindIndexInCanonicalTypeArguments(isolate, 4128 intptr_t index = FindIndexInCanonicalTypeArguments(isolate,
4123 table, 4129 table,
4124 *this, 4130 *this,
4125 Hash()); 4131 Hash());
4126 TypeArguments& result = TypeArguments::Handle(isolate); 4132 TypeArguments& result = TypeArguments::Handle(isolate);
4127 result ^= table.At(index); 4133 result ^= table.At(index);
4128 if (result.IsNull()) { 4134 if (result.IsNull()) {
4129 // Canonicalize each type argument. 4135 // Canonicalize each type argument.
4130 const intptr_t num_types = Length(); 4136 const intptr_t num_types = Length();
4131 AbstractType& type = AbstractType::Handle(isolate); 4137 AbstractType& type = AbstractType::Handle(isolate);
4132 for (intptr_t i = 0; i < num_types; i++) { 4138 for (intptr_t i = 0; i < num_types; i++) {
4133 type = TypeAt(i); 4139 type = TypeAt(i);
4134 type = type.Canonicalize(); 4140 type = type.Canonicalize(trail);
4135 SetTypeAt(i, type); 4141 SetTypeAt(i, type);
4136 } 4142 }
4137 // Make sure we have an old space object and add it to the table. 4143 // Make sure we have an old space object and add it to the table.
4138 if (this->IsNew()) { 4144 if (this->IsNew()) {
4139 result ^= Object::Clone(*this, Heap::kOld); 4145 result ^= Object::Clone(*this, Heap::kOld);
4140 } else { 4146 } else {
4141 result ^= this->raw(); 4147 result ^= this->raw();
4142 } 4148 }
4143 ASSERT(result.IsOld()); 4149 ASSERT(result.IsOld());
4144 InsertIntoCanonicalTypeArguments(isolate, table, result, index); 4150 InsertIntoCanonicalTypeArguments(isolate, table, result, index);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4198 4204
4199 4205
4200 void InstantiatedTypeArguments::SetTypeAt(intptr_t index, 4206 void InstantiatedTypeArguments::SetTypeAt(intptr_t index,
4201 const AbstractType& value) const { 4207 const AbstractType& value) const {
4202 // We only replace individual argument types during resolution at compile 4208 // We only replace individual argument types during resolution at compile
4203 // time, when no type parameters are instantiated yet. 4209 // time, when no type parameters are instantiated yet.
4204 UNREACHABLE(); 4210 UNREACHABLE();
4205 } 4211 }
4206 4212
4207 4213
4208 RawAbstractTypeArguments* InstantiatedTypeArguments::Canonicalize() const { 4214 RawAbstractTypeArguments* InstantiatedTypeArguments::Canonicalize(
4215 GrowableObjectArray* trail) const {
4209 const intptr_t num_types = Length(); 4216 const intptr_t num_types = Length();
4210 const TypeArguments& type_args = TypeArguments::Handle( 4217 const TypeArguments& type_args = TypeArguments::Handle(
4211 TypeArguments::New(num_types, Heap::kOld)); 4218 TypeArguments::New(num_types, Heap::kOld));
4212 AbstractType& type = AbstractType::Handle(); 4219 AbstractType& type = AbstractType::Handle();
4213 for (intptr_t i = 0; i < num_types; i++) { 4220 for (intptr_t i = 0; i < num_types; i++) {
4214 type = TypeAt(i); 4221 type = TypeAt(i);
4215 type_args.SetTypeAt(i, type); 4222 type_args.SetTypeAt(i, type);
4216 } 4223 }
4217 return type_args.Canonicalize(); 4224 return type_args.Canonicalize(trail);
4218 } 4225 }
4219 4226
4220 4227
4221 void InstantiatedTypeArguments::set_uninstantiated_type_arguments( 4228 void InstantiatedTypeArguments::set_uninstantiated_type_arguments(
4222 const AbstractTypeArguments& value) const { 4229 const AbstractTypeArguments& value) const {
4223 StorePointer(&raw_ptr()->uninstantiated_type_arguments_, value.raw()); 4230 StorePointer(&raw_ptr()->uninstantiated_type_arguments_, value.raw());
4224 } 4231 }
4225 4232
4226 4233
4227 void InstantiatedTypeArguments::set_instantiator_type_arguments( 4234 void InstantiatedTypeArguments::set_instantiator_type_arguments(
(...skipping 7585 matching lines...) Expand 10 before | Expand all | Expand 10 after
11813 } 11820 }
11814 11821
11815 11822
11816 intptr_t AbstractType::token_pos() const { 11823 intptr_t AbstractType::token_pos() const {
11817 // AbstractType is an abstract class. 11824 // AbstractType is an abstract class.
11818 UNREACHABLE(); 11825 UNREACHABLE();
11819 return -1; 11826 return -1;
11820 } 11827 }
11821 11828
11822 11829
11823 bool AbstractType::IsInstantiated() const { 11830 bool AbstractType::IsInstantiated(GrowableObjectArray* trail) const {
11824 // AbstractType is an abstract class. 11831 // AbstractType is an abstract class.
11825 UNREACHABLE(); 11832 UNREACHABLE();
11826 return false; 11833 return false;
11827 } 11834 }
11828 11835
11829 11836
11830 bool AbstractType::IsFinalized() const { 11837 bool AbstractType::IsFinalized() const {
11831 // AbstractType is an abstract class. 11838 // AbstractType is an abstract class.
11832 UNREACHABLE(); 11839 UNREACHABLE();
11833 return false; 11840 return false;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
11868 return LanguageError::null(); 11875 return LanguageError::null();
11869 } 11876 }
11870 11877
11871 11878
11872 void AbstractType::set_error(const LanguageError& value) const { 11879 void AbstractType::set_error(const LanguageError& value) const {
11873 // AbstractType is an abstract class. 11880 // AbstractType is an abstract class.
11874 UNREACHABLE(); 11881 UNREACHABLE();
11875 } 11882 }
11876 11883
11877 11884
11878 bool AbstractType::Equals(const Instance& other) const { 11885 bool AbstractType::IsEquivalent(const Instance& other,
11886 GrowableObjectArray* trail) const {
11879 // AbstractType is an abstract class. 11887 // AbstractType is an abstract class.
11880 UNREACHABLE(); 11888 UNREACHABLE();
11881 return false; 11889 return false;
11882 } 11890 }
11883 11891
11884 11892
11885 RawAbstractType* AbstractType::InstantiateFrom( 11893 RawAbstractType* AbstractType::InstantiateFrom(
11886 const AbstractTypeArguments& instantiator_type_arguments, 11894 const AbstractTypeArguments& instantiator_type_arguments,
11887 Error* bound_error) const { 11895 Error* bound_error,
11896 GrowableObjectArray* trail) const {
11888 // AbstractType is an abstract class. 11897 // AbstractType is an abstract class.
11889 UNREACHABLE(); 11898 UNREACHABLE();
11890 return NULL; 11899 return NULL;
11891 } 11900 }
11892 11901
11893 11902
11894 RawAbstractType* AbstractType::CloneUnfinalized() const { 11903 RawAbstractType* AbstractType::CloneUnfinalized() const {
11895 // AbstractType is an abstract class. 11904 // AbstractType is an abstract class.
11896 UNREACHABLE(); 11905 UNREACHABLE();
11897 return NULL; 11906 return NULL;
11898 } 11907 }
11899 11908
11900 11909
11901 RawAbstractType* AbstractType::Canonicalize() const { 11910 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const {
11902 // AbstractType is an abstract class. 11911 // AbstractType is an abstract class.
11903 UNREACHABLE(); 11912 UNREACHABLE();
11904 return NULL; 11913 return NULL;
11905 } 11914 }
11906 11915
11907 11916
11908 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { 11917 RawString* AbstractType::BuildName(NameVisibility name_visibility) const {
11909 if (IsBoundedType()) { 11918 if (IsBoundedType()) {
11910 const AbstractType& type = AbstractType::Handle( 11919 const AbstractType& type = AbstractType::Handle(
11911 BoundedType::Cast(*this).type()); 11920 BoundedType::Cast(*this).type());
11912 if (name_visibility == kUserVisibleName) { 11921 if (name_visibility == kUserVisibleName) {
11913 return type.BuildName(kUserVisibleName); 11922 return type.BuildName(kUserVisibleName);
11914 } 11923 }
11915 String& type_name = String::Handle(type.BuildName(kInternalName)); 11924 String& type_name = String::Handle(type.BuildName(kInternalName));
11916 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); 11925 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace());
11917 // Building the bound name may lead into cycles. 11926 // Build the bound name without causing divergence.
11918 const AbstractType& bound = AbstractType::Handle( 11927 const AbstractType& bound = AbstractType::Handle(
11919 BoundedType::Cast(*this).bound()); 11928 BoundedType::Cast(*this).bound());
11920 String& bound_name = String::Handle(); 11929 String& bound_name = String::Handle();
11921 if (bound.IsTypeParameter()) { 11930 if (bound.IsTypeParameter()) {
11922 bound_name = TypeParameter::Cast(bound).name(); 11931 bound_name = TypeParameter::Cast(bound).name();
11923 } else if (bound.IsType()) { 11932 } else if (bound.IsType()) {
11924 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); 11933 const Class& cls = Class::Handle(Type::Cast(bound).type_class());
11925 bound_name = cls.Name(); 11934 bound_name = cls.Name();
11926 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { 11935 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) {
11927 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); 11936 bound_name = String::Concat(bound_name, Symbols::OptimizedOut());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
11968 // The actual type argument vector can be longer than necessary, because 11977 // The actual type argument vector can be longer than necessary, because
11969 // of type optimizations. 11978 // of type optimizations.
11970 if (IsFinalized() && cls.is_type_finalized()) { 11979 if (IsFinalized() && cls.is_type_finalized()) {
11971 first_type_param_index = cls.NumTypeArguments() - num_type_params; 11980 first_type_param_index = cls.NumTypeArguments() - num_type_params;
11972 } else { 11981 } else {
11973 first_type_param_index = num_args - num_type_params; 11982 first_type_param_index = num_args - num_type_params;
11974 } 11983 }
11975 } 11984 }
11976 if (cls.IsSignatureClass()) { 11985 if (cls.IsSignatureClass()) {
11977 // We may be reporting an error about a malformed function type. In that 11986 // We may be reporting an error about a malformed function type. In that
11978 // case, avoid instantiating the signature, since it may lead to cycles. 11987 // case, avoid instantiating the signature, since it may cause divergence.
11979 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { 11988 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
11980 return class_name.raw(); 11989 return class_name.raw();
11981 } 11990 }
11982 // In order to avoid cycles, print the name of a typedef (non-canonical 11991 // To avoid divergence, print the name of a typedef (non-canonical
11983 // signature class) as a regular, possibly parameterized, class. 11992 // signature class) as a regular, possibly parameterized, class.
11984 if (cls.IsCanonicalSignatureClass()) { 11993 if (cls.IsCanonicalSignatureClass()) {
11985 const Function& signature_function = Function::Handle( 11994 const Function& signature_function = Function::Handle(
11986 cls.signature_function()); 11995 cls.signature_function());
11987 // Signature classes have no super type, however, they take as many 11996 // Signature classes have no super type, however, they take as many
11988 // type arguments as the owner class of their signature function (if it 11997 // type arguments as the owner class of their signature function (if it
11989 // is non static and generic, see Class::NumTypeArguments()). Therefore, 11998 // is non static and generic, see Class::NumTypeArguments()). Therefore,
11990 // first_type_param_index may be greater than 0 here. 11999 // first_type_param_index may be greater than 0 here.
11991 return signature_function.InstantiatedSignatureFrom(args, 12000 return signature_function.InstantiatedSignatureFrom(args,
11992 name_visibility); 12001 name_visibility);
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
12377 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_); 12386 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_);
12378 #endif 12387 #endif
12379 } 12388 }
12380 12389
12381 12390
12382 RawAbstractTypeArguments* Type::arguments() const { 12391 RawAbstractTypeArguments* Type::arguments() const {
12383 return raw_ptr()->arguments_; 12392 return raw_ptr()->arguments_;
12384 } 12393 }
12385 12394
12386 12395
12387 bool Type::IsInstantiated() const { 12396 bool Type::IsInstantiated(GrowableObjectArray* trail) const {
12388 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { 12397 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
12389 return true; 12398 return true;
12390 } 12399 }
12391 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { 12400 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) {
12392 return false; 12401 return false;
12393 } 12402 }
12394 const AbstractTypeArguments& args = 12403 const AbstractTypeArguments& args =
12395 AbstractTypeArguments::Handle(arguments()); 12404 AbstractTypeArguments::Handle(arguments());
12396 return args.IsNull() || args.IsInstantiated(); 12405 return args.IsNull() || args.IsInstantiated(trail);
12397 } 12406 }
12398 12407
12399 12408
12400 RawAbstractType* Type::InstantiateFrom( 12409 RawAbstractType* Type::InstantiateFrom(
12401 const AbstractTypeArguments& instantiator_type_arguments, 12410 const AbstractTypeArguments& instantiator_type_arguments,
12402 Error* bound_error) const { 12411 Error* bound_error,
12412 GrowableObjectArray* trail) const {
12403 ASSERT(IsFinalized() || IsBeingFinalized()); 12413 ASSERT(IsFinalized() || IsBeingFinalized());
12404 ASSERT(!IsInstantiated()); 12414 ASSERT(!IsInstantiated());
12405 // Return the uninstantiated type unchanged if malformed. No copy needed. 12415 // Return the uninstantiated type unchanged if malformed. No copy needed.
12406 if (IsMalformed()) { 12416 if (IsMalformed()) {
12407 return raw(); 12417 return raw();
12408 } 12418 }
12409 AbstractTypeArguments& type_arguments = 12419 AbstractTypeArguments& type_arguments =
12410 AbstractTypeArguments::Handle(arguments()); 12420 AbstractTypeArguments::Handle(arguments());
12411 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, 12421 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
12412 bound_error); 12422 bound_error,
12423 trail);
12413 // Note that the type class has to be resolved at this time, but not 12424 // Note that the type class has to be resolved at this time, but not
12414 // necessarily finalized yet. We may be checking bounds at compile time. 12425 // necessarily finalized yet. We may be checking bounds at compile time.
12415 const Class& cls = Class::Handle(type_class()); 12426 const Class& cls = Class::Handle(type_class());
12416 // This uninstantiated type is not modified, as it can be instantiated 12427 // This uninstantiated type is not modified, as it can be instantiated
12417 // with different instantiators. 12428 // with different instantiators.
12418 Type& instantiated_type = Type::Handle( 12429 Type& instantiated_type = Type::Handle(
12419 Type::New(cls, type_arguments, token_pos())); 12430 Type::New(cls, type_arguments, token_pos()));
12420 ASSERT(type_arguments.IsNull() || 12431 ASSERT(type_arguments.IsNull() ||
12421 (type_arguments.Length() == cls.NumTypeArguments())); 12432 (type_arguments.Length() == cls.NumTypeArguments()));
12422 instantiated_type.SetIsFinalized(); 12433 instantiated_type.SetIsFinalized();
12423 return instantiated_type.raw(); 12434 return instantiated_type.raw();
12424 } 12435 }
12425 12436
12426 12437
12427 bool Type::Equals(const Instance& other) const { 12438 bool Type::IsEquivalent(const Instance& other,
12439 GrowableObjectArray* trail) const {
12428 ASSERT(!IsNull()); 12440 ASSERT(!IsNull());
12429 if (raw() == other.raw()) { 12441 if (raw() == other.raw()) {
12430 return true; 12442 return true;
12431 } 12443 }
12432 if (other.IsTypeRef()) { 12444 if (other.IsTypeRef()) {
12433 // TODO(regis): Use trail. For now, we "unfold" the right hand type. 12445 // Unfold right hand type. Divergence is controlled by left hand type.
12434 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); 12446 const AbstractType& other_ref_type = AbstractType::Handle(
12447 TypeRef::Cast(other).type());
12448 ASSERT(!other_ref_type.IsTypeRef());
12449 return IsEquivalent(other_ref_type, trail);
12435 } 12450 }
12436 if (!other.IsType()) { 12451 if (!other.IsType()) {
12437 return false; 12452 return false;
12438 } 12453 }
12439 const Type& other_type = Type::Cast(other); 12454 const Type& other_type = Type::Cast(other);
12440 ASSERT(IsResolved() && other_type.IsResolved()); 12455 ASSERT(IsResolved() && other_type.IsResolved());
12441 if (IsMalformed() || other_type.IsMalformed()) { 12456 if (IsMalformed() || other_type.IsMalformed()) {
12442 return false; 12457 return false;
12443 } 12458 }
12444 if (type_class() != other_type.type_class()) { 12459 if (type_class() != other_type.type_class()) {
(...skipping 23 matching lines...) Expand all
12468 if (other_type_args.IsNull()) { 12483 if (other_type_args.IsNull()) {
12469 return type_args.IsRaw(from_index, num_type_params); 12484 return type_args.IsRaw(from_index, num_type_params);
12470 } 12485 }
12471 ASSERT(type_args.Length() >= (from_index + num_type_params)); 12486 ASSERT(type_args.Length() >= (from_index + num_type_params));
12472 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); 12487 ASSERT(other_type_args.Length() >= (from_index + num_type_params));
12473 AbstractType& type_arg = AbstractType::Handle(); 12488 AbstractType& type_arg = AbstractType::Handle();
12474 AbstractType& other_type_arg = AbstractType::Handle(); 12489 AbstractType& other_type_arg = AbstractType::Handle();
12475 for (intptr_t i = 0; i < num_type_params; i++) { 12490 for (intptr_t i = 0; i < num_type_params; i++) {
12476 type_arg = type_args.TypeAt(from_index + i); 12491 type_arg = type_args.TypeAt(from_index + i);
12477 other_type_arg = other_type_args.TypeAt(from_index + i); 12492 other_type_arg = other_type_args.TypeAt(from_index + i);
12478 if (!type_arg.Equals(other_type_arg)) { 12493 if (!type_arg.IsEquivalent(other_type_arg, trail)) {
12479 return false; 12494 return false;
12480 } 12495 }
12481 } 12496 }
12482 return true; 12497 return true;
12483 } 12498 }
12484 12499
12485 12500
12486 RawAbstractType* Type::CloneUnfinalized() const { 12501 RawAbstractType* Type::CloneUnfinalized() const {
12487 ASSERT(IsResolved()); 12502 ASSERT(IsResolved());
12488 if (IsFinalized()) { 12503 if (IsFinalized()) {
12489 return raw(); 12504 return raw();
12490 } 12505 }
12491 ASSERT(!IsMalformed()); // Malformed types are finalized. 12506 ASSERT(!IsMalformed()); // Malformed types are finalized.
12492 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. 12507 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization.
12493 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); 12508 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments());
12494 type_args = type_args.CloneUnfinalized(); 12509 type_args = type_args.CloneUnfinalized();
12495 const Class& type_cls = Class::Handle(type_class()); 12510 const Class& type_cls = Class::Handle(type_class());
12496 return Type::New(type_cls, type_args, token_pos()); 12511 return Type::New(type_cls, type_args, token_pos());
12497 } 12512 }
12498 12513
12499 12514
12500 RawAbstractType* Type::Canonicalize() const { 12515 RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
12501 ASSERT(IsFinalized()); 12516 ASSERT(IsFinalized());
12502 if (IsCanonical() || IsMalformed()) { 12517 if (IsCanonical() || IsMalformed()) {
12503 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); 12518 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld());
12504 return this->raw(); 12519 return this->raw();
12505 } 12520 }
12506 Isolate* isolate = Isolate::Current(); 12521 Isolate* isolate = Isolate::Current();
12507 Type& type = Type::Handle(isolate); 12522 Type& type = Type::Handle(isolate);
12508 const Class& cls = Class::Handle(isolate, type_class()); 12523 const Class& cls = Class::Handle(isolate, type_class());
12509 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) { 12524 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
12510 return Object::dynamic_type(); 12525 return Object::dynamic_type();
(...skipping 30 matching lines...) Expand all
12541 ASSERT(type.IsFinalized()); 12556 ASSERT(type.IsFinalized());
12542 if (this->Equals(type)) { 12557 if (this->Equals(type)) {
12543 return type.raw(); 12558 return type.raw();
12544 } 12559 }
12545 index++; 12560 index++;
12546 } 12561 }
12547 // Canonicalize the type arguments. 12562 // Canonicalize the type arguments.
12548 AbstractTypeArguments& type_args = 12563 AbstractTypeArguments& type_args =
12549 AbstractTypeArguments::Handle(isolate, arguments()); 12564 AbstractTypeArguments::Handle(isolate, arguments());
12550 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); 12565 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments()));
12551 type_args = type_args.Canonicalize(); 12566 type_args = type_args.Canonicalize(trail);
12552 set_arguments(type_args); 12567 set_arguments(type_args);
12553 // The type needs to be added to the list. Grow the list if it is full. 12568 // The type needs to be added to the list. Grow the list if it is full.
12554 if (index == canonical_types_len) { 12569 if (index == canonical_types_len) {
12555 const intptr_t kLengthIncrement = 2; // Raw and parameterized. 12570 const intptr_t kLengthIncrement = 2; // Raw and parameterized.
12556 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; 12571 const intptr_t new_length = canonical_types.Length() + kLengthIncrement;
12557 const Array& new_canonical_types = Array::Handle( 12572 const Array& new_canonical_types = Array::Handle(
12558 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); 12573 isolate, Array::Grow(canonical_types, new_length, Heap::kOld));
12559 cls.set_canonical_types(new_canonical_types); 12574 cls.set_canonical_types(new_canonical_types);
12560 new_canonical_types.SetAt(index, *this); 12575 new_canonical_types.SetAt(index, *this);
12561 } else { 12576 } else {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
12680 return "Unresolved Type"; 12695 return "Unresolved Type";
12681 } 12696 }
12682 } 12697 }
12683 12698
12684 12699
12685 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const { 12700 void Type::PrintToJSONStream(JSONStream* stream, bool ref) const {
12686 JSONObject jsobj(stream); 12701 JSONObject jsobj(stream);
12687 } 12702 }
12688 12703
12689 12704
12690 bool TypeRef::IsInstantiated() const { 12705 bool TypeRef::IsInstantiated(GrowableObjectArray* trail) const {
12691 if (is_being_checked()) { 12706 if (TestAndAddToTrail(&trail)) {
12692 return true; 12707 return true;
12693 } 12708 }
12694 set_is_being_checked(true); 12709 return AbstractType::Handle(type()).IsInstantiated(trail);
12695 const bool result = AbstractType::Handle(type()).IsInstantiated();
12696 set_is_being_checked(false);
12697 return result;
12698 } 12710 }
12699 12711
12700 12712
12701 bool TypeRef::Equals(const Instance& other) const { 12713 bool TypeRef::IsEquivalent(const Instance& other,
12702 // TODO(regis): Use trail instead of mark bit. 12714 GrowableObjectArray* trail) const {
12703 if (raw() == other.raw()) { 12715 if (raw() == other.raw()) {
12704 return true; 12716 return true;
12705 } 12717 }
12706 if (is_being_checked()) { 12718 if (TestAndAddBuddyToTrail(&trail, other)) {
12707 return true; 12719 return true;
12708 } 12720 }
12709 set_is_being_checked(true); 12721 return AbstractType::Handle(type()).IsEquivalent(other, trail);
12710 const bool result = AbstractType::Handle(type()).Equals(other);
12711 set_is_being_checked(false);
12712 return result;
12713 } 12722 }
12714 12723
12715 12724
12716 RawAbstractType* TypeRef::InstantiateFrom( 12725 RawAbstractType* TypeRef::InstantiateFrom(
12717 const AbstractTypeArguments& instantiator_type_arguments, 12726 const AbstractTypeArguments& instantiator_type_arguments,
12718 Error* bound_error) const { 12727 Error* bound_error,
12728 GrowableObjectArray* trail) const {
12729 TypeRef& instantiated_type_ref = TypeRef::Handle();
12730 instantiated_type_ref ^= OnlyBuddyInTrail(trail);
12731 if (!instantiated_type_ref.IsNull()) {
12732 return instantiated_type_ref.raw();
12733 }
12734 instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType()));
12735 AddOnlyBuddyToTrail(&trail, instantiated_type_ref);
12719 const AbstractType& ref_type = AbstractType::Handle(type()); 12736 const AbstractType& ref_type = AbstractType::Handle(type());
12720 // TODO(regis): Use trail instead of mark bit plus temporary redirection,
12721 // because it could be marked for another reason.
12722 if (is_being_checked()) {
12723 ASSERT(ref_type.IsTypeRef());
12724 return ref_type.raw();
12725 }
12726 set_is_being_checked(true);
12727 ASSERT(!ref_type.IsTypeRef()); 12737 ASSERT(!ref_type.IsTypeRef());
12728 const TypeRef& instantiated_type_ref = TypeRef::Handle(
12729 TypeRef::New(ref_type));
12730 // TODO(regis): instantiated_type_ref should be stored in the trail instead.
12731 set_type(instantiated_type_ref);
12732 const AbstractType& instantiated_ref_type = AbstractType::Handle( 12738 const AbstractType& instantiated_ref_type = AbstractType::Handle(
12733 ref_type.InstantiateFrom(instantiator_type_arguments, bound_error)); 12739 ref_type.InstantiateFrom(instantiator_type_arguments,
12740 bound_error,
12741 trail));
12734 instantiated_type_ref.set_type(instantiated_ref_type); 12742 instantiated_type_ref.set_type(instantiated_ref_type);
12735 set_type(ref_type);
12736 set_is_being_checked(false);
12737 return instantiated_type_ref.raw(); 12743 return instantiated_type_ref.raw();
12738 } 12744 }
12739 12745
12740 12746
12741 void TypeRef::set_type(const AbstractType& value) const { 12747 void TypeRef::set_type(const AbstractType& value) const {
12742 ASSERT(value.HasResolvedTypeClass()); 12748 ASSERT(value.HasResolvedTypeClass());
12743 StorePointer(&raw_ptr()->type_, value.raw()); 12749 StorePointer(&raw_ptr()->type_, value.raw());
12744 } 12750 }
12745 12751
12746 12752
12747 void TypeRef::set_is_being_checked(bool value) const { 12753 // A TypeRef cannot be canonical by definition. Only its referenced type can be.
12748 raw_ptr()->is_being_checked_ = value;
12749 }
12750
12751
12752 // This function only canonicalizes the referenced type, but not the TypeRef
12753 // itself, since it cannot be canonical by definition.
12754 // Consider the type Derived, where class Derived extends Base<Derived>. 12754 // Consider the type Derived, where class Derived extends Base<Derived>.
12755 // The first type argument of its flattened type argument vector is Derived, 12755 // The first type argument of its flattened type argument vector is Derived,
12756 // i.e. itself, but pointer equality is not possible. 12756 // i.e. itself, but pointer equality is not possible.
12757 RawAbstractType* TypeRef::Canonicalize() const { 12757 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const {
12758 // TODO(regis): Use trail, not mark bit. 12758 if (TestAndAddToTrail(&trail)) {
12759 if (is_being_checked()) {
12760 return raw(); 12759 return raw();
12761 } 12760 }
12762 set_is_being_checked(true);
12763 AbstractType& ref_type = AbstractType::Handle(type()); 12761 AbstractType& ref_type = AbstractType::Handle(type());
12764 ASSERT(!ref_type.IsTypeRef()); 12762 ref_type = ref_type.Canonicalize(trail);
12765 ref_type = ref_type.Canonicalize();
12766 set_type(ref_type); 12763 set_type(ref_type);
12767 // No need to call SetCanonical(), since a TypeRef cannot be canonical by 12764 return raw();
12768 // definition.
12769 set_is_being_checked(false);
12770 // We return the referenced type instead of the TypeRef in order to provide
12771 // pointer equality in simple cases, e.g. in language/f_bounded_equality_test.
12772 return ref_type.raw();
12773 } 12765 }
12774 12766
12775 12767
12776 intptr_t TypeRef::Hash() const { 12768 intptr_t TypeRef::Hash() const {
12777 // TODO(regis): Use trail and hash of referenced type. 12769 // Do not calculate the hash of the referenced type to avoid divergence.
12778 // Do not calculate the hash of the referenced type to avoid cycles.
12779 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); 12770 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id();
12780 return FinalizeHash(result); 12771 return FinalizeHash(result);
12781 } 12772 }
12782 12773
12783 12774
12775 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const {
12776 if (*trail == NULL) {
12777 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12778 } else {
12779 const intptr_t len = (*trail)->Length();
12780 for (intptr_t i = 0; i < len; i++) {
12781 if ((*trail)->At(i) == this->raw()) {
12782 return true;
12783 }
12784 }
12785 }
12786 (*trail)->Add(*this);
12787 return false;
12788 }
12789
12790
12791 bool TypeRef::TestAndAddBuddyToTrail(GrowableObjectArray** trail,
12792 const Object& buddy) const {
12793 if (*trail == NULL) {
12794 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12795 } else {
12796 const intptr_t len = (*trail)->Length();
12797 ASSERT((len % 2) == 0);
12798 for (intptr_t i = 0; i < len; i += 2) {
12799 if (((*trail)->At(i) == this->raw()) &&
12800 ((*trail)->At(i + 1) == buddy.raw())) {
12801 return true;
12802 }
12803 }
12804 }
12805 (*trail)->Add(*this);
12806 (*trail)->Add(buddy);
12807 return false;
12808 }
12809
12810
12811 RawObject* TypeRef::OnlyBuddyInTrail(GrowableObjectArray* trail) const {
12812 if (trail == NULL) {
12813 return Object::null();
12814 }
12815 const intptr_t len = trail->Length();
12816 ASSERT((len % 2) == 0);
12817 for (intptr_t i = 0; i < len; i += 2) {
12818 if (trail->At(i) == this->raw()) {
12819 ASSERT(trail->At(i + 1) != Object::null());
12820 return trail->At(i + 1);
12821 }
12822 }
12823 return Object::null();
12824 }
12825
12826
12827 void TypeRef::AddOnlyBuddyToTrail(GrowableObjectArray** trail,
12828 const Object& buddy) const {
12829 if (*trail == NULL) {
12830 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12831 } else {
12832 ASSERT(OnlyBuddyInTrail(*trail) == Object::null());
12833 }
12834 (*trail)->Add(*this);
12835 (*trail)->Add(buddy);
12836 }
12837
12838
12784 RawTypeRef* TypeRef::New() { 12839 RawTypeRef* TypeRef::New() {
12785 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); 12840 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null());
12786 RawObject* raw = Object::Allocate(TypeRef::kClassId, 12841 RawObject* raw = Object::Allocate(TypeRef::kClassId,
12787 TypeRef::InstanceSize(), 12842 TypeRef::InstanceSize(),
12788 Heap::kOld); 12843 Heap::kOld);
12789 return reinterpret_cast<RawTypeRef*>(raw); 12844 return reinterpret_cast<RawTypeRef*>(raw);
12790 } 12845 }
12791 12846
12792 12847
12793 RawTypeRef* TypeRef::New(const AbstractType& type) { 12848 RawTypeRef* TypeRef::New(const AbstractType& type) {
12794 const TypeRef& result = TypeRef::Handle(TypeRef::New()); 12849 const TypeRef& result = TypeRef::Handle(TypeRef::New());
12795 result.set_type(type); 12850 result.set_type(type);
12796 result.set_is_being_checked(false);
12797 return result.raw(); 12851 return result.raw();
12798 } 12852 }
12799 12853
12800 12854
12801 const char* TypeRef::ToCString() const { 12855 const char* TypeRef::ToCString() const {
12802 const char* format = "TypeRef: %s%s"; 12856 const char* format = "TypeRef: %s%s";
12803 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( 12857 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle(
12804 type()).type_class()).Name()).ToCString(); 12858 type()).type_class()).Name()).ToCString();
12805 const char* args_cstr = (AbstractType::Handle( 12859 const char* args_cstr = (AbstractType::Handle(
12806 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>"; 12860 type()).arguments() == AbstractTypeArguments::null()) ? "" : "<...>";
12807 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; 12861 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1;
12808 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 12862 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
12809 OS::SNPrint(chars, len, format, type_cstr, args_cstr); 12863 OS::SNPrint(chars, len, format, type_cstr, args_cstr);
12810 return chars; 12864 return chars;
12811 } 12865 }
12812 12866
12813 12867
12814 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { 12868 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const {
12815 JSONObject jsobj(stream); 12869 JSONObject jsobj(stream);
12816 } 12870 }
12817 12871
12818 12872
12819 void TypeParameter::set_is_finalized() const { 12873 void TypeParameter::set_is_finalized() const {
12820 ASSERT(!IsFinalized()); 12874 ASSERT(!IsFinalized());
12821 set_type_state(RawTypeParameter::kFinalizedUninstantiated); 12875 set_type_state(RawTypeParameter::kFinalizedUninstantiated);
12822 } 12876 }
12823 12877
12824 12878
12825 bool TypeParameter::Equals(const Instance& other) const { 12879 bool TypeParameter::IsEquivalent(const Instance& other,
12880 GrowableObjectArray* trail) const {
12826 if (raw() == other.raw()) { 12881 if (raw() == other.raw()) {
12827 return true; 12882 return true;
12828 } 12883 }
12829 if (other.IsTypeRef()) { 12884 if (other.IsTypeRef()) {
12830 // TODO(regis): Use trail. For now, we "unfold" the right hand type. 12885 // Unfold right hand type. Divergence is controlled by left hand type.
12831 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); 12886 const AbstractType& other_ref_type = AbstractType::Handle(
12887 TypeRef::Cast(other).type());
12888 ASSERT(!other_ref_type.IsTypeRef());
12889 return IsEquivalent(other_ref_type, trail);
12832 } 12890 }
12833 if (!other.IsTypeParameter()) { 12891 if (!other.IsTypeParameter()) {
12834 return false; 12892 return false;
12835 } 12893 }
12836 const TypeParameter& other_type_param = TypeParameter::Cast(other); 12894 const TypeParameter& other_type_param = TypeParameter::Cast(other);
12837 if (parameterized_class() != other_type_param.parameterized_class()) { 12895 if (parameterized_class() != other_type_param.parameterized_class()) {
12838 return false; 12896 return false;
12839 } 12897 }
12840 if (IsFinalized() == other_type_param.IsFinalized()) { 12898 if (IsFinalized() == other_type_param.IsFinalized()) {
12841 return index() == other_type_param.index(); 12899 return index() == other_type_param.index();
(...skipping 20 matching lines...) Expand all
12862 } 12920 }
12863 12921
12864 12922
12865 void TypeParameter::set_bound(const AbstractType& value) const { 12923 void TypeParameter::set_bound(const AbstractType& value) const {
12866 StorePointer(&raw_ptr()->bound_, value.raw()); 12924 StorePointer(&raw_ptr()->bound_, value.raw());
12867 } 12925 }
12868 12926
12869 12927
12870 RawAbstractType* TypeParameter::InstantiateFrom( 12928 RawAbstractType* TypeParameter::InstantiateFrom(
12871 const AbstractTypeArguments& instantiator_type_arguments, 12929 const AbstractTypeArguments& instantiator_type_arguments,
12872 Error* bound_error) const { 12930 Error* bound_error,
12931 GrowableObjectArray* trail) const {
12873 ASSERT(IsFinalized()); 12932 ASSERT(IsFinalized());
12874 if (instantiator_type_arguments.IsNull()) { 12933 if (instantiator_type_arguments.IsNull()) {
12875 return Type::DynamicType(); 12934 return Type::DynamicType();
12876 } 12935 }
12877 const AbstractType& type_arg = AbstractType::Handle( 12936 const AbstractType& type_arg = AbstractType::Handle(
12878 instantiator_type_arguments.TypeAt(index())); 12937 instantiator_type_arguments.TypeAt(index()));
12879 // There is no need to canonicalize the instantiated type parameter, since all 12938 // There is no need to canonicalize the instantiated type parameter, since all
12880 // type arguments are canonicalized at type finalization time. It would be too 12939 // type arguments are canonicalized at type finalization time. It would be too
12881 // early to canonicalize the returned type argument here, since instantiation 12940 // early to canonicalize the returned type argument here, since instantiation
12882 // not only happens at run time, but also during type finalization. 12941 // not only happens at run time, but also during type finalization.
12883 // However, if the type argument is a reference to a canonical type, we
12884 // return the referenced canonical type instead of the type reference to
12885 // provide pointer equality in some simple cases, e.g. in
12886 // language/f_bounded_equality_test.
12887 if (type_arg.IsTypeRef()) {
12888 const AbstractType& ref_type = AbstractType::Handle(
12889 TypeRef::Cast(type_arg).type());
12890 if (ref_type.IsCanonical()) {
12891 return ref_type.raw();
12892 }
12893 }
12894 return type_arg.raw(); 12942 return type_arg.raw();
12895 } 12943 }
12896 12944
12897 12945
12898 bool TypeParameter::CheckBound(const AbstractType& bounded_type, 12946 bool TypeParameter::CheckBound(const AbstractType& bounded_type,
12899 const AbstractType& upper_bound, 12947 const AbstractType& upper_bound,
12900 Error* bound_error) const { 12948 Error* bound_error) const {
12901 ASSERT((bound_error != NULL) && bound_error->IsNull()); 12949 ASSERT((bound_error != NULL) && bound_error->IsNull());
12902 ASSERT(bounded_type.IsFinalized()); 12950 ASSERT(bounded_type.IsFinalized());
12903 ASSERT(upper_bound.IsFinalized()); 12951 ASSERT(upper_bound.IsFinalized());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
12950 index(), 12998 index(),
12951 String::Handle(name()), 12999 String::Handle(name()),
12952 AbstractType::Handle(bound()), 13000 AbstractType::Handle(bound()),
12953 token_pos()); 13001 token_pos());
12954 } 13002 }
12955 13003
12956 13004
12957 intptr_t TypeParameter::Hash() const { 13005 intptr_t TypeParameter::Hash() const {
12958 ASSERT(IsFinalized()); 13006 ASSERT(IsFinalized());
12959 uword result = Class::Handle(parameterized_class()).id(); 13007 uword result = Class::Handle(parameterized_class()).id();
12960 // Do not include the hash of the bound, which could lead to cycles. 13008 // No need to include the hash of the bound, since the type parameter is fully
13009 // identified by its class and index.
12961 result <<= index(); 13010 result <<= index();
12962 return FinalizeHash(result); 13011 return FinalizeHash(result);
12963 } 13012 }
12964 13013
12965 13014
12966 RawTypeParameter* TypeParameter::New() { 13015 RawTypeParameter* TypeParameter::New() {
12967 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != 13016 ASSERT(Isolate::Current()->object_store()->type_parameter_class() !=
12968 Class::null()); 13017 Class::null());
12969 RawObject* raw = Object::Allocate(TypeParameter::kClassId, 13018 RawObject* raw = Object::Allocate(TypeParameter::kClassId,
12970 TypeParameter::InstanceSize(), 13019 TypeParameter::InstanceSize(),
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
13034 bool BoundedType::IsMalformedOrMalbounded() const { 13083 bool BoundedType::IsMalformedOrMalbounded() const {
13035 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); 13084 return AbstractType::Handle(type()).IsMalformedOrMalbounded();
13036 } 13085 }
13037 13086
13038 13087
13039 RawLanguageError* BoundedType::error() const { 13088 RawLanguageError* BoundedType::error() const {
13040 return AbstractType::Handle(type()).error(); 13089 return AbstractType::Handle(type()).error();
13041 } 13090 }
13042 13091
13043 13092
13044 bool BoundedType::Equals(const Instance& other) const { 13093 bool BoundedType::IsEquivalent(const Instance& other,
13094 GrowableObjectArray* trail) const {
13045 // BoundedType are not canonicalized, because their bound may get finalized 13095 // BoundedType are not canonicalized, because their bound may get finalized
13046 // after the BoundedType is created and initialized. 13096 // after the BoundedType is created and initialized.
13047 if (raw() == other.raw()) { 13097 if (raw() == other.raw()) {
13048 return true; 13098 return true;
13049 } 13099 }
13050 if (other.IsTypeRef()) { 13100 if (other.IsTypeRef()) {
13051 // TODO(regis): Use trail. For now, we "unfold" the right hand type. 13101 // Unfold right hand type. Divergence is controlled by left hand type.
13052 return Equals(AbstractType::Handle(TypeRef::Cast(other).type())); 13102 const AbstractType& other_ref_type = AbstractType::Handle(
13103 TypeRef::Cast(other).type());
13104 ASSERT(!other_ref_type.IsTypeRef());
13105 return IsEquivalent(other_ref_type, trail);
13053 } 13106 }
13054 if (!other.IsBoundedType()) { 13107 if (!other.IsBoundedType()) {
13055 return false; 13108 return false;
13056 } 13109 }
13057 const BoundedType& other_bounded = BoundedType::Cast(other); 13110 const BoundedType& other_bounded = BoundedType::Cast(other);
13058 if (type_parameter() != other_bounded.type_parameter()) { 13111 if (type_parameter() != other_bounded.type_parameter()) {
13059 // Not a structural compare.
13060 // Note that a deep comparison of bounds could lead to cycles.
13061 return false; 13112 return false;
13062 } 13113 }
13063 const AbstractType& this_type = AbstractType::Handle(type()); 13114 const AbstractType& this_type = AbstractType::Handle(type());
13064 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); 13115 const AbstractType& other_type = AbstractType::Handle(other_bounded.type());
13065 if (!this_type.Equals(other_type)) { 13116 if (!this_type.IsEquivalent(other_type, trail)) {
13066 return false; 13117 return false;
13067 } 13118 }
13068 const AbstractType& this_bound = AbstractType::Handle(bound()); 13119 const AbstractType& this_bound = AbstractType::Handle(bound());
13069 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); 13120 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound());
13070 return this_bound.IsFinalized() && 13121 return this_bound.IsFinalized() &&
13071 other_bound.IsFinalized() && 13122 other_bound.IsFinalized() &&
13072 this_bound.Equals(other_bound); 13123 this_bound.Equals(other_bound); // Different graph, do not pass trail.
13073 } 13124 }
13074 13125
13075 13126
13076 void BoundedType::set_type(const AbstractType& value) const { 13127 void BoundedType::set_type(const AbstractType& value) const {
13077 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); 13128 ASSERT(value.IsFinalized() || value.IsBeingFinalized());
13078 ASSERT(!value.IsMalformed()); 13129 ASSERT(!value.IsMalformed());
13079 StorePointer(&raw_ptr()->type_, value.raw()); 13130 StorePointer(&raw_ptr()->type_, value.raw());
13080 } 13131 }
13081 13132
13082 13133
13083 void BoundedType::set_bound(const AbstractType& value) const { 13134 void BoundedType::set_bound(const AbstractType& value) const {
13084 // The bound may still be unfinalized because of legal cycles. 13135 // The bound may still be unfinalized because of legal cycles.
13085 // It must be finalized before it is checked at run time, though. 13136 // It must be finalized before it is checked at run time, though.
13086 StorePointer(&raw_ptr()->bound_, value.raw()); 13137 StorePointer(&raw_ptr()->bound_, value.raw());
13087 } 13138 }
13088 13139
13089 13140
13090 void BoundedType::set_type_parameter(const TypeParameter& value) const { 13141 void BoundedType::set_type_parameter(const TypeParameter& value) const {
13091 // A null type parameter is set when marking a type malformed because of a 13142 // A null type parameter is set when marking a type malformed because of a
13092 // bound error at compile time. 13143 // bound error at compile time.
13093 ASSERT(value.IsNull() || value.IsFinalized()); 13144 ASSERT(value.IsNull() || value.IsFinalized());
13094 StorePointer(&raw_ptr()->type_parameter_, value.raw()); 13145 StorePointer(&raw_ptr()->type_parameter_, value.raw());
13095 } 13146 }
13096 13147
13097 13148
13098 void BoundedType::set_is_being_checked(bool value) const {
13099 raw_ptr()->is_being_checked_ = value;
13100 }
13101
13102
13103 RawAbstractType* BoundedType::InstantiateFrom( 13149 RawAbstractType* BoundedType::InstantiateFrom(
13104 const AbstractTypeArguments& instantiator_type_arguments, 13150 const AbstractTypeArguments& instantiator_type_arguments,
13105 Error* bound_error) const { 13151 Error* bound_error,
13152 GrowableObjectArray* trail) const {
13106 ASSERT(IsFinalized()); 13153 ASSERT(IsFinalized());
13107 AbstractType& bounded_type = AbstractType::Handle(type()); 13154 AbstractType& bounded_type = AbstractType::Handle(type());
13108 if (!bounded_type.IsInstantiated()) { 13155 if (!bounded_type.IsInstantiated()) {
13109 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, 13156 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments,
13110 bound_error); 13157 bound_error,
13158 trail);
13111 } 13159 }
13112 if (FLAG_enable_type_checks && 13160 if (FLAG_enable_type_checks && bound_error->IsNull()) {
13113 bound_error->IsNull() &&
13114 !is_being_checked()) {
13115 // Avoid endless recursion while checking and instantiating bound.
13116 set_is_being_checked(true);
13117 AbstractType& upper_bound = AbstractType::Handle(bound()); 13161 AbstractType& upper_bound = AbstractType::Handle(bound());
13118 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); 13162 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
13119 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); 13163 const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
13120 if (!upper_bound.IsInstantiated()) { 13164 if (!upper_bound.IsInstantiated()) {
13121 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, 13165 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
13122 bound_error); 13166 bound_error,
13167 trail);
13123 } 13168 }
13124 if (bound_error->IsNull()) { 13169 if (bound_error->IsNull()) {
13125 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && 13170 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
13126 bound_error->IsNull()) { 13171 bound_error->IsNull()) {
13127 // We cannot determine yet whether the bounded_type is below the 13172 // We cannot determine yet whether the bounded_type is below the
13128 // upper_bound, because one or both of them is still uninstantiated. 13173 // upper_bound, because one or both of them is still uninstantiated.
13129 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); 13174 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated());
13130 // Postpone bound check by returning a new BoundedType with partially 13175 // Postpone bound check by returning a new BoundedType with partially
13131 // instantiated bounded_type and upper_bound, but keeping type_param. 13176 // instantiated bounded_type and upper_bound, but keeping type_param.
13132 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); 13177 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param);
13133 } 13178 }
13134 } 13179 }
13135 set_is_being_checked(false);
13136 } 13180 }
13137 return bounded_type.raw(); 13181 return bounded_type.raw();
13138 } 13182 }
13139 13183
13140 13184
13141 RawAbstractType* BoundedType::CloneUnfinalized() const { 13185 RawAbstractType* BoundedType::CloneUnfinalized() const {
13142 if (IsFinalized()) { 13186 if (IsFinalized()) {
13143 return raw(); 13187 return raw();
13144 } 13188 }
13145 AbstractType& bounded_type = AbstractType::Handle(type()); 13189 AbstractType& bounded_type = AbstractType::Handle(type());
13146 13190
13147 bounded_type = bounded_type.CloneUnfinalized(); 13191 bounded_type = bounded_type.CloneUnfinalized();
13148 // No need to clone bound or type parameter, as they are not part of the 13192 // No need to clone bound or type parameter, as they are not part of the
13149 // finalization state of this bounded type. 13193 // finalization state of this bounded type.
13150 return BoundedType::New(bounded_type, 13194 return BoundedType::New(bounded_type,
13151 AbstractType::Handle(bound()), 13195 AbstractType::Handle(bound()),
13152 TypeParameter::Handle(type_parameter())); 13196 TypeParameter::Handle(type_parameter()));
13153 } 13197 }
13154 13198
13155 13199
13156 intptr_t BoundedType::Hash() const { 13200 intptr_t BoundedType::Hash() const {
13157 uword result = AbstractType::Handle(type()).Hash(); 13201 uword result = AbstractType::Handle(type()).Hash();
13158 // Do not include the hash of the bound, which could lead to cycles. 13202 // No need to include the hash of the bound, since the bound is defined by the
13203 // type parameter (modulo instantiation state).
13159 result += TypeParameter::Handle(type_parameter()).Hash(); 13204 result += TypeParameter::Handle(type_parameter()).Hash();
13160 return FinalizeHash(result); 13205 return FinalizeHash(result);
13161 } 13206 }
13162 13207
13163 13208
13164 RawBoundedType* BoundedType::New() { 13209 RawBoundedType* BoundedType::New() {
13165 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != 13210 ASSERT(Isolate::Current()->object_store()->bounded_type_class() !=
13166 Class::null()); 13211 Class::null());
13167 RawObject* raw = Object::Allocate(BoundedType::kClassId, 13212 RawObject* raw = Object::Allocate(BoundedType::kClassId,
13168 BoundedType::InstanceSize(), 13213 BoundedType::InstanceSize(),
13169 Heap::kOld); 13214 Heap::kOld);
13170 return reinterpret_cast<RawBoundedType*>(raw); 13215 return reinterpret_cast<RawBoundedType*>(raw);
13171 } 13216 }
13172 13217
13173 13218
13174 RawBoundedType* BoundedType::New(const AbstractType& type, 13219 RawBoundedType* BoundedType::New(const AbstractType& type,
13175 const AbstractType& bound, 13220 const AbstractType& bound,
13176 const TypeParameter& type_parameter) { 13221 const TypeParameter& type_parameter) {
13177 const BoundedType& result = BoundedType::Handle(BoundedType::New()); 13222 const BoundedType& result = BoundedType::Handle(BoundedType::New());
13178 result.set_type(type); 13223 result.set_type(type);
13179 result.set_bound(bound); 13224 result.set_bound(bound);
13180 result.set_type_parameter(type_parameter); 13225 result.set_type_parameter(type_parameter);
13181 result.set_is_being_checked(false);
13182 return result.raw(); 13226 return result.raw();
13183 } 13227 }
13184 13228
13185 13229
13186 const char* BoundedType::ToCString() const { 13230 const char* BoundedType::ToCString() const {
13187 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; 13231 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s";
13188 const char* type_cstr = String::Handle(AbstractType::Handle( 13232 const char* type_cstr = String::Handle(AbstractType::Handle(
13189 type()).Name()).ToCString(); 13233 type()).Name()).ToCString();
13190 const char* bound_cstr = String::Handle(AbstractType::Handle( 13234 const char* bound_cstr = String::Handle(AbstractType::Handle(
13191 bound()).Name()).ToCString(); 13235 bound()).Name()).ToCString();
(...skipping 3735 matching lines...) Expand 10 before | Expand all | Expand 10 after
16927 return "_MirrorReference"; 16971 return "_MirrorReference";
16928 } 16972 }
16929 16973
16930 16974
16931 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 16975 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
16932 Instance::PrintToJSONStream(stream, ref); 16976 Instance::PrintToJSONStream(stream, ref);
16933 } 16977 }
16934 16978
16935 16979
16936 } // namespace dart 16980 } // namespace dart
OLDNEW
« no previous file with comments | « 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