Chromium Code Reviews| 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; | |
|
srdjan
2014/03/26 21:35:02
Why don't you return uint32_t instead of convertin
regis
2014/03/26 23:24:58
Done.
| |
| 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 | |
|
hausner
2014/03/26 21:37:21
if you rewrite this as if (DEBUG) {...} then the c
regis
2014/03/26 23:24:58
I am reluctant to use yet another pattern. We alre
| |
| 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 7979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12659 | 12697 |
| 12660 | 12698 |
| 12661 bool AbstractType::IsEquivalent(const Instance& other, | 12699 bool AbstractType::IsEquivalent(const Instance& other, |
| 12662 GrowableObjectArray* trail) const { | 12700 GrowableObjectArray* trail) const { |
| 12663 // AbstractType is an abstract class. | 12701 // AbstractType is an abstract class. |
| 12664 UNREACHABLE(); | 12702 UNREACHABLE(); |
| 12665 return false; | 12703 return false; |
| 12666 } | 12704 } |
| 12667 | 12705 |
| 12668 | 12706 |
| 12707 bool AbstractType::IsRecursive() const { | |
| 12708 // AbstractType is an abstract class. | |
| 12709 UNREACHABLE(); | |
| 12710 return false; | |
| 12711 } | |
| 12712 | |
| 12713 | |
| 12669 RawAbstractType* AbstractType::InstantiateFrom( | 12714 RawAbstractType* AbstractType::InstantiateFrom( |
| 12670 const TypeArguments& instantiator_type_arguments, | 12715 const TypeArguments& instantiator_type_arguments, |
| 12671 Error* bound_error, | 12716 Error* bound_error, |
| 12672 GrowableObjectArray* trail) const { | 12717 GrowableObjectArray* trail) 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::CloneUnfinalized() const { | 12724 RawAbstractType* AbstractType::CloneUnfinalized() 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 |
| 12686 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const { | 12731 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const { |
| 12687 // AbstractType is an abstract class. | 12732 // AbstractType is an abstract class. |
| 12688 UNREACHABLE(); | 12733 UNREACHABLE(); |
| 12689 return NULL; | 12734 return NULL; |
| 12690 } | 12735 } |
| 12691 | 12736 |
| 12692 | 12737 |
| 12738 RawObject* AbstractType::OnlyBuddyInTrail(GrowableObjectArray* trail) const { | |
| 12739 if (trail == NULL) { | |
| 12740 return Object::null(); | |
| 12741 } | |
| 12742 const intptr_t len = trail->Length(); | |
| 12743 ASSERT((len % 2) == 0); | |
| 12744 for (intptr_t i = 0; i < len; i += 2) { | |
| 12745 if (trail->At(i) == this->raw()) { | |
| 12746 ASSERT(trail->At(i + 1) != Object::null()); | |
| 12747 return trail->At(i + 1); | |
| 12748 } | |
| 12749 } | |
| 12750 return Object::null(); | |
| 12751 } | |
| 12752 | |
| 12753 | |
| 12754 void AbstractType::AddOnlyBuddyToTrail(GrowableObjectArray** trail, | |
| 12755 const Object& buddy) const { | |
| 12756 if (*trail == NULL) { | |
| 12757 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); | |
| 12758 } else { | |
| 12759 ASSERT(OnlyBuddyInTrail(*trail) == Object::null()); | |
| 12760 } | |
| 12761 (*trail)->Add(*this); | |
| 12762 (*trail)->Add(buddy); | |
| 12763 } | |
| 12764 | |
| 12765 | |
| 12693 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 12766 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
| 12694 if (IsBoundedType()) { | 12767 if (IsBoundedType()) { |
| 12695 const AbstractType& type = AbstractType::Handle( | 12768 const AbstractType& type = AbstractType::Handle( |
| 12696 BoundedType::Cast(*this).type()); | 12769 BoundedType::Cast(*this).type()); |
| 12697 if (name_visibility == kUserVisibleName) { | 12770 if (name_visibility == kUserVisibleName) { |
| 12698 return type.BuildName(kUserVisibleName); | 12771 return type.BuildName(kUserVisibleName); |
| 12699 } | 12772 } |
| 12700 String& type_name = String::Handle(type.BuildName(kInternalName)); | 12773 String& type_name = String::Handle(type.BuildName(kInternalName)); |
| 12701 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); | 12774 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); |
| 12702 // Build the bound name without causing divergence. | 12775 // Build the bound name without causing divergence. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 12722 } | 12795 } |
| 12723 // If the type is still being finalized, we may be reporting an error about | 12796 // If the type is still being finalized, we may be reporting an error about |
| 12724 // a malformed type, so proceed with caution. | 12797 // a malformed type, so proceed with caution. |
| 12725 const TypeArguments& args = TypeArguments::Handle(arguments()); | 12798 const TypeArguments& args = TypeArguments::Handle(arguments()); |
| 12726 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); | 12799 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); |
| 12727 String& class_name = String::Handle(); | 12800 String& class_name = String::Handle(); |
| 12728 intptr_t first_type_param_index; | 12801 intptr_t first_type_param_index; |
| 12729 intptr_t num_type_params; // Number of type parameters to print. | 12802 intptr_t num_type_params; // Number of type parameters to print. |
| 12730 if (HasResolvedTypeClass()) { | 12803 if (HasResolvedTypeClass()) { |
| 12731 const Class& cls = Class::Handle(type_class()); | 12804 const Class& cls = Class::Handle(type_class()); |
| 12732 num_type_params = cls.NumTypeParameters(); // Do not print the full vector. | 12805 if (IsResolved() || !cls.IsMixinApplication()) { |
| 12806 // Do not print the full vector, but only the declared type parameters. | |
| 12807 num_type_params = cls.NumTypeParameters(); | |
| 12808 } else { | |
| 12809 // Do not print the type parameters of an unresolved mixin application, | |
| 12810 // since it would prematurely trigger the application of the mixin type. | |
| 12811 num_type_params = 0; | |
| 12812 } | |
| 12733 if (name_visibility == kInternalName) { | 12813 if (name_visibility == kInternalName) { |
| 12734 class_name = cls.Name(); | 12814 class_name = cls.Name(); |
| 12735 } else { | 12815 } else { |
| 12736 ASSERT(name_visibility == kUserVisibleName); | 12816 ASSERT(name_visibility == kUserVisibleName); |
| 12737 // Map internal types to their corresponding public interfaces. | 12817 // Map internal types to their corresponding public interfaces. |
| 12738 class_name = cls.UserVisibleName(); | 12818 class_name = cls.UserVisibleName(); |
| 12739 } | 12819 } |
| 12740 if (num_type_params > num_args) { | 12820 if (num_type_params > num_args) { |
| 12741 first_type_param_index = 0; | 12821 first_type_param_index = 0; |
| 12742 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { | 12822 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13174 } | 13254 } |
| 13175 | 13255 |
| 13176 | 13256 |
| 13177 bool Type::IsInstantiated(GrowableObjectArray* trail) const { | 13257 bool Type::IsInstantiated(GrowableObjectArray* trail) const { |
| 13178 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 13258 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
| 13179 return true; | 13259 return true; |
| 13180 } | 13260 } |
| 13181 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | 13261 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
| 13182 return false; | 13262 return false; |
| 13183 } | 13263 } |
| 13264 if (arguments() == TypeArguments::null()) { | |
| 13265 return true; | |
| 13266 } | |
| 13184 const TypeArguments& args = TypeArguments::Handle(arguments()); | 13267 const TypeArguments& args = TypeArguments::Handle(arguments()); |
| 13185 return args.IsNull() || args.IsInstantiated(trail); | 13268 const intptr_t num_type_args = args.Length(); |
| 13269 intptr_t len = num_type_args; // Check the full vector of type args. | |
| 13270 ASSERT(num_type_args > 0); | |
| 13271 // This type is not instantiated if it refers to type parameters. | |
| 13272 // This IsInstantiated() call may be invoked on an unresolved signature type. | |
| 13273 // Although this type may still be unresolved, the type parameters it may | |
| 13274 // refer to are resolved by definition. We can therefore return the correct | |
| 13275 // result even for an unresolved type. We just need to look at all type | |
| 13276 // arguments and not just at the type parameters. | |
| 13277 if (HasResolvedTypeClass()) { | |
| 13278 const Class& cls = Class::Handle(type_class()); | |
| 13279 len = cls.NumTypeParameters(); // Check the type parameters only. | |
| 13280 ASSERT(num_type_args == cls.NumTypeArguments()); | |
| 13281 } | |
| 13282 return (len == 0) || args.IsSubvectorInstantiated(num_type_args - len, len); | |
| 13186 } | 13283 } |
| 13187 | 13284 |
| 13188 | 13285 |
| 13189 RawAbstractType* Type::InstantiateFrom( | 13286 RawAbstractType* Type::InstantiateFrom( |
| 13190 const TypeArguments& instantiator_type_arguments, | 13287 const TypeArguments& instantiator_type_arguments, |
| 13191 Error* bound_error, | 13288 Error* bound_error, |
| 13192 GrowableObjectArray* trail) const { | 13289 GrowableObjectArray* trail) const { |
| 13193 ASSERT(IsFinalized() || IsBeingFinalized()); | 13290 ASSERT(IsFinalized() || IsBeingFinalized()); |
| 13194 ASSERT(!IsInstantiated()); | 13291 ASSERT(!IsInstantiated()); |
| 13195 // Return the uninstantiated type unchanged if malformed. No copy needed. | 13292 // Return the uninstantiated type unchanged if malformed. No copy needed. |
| 13196 if (IsMalformed()) { | 13293 if (IsMalformed()) { |
| 13197 return raw(); | 13294 return raw(); |
| 13198 } | 13295 } |
| 13199 TypeArguments& type_arguments = TypeArguments::Handle(arguments()); | |
| 13200 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
| 13201 bound_error, | |
| 13202 trail); | |
| 13203 // Note that the type class has to be resolved at this time, but not | 13296 // Note that the type class has to be resolved at this time, but not |
| 13204 // necessarily finalized yet. We may be checking bounds at compile time. | 13297 // necessarily finalized yet. We may be checking bounds at compile time or |
| 13298 // finalizing the type argument vector of a recursive type. | |
| 13205 const Class& cls = Class::Handle(type_class()); | 13299 const Class& cls = Class::Handle(type_class()); |
| 13206 // This uninstantiated type is not modified, as it can be instantiated | 13300 // This uninstantiated type is not modified, as it can be instantiated |
| 13207 // with different instantiators. | 13301 // with different instantiators. |
| 13208 Type& instantiated_type = Type::Handle( | 13302 Type& instantiated_type = Type::Handle( |
| 13209 Type::New(cls, type_arguments, token_pos())); | 13303 Type::New(cls, TypeArguments::Handle(), token_pos())); |
| 13210 ASSERT(type_arguments.IsNull() || | 13304 if (arguments() != TypeArguments::null()) { |
| 13211 (type_arguments.Length() == cls.NumTypeArguments())); | 13305 TypeArguments& type_arguments = TypeArguments::Handle(arguments()); |
| 13306 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | |
| 13307 if (type_arguments.IsRecursive()) { | |
| 13308 AddOnlyBuddyToTrail(&trail, instantiated_type); | |
| 13309 } | |
| 13310 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
| 13311 bound_error, | |
| 13312 trail); | |
| 13313 instantiated_type.set_arguments(type_arguments); | |
| 13314 } | |
| 13212 instantiated_type.SetIsFinalized(); | 13315 instantiated_type.SetIsFinalized(); |
| 13213 // Canonicalization is not part of instantiation. | 13316 // Canonicalization is not part of instantiation. |
| 13214 return instantiated_type.raw(); | 13317 return instantiated_type.raw(); |
| 13215 } | 13318 } |
| 13216 | 13319 |
| 13217 | 13320 |
| 13218 bool Type::IsEquivalent(const Instance& other, | 13321 bool Type::IsEquivalent(const Instance& other, |
| 13219 GrowableObjectArray* trail) const { | 13322 GrowableObjectArray* trail) const { |
| 13220 ASSERT(!IsNull()); | 13323 ASSERT(!IsNull()); |
| 13221 if (raw() == other.raw()) { | 13324 if (raw() == other.raw()) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 13251 if (num_type_params == 0) { | 13354 if (num_type_params == 0) { |
| 13252 // Shortcut unnecessary handle allocation below. | 13355 // Shortcut unnecessary handle allocation below. |
| 13253 return true; | 13356 return true; |
| 13254 } | 13357 } |
| 13255 const intptr_t num_type_args = cls.NumTypeArguments(); | 13358 const intptr_t num_type_args = cls.NumTypeArguments(); |
| 13256 const intptr_t from_index = num_type_args - num_type_params; | 13359 const intptr_t from_index = num_type_args - num_type_params; |
| 13257 const TypeArguments& type_args = TypeArguments::Handle(isolate, arguments()); | 13360 const TypeArguments& type_args = TypeArguments::Handle(isolate, arguments()); |
| 13258 const TypeArguments& other_type_args = TypeArguments::Handle( | 13361 const TypeArguments& other_type_args = TypeArguments::Handle( |
| 13259 isolate, other_type.arguments()); | 13362 isolate, other_type.arguments()); |
| 13260 if (type_args.IsNull()) { | 13363 if (type_args.IsNull()) { |
| 13261 return other_type_args.IsRaw(from_index, num_type_params); | 13364 // Ignore from_index. |
| 13365 return other_type_args.IsRaw(0, num_type_params); | |
| 13262 } | 13366 } |
| 13263 if (other_type_args.IsNull()) { | 13367 if (other_type_args.IsNull()) { |
| 13264 return type_args.IsRaw(from_index, num_type_params); | 13368 // Ignore from_index. |
| 13369 return type_args.IsRaw(0, num_type_params); | |
| 13265 } | 13370 } |
| 13266 ASSERT(type_args.Length() >= (from_index + num_type_params)); | 13371 if (!type_args.IsSubvectorEquivalent(other_type_args, |
| 13267 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | 13372 from_index, |
| 13268 AbstractType& type_arg = AbstractType::Handle(isolate); | 13373 num_type_params)) { |
| 13269 AbstractType& other_type_arg = AbstractType::Handle(isolate); | 13374 return false; |
| 13270 for (intptr_t i = 0; i < num_type_params; i++) { | 13375 } |
| 13271 type_arg = type_args.TypeAt(from_index + i); | 13376 #ifdef DEBUG |
|
hausner
2014/03/26 21:37:21
ditto
regis
2014/03/26 23:24:58
Not done.
| |
| 13272 other_type_arg = other_type_args.TypeAt(from_index + i); | 13377 if (from_index > 0) { |
| 13273 if (!type_arg.IsEquivalent(other_type_arg, trail)) { | 13378 // Verify that the type arguments of the super class match, since they |
| 13274 return false; | 13379 // depend solely on the type parameters that were just verified to match. |
| 13380 ASSERT(type_args.Length() >= (from_index + num_type_params)); | |
| 13381 ASSERT(other_type_args.Length() >= (from_index + num_type_params)); | |
| 13382 AbstractType& type_arg = AbstractType::Handle(isolate); | |
| 13383 AbstractType& other_type_arg = AbstractType::Handle(isolate); | |
| 13384 for (intptr_t i = 0; i < from_index; i++) { | |
| 13385 type_arg = type_args.TypeAt(i); | |
| 13386 other_type_arg = other_type_args.TypeAt(i); | |
| 13387 ASSERT(type_arg.IsEquivalent(other_type_arg, trail)); | |
| 13275 } | 13388 } |
| 13276 } | 13389 } |
| 13390 #endif | |
| 13277 return true; | 13391 return true; |
| 13278 } | 13392 } |
| 13279 | 13393 |
| 13280 | 13394 |
| 13395 bool Type::IsRecursive() const { | |
| 13396 return TypeArguments::Handle(arguments()).IsRecursive(); | |
| 13397 } | |
| 13398 | |
| 13399 | |
| 13281 RawAbstractType* Type::CloneUnfinalized() const { | 13400 RawAbstractType* Type::CloneUnfinalized() const { |
| 13282 ASSERT(IsResolved()); | 13401 ASSERT(IsResolved()); |
| 13283 if (IsFinalized()) { | 13402 if (IsFinalized()) { |
| 13284 return raw(); | 13403 return raw(); |
| 13285 } | 13404 } |
| 13286 ASSERT(!IsMalformed()); // Malformed types are finalized. | 13405 ASSERT(!IsMalformed()); // Malformed types are finalized. |
| 13287 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. | 13406 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. |
| 13288 TypeArguments& type_args = TypeArguments::Handle(arguments()); | 13407 TypeArguments& type_args = TypeArguments::Handle(arguments()); |
| 13289 type_args = type_args.CloneUnfinalized(); | 13408 type_args = type_args.CloneUnfinalized(); |
| 13290 const Class& type_cls = Class::Handle(type_class()); | 13409 const Class& type_cls = Class::Handle(type_class()); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13408 #endif | 13527 #endif |
| 13409 ASSERT(IsOld()); | 13528 ASSERT(IsOld()); |
| 13410 ASSERT(type_args.IsNull() || type_args.IsOld()); | 13529 ASSERT(type_args.IsNull() || type_args.IsOld()); |
| 13411 SetCanonical(); | 13530 SetCanonical(); |
| 13412 return this->raw(); | 13531 return this->raw(); |
| 13413 } | 13532 } |
| 13414 | 13533 |
| 13415 | 13534 |
| 13416 intptr_t Type::Hash() const { | 13535 intptr_t Type::Hash() const { |
| 13417 ASSERT(IsFinalized()); | 13536 ASSERT(IsFinalized()); |
| 13418 uword result = 1; | 13537 intptr_t result = 1; |
| 13419 if (IsMalformed()) return result; | 13538 if (IsMalformed()) return result; |
| 13420 result += Class::Handle(type_class()).id(); | 13539 result = CombineHashes(result, Class::Handle(type_class()).id()); |
| 13421 result += TypeArguments::Handle(arguments()).Hash(); | 13540 result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash()); |
| 13422 return FinalizeHash(result); | 13541 return FinalizeHash(result); |
| 13423 } | 13542 } |
| 13424 | 13543 |
| 13425 | 13544 |
| 13426 void Type::set_type_class(const Object& value) const { | 13545 void Type::set_type_class(const Object& value) const { |
| 13427 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | 13546 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
| 13428 StorePointer(&raw_ptr()->type_class_, value.raw()); | 13547 StorePointer(&raw_ptr()->type_class_, value.raw()); |
| 13429 } | 13548 } |
| 13430 | 13549 |
| 13431 | 13550 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13478 Class::Handle(type_class()).Name()).ToCString(); | 13597 Class::Handle(type_class()).Name()).ToCString(); |
| 13479 } else { | 13598 } else { |
| 13480 class_name = UnresolvedClass::Handle(unresolved_class()).ToCString(); | 13599 class_name = UnresolvedClass::Handle(unresolved_class()).ToCString(); |
| 13481 } | 13600 } |
| 13482 if (type_arguments.IsNull()) { | 13601 if (type_arguments.IsNull()) { |
| 13483 const char* format = "Type: class '%s'"; | 13602 const char* format = "Type: class '%s'"; |
| 13484 const intptr_t len = OS::SNPrint(NULL, 0, format, class_name) + 1; | 13603 const intptr_t len = OS::SNPrint(NULL, 0, format, class_name) + 1; |
| 13485 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 13604 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 13486 OS::SNPrint(chars, len, format, class_name); | 13605 OS::SNPrint(chars, len, format, class_name); |
| 13487 return chars; | 13606 return chars; |
| 13607 } else if (IsFinalized() && IsRecursive()) { | |
| 13608 const char* format = "Type: (@%" Px " H%" Px ") class '%s', args:[%s]"; | |
| 13609 const intptr_t hash = Hash(); | |
| 13610 const char* args_cstr = TypeArguments::Handle(arguments()).ToCString(); | |
| 13611 const intptr_t len = | |
| 13612 OS::SNPrint(NULL, 0, format, raw(), hash, class_name, args_cstr) + 1; | |
| 13613 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 13614 OS::SNPrint(chars, len, format, raw(), hash, class_name, args_cstr); | |
| 13615 return chars; | |
| 13488 } else { | 13616 } else { |
| 13489 const char* format = "Type: class '%s', args:[%s]"; | 13617 const char* format = "Type: class '%s', args:[%s]"; |
| 13490 const char* args_cstr = TypeArguments::Handle(arguments()).ToCString(); | 13618 const char* args_cstr = TypeArguments::Handle(arguments()).ToCString(); |
| 13491 intptr_t len = OS::SNPrint(NULL, 0, format, class_name, args_cstr) + 1; | 13619 const intptr_t len = |
| 13620 OS::SNPrint(NULL, 0, format, class_name, args_cstr) + 1; | |
| 13492 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 13621 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 13493 OS::SNPrint(chars, len, format, class_name, args_cstr); | 13622 OS::SNPrint(chars, len, format, class_name, args_cstr); |
| 13494 return chars; | 13623 return chars; |
| 13495 } | 13624 } |
| 13496 } else { | 13625 } else { |
| 13497 return "Unresolved Type"; | 13626 return "Unresolved Type"; |
| 13498 } | 13627 } |
| 13499 } | 13628 } |
| 13500 | 13629 |
| 13501 | 13630 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13542 return true; | 13671 return true; |
| 13543 } | 13672 } |
| 13544 return AbstractType::Handle(type()).IsEquivalent(other, trail); | 13673 return AbstractType::Handle(type()).IsEquivalent(other, trail); |
| 13545 } | 13674 } |
| 13546 | 13675 |
| 13547 | 13676 |
| 13548 RawAbstractType* TypeRef::InstantiateFrom( | 13677 RawAbstractType* TypeRef::InstantiateFrom( |
| 13549 const TypeArguments& instantiator_type_arguments, | 13678 const TypeArguments& instantiator_type_arguments, |
| 13550 Error* bound_error, | 13679 Error* bound_error, |
| 13551 GrowableObjectArray* trail) const { | 13680 GrowableObjectArray* trail) const { |
| 13552 TypeRef& instantiated_type_ref = TypeRef::Handle(); | 13681 AbstractType& ref_type = AbstractType::Handle(type()); |
| 13553 instantiated_type_ref ^= OnlyBuddyInTrail(trail); | 13682 ASSERT(!ref_type.IsTypeRef()); |
| 13554 if (!instantiated_type_ref.IsNull()) { | 13683 AbstractType& instantiated_ref_type = AbstractType::Handle(); |
| 13555 return instantiated_type_ref.raw(); | 13684 instantiated_ref_type ^= ref_type.OnlyBuddyInTrail(trail); |
| 13685 if (instantiated_ref_type.IsNull()) { | |
| 13686 // The referenced type is first encountered here during instantiation. | |
| 13687 instantiated_ref_type = ref_type.InstantiateFrom( | |
| 13688 instantiator_type_arguments, bound_error, trail); | |
| 13556 } | 13689 } |
| 13557 instantiated_type_ref = TypeRef::New(Type::Handle(Type::DynamicType())); | 13690 ASSERT(!instantiated_ref_type.IsTypeRef()); |
| 13558 AddOnlyBuddyToTrail(&trail, instantiated_type_ref); | 13691 return TypeRef::New(instantiated_ref_type); |
| 13559 const AbstractType& ref_type = AbstractType::Handle(type()); | |
| 13560 ASSERT(!ref_type.IsTypeRef()); | |
| 13561 const AbstractType& instantiated_ref_type = AbstractType::Handle( | |
| 13562 ref_type.InstantiateFrom(instantiator_type_arguments, | |
| 13563 bound_error, | |
| 13564 trail)); | |
| 13565 instantiated_type_ref.set_type(instantiated_ref_type); | |
| 13566 return instantiated_type_ref.raw(); | |
| 13567 } | 13692 } |
| 13568 | 13693 |
| 13569 | 13694 |
| 13570 void TypeRef::set_type(const AbstractType& value) const { | 13695 void TypeRef::set_type(const AbstractType& value) const { |
| 13571 ASSERT(value.HasResolvedTypeClass()); | 13696 ASSERT(value.HasResolvedTypeClass()); |
| 13572 StorePointer(&raw_ptr()->type_, value.raw()); | 13697 StorePointer(&raw_ptr()->type_, value.raw()); |
| 13573 } | 13698 } |
| 13574 | 13699 |
| 13575 | 13700 |
| 13576 // A TypeRef cannot be canonical by definition. Only its referenced type can be. | 13701 // A TypeRef cannot be canonical by definition. Only its referenced type can be. |
| 13577 // Consider the type Derived, where class Derived extends Base<Derived>. | 13702 // Consider the type Derived, where class Derived extends Base<Derived>. |
| 13578 // The first type argument of its flattened type argument vector is Derived, | 13703 // The first type argument of its flattened type argument vector is Derived, |
| 13579 // i.e. itself, but pointer equality is not possible. | 13704 // represented by a TypeRef pointing to itself. |
| 13580 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { | 13705 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { |
| 13581 if (TestAndAddToTrail(&trail)) { | 13706 if (TestAndAddToTrail(&trail)) { |
| 13582 return raw(); | 13707 return raw(); |
| 13583 } | 13708 } |
| 13584 AbstractType& ref_type = AbstractType::Handle(type()); | 13709 AbstractType& ref_type = AbstractType::Handle(type()); |
| 13585 ref_type = ref_type.Canonicalize(trail); | 13710 ref_type = ref_type.Canonicalize(trail); |
| 13586 set_type(ref_type); | 13711 set_type(ref_type); |
| 13587 return raw(); | 13712 return raw(); |
| 13588 } | 13713 } |
| 13589 | 13714 |
| 13590 | 13715 |
| 13591 intptr_t TypeRef::Hash() const { | 13716 intptr_t TypeRef::Hash() const { |
| 13592 // Do not calculate the hash of the referenced type to avoid divergence. | 13717 // Do not calculate the hash of the referenced type to avoid divergence. |
| 13593 uword result = Class::Handle(AbstractType::Handle(type()).type_class()).id(); | 13718 const intptr_t result = |
| 13719 Class::Handle(AbstractType::Handle(type()).type_class()).id(); | |
| 13594 return FinalizeHash(result); | 13720 return FinalizeHash(result); |
| 13595 } | 13721 } |
| 13596 | 13722 |
| 13597 | 13723 |
| 13598 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const { | 13724 bool TypeRef::TestAndAddToTrail(GrowableObjectArray** trail) const { |
| 13599 if (*trail == NULL) { | 13725 if (*trail == NULL) { |
| 13600 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); | 13726 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); |
| 13601 } else { | 13727 } else { |
| 13602 const intptr_t len = (*trail)->Length(); | 13728 const intptr_t len = (*trail)->Length(); |
| 13603 for (intptr_t i = 0; i < len; i++) { | 13729 for (intptr_t i = 0; i < len; i++) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 13624 return true; | 13750 return true; |
| 13625 } | 13751 } |
| 13626 } | 13752 } |
| 13627 } | 13753 } |
| 13628 (*trail)->Add(*this); | 13754 (*trail)->Add(*this); |
| 13629 (*trail)->Add(buddy); | 13755 (*trail)->Add(buddy); |
| 13630 return false; | 13756 return false; |
| 13631 } | 13757 } |
| 13632 | 13758 |
| 13633 | 13759 |
| 13634 RawObject* TypeRef::OnlyBuddyInTrail(GrowableObjectArray* trail) const { | |
| 13635 if (trail == NULL) { | |
| 13636 return Object::null(); | |
| 13637 } | |
| 13638 const intptr_t len = trail->Length(); | |
| 13639 ASSERT((len % 2) == 0); | |
| 13640 for (intptr_t i = 0; i < len; i += 2) { | |
| 13641 if (trail->At(i) == this->raw()) { | |
| 13642 ASSERT(trail->At(i + 1) != Object::null()); | |
| 13643 return trail->At(i + 1); | |
| 13644 } | |
| 13645 } | |
| 13646 return Object::null(); | |
| 13647 } | |
| 13648 | |
| 13649 | |
| 13650 void TypeRef::AddOnlyBuddyToTrail(GrowableObjectArray** trail, | |
| 13651 const Object& buddy) const { | |
| 13652 if (*trail == NULL) { | |
| 13653 *trail = &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New()); | |
| 13654 } else { | |
| 13655 ASSERT(OnlyBuddyInTrail(*trail) == Object::null()); | |
| 13656 } | |
| 13657 (*trail)->Add(*this); | |
| 13658 (*trail)->Add(buddy); | |
| 13659 } | |
| 13660 | |
| 13661 | |
| 13662 RawTypeRef* TypeRef::New() { | 13760 RawTypeRef* TypeRef::New() { |
| 13663 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); | 13761 ASSERT(Isolate::Current()->object_store()->type_ref_class() != Class::null()); |
| 13664 RawObject* raw = Object::Allocate(TypeRef::kClassId, | 13762 RawObject* raw = Object::Allocate(TypeRef::kClassId, |
| 13665 TypeRef::InstanceSize(), | 13763 TypeRef::InstanceSize(), |
| 13666 Heap::kOld); | 13764 Heap::kOld); |
| 13667 return reinterpret_cast<RawTypeRef*>(raw); | 13765 return reinterpret_cast<RawTypeRef*>(raw); |
| 13668 } | 13766 } |
| 13669 | 13767 |
| 13670 | 13768 |
| 13671 RawTypeRef* TypeRef::New(const AbstractType& type) { | 13769 RawTypeRef* TypeRef::New(const AbstractType& type) { |
| 13672 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 13770 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
| 13673 result.set_type(type); | 13771 result.set_type(type); |
| 13674 return result.raw(); | 13772 return result.raw(); |
| 13675 } | 13773 } |
| 13676 | 13774 |
| 13677 | 13775 |
| 13678 const char* TypeRef::ToCString() const { | 13776 const char* TypeRef::ToCString() const { |
| 13679 const char* format = "TypeRef: %s%s"; | 13777 const char* type_cstr = String::Handle(Class::Handle( |
| 13680 const char* type_cstr = String::Handle(Class::Handle(AbstractType::Handle( | 13778 type_class()).Name()).ToCString(); |
| 13681 type()).type_class()).Name()).ToCString(); | 13779 AbstractType& ref_type = AbstractType::Handle(type()); |
| 13682 const char* args_cstr = (AbstractType::Handle( | 13780 if (ref_type.IsFinalized()) { |
| 13683 type()).arguments() == TypeArguments::null()) ? "" : "<...>"; | 13781 const char* format = "TypeRef: %s<...> (@%" Px " H%" Px ")"; |
| 13684 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, args_cstr) + 1; | 13782 const intptr_t hash = ref_type.Hash(); |
| 13685 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 13783 const intptr_t len = |
| 13686 OS::SNPrint(chars, len, format, type_cstr, args_cstr); | 13784 OS::SNPrint(NULL, 0, format, type_cstr, ref_type.raw(), hash) + 1; |
| 13687 return chars; | 13785 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 13786 OS::SNPrint(chars, len, format, type_cstr, ref_type.raw(), hash); | |
| 13787 return chars; | |
| 13788 } else { | |
| 13789 const char* format = "TypeRef: %s<...>"; | |
| 13790 const intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr) + 1; | |
| 13791 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 13792 OS::SNPrint(chars, len, format, type_cstr); | |
| 13793 return chars; | |
| 13794 } | |
| 13688 } | 13795 } |
| 13689 | 13796 |
| 13690 | 13797 |
| 13691 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { | 13798 void TypeRef::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 13692 JSONObject jsobj(stream); | 13799 JSONObject jsobj(stream); |
| 13693 PrintSharedInstanceJSON(&jsobj, ref); | 13800 PrintSharedInstanceJSON(&jsobj, ref); |
| 13694 ObjectIdRing* ring = Isolate::Current()->object_id_ring(); | 13801 ObjectIdRing* ring = Isolate::Current()->object_id_ring(); |
| 13695 const intptr_t id = ring->GetIdForObject(raw()); | 13802 const intptr_t id = ring->GetIdForObject(raw()); |
| 13696 jsobj.AddPropertyF("id", "objects/%" Pd "", id); | 13803 jsobj.AddPropertyF("id", "objects/%" Pd "", id); |
| 13697 const char* name = String::Handle(Name()).ToCString(); | 13804 const char* name = String::Handle(Name()).ToCString(); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13832 return TypeParameter::New(Class::Handle(parameterized_class()), | 13939 return TypeParameter::New(Class::Handle(parameterized_class()), |
| 13833 index(), | 13940 index(), |
| 13834 String::Handle(name()), | 13941 String::Handle(name()), |
| 13835 AbstractType::Handle(bound()), | 13942 AbstractType::Handle(bound()), |
| 13836 token_pos()); | 13943 token_pos()); |
| 13837 } | 13944 } |
| 13838 | 13945 |
| 13839 | 13946 |
| 13840 intptr_t TypeParameter::Hash() const { | 13947 intptr_t TypeParameter::Hash() const { |
| 13841 ASSERT(IsFinalized()); | 13948 ASSERT(IsFinalized()); |
| 13842 uword result = Class::Handle(parameterized_class()).id(); | 13949 intptr_t result = Class::Handle(parameterized_class()).id(); |
| 13843 // No need to include the hash of the bound, since the type parameter is fully | 13950 // No need to include the hash of the bound, since the type parameter is fully |
| 13844 // identified by its class and index. | 13951 // identified by its class and index. |
| 13845 result <<= index(); | 13952 result = CombineHashes(result, index()); |
| 13846 return FinalizeHash(result); | 13953 return FinalizeHash(result); |
| 13847 } | 13954 } |
| 13848 | 13955 |
| 13849 | 13956 |
| 13850 RawTypeParameter* TypeParameter::New() { | 13957 RawTypeParameter* TypeParameter::New() { |
| 13851 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != | 13958 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
| 13852 Class::null()); | 13959 Class::null()); |
| 13853 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 13960 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
| 13854 TypeParameter::InstanceSize(), | 13961 TypeParameter::InstanceSize(), |
| 13855 Heap::kOld); | 13962 Heap::kOld); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13972 return false; | 14079 return false; |
| 13973 } | 14080 } |
| 13974 const AbstractType& this_bound = AbstractType::Handle(bound()); | 14081 const AbstractType& this_bound = AbstractType::Handle(bound()); |
| 13975 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 14082 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
| 13976 return this_bound.IsFinalized() && | 14083 return this_bound.IsFinalized() && |
| 13977 other_bound.IsFinalized() && | 14084 other_bound.IsFinalized() && |
| 13978 this_bound.Equals(other_bound); // Different graph, do not pass trail. | 14085 this_bound.Equals(other_bound); // Different graph, do not pass trail. |
| 13979 } | 14086 } |
| 13980 | 14087 |
| 13981 | 14088 |
| 14089 bool BoundedType::IsRecursive() const { | |
| 14090 return AbstractType::Handle(type()).IsRecursive(); | |
| 14091 } | |
| 14092 | |
| 14093 | |
| 13982 void BoundedType::set_type(const AbstractType& value) const { | 14094 void BoundedType::set_type(const AbstractType& value) const { |
| 13983 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); | 14095 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |
| 13984 ASSERT(!value.IsMalformed()); | 14096 ASSERT(!value.IsMalformed()); |
| 13985 StorePointer(&raw_ptr()->type_, value.raw()); | 14097 StorePointer(&raw_ptr()->type_, value.raw()); |
| 13986 } | 14098 } |
| 13987 | 14099 |
| 13988 | 14100 |
| 13989 void BoundedType::set_bound(const AbstractType& value) const { | 14101 void BoundedType::set_bound(const AbstractType& value) const { |
| 13990 // The bound may still be unfinalized because of legal cycles. | 14102 // The bound may still be unfinalized because of legal cycles. |
| 13991 // It must be finalized before it is checked at run time, though. | 14103 // 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... | |
| 14046 bounded_type = bounded_type.CloneUnfinalized(); | 14158 bounded_type = bounded_type.CloneUnfinalized(); |
| 14047 // No need to clone bound or type parameter, as they are not part of the | 14159 // No need to clone bound or type parameter, as they are not part of the |
| 14048 // finalization state of this bounded type. | 14160 // finalization state of this bounded type. |
| 14049 return BoundedType::New(bounded_type, | 14161 return BoundedType::New(bounded_type, |
| 14050 AbstractType::Handle(bound()), | 14162 AbstractType::Handle(bound()), |
| 14051 TypeParameter::Handle(type_parameter())); | 14163 TypeParameter::Handle(type_parameter())); |
| 14052 } | 14164 } |
| 14053 | 14165 |
| 14054 | 14166 |
| 14055 intptr_t BoundedType::Hash() const { | 14167 intptr_t BoundedType::Hash() const { |
| 14056 uword result = AbstractType::Handle(type()).Hash(); | 14168 intptr_t result = AbstractType::Handle(type()).Hash(); |
| 14057 // No need to include the hash of the bound, since the bound is defined by the | 14169 // No need to include the hash of the bound, since the bound is defined by the |
| 14058 // type parameter (modulo instantiation state). | 14170 // type parameter (modulo instantiation state). |
| 14059 result += TypeParameter::Handle(type_parameter()).Hash(); | 14171 result = CombineHashes(result, |
| 14060 return FinalizeHash(result); | 14172 TypeParameter::Handle(type_parameter()).Hash()); |
| 14173 return FinalizeHash(result); | |
| 14061 } | 14174 } |
| 14062 | 14175 |
| 14063 | 14176 |
| 14064 RawBoundedType* BoundedType::New() { | 14177 RawBoundedType* BoundedType::New() { |
| 14065 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != | 14178 ASSERT(Isolate::Current()->object_store()->bounded_type_class() != |
| 14066 Class::null()); | 14179 Class::null()); |
| 14067 RawObject* raw = Object::Allocate(BoundedType::kClassId, | 14180 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
| 14068 BoundedType::InstanceSize(), | 14181 BoundedType::InstanceSize(), |
| 14069 Heap::kOld); | 14182 Heap::kOld); |
| 14070 return reinterpret_cast<RawBoundedType*>(raw); | 14183 return reinterpret_cast<RawBoundedType*>(raw); |
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15051 void Bigint::PrintToJSONStream(JSONStream* stream, bool ref) const { | 15164 void Bigint::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 15052 Number::PrintToJSONStream(stream, ref); | 15165 Number::PrintToJSONStream(stream, ref); |
| 15053 } | 15166 } |
| 15054 | 15167 |
| 15055 | 15168 |
| 15056 // Synchronize with implementation in compiler (intrinsifier). | 15169 // Synchronize with implementation in compiler (intrinsifier). |
| 15057 class StringHasher : ValueObject { | 15170 class StringHasher : ValueObject { |
| 15058 public: | 15171 public: |
| 15059 StringHasher() : hash_(0) {} | 15172 StringHasher() : hash_(0) {} |
| 15060 void Add(int32_t ch) { | 15173 void Add(int32_t ch) { |
| 15061 hash_ += ch; | 15174 hash_ = CombineHashes(hash_, ch); |
| 15062 hash_ += hash_ << 10; | |
| 15063 hash_ ^= hash_ >> 6; | |
| 15064 } | 15175 } |
| 15065 // Return a non-zero hash of at most 'bits' bits. | 15176 // Return a non-zero hash of at most 'bits' bits. |
| 15066 intptr_t Finalize(int bits) { | 15177 intptr_t Finalize(int bits) { |
| 15067 ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); | 15178 ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); |
| 15068 hash_ += hash_ << 3; | 15179 hash_ = FinalizeHash(hash_); |
| 15069 hash_ ^= hash_ >> 11; | |
| 15070 hash_ += hash_ << 15; | |
| 15071 hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); | 15180 hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); |
| 15072 ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); | 15181 ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); |
| 15073 return hash_ == 0 ? 1 : hash_; | 15182 return hash_ == 0 ? 1 : hash_; |
| 15074 } | 15183 } |
| 15075 private: | 15184 private: |
| 15076 uint32_t hash_; | 15185 uint32_t hash_; |
| 15077 }; | 15186 }; |
| 15078 | 15187 |
| 15079 | 15188 |
| 15080 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { | 15189 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { |
| (...skipping 2922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18003 return "_MirrorReference"; | 18112 return "_MirrorReference"; |
| 18004 } | 18113 } |
| 18005 | 18114 |
| 18006 | 18115 |
| 18007 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 18116 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 18008 Instance::PrintToJSONStream(stream, ref); | 18117 Instance::PrintToJSONStream(stream, ref); |
| 18009 } | 18118 } |
| 18010 | 18119 |
| 18011 | 18120 |
| 18012 } // namespace dart | 18121 } // namespace dart |
| OLD | NEW |