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

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

Issue 211963003: Detect and reject illegal recursive types (non-contractive types). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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
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 3994 matching lines...) Expand 10 before | Expand all | Expand 10 after
4005 OS::SNPrint(chars, len, format, cname); 4005 OS::SNPrint(chars, len, format, cname);
4006 return chars; 4006 return chars;
4007 } 4007 }
4008 4008
4009 4009
4010 void UnresolvedClass::PrintToJSONStream(JSONStream* stream, bool ref) const { 4010 void UnresolvedClass::PrintToJSONStream(JSONStream* stream, bool ref) const {
4011 Object::PrintToJSONStream(stream, ref); 4011 Object::PrintToJSONStream(stream, ref);
4012 } 4012 }
4013 4013
4014 4014
4015 static intptr_t FinalizeHash(uword hash) { 4015 static intptr_t CombineHashes(uint32_t hash, uint32_t other_hash) {
4016 hash += other_hash;
4017 hash += hash << 10;
4018 hash ^= hash >> 6; // Logical shift, unsigned hash.
4019 return hash;
4020 }
4021
4022
4023 static intptr_t FinalizeHash(uint32_t hash) {
4016 hash += hash << 3; 4024 hash += hash << 3;
4017 hash ^= hash >> 11; 4025 hash ^= hash >> 11; // Logical shift, unsigned hash.
4018 hash += hash << 15; 4026 hash += hash << 15;
4019 return hash; 4027 return hash;
4020 } 4028 }
4021 4029
4022 4030
4023 intptr_t TypeArguments::Hash() const { 4031 intptr_t TypeArguments::Hash() const {
4024 if (IsNull()) return 0; 4032 if (IsNull()) return 0;
4025 const intptr_t num_types = Length(); 4033 const intptr_t num_types = Length();
4026 if (IsRaw(0, num_types)) return 0; 4034 if (IsRaw(0, num_types)) return 0;
4027 intptr_t result = 0; 4035 intptr_t result = 0;
4028 AbstractType& type = AbstractType::Handle(); 4036 AbstractType& type = AbstractType::Handle();
4029 for (intptr_t i = 0; i < num_types; i++) { 4037 for (intptr_t i = 0; i < num_types; i++) {
4030 type = TypeAt(i); 4038 type = TypeAt(i);
4031 result += type.Hash(); 4039 result = CombineHashes(result, type.Hash());
4032 result += result << 10;
4033 result ^= result >> 6;
4034 } 4040 }
4035 return FinalizeHash(result); 4041 return FinalizeHash(result);
4036 } 4042 }
4037 4043
4038 4044
4039 RawString* TypeArguments::SubvectorName(intptr_t from_index, 4045 RawString* TypeArguments::SubvectorName(intptr_t from_index,
4040 intptr_t len, 4046 intptr_t len,
4041 NameVisibility name_visibility) const { 4047 NameVisibility name_visibility) const {
4042 ASSERT(from_index + len <= Length()); 4048 ASSERT(from_index + len <= Length());
4043 String& name = String::Handle(); 4049 String& name = String::Handle();
(...skipping 10 matching lines...) Expand all
4054 strings.SetAt(s++, Symbols::CommaSpace()); 4060 strings.SetAt(s++, Symbols::CommaSpace());
4055 } 4061 }
4056 } 4062 }
4057 strings.SetAt(s++, Symbols::RAngleBracket()); 4063 strings.SetAt(s++, Symbols::RAngleBracket());
4058 ASSERT(s == num_strings); 4064 ASSERT(s == num_strings);
4059 name = String::ConcatAll(strings); 4065 name = String::ConcatAll(strings);
4060 return Symbols::New(name); 4066 return Symbols::New(name);
4061 } 4067 }
4062 4068
4063 4069
4064 bool TypeArguments::IsEquivalent(const TypeArguments& other, 4070 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other,
4065 GrowableObjectArray* trail) const { 4071 intptr_t from_index,
4072 intptr_t len,
4073 GrowableObjectArray* trail) const {
4066 if (this->raw() == other.raw()) { 4074 if (this->raw() == other.raw()) {
4067 return true; 4075 return true;
4068 } 4076 }
4069 if (IsNull() || other.IsNull()) { 4077 if (IsNull() || other.IsNull()) {
4070 return false; 4078 return false;
4071 } 4079 }
4072 const intptr_t num_types = Length(); 4080 const intptr_t num_types = Length();
4073 if (num_types != other.Length()) { 4081 if (num_types != other.Length()) {
4074 return false; 4082 return false;
4075 } 4083 }
4076 AbstractType& type = AbstractType::Handle(); 4084 AbstractType& type = AbstractType::Handle();
4077 AbstractType& other_type = AbstractType::Handle(); 4085 AbstractType& other_type = AbstractType::Handle();
4078 for (intptr_t i = 0; i < num_types; i++) { 4086 for (intptr_t i = from_index; i < from_index + len; i++) {
4079 type = TypeAt(i); 4087 type = TypeAt(i);
4080 other_type = other.TypeAt(i); 4088 other_type = other.TypeAt(i);
4081 if (!type.IsEquivalent(other_type, trail)) { 4089 if (!type.IsEquivalent(other_type, trail)) {
4082 return false; 4090 return false;
4083 } 4091 }
4084 } 4092 }
4085 return true; 4093 return true;
4086 } 4094 }
4087 4095
4088 4096
4097 bool TypeArguments::IsRecursive() const {
4098 if (IsNull()) return false;
4099 const intptr_t num_types = Length();
4100 AbstractType& type = AbstractType::Handle();
4101 for (intptr_t i = 0; i < num_types; i++) {
4102 type = TypeAt(i);
4103 if (type.IsRecursive()) {
4104 return true;
4105 }
4106 }
4107 return false;
4108 }
4109
4110
4089 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, 4111 bool TypeArguments::IsDynamicTypes(bool raw_instantiated,
4090 intptr_t from_index, 4112 intptr_t from_index,
4091 intptr_t len) const { 4113 intptr_t len) const {
4092 ASSERT(Length() >= (from_index + len)); 4114 ASSERT(Length() >= (from_index + len));
4093 AbstractType& type = AbstractType::Handle(); 4115 AbstractType& type = AbstractType::Handle();
4094 Class& type_class = Class::Handle(); 4116 Class& type_class = Class::Handle();
4095 for (intptr_t i = 0; i < len; i++) { 4117 for (intptr_t i = 0; i < len; i++) {
4096 type = TypeAt(from_index + i); 4118 type = TypeAt(from_index + i);
4097 ASSERT(!type.IsNull());
4098 if (!type.HasResolvedTypeClass()) { 4119 if (!type.HasResolvedTypeClass()) {
4099 if (raw_instantiated && type.IsTypeParameter()) { 4120 if (raw_instantiated && type.IsTypeParameter()) {
4100 // An uninstantiated type parameter is equivalent to dynamic (even in 4121 // An uninstantiated type parameter is equivalent to dynamic (even in
4101 // the presence of a malformed bound in checked mode). 4122 // the presence of a malformed bound in checked mode).
4102 continue; 4123 continue;
4103 } 4124 }
4104 return false; 4125 return false;
4105 } 4126 }
4106 type_class = type.type_class(); 4127 type_class = type.type_class();
4107 if (!type_class.IsDynamicClass()) { 4128 if (!type_class.IsDynamicClass()) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
4255 for (intptr_t i = 0; i < num_types; i++) { 4276 for (intptr_t i = 0; i < num_types; i++) {
4256 type = TypeAt(i); 4277 type = TypeAt(i);
4257 if (!type.IsResolved()) { 4278 if (!type.IsResolved()) {
4258 return false; 4279 return false;
4259 } 4280 }
4260 } 4281 }
4261 return true; 4282 return true;
4262 } 4283 }
4263 4284
4264 4285
4265 bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const { 4286 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index,
4287 intptr_t len,
4288 GrowableObjectArray* trail) const {
4289 ASSERT(!IsNull());
4266 AbstractType& type = AbstractType::Handle(); 4290 AbstractType& type = AbstractType::Handle();
4267 const intptr_t num_types = Length(); 4291 for (intptr_t i = 0; i < len; i++) {
4268 for (intptr_t i = 0; i < num_types; i++) { 4292 type = TypeAt(from_index + i);
4269 type = TypeAt(i); 4293 if (!type.IsInstantiated(trail)) {
4270 if (!type.IsBeingFinalized() && !type.IsInstantiated(trail)) {
4271 return false; 4294 return false;
4272 } 4295 }
4273 } 4296 }
4274 return true; 4297 return true;
4275 } 4298 }
4276 4299
4277 4300
4278 bool TypeArguments::IsUninstantiatedIdentity() const { 4301 bool TypeArguments::IsUninstantiatedIdentity() const {
4279 ASSERT(!IsInstantiated()); 4302 ASSERT(!IsInstantiated());
4280 AbstractType& type = AbstractType::Handle(); 4303 AbstractType& type = AbstractType::Handle();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
4424 IsUninstantiatedIdentity() && 4447 IsUninstantiatedIdentity() &&
4425 (instantiator_type_arguments.Length() == Length())) { 4448 (instantiator_type_arguments.Length() == Length())) {
4426 return instantiator_type_arguments.raw(); 4449 return instantiator_type_arguments.raw();
4427 } 4450 }
4428 const intptr_t num_types = Length(); 4451 const intptr_t num_types = Length();
4429 TypeArguments& instantiated_array = 4452 TypeArguments& instantiated_array =
4430 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); 4453 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew));
4431 AbstractType& type = AbstractType::Handle(); 4454 AbstractType& type = AbstractType::Handle();
4432 for (intptr_t i = 0; i < num_types; i++) { 4455 for (intptr_t i = 0; i < num_types; i++) {
4433 type = TypeAt(i); 4456 type = TypeAt(i);
4434 if (!type.IsBeingFinalized() && !type.IsInstantiated()) { 4457 if (!type.IsInstantiated()) {
4435 type = type.InstantiateFrom(instantiator_type_arguments, 4458 type = type.InstantiateFrom(instantiator_type_arguments,
4436 bound_error, 4459 bound_error,
4437 trail); 4460 trail);
4438 } 4461 }
4439 instantiated_array.SetTypeAt(i, type); 4462 instantiated_array.SetTypeAt(i, type);
4440 } 4463 }
4441 return instantiated_array.raw(); 4464 return instantiated_array.raw();
4442 } 4465 }
4443 4466
4444 4467
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4540 const intptr_t table_size = table.Length() - 1; 4563 const intptr_t table_size = table.Length() - 1;
4541 const intptr_t new_table_size = table_size * 2; 4564 const intptr_t new_table_size = table_size * 2;
4542 Array& new_table = Array::Handle(isolate, Array::New(new_table_size + 1)); 4565 Array& new_table = Array::Handle(isolate, Array::New(new_table_size + 1));
4543 // Copy all elements from the original table to the newly allocated 4566 // Copy all elements from the original table to the newly allocated
4544 // array. 4567 // array.
4545 TypeArguments& element = TypeArguments::Handle(isolate); 4568 TypeArguments& element = TypeArguments::Handle(isolate);
4546 Object& new_element = Object::Handle(isolate); 4569 Object& new_element = Object::Handle(isolate);
4547 for (intptr_t i = 0; i < table_size; i++) { 4570 for (intptr_t i = 0; i < table_size; i++) {
4548 element ^= table.At(i); 4571 element ^= table.At(i);
4549 if (!element.IsNull()) { 4572 if (!element.IsNull()) {
4550 intptr_t hash = element.Hash(); 4573 const intptr_t hash = element.Hash();
4551 ASSERT(Utils::IsPowerOfTwo(new_table_size)); 4574 ASSERT(Utils::IsPowerOfTwo(new_table_size));
4552 intptr_t index = hash & (new_table_size - 1); 4575 intptr_t index = hash & (new_table_size - 1);
4553 new_element = new_table.At(index); 4576 new_element = new_table.At(index);
4554 while (!new_element.IsNull()) { 4577 while (!new_element.IsNull()) {
4555 index = (index + 1) & (new_table_size - 1); // Move to next element. 4578 index = (index + 1) & (new_table_size - 1); // Move to next element.
4556 new_element = new_table.At(index); 4579 new_element = new_table.At(index);
4557 } 4580 }
4558 new_table.SetAt(index, element); 4581 new_table.SetAt(index, element);
4559 } 4582 }
4560 } 4583 }
(...skipping 12 matching lines...) Expand all
4573 arguments.SetCanonical(); // Mark object as being canonical. 4596 arguments.SetCanonical(); // Mark object as being canonical.
4574 table.SetAt(index, arguments); // Remember the new element. 4597 table.SetAt(index, arguments); // Remember the new element.
4575 // Update used count. 4598 // Update used count.
4576 // Last element of the array is the number of used elements. 4599 // Last element of the array is the number of used elements.
4577 const intptr_t table_size = table.Length() - 1; 4600 const intptr_t table_size = table.Length() - 1;
4578 const intptr_t used_elements = 4601 const intptr_t used_elements =
4579 Smi::Value(Smi::RawCast(table.At(table_size))) + 1; 4602 Smi::Value(Smi::RawCast(table.At(table_size))) + 1;
4580 const Smi& used = Smi::Handle(isolate, Smi::New(used_elements)); 4603 const Smi& used = Smi::Handle(isolate, Smi::New(used_elements));
4581 table.SetAt(table_size, used); 4604 table.SetAt(table_size, used);
4582 4605
4606 #ifdef DEBUG
4607 // Verify that there are no duplicates.
4608 // Duplicates could appear if hash values are not kept constant across
4609 // snapshots, e.g. if class ids are not preserved by the snapshots.
4610 TypeArguments& other_arguments = TypeArguments::Handle();
4611 for (intptr_t i = 0; i < table_size; i++) {
4612 if ((i != index) && (table.At(i) != TypeArguments::null())) {
4613 other_arguments ^= table.At(i);
4614 if (arguments.Equals(other_arguments)) {
4615 // Recursive types may be equal, but have different hashes.
4616 ASSERT(arguments.IsRecursive());
4617 ASSERT(other_arguments.IsRecursive());
4618 ASSERT(arguments.Hash() != other_arguments.Hash());
4619 }
4620 }
4621 }
4622 #endif
4623
4583 // Rehash if table is 75% full. 4624 // Rehash if table is 75% full.
4584 if (used_elements > ((table_size / 4) * 3)) { 4625 if (used_elements > ((table_size / 4) * 3)) {
4585 GrowCanonicalTypeArguments(isolate, table); 4626 GrowCanonicalTypeArguments(isolate, table);
4586 } 4627 }
4587 } 4628 }
4588 4629
4589 4630
4590 static intptr_t FindIndexInCanonicalTypeArguments( 4631 static intptr_t FindIndexInCanonicalTypeArguments(
4591 Isolate* isolate, 4632 Isolate* isolate,
4592 const Array& table, 4633 const Array& table,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4634 } 4675 }
4635 const intptr_t num_types = Length(); 4676 const intptr_t num_types = Length();
4636 if (IsRaw(0, num_types)) { 4677 if (IsRaw(0, num_types)) {
4637 return TypeArguments::null(); 4678 return TypeArguments::null();
4638 } 4679 }
4639 Isolate* isolate = Isolate::Current(); 4680 Isolate* isolate = Isolate::Current();
4640 ObjectStore* object_store = isolate->object_store(); 4681 ObjectStore* object_store = isolate->object_store();
4641 Array& table = Array::Handle(isolate, 4682 Array& table = Array::Handle(isolate,
4642 object_store->canonical_type_arguments()); 4683 object_store->canonical_type_arguments());
4643 // Last element of the array is the number of used elements. 4684 // Last element of the array is the number of used elements.
4644 const intptr_t used_elements = 4685 const intptr_t num_used =
4645 Smi::Value(Smi::RawCast(table.At(table.Length() - 1))); 4686 Smi::Value(Smi::RawCast(table.At(table.Length() - 1)));
4646 const intptr_t hash = Hash(); 4687 const intptr_t hash = Hash();
4647 intptr_t index = 4688 intptr_t index =
4648 FindIndexInCanonicalTypeArguments(isolate, table, *this, hash); 4689 FindIndexInCanonicalTypeArguments(isolate, table, *this, hash);
4649 TypeArguments& result = TypeArguments::Handle(isolate); 4690 TypeArguments& result = TypeArguments::Handle(isolate);
4650 result ^= table.At(index); 4691 result ^= table.At(index);
4651 if (result.IsNull()) { 4692 if (result.IsNull()) {
4652 // Canonicalize each type argument. 4693 // Canonicalize each type argument.
4653 AbstractType& type_arg = AbstractType::Handle(isolate); 4694 AbstractType& type_arg = AbstractType::Handle(isolate);
4654 for (intptr_t i = 0; i < num_types; i++) { 4695 for (intptr_t i = 0; i < num_types; i++) {
4655 type_arg = TypeAt(i); 4696 type_arg = TypeAt(i);
4656 type_arg = type_arg.Canonicalize(trail); 4697 type_arg = type_arg.Canonicalize(trail);
4657 SetTypeAt(i, type_arg); 4698 SetTypeAt(i, type_arg);
4658 } 4699 }
4659 // Canonicalization of a recursive type may change its hash. 4700 // Canonicalization of a type should not change its hash. Verify.
4660 const intptr_t new_hash = Hash(); 4701 ASSERT(Hash() == hash);
4661 // Canonicalization of the type argument's own type arguments may add an 4702 // Canonicalization of the type argument's own type arguments may add an
4662 // entry to the table, or even grow the table, and thereby change the 4703 // entry to the table, or even grow the table, and thereby change the
4663 // previously calculated index. 4704 // previously calculated index.
4664 table = object_store->canonical_type_arguments(); 4705 table = object_store->canonical_type_arguments();
4665 if ((new_hash != hash) || 4706 if (Smi::Value(Smi::RawCast(table.At(table.Length() - 1))) != num_used) {
4666 (Smi::Value(Smi::RawCast(table.At(table.Length() - 1))) 4707 index = FindIndexInCanonicalTypeArguments(isolate, table, *this, hash);
4667 != used_elements)) {
4668 index =
4669 FindIndexInCanonicalTypeArguments(isolate, table, *this, new_hash);
4670 result ^= table.At(index); 4708 result ^= table.At(index);
4671 } 4709 }
4672 if (result.IsNull()) { 4710 if (result.IsNull()) {
4673 // Make sure we have an old space object and add it to the table. 4711 // Make sure we have an old space object and add it to the table.
4674 if (this->IsNew()) { 4712 if (this->IsNew()) {
4675 result ^= Object::Clone(*this, Heap::kOld); 4713 result ^= Object::Clone(*this, Heap::kOld);
4676 } else { 4714 } else {
4677 result ^= this->raw(); 4715 result ^= this->raw();
4678 } 4716 }
4679 ASSERT(result.IsOld()); 4717 ASSERT(result.IsOld());
(...skipping 7972 matching lines...) Expand 10 before | Expand all | Expand 10 after
12652 12690
12653 12691
12654 bool AbstractType::IsEquivalent(const Instance& other, 12692 bool AbstractType::IsEquivalent(const Instance& other,
12655 GrowableObjectArray* trail) const { 12693 GrowableObjectArray* trail) const {
12656 // AbstractType is an abstract class. 12694 // AbstractType is an abstract class.
12657 UNREACHABLE(); 12695 UNREACHABLE();
12658 return false; 12696 return false;
12659 } 12697 }
12660 12698
12661 12699
12700 bool AbstractType::IsRecursive() const {
12701 // AbstractType is an abstract class.
12702 UNREACHABLE();
12703 return false;
12704 }
12705
12706
12662 RawAbstractType* AbstractType::InstantiateFrom( 12707 RawAbstractType* AbstractType::InstantiateFrom(
12663 const TypeArguments& instantiator_type_arguments, 12708 const TypeArguments& instantiator_type_arguments,
12664 Error* bound_error, 12709 Error* bound_error,
12665 GrowableObjectArray* trail) const { 12710 GrowableObjectArray* trail) const {
12666 // AbstractType is an abstract class. 12711 // AbstractType is an abstract class.
12667 UNREACHABLE(); 12712 UNREACHABLE();
12668 return NULL; 12713 return NULL;
12669 } 12714 }
12670 12715
12671 12716
12672 RawAbstractType* AbstractType::CloneUnfinalized() const { 12717 RawAbstractType* AbstractType::CloneUnfinalized() const {
12673 // AbstractType is an abstract class. 12718 // AbstractType is an abstract class.
12674 UNREACHABLE(); 12719 UNREACHABLE();
12675 return NULL; 12720 return NULL;
12676 } 12721 }
12677 12722
12678 12723
12679 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const { 12724 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const {
12680 // AbstractType is an abstract class. 12725 // AbstractType is an abstract class.
12681 UNREACHABLE(); 12726 UNREACHABLE();
12682 return NULL; 12727 return NULL;
12683 } 12728 }
12684 12729
12685 12730
12731 RawObject* AbstractType::OnlyBuddyInTrail(GrowableObjectArray* trail) const {
12732 if (trail == NULL) {
12733 return Object::null();
12734 }
12735 const intptr_t len = trail->Length();
12736 ASSERT((len % 2) == 0);
12737 for (intptr_t i = 0; i < len; i += 2) {
12738 if (trail->At(i) == this->raw()) {
12739 ASSERT(trail->At(i + 1) != Object::null());
12740 return trail->At(i + 1);
12741 }
12742 }
12743 return Object::null();
12744 }
12745
12746
12747 void AbstractType::AddOnlyBuddyToTrail(GrowableObjectArray** trail,
12748 const Object& buddy) const {
12749 if (*trail == NULL) {
12750 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
12751 } else {
12752 ASSERT(OnlyBuddyInTrail(*trail) == Object::null());
12753 }
12754 (*trail)->Add(*this);
12755 (*trail)->Add(buddy);
12756 }
12757
12758
12686 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { 12759 RawString* AbstractType::BuildName(NameVisibility name_visibility) const {
12687 if (IsBoundedType()) { 12760 if (IsBoundedType()) {
12688 const AbstractType& type = AbstractType::Handle( 12761 const AbstractType& type = AbstractType::Handle(
12689 BoundedType::Cast(*this).type()); 12762 BoundedType::Cast(*this).type());
12690 if (name_visibility == kUserVisibleName) { 12763 if (name_visibility == kUserVisibleName) {
12691 return type.BuildName(kUserVisibleName); 12764 return type.BuildName(kUserVisibleName);
12692 } 12765 }
12693 String& type_name = String::Handle(type.BuildName(kInternalName)); 12766 String& type_name = String::Handle(type.BuildName(kInternalName));
12694 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); 12767 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace());
12695 // Build the bound name without causing divergence. 12768 // Build the bound name without causing divergence.
(...skipping 19 matching lines...) Expand all
12715 } 12788 }
12716 // If the type is still being finalized, we may be reporting an error about 12789 // If the type is still being finalized, we may be reporting an error about
12717 // a malformed type, so proceed with caution. 12790 // a malformed type, so proceed with caution.
12718 const TypeArguments& args = TypeArguments::Handle(arguments()); 12791 const TypeArguments& args = TypeArguments::Handle(arguments());
12719 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); 12792 const intptr_t num_args = args.IsNull() ? 0 : args.Length();
12720 String& class_name = String::Handle(); 12793 String& class_name = String::Handle();
12721 intptr_t first_type_param_index; 12794 intptr_t first_type_param_index;
12722 intptr_t num_type_params; // Number of type parameters to print. 12795 intptr_t num_type_params; // Number of type parameters to print.
12723 if (HasResolvedTypeClass()) { 12796 if (HasResolvedTypeClass()) {
12724 const Class& cls = Class::Handle(type_class()); 12797 const Class& cls = Class::Handle(type_class());
12725 num_type_params = cls.NumTypeParameters(); // Do not print the full vector. 12798 if (IsResolved() || !cls.IsMixinApplication()) {
12799 // Do not print the full vector, but only the declared type parameters.
12800 num_type_params = cls.NumTypeParameters();
12801 } else {
12802 // Do not print the type parameters of an unresolved mixin application,
12803 // since it would prematurely trigger the application of the mixin type.
12804 num_type_params = 0;
12805 }
12726 if (name_visibility == kInternalName) { 12806 if (name_visibility == kInternalName) {
12727 class_name = cls.Name(); 12807 class_name = cls.Name();
12728 } else { 12808 } else {
12729 ASSERT(name_visibility == kUserVisibleName); 12809 ASSERT(name_visibility == kUserVisibleName);
12730 // Map internal types to their corresponding public interfaces. 12810 // Map internal types to their corresponding public interfaces.
12731 class_name = cls.UserVisibleName(); 12811 class_name = cls.UserVisibleName();
12732 } 12812 }
12733 if (num_type_params > num_args) { 12813 if (num_type_params > num_args) {
12734 first_type_param_index = 0; 12814 first_type_param_index = 0;
12735 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { 12815 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
13167 } 13247 }
13168 13248
13169 13249
13170 bool Type::IsInstantiated(GrowableObjectArray* trail) const { 13250 bool Type::IsInstantiated(GrowableObjectArray* trail) const {
13171 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { 13251 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
13172 return true; 13252 return true;
13173 } 13253 }
13174 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { 13254 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) {
13175 return false; 13255 return false;
13176 } 13256 }
13257 if (arguments() == TypeArguments::null()) {
13258 return true;
13259 }
13177 const TypeArguments& args = TypeArguments::Handle(arguments()); 13260 const TypeArguments& args = TypeArguments::Handle(arguments());
13178 return args.IsNull() || args.IsInstantiated(trail); 13261 const intptr_t num_type_args = args.Length();
13262 intptr_t len = num_type_args; // Check the full vector of type args.
13263 ASSERT(num_type_args > 0);
13264 // This type is not instantiated if it refers to type parameters.
13265 // This IsInstantiated() call may be invoked on an unresolved signature type.
13266 // Although this type may still be unresolved, the type parameters it may
13267 // refer to are resolved by definition. We can therefore return the correct
13268 // result even for an unresolved type. We just need to look at all type
13269 // arguments and not just at the type parameters.
13270 if (HasResolvedTypeClass()) {
13271 const Class& cls = Class::Handle(type_class());
13272 len = cls.NumTypeParameters(); // Check the type parameters only.
13273 ASSERT(num_type_args == cls.NumTypeArguments());
13274 }
13275 return (len == 0) || args.IsSubvectorInstantiated(num_type_args - len, len);
13179 } 13276 }
13180 13277
13181 13278
13182 RawAbstractType* Type::InstantiateFrom( 13279 RawAbstractType* Type::InstantiateFrom(
13183 const TypeArguments& instantiator_type_arguments, 13280 const TypeArguments& instantiator_type_arguments,
13184 Error* bound_error, 13281 Error* bound_error,
13185 GrowableObjectArray* trail) const { 13282 GrowableObjectArray* trail) const {
13186 ASSERT(IsFinalized() || IsBeingFinalized()); 13283 ASSERT(IsFinalized() || IsBeingFinalized());
13187 ASSERT(!IsInstantiated()); 13284 ASSERT(!IsInstantiated());
13188 // Return the uninstantiated type unchanged if malformed. No copy needed. 13285 // Return the uninstantiated type unchanged if malformed. No copy needed.
13189 if (IsMalformed()) { 13286 if (IsMalformed()) {
13190 return raw(); 13287 return raw();
13191 } 13288 }
13192 TypeArguments& type_arguments = TypeArguments::Handle(arguments());
13193 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
13194 bound_error,
13195 trail);
13196 // Note that the type class has to be resolved at this time, but not 13289 // Note that the type class has to be resolved at this time, but not
13197 // necessarily finalized yet. We may be checking bounds at compile time. 13290 // necessarily finalized yet. We may be checking bounds at compile time or
13291 // finalizing the type argument vector of a recursive type.
13198 const Class& cls = Class::Handle(type_class()); 13292 const Class& cls = Class::Handle(type_class());
13199 // This uninstantiated type is not modified, as it can be instantiated 13293 // This uninstantiated type is not modified, as it can be instantiated
13200 // with different instantiators. 13294 // with different instantiators.
13201 Type& instantiated_type = Type::Handle( 13295 Type& instantiated_type = Type::Handle(
13202 Type::New(cls, type_arguments, token_pos())); 13296 Type::New(cls, TypeArguments::Handle(), token_pos()));
13203 ASSERT(type_arguments.IsNull() || 13297 if (arguments() != TypeArguments::null()) {
13204 (type_arguments.Length() == cls.NumTypeArguments())); 13298 TypeArguments& type_arguments = TypeArguments::Handle(arguments());
13299 ASSERT(type_arguments.Length() == cls.NumTypeArguments());
13300 if (type_arguments.IsRecursive()) {
13301 AddOnlyBuddyToTrail(&trail, instantiated_type);
13302 }
13303 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
13304 bound_error,
13305 trail);
13306 instantiated_type.set_arguments(type_arguments);
13307 }
13205 instantiated_type.SetIsFinalized(); 13308 instantiated_type.SetIsFinalized();
13206 // Canonicalization is not part of instantiation. 13309 // Canonicalization is not part of instantiation.
13207 return instantiated_type.raw(); 13310 return instantiated_type.raw();
13208 } 13311 }
13209 13312
13210 13313
13211 bool Type::IsEquivalent(const Instance& other, 13314 bool Type::IsEquivalent(const Instance& other,
13212 GrowableObjectArray* trail) const { 13315 GrowableObjectArray* trail) const {
13213 ASSERT(!IsNull()); 13316 ASSERT(!IsNull());
13214 if (raw() == other.raw()) { 13317 if (raw() == other.raw()) {
(...skipping 29 matching lines...) Expand all
13244 if (num_type_params == 0) { 13347 if (num_type_params == 0) {
13245 // Shortcut unnecessary handle allocation below. 13348 // Shortcut unnecessary handle allocation below.
13246 return true; 13349 return true;
13247 } 13350 }
13248 const intptr_t num_type_args = cls.NumTypeArguments(); 13351 const intptr_t num_type_args = cls.NumTypeArguments();
13249 const intptr_t from_index = num_type_args - num_type_params; 13352 const intptr_t from_index = num_type_args - num_type_params;
13250 const TypeArguments& type_args = TypeArguments::Handle(isolate, arguments()); 13353 const TypeArguments& type_args = TypeArguments::Handle(isolate, arguments());
13251 const TypeArguments& other_type_args = TypeArguments::Handle( 13354 const TypeArguments& other_type_args = TypeArguments::Handle(
13252 isolate, other_type.arguments()); 13355 isolate, other_type.arguments());
13253 if (type_args.IsNull()) { 13356 if (type_args.IsNull()) {
13254 return other_type_args.IsRaw(from_index, num_type_params); 13357 // Ignore from_index.
13358 return other_type_args.IsRaw(0, num_type_params);
13255 } 13359 }
13256 if (other_type_args.IsNull()) { 13360 if (other_type_args.IsNull()) {
13257 return type_args.IsRaw(from_index, num_type_params); 13361 // Ignore from_index.
13362 return type_args.IsRaw(0, num_type_params);
13258 } 13363 }
13259 ASSERT(type_args.Length() >= (from_index + num_type_params)); 13364 if (!type_args.IsSubvectorEquivalent(other_type_args,
13260 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); 13365 from_index,
13261 AbstractType& type_arg = AbstractType::Handle(isolate); 13366 num_type_params)) {
13262 AbstractType& other_type_arg = AbstractType::Handle(isolate); 13367 return false;
13263 for (intptr_t i = 0; i < num_type_params; i++) { 13368 }
13264 type_arg = type_args.TypeAt(from_index + i); 13369 #ifdef DEBUG
13265 other_type_arg = other_type_args.TypeAt(from_index + i); 13370 if (from_index > 0) {
13266 if (!type_arg.IsEquivalent(other_type_arg, trail)) { 13371 // Verify that the type arguments of the super class match, since they
13267 return false; 13372 // depend solely on the type parameters that were just verified to match.
13373 ASSERT(type_args.Length() >= (from_index + num_type_params));
13374 ASSERT(other_type_args.Length() >= (from_index + num_type_params));
13375 AbstractType& type_arg = AbstractType::Handle(isolate);
13376 AbstractType& other_type_arg = AbstractType::Handle(isolate);
13377 for (intptr_t i = 0; i < from_index; i++) {
13378 type_arg = type_args.TypeAt(i);
13379 other_type_arg = other_type_args.TypeAt(i);
13380 ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
13268 } 13381 }
13269 } 13382 }
13383 #endif
13270 return true; 13384 return true;
13271 } 13385 }
13272 13386
13273 13387
13388 bool Type::IsRecursive() const {
13389 return TypeArguments::Handle(arguments()).IsRecursive();
13390 }
13391
13392
13274 RawAbstractType* Type::CloneUnfinalized() const { 13393 RawAbstractType* Type::CloneUnfinalized() const {
13275 ASSERT(IsResolved()); 13394 ASSERT(IsResolved());
13276 if (IsFinalized()) { 13395 if (IsFinalized()) {
13277 return raw(); 13396 return raw();
13278 } 13397 }
13279 ASSERT(!IsMalformed()); // Malformed types are finalized. 13398 ASSERT(!IsMalformed()); // Malformed types are finalized.
13280 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. 13399 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization.
13281 TypeArguments& type_args = TypeArguments::Handle(arguments()); 13400 TypeArguments& type_args = TypeArguments::Handle(arguments());
13282 type_args = type_args.CloneUnfinalized(); 13401 type_args = type_args.CloneUnfinalized();
13283 const Class& type_cls = Class::Handle(type_class()); 13402 const Class& type_cls = Class::Handle(type_class());
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
13401 #endif 13520 #endif
13402 ASSERT(IsOld()); 13521 ASSERT(IsOld());
13403 ASSERT(type_args.IsNull() || type_args.IsOld()); 13522 ASSERT(type_args.IsNull() || type_args.IsOld());
13404 SetCanonical(); 13523 SetCanonical();
13405 return this->raw(); 13524 return this->raw();
13406 } 13525 }
13407 13526
13408 13527
13409 intptr_t Type::Hash() const { 13528 intptr_t Type::Hash() const {
13410 ASSERT(IsFinalized()); 13529 ASSERT(IsFinalized());
13411 uword result = 1; 13530 intptr_t result = 1;
13412 if (IsMalformed()) return result; 13531 if (IsMalformed()) return result;
13413 result += Class::Handle(type_class()).id(); 13532 result = CombineHashes(result, Class::Handle(type_class()).id());
13414 result += TypeArguments::Handle(arguments()).Hash(); 13533 result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash());
13415 return FinalizeHash(result); 13534 return FinalizeHash(result);
13416 } 13535 }
13417 13536
13418 13537
13419 void Type::set_type_class(const Object& value) const { 13538 void Type::set_type_class(const Object& value) const {
13420 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); 13539 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass()));
13421 StorePointer(&raw_ptr()->type_class_, value.raw()); 13540 StorePointer(&raw_ptr()->type_class_, value.raw());
13422 } 13541 }
13423 13542
13424 13543
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
13471 Class::Handle(type_class()).Name()).ToCString(); 13590 Class::Handle(type_class()).Name()).ToCString();
13472 } else { 13591 } else {
13473 class_name = UnresolvedClass::Handle(unresolved_class()).ToCString(); 13592 class_name = UnresolvedClass::Handle(unresolved_class()).ToCString();
13474 } 13593 }
13475 if (type_arguments.IsNull()) { 13594 if (type_arguments.IsNull()) {
13476 const char* format = "Type: class '%s'"; 13595 const char* format = "Type: class '%s'";
13477 const intptr_t len = OS::SNPrint(NULL, 0, format, class_name) + 1; 13596 const intptr_t len = OS::SNPrint(NULL, 0, format, class_name) + 1;
13478 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 13597 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
13479 OS::SNPrint(chars, len, format, class_name); 13598 OS::SNPrint(chars, len, format, class_name);
13480 return chars; 13599 return chars;
13600 } else if (IsFinalized() && IsRecursive()) {
13601 const char* format = "Type: (@%" Px " H%" Px ") class '%s', args:[%s]";
13602 const intptr_t hash = Hash();
13603 const char* args_cstr = TypeArguments::Handle(arguments()).ToCString();
13604 const intptr_t len =
13605 OS::SNPrint(NULL, 0, format, raw(), hash, class_name, args_cstr) + 1;
13606 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
13607 OS::SNPrint(chars, len, format, raw(), hash, class_name, args_cstr);
13608 return chars;
13481 } else { 13609 } else {
13482 const char* format = "Type: class '%s', args:[%s]"; 13610 const char* format = "Type: class '%s', args:[%s]";
13483 const char* args_cstr = TypeArguments::Handle(arguments()).ToCString(); 13611 const char* args_cstr = TypeArguments::Handle(arguments()).ToCString();
13484 intptr_t len = OS::SNPrint(NULL, 0, format, class_name, args_cstr) + 1; 13612 const intptr_t len =
13613 OS::SNPrint(NULL, 0, format, class_name, args_cstr) + 1;
13485 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 13614 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
13486 OS::SNPrint(chars, len, format, class_name, args_cstr); 13615 OS::SNPrint(chars, len, format, class_name, args_cstr);
13487 return chars; 13616 return chars;
13488 } 13617 }
13489 } else { 13618 } else {
13490 return "Unresolved Type"; 13619 return "Unresolved Type";
13491 } 13620 }
13492 } 13621 }
13493 13622
13494 13623
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
13534 return true; 13663 return true;
13535 } 13664 }
13536 return AbstractType::Handle(type()).IsEquivalent(other, trail); 13665 return AbstractType::Handle(type()).IsEquivalent(other, trail);
13537 } 13666 }
13538 13667
13539 13668
13540 RawAbstractType* TypeRef::InstantiateFrom( 13669 RawAbstractType* TypeRef::InstantiateFrom(
13541 const TypeArguments& instantiator_type_arguments, 13670 const TypeArguments& instantiator_type_arguments,
13542 Error* bound_error, 13671 Error* bound_error,
13543 GrowableObjectArray* trail) const { 13672 GrowableObjectArray* trail) const {
13544 TypeRef& instantiated_type_ref = TypeRef::Handle(); 13673 AbstractType& ref_type = AbstractType::Handle(type());
13545 instantiated_type_ref ^= OnlyBuddyInTrail(trail); 13674 ASSERT(!ref_type.IsTypeRef());
13546 if (!instantiated_type_ref.IsNull()) { 13675 AbstractType& instantiated_ref_type = AbstractType::Handle();
13547 return instantiated_type_ref.raw(); 13676 instantiated_ref_type ^= ref_type.OnlyBuddyInTrail(trail);
13677 if (instantiated_ref_type.IsNull()) {
13678 // The referenced type is first encountered here during instantiation.
13679 instantiated_ref_type = ref_type.InstantiateFrom(
13680 instantiator_type_arguments, bound_error, trail);
13548 } 13681 }
13549 instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType())); 13682 ASSERT(!instantiated_ref_type.IsTypeRef());
13550 AddOnlyBuddyToTrail(&trail, instantiated_type_ref); 13683 return TypeRef::New(instantiated_ref_type);
13551 const AbstractType& ref_type = AbstractType::Handle(type());
13552 ASSERT(!ref_type.IsTypeRef());
13553 const AbstractType& instantiated_ref_type = AbstractType::Handle(
13554 ref_type.InstantiateFrom(instantiator_type_arguments,
13555 bound_error,
13556 trail));
13557 instantiated_type_ref.set_type(instantiated_ref_type);
13558 return instantiated_type_ref.raw();
13559 } 13684 }
13560 13685
13561 13686
13562 void TypeRef::set_type(const AbstractType& value) const { 13687 void TypeRef::set_type(const AbstractType& value) const {
13563 ASSERT(value.HasResolvedTypeClass()); 13688 ASSERT(value.HasResolvedTypeClass());
13564 StorePointer(&raw_ptr()->type_, value.raw()); 13689 StorePointer(&raw_ptr()->type_, value.raw());
13565 } 13690 }
13566 13691
13567 13692
13568 // A TypeRef cannot be canonical by definition. Only its referenced type can be. 13693 // A TypeRef cannot be canonical by definition. Only its referenced type can be.
13569 // Consider the type Derived, where class Derived extends Base<Derived>. 13694 // Consider the type Derived, where class Derived extends Base<Derived>.
13570 // The first type argument of its flattened type argument vector is Derived, 13695 // The first type argument of its flattened type argument vector is Derived,
13571 // i.e. itself, but pointer equality is not possible. 13696 // represented by a TypeRef pointing to itself.
13572 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { 13697 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const {
13573 if (TestAndAddToTrail(&trail)) { 13698 if (TestAndAddToTrail(&trail)) {
13574 return raw(); 13699 return raw();
13575 } 13700 }
13576 AbstractType& ref_type = AbstractType::Handle(type()); 13701 AbstractType& ref_type = AbstractType::Handle(type());
13577 ref_type = ref_type.Canonicalize(trail); 13702 ref_type = ref_type.Canonicalize(trail);
13578 set_type(ref_type); 13703 set_type(ref_type);
13579 return raw(); 13704 return raw();
13580 } 13705 }
13581 13706
13582 13707
13583 intptr_t TypeRef::Hash() const { 13708 intptr_t TypeRef::Hash() const {
13584 // Do not calculate the hash of the referenced type to avoid divergence. 13709 // Do not calculate the hash of the referenced type to avoid divergence.
13585 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); 13710 const intptr_t result =
13711 Class::Handle(AbstractType::Handle(type()).type_class()).id();
13586 return FinalizeHash(result); 13712 return FinalizeHash(result);
13587 } 13713 }
13588 13714
13589 13715
13590 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const { 13716 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const {
13591 if (*trail == NULL) { 13717 if (*trail == NULL) {
13592 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); 13718 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
13593 } else { 13719 } else {
13594 const intptr_t len = (*trail)->Length(); 13720 const intptr_t len = (*trail)->Length();
13595 for (intptr_t i = 0; i < len; i++) { 13721 for (intptr_t i = 0; i < len; i++) {
(...skipping 20 matching lines...) Expand all
13616 return true; 13742 return true;
13617 } 13743 }
13618 } 13744 }
13619 } 13745 }
13620 (*trail)->Add(*this); 13746 (*trail)->Add(*this);
13621 (*trail)->Add(buddy); 13747 (*trail)->Add(buddy);
13622 return false; 13748 return false;
13623 } 13749 }
13624 13750
13625 13751
13626 RawObject* TypeRef::OnlyBuddyInTrail(GrowableObjectArray* trail) const {
13627 if (trail == NULL) {
13628 return Object::null();
13629 }
13630 const intptr_t len = trail->Length();
13631 ASSERT((len % 2) == 0);
13632 for (intptr_t i = 0; i < len; i += 2) {
13633 if (trail->At(i) == this->raw()) {
13634 ASSERT(trail->At(i + 1) != Object::null());
13635 return trail->At(i + 1);
13636 }
13637 }
13638 return Object::null();
13639 }
13640
13641
13642 void TypeRef::AddOnlyBuddyToTrail(GrowableObjectArray** trail,
13643 const Object& buddy) const {
13644 if (*trail == NULL) {
13645 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New());
13646 } else {
13647 ASSERT(OnlyBuddyInTrail(*trail) == Object::null());
13648 }
13649 (*trail)->Add(*this);
13650 (*trail)->Add(buddy);
13651 }
13652
13653
13654 RawTypeRef* TypeRef::New() { 13752 RawTypeRef* TypeRef::New() {
13655 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); 13753 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null());
13656 RawObject* raw = Object::Allocate(TypeRef::kClassId, 13754 RawObject* raw = Object::Allocate(TypeRef::kClassId,
13657 TypeRef::InstanceSize(), 13755 TypeRef::InstanceSize(),
13658 Heap::kOld); 13756 Heap::kOld);
13659 return reinterpret_cast<RawTypeRef*>(raw); 13757 return reinterpret_cast<RawTypeRef*>(raw);
13660 } 13758 }
13661 13759
13662 13760
13663 RawTypeRef* TypeRef::New(const AbstractType& type) { 13761 RawTypeRef* TypeRef::New(const AbstractType& type) {
13664 const TypeRef& result = TypeRef::Handle(TypeRef::New()); 13762 const TypeRef& result = TypeRef::Handle(TypeRef::New());
13665 result.set_type(type); 13763 result.set_type(type);
13666 return result.raw(); 13764 return result.raw();
13667 } 13765 }
13668 13766
13669 13767
13670 const char* TypeRef::ToCString() const { 13768 const char* TypeRef::ToCString() const {
13671 const char* format = "TypeRef: %s%s"; 13769 const char* type_cstr = String::Handle(Class::Handle(
13672 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( 13770 type_class()).Name()).ToCString();
13673 type()).type_class()).Name()).ToCString(); 13771 AbstractType& ref_type = AbstractType::Handle(type());
13674 const char* args_cstr = (AbstractType::Handle( 13772 if (ref_type.IsFinalized()) {
13675 type()).arguments() == TypeArguments::null()) ? "" : "<...>"; 13773 const char* format = "TypeRef: %s<...> (@%" Px " H%" Px ")";
13676 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; 13774 const intptr_t hash = ref_type.Hash();
13677 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 13775 const intptr_t len =
13678 OS::SNPrint(chars, len, format, type_cstr, args_cstr); 13776 OS::SNPrint(NULL, 0, format, type_cstr, ref_type.raw(), hash) + 1;
13679 return chars; 13777 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
13778 OS::SNPrint(chars, len, format, type_cstr, ref_type.raw(), hash);
13779 return chars;
13780 } else {
13781 const char* format = "TypeRef: %s<...>";
13782 const intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr) + 1;
13783 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
13784 OS::SNPrint(chars, len, format, type_cstr);
13785 return chars;
13786 }
13680 } 13787 }
13681 13788
13682 13789
13683 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { 13790 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const {
13684 JSONObject jsobj(stream); 13791 JSONObject jsobj(stream);
13685 ObjectIdRing* ring = Isolate::Current()->object_id_ring(); 13792 ObjectIdRing* ring = Isolate::Current()->object_id_ring();
13686 const intptr_t id = ring->GetIdForObject(raw()); 13793 const intptr_t id = ring->GetIdForObject(raw());
13687 jsobj.AddProperty("type", JSONType(ref)); 13794 jsobj.AddProperty("type", JSONType(ref));
13688 jsobj.AddPropertyF("id", "objects/%" Pd "", id); 13795 jsobj.AddPropertyF("id", "objects/%" Pd "", id);
13689 const char* name = String::Handle(Name()).ToCString(); 13796 const char* name = String::Handle(Name()).ToCString();
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
13824 return TypeParameter::New(Class::Handle(parameterized_class()), 13931 return TypeParameter::New(Class::Handle(parameterized_class()),
13825 index(), 13932 index(),
13826 String::Handle(name()), 13933 String::Handle(name()),
13827 AbstractType::Handle(bound()), 13934 AbstractType::Handle(bound()),
13828 token_pos()); 13935 token_pos());
13829 } 13936 }
13830 13937
13831 13938
13832 intptr_t TypeParameter::Hash() const { 13939 intptr_t TypeParameter::Hash() const {
13833 ASSERT(IsFinalized()); 13940 ASSERT(IsFinalized());
13834 uword result = Class::Handle(parameterized_class()).id(); 13941 intptr_t result = Class::Handle(parameterized_class()).id();
13835 // No need to include the hash of the bound, since the type parameter is fully 13942 // No need to include the hash of the bound, since the type parameter is fully
13836 // identified by its class and index. 13943 // identified by its class and index.
13837 result <<= index(); 13944 result = CombineHashes(result, index());
13838 return FinalizeHash(result); 13945 return FinalizeHash(result);
13839 } 13946 }
13840 13947
13841 13948
13842 RawTypeParameter* TypeParameter::New() { 13949 RawTypeParameter* TypeParameter::New() {
13843 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != 13950 ASSERT(Isolate::Current()->object_store()->type_parameter_class() !=
13844 Class::null()); 13951 Class::null());
13845 RawObject* raw = Object::Allocate(TypeParameter::kClassId, 13952 RawObject* raw = Object::Allocate(TypeParameter::kClassId,
13846 TypeParameter::InstanceSize(), 13953 TypeParameter::InstanceSize(),
13847 Heap::kOld); 13954 Heap::kOld);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
13964 return false; 14071 return false;
13965 } 14072 }
13966 const AbstractType& this_bound = AbstractType::Handle(bound()); 14073 const AbstractType& this_bound = AbstractType::Handle(bound());
13967 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); 14074 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound());
13968 return this_bound.IsFinalized() && 14075 return this_bound.IsFinalized() &&
13969 other_bound.IsFinalized() && 14076 other_bound.IsFinalized() &&
13970 this_bound.Equals(other_bound); // Different graph, do not pass trail. 14077 this_bound.Equals(other_bound); // Different graph, do not pass trail.
13971 } 14078 }
13972 14079
13973 14080
14081 bool BoundedType::IsRecursive() const {
14082 return AbstractType::Handle(type()).IsRecursive();
14083 }
14084
14085
13974 void BoundedType::set_type(const AbstractType& value) const { 14086 void BoundedType::set_type(const AbstractType& value) const {
13975 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); 14087 ASSERT(value.IsFinalized() || value.IsBeingFinalized());
13976 ASSERT(!value.IsMalformed()); 14088 ASSERT(!value.IsMalformed());
13977 StorePointer(&raw_ptr()->type_, value.raw()); 14089 StorePointer(&raw_ptr()->type_, value.raw());
13978 } 14090 }
13979 14091
13980 14092
13981 void BoundedType::set_bound(const AbstractType& value) const { 14093 void BoundedType::set_bound(const AbstractType& value) const {
13982 // The bound may still be unfinalized because of legal cycles. 14094 // The bound may still be unfinalized because of legal cycles.
13983 // It must be finalized before it is checked at run time, though. 14095 // It must be finalized before it is checked at run time, though.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
14038 bounded_type = bounded_type.CloneUnfinalized(); 14150 bounded_type = bounded_type.CloneUnfinalized();
14039 // No need to clone bound or type parameter, as they are not part of the 14151 // No need to clone bound or type parameter, as they are not part of the
14040 // finalization state of this bounded type. 14152 // finalization state of this bounded type.
14041 return BoundedType::New(bounded_type, 14153 return BoundedType::New(bounded_type,
14042 AbstractType::Handle(bound()), 14154 AbstractType::Handle(bound()),
14043 TypeParameter::Handle(type_parameter())); 14155 TypeParameter::Handle(type_parameter()));
14044 } 14156 }
14045 14157
14046 14158
14047 intptr_t BoundedType::Hash() const { 14159 intptr_t BoundedType::Hash() const {
14048 uword result = AbstractType::Handle(type()).Hash(); 14160 intptr_t result = AbstractType::Handle(type()).Hash();
14049 // No need to include the hash of the bound, since the bound is defined by the 14161 // No need to include the hash of the bound, since the bound is defined by the
14050 // type parameter (modulo instantiation state). 14162 // type parameter (modulo instantiation state).
14051 result += TypeParameter::Handle(type_parameter()).Hash(); 14163 result = CombineHashes(result,
14052 return FinalizeHash(result); 14164 TypeParameter::Handle(type_parameter()).Hash());
14165 return FinalizeHash(result);
14053 } 14166 }
14054 14167
14055 14168
14056 RawBoundedType* BoundedType::New() { 14169 RawBoundedType* BoundedType::New() {
14057 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != 14170 ASSERT(Isolate::Current()->object_store()->bounded_type_class() !=
14058 Class::null()); 14171 Class::null());
14059 RawObject* raw = Object::Allocate(BoundedType::kClassId, 14172 RawObject* raw = Object::Allocate(BoundedType::kClassId,
14060 BoundedType::InstanceSize(), 14173 BoundedType::InstanceSize(),
14061 Heap::kOld); 14174 Heap::kOld);
14062 return reinterpret_cast<RawBoundedType*>(raw); 14175 return reinterpret_cast<RawBoundedType*>(raw);
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after
15043 void Bigint::PrintToJSONStream(JSONStream* stream, bool ref) const { 15156 void Bigint::PrintToJSONStream(JSONStream* stream, bool ref) const {
15044 Number::PrintToJSONStream(stream, ref); 15157 Number::PrintToJSONStream(stream, ref);
15045 } 15158 }
15046 15159
15047 15160
15048 // Synchronize with implementation in compiler (intrinsifier). 15161 // Synchronize with implementation in compiler (intrinsifier).
15049 class StringHasher : ValueObject { 15162 class StringHasher : ValueObject {
15050 public: 15163 public:
15051 StringHasher() : hash_(0) {} 15164 StringHasher() : hash_(0) {}
15052 void Add(int32_t ch) { 15165 void Add(int32_t ch) {
15053 hash_ += ch; 15166 hash_ = CombineHashes(hash_, ch);
15054 hash_ += hash_ << 10;
15055 hash_ ^= hash_ >> 6;
15056 } 15167 }
15057 // Return a non-zero hash of at most 'bits' bits. 15168 // Return a non-zero hash of at most 'bits' bits.
15058 intptr_t Finalize(int bits) { 15169 intptr_t Finalize(int bits) {
15059 ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); 15170 ASSERT(1 <= bits && bits <= (kBitsPerWord - 1));
15060 hash_ += hash_ << 3; 15171 hash_ = FinalizeHash(hash_);
15061 hash_ ^= hash_ >> 11;
15062 hash_ += hash_ << 15;
15063 hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); 15172 hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
15064 ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); 15173 ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32));
15065 return hash_ == 0 ? 1 : hash_; 15174 return hash_ == 0 ? 1 : hash_;
15066 } 15175 }
15067 private: 15176 private:
15068 uint32_t hash_; 15177 uint32_t hash_;
15069 }; 15178 };
15070 15179
15071 15180
15072 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { 15181 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) {
(...skipping 2926 matching lines...) Expand 10 before | Expand all | Expand 10 after
17999 return "_MirrorReference"; 18108 return "_MirrorReference";
18000 } 18109 }
18001 18110
18002 18111
18003 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 18112 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
18004 Instance::PrintToJSONStream(stream, ref); 18113 Instance::PrintToJSONStream(stream, ref);
18005 } 18114 }
18006 18115
18007 18116
18008 } // namespace dart 18117 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698