| 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 3994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |