OLD | NEW |
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 3540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3551 if (!IsGeneric() && !IsClosureClass()) { | 3551 if (!IsGeneric() && !IsClosureClass()) { |
3552 ASSERT((canonical_types() == Object::null()) || | 3552 ASSERT((canonical_types() == Object::null()) || |
3553 (canonical_types() == type.raw())); // Set during own finalization. | 3553 (canonical_types() == type.raw())); // Set during own finalization. |
3554 set_canonical_types(type); | 3554 set_canonical_types(type); |
3555 } else { | 3555 } else { |
3556 Array& types = Array::Handle(); | 3556 Array& types = Array::Handle(); |
3557 types ^= canonical_types(); | 3557 types ^= canonical_types(); |
3558 ASSERT(!types.IsNull() && (types.Length() > 1)); | 3558 ASSERT(!types.IsNull() && (types.Length() > 1)); |
3559 ASSERT((types.At(0) == Object::null()) || (types.At(0) == type.raw())); | 3559 ASSERT((types.At(0) == Object::null()) || (types.At(0) == type.raw())); |
3560 types.SetAt(0, type); | 3560 types.SetAt(0, type); |
| 3561 // Makes sure that 'canonical_types' has not changed. |
| 3562 ASSERT(types.raw() == canonical_types()); |
3561 } | 3563 } |
3562 } | 3564 } |
3563 | 3565 |
3564 | 3566 |
3565 intptr_t Class::FindCanonicalTypeIndex(const AbstractType& needle) const { | 3567 intptr_t Class::FindCanonicalTypeIndex(const AbstractType& needle) const { |
3566 Thread* thread = Thread::Current(); | 3568 Thread* thread = Thread::Current(); |
3567 if (EnsureIsFinalized(thread) != Error::null()) { | 3569 if (EnsureIsFinalized(thread) != Error::null()) { |
3568 return -1; | 3570 return -1; |
3569 } | 3571 } |
3570 if (needle.raw() == CanonicalType()) { | 3572 if (needle.raw() == CanonicalType()) { |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4120 Zone* zone = Thread::Current()->zone(); | 4122 Zone* zone = Thread::Current()->zone(); |
4121 const Library& lib = Library::Handle(zone, library()); | 4123 const Library& lib = Library::Handle(zone, library()); |
4122 const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name)); | 4124 const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name)); |
4123 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 4125 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
4124 return LibraryPrefix::Cast(obj).raw(); | 4126 return LibraryPrefix::Cast(obj).raw(); |
4125 } | 4127 } |
4126 return LibraryPrefix::null(); | 4128 return LibraryPrefix::null(); |
4127 } | 4129 } |
4128 | 4130 |
4129 | 4131 |
| 4132 // Canonicalizing the type arguments may have changed the index, may have |
| 4133 // grown the table, or may even have canonicalized this type. Therefore |
| 4134 // conrtinue search for canonical type at the last index visited. |
| 4135 RawAbstractType* Class::LookupOrAddCanonicalType( |
| 4136 const AbstractType& lookup_type, intptr_t start_index) const { |
| 4137 intptr_t index = start_index; |
| 4138 Zone* zone = Thread::Current()->zone(); |
| 4139 AbstractType& type = Type::Handle(zone); |
| 4140 Array& canonical_types = Array::Handle(zone); |
| 4141 canonical_types ^= this->canonical_types(); |
| 4142 if (canonical_types.IsNull()) { |
| 4143 canonical_types = empty_array().raw(); |
| 4144 } |
| 4145 ASSERT(canonical_types.IsArray()); |
| 4146 const intptr_t length = canonical_types.Length(); |
| 4147 while (index < length) { |
| 4148 type ^= canonical_types.At(index); |
| 4149 if (type.IsNull()) { |
| 4150 break; |
| 4151 } |
| 4152 ASSERT(type.IsFinalized()); |
| 4153 if (lookup_type.Equals(type)) { |
| 4154 ASSERT(type.IsCanonical()); |
| 4155 return type.raw(); |
| 4156 } |
| 4157 index++; |
| 4158 } |
| 4159 |
| 4160 lookup_type.SetCanonical(); |
| 4161 |
| 4162 // The type needs to be added to the list. Grow the list if it is full. |
| 4163 if (index >= length) { |
| 4164 ASSERT((index == length) || ((index == 1) && (length == 0))); |
| 4165 const intptr_t new_length = (length > 64) ? |
| 4166 (length + 64) : |
| 4167 ((length == 0) ? 2 : (length * 2)); |
| 4168 const Array& new_canonical_types = Array::Handle( |
| 4169 zone, Array::Grow(canonical_types, new_length, Heap::kOld)); |
| 4170 new_canonical_types.SetAt(index, lookup_type); |
| 4171 this->set_canonical_types(new_canonical_types); |
| 4172 } else { |
| 4173 canonical_types.SetAt(index, lookup_type); |
| 4174 } |
| 4175 return lookup_type.raw(); |
| 4176 } |
| 4177 |
| 4178 |
4130 const char* Class::ToCString() const { | 4179 const char* Class::ToCString() const { |
4131 const Library& lib = Library::Handle(library()); | 4180 const Library& lib = Library::Handle(library()); |
4132 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); | 4181 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); |
4133 const char* patch_prefix = is_patch() ? "Patch " : ""; | 4182 const char* patch_prefix = is_patch() ? "Patch " : ""; |
4134 const char* class_name = String::Handle(Name()).ToCString(); | 4183 const char* class_name = String::Handle(Name()).ToCString(); |
4135 return OS::SCreate(Thread::Current()->zone(), | 4184 return OS::SCreate(Thread::Current()->zone(), |
4136 "%s %sClass: %s", library_name, patch_prefix, class_name); | 4185 "%s %sClass: %s", library_name, patch_prefix, class_name); |
4137 } | 4186 } |
4138 | 4187 |
4139 | 4188 |
(...skipping 11646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15786 // In case the type is first canonicalized at runtime, its type argument | 15835 // In case the type is first canonicalized at runtime, its type argument |
15787 // vector may be longer than necessary. This is not an issue. | 15836 // vector may be longer than necessary. This is not an issue. |
15788 ASSERT(type_args.IsNull() || (type_args.Length() >= cls.NumTypeArguments())); | 15837 ASSERT(type_args.IsNull() || (type_args.Length() >= cls.NumTypeArguments())); |
15789 type_args = type_args.Canonicalize(trail); | 15838 type_args = type_args.Canonicalize(trail); |
15790 if (IsCanonical()) { | 15839 if (IsCanonical()) { |
15791 // Canonicalizing type_args canonicalized this type as a side effect. | 15840 // Canonicalizing type_args canonicalized this type as a side effect. |
15792 ASSERT(IsRecursive()); | 15841 ASSERT(IsRecursive()); |
15793 return this->raw(); | 15842 return this->raw(); |
15794 } | 15843 } |
15795 set_arguments(type_args); | 15844 set_arguments(type_args); |
| 15845 ASSERT(type_args.IsNull() || type_args.IsOld()); |
15796 | 15846 |
15797 // Canonicalizing the type arguments may have changed the index, may have | 15847 return cls.LookupOrAddCanonicalType(*this, index); |
15798 // grown the table, or may even have canonicalized this type. | |
15799 canonical_types ^= cls.canonical_types(); | |
15800 if (canonical_types.IsNull()) { | |
15801 canonical_types = empty_array().raw(); | |
15802 } | |
15803 length = canonical_types.Length(); | |
15804 while (index < length) { | |
15805 type ^= canonical_types.At(index); | |
15806 if (type.IsNull()) { | |
15807 break; | |
15808 } | |
15809 ASSERT(type.IsFinalized()); | |
15810 if (this->Equals(type)) { | |
15811 ASSERT(type.IsCanonical()); | |
15812 return type.raw(); | |
15813 } | |
15814 index++; | |
15815 } | |
15816 | |
15817 // The type needs to be added to the list. Grow the list if it is full. | |
15818 if (index >= length) { | |
15819 ASSERT((index == length) || ((index == 1) && (length == 0))); | |
15820 const intptr_t new_length = (length > 64) ? | |
15821 (length + 64) : | |
15822 ((length == 0) ? 2 : (length * 2)); | |
15823 const Array& new_canonical_types = Array::Handle( | |
15824 zone, Array::Grow(canonical_types, new_length, Heap::kOld)); | |
15825 cls.set_canonical_types(new_canonical_types); | |
15826 canonical_types = new_canonical_types.raw(); | |
15827 } | |
15828 canonical_types.SetAt(index, *this); | |
15829 ASSERT(IsOld()); | |
15830 ASSERT(type_args.IsNull() || type_args.IsOld()); | |
15831 SetCanonical(); | |
15832 return this->raw(); | |
15833 } | 15848 } |
15834 | 15849 |
15835 | 15850 |
15836 RawString* Type::EnumerateURIs() const { | 15851 RawString* Type::EnumerateURIs() const { |
15837 if (IsDynamicType()) { | 15852 if (IsDynamicType()) { |
15838 return Symbols::Empty().raw(); | 15853 return Symbols::Empty().raw(); |
15839 } | 15854 } |
15840 Zone* zone = Thread::Current()->zone(); | 15855 Zone* zone = Thread::Current()->zone(); |
15841 GrowableHandlePtrArray<const String> pieces(zone, 6); | 15856 GrowableHandlePtrArray<const String> pieces(zone, 6); |
15842 const Class& cls = Class::Handle(zone, type_class()); | 15857 const Class& cls = Class::Handle(zone, type_class()); |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16296 sig_fun.set_parameter_types(Array::Handle(Array::New(num_params, | 16311 sig_fun.set_parameter_types(Array::Handle(Array::New(num_params, |
16297 Heap::kOld))); | 16312 Heap::kOld))); |
16298 for (intptr_t i = 0; i < num_params; i++) { | 16313 for (intptr_t i = 0; i < num_params; i++) { |
16299 type = fun.ParameterTypeAt(i); | 16314 type = fun.ParameterTypeAt(i); |
16300 type = type.Canonicalize(trail); | 16315 type = type.Canonicalize(trail); |
16301 sig_fun.SetParameterTypeAt(i, type); | 16316 sig_fun.SetParameterTypeAt(i, type); |
16302 } | 16317 } |
16303 sig_fun.set_parameter_names(Array::Handle(zone, fun.parameter_names())); | 16318 sig_fun.set_parameter_names(Array::Handle(zone, fun.parameter_names())); |
16304 set_signature(sig_fun); | 16319 set_signature(sig_fun); |
16305 } | 16320 } |
| 16321 ASSERT(type_args.IsNull() || type_args.IsOld()); |
16306 | 16322 |
16307 // Canonicalizing the type arguments and the signature may have changed the | 16323 return scope_cls.LookupOrAddCanonicalType(*this, index); |
16308 // index, may have grown the table, or may even have canonicalized this type. | |
16309 canonical_types ^= scope_cls.canonical_types(); | |
16310 if (canonical_types.IsNull()) { | |
16311 canonical_types = empty_array().raw(); | |
16312 } | |
16313 length = canonical_types.Length(); | |
16314 while (index < length) { | |
16315 type ^= canonical_types.At(index); | |
16316 if (type.IsNull()) { | |
16317 break; | |
16318 } | |
16319 ASSERT(type.IsFinalized()); | |
16320 if (this->Equals(type)) { | |
16321 ASSERT(type.IsCanonical()); | |
16322 return type.raw(); | |
16323 } | |
16324 index++; | |
16325 } | |
16326 | |
16327 // The type needs to be added to the list. Grow the list if it is full. | |
16328 if (index >= length) { | |
16329 ASSERT((index == length) || ((index == 1) && (length == 0))); | |
16330 const intptr_t new_length = (length > 64) ? | |
16331 (length + 64) : | |
16332 ((length == 0) ? 2 : (length * 2)); | |
16333 const Array& new_canonical_types = Array::Handle( | |
16334 zone, Array::Grow(canonical_types, new_length, Heap::kOld)); | |
16335 scope_cls.set_canonical_types(new_canonical_types); | |
16336 canonical_types = new_canonical_types.raw(); | |
16337 } | |
16338 canonical_types.SetAt(index, *this); | |
16339 ASSERT(IsOld()); | |
16340 ASSERT(type_args.IsNull() || type_args.IsOld()); | |
16341 SetCanonical(); | |
16342 return this->raw(); | |
16343 } | 16324 } |
16344 | 16325 |
16345 | 16326 |
16346 RawString* FunctionType::EnumerateURIs() const { | 16327 RawString* FunctionType::EnumerateURIs() const { |
16347 Zone* zone = Thread::Current()->zone(); | 16328 Zone* zone = Thread::Current()->zone(); |
16348 // The scope class and type arguments do not appear explicitly in the user | 16329 // The scope class and type arguments do not appear explicitly in the user |
16349 // visible name. The type arguments were used to instantiate the function type | 16330 // visible name. The type arguments were used to instantiate the function type |
16350 // prior to this call. | 16331 // prior to this call. |
16351 const Function& sig_fun = Function::Handle(zone, signature()); | 16332 const Function& sig_fun = Function::Handle(zone, signature()); |
16352 AbstractType& type = AbstractType::Handle(zone); | 16333 AbstractType& type = AbstractType::Handle(zone); |
(...skipping 5327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21680 return UserTag::null(); | 21661 return UserTag::null(); |
21681 } | 21662 } |
21682 | 21663 |
21683 | 21664 |
21684 const char* UserTag::ToCString() const { | 21665 const char* UserTag::ToCString() const { |
21685 const String& tag_label = String::Handle(label()); | 21666 const String& tag_label = String::Handle(label()); |
21686 return tag_label.ToCString(); | 21667 return tag_label.ToCString(); |
21687 } | 21668 } |
21688 | 21669 |
21689 } // namespace dart | 21670 } // namespace dart |
OLD | NEW |