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

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

Issue 211963003: Detect and reject illegal recursive types (non-contractive types). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 3994 matching lines...) Expand 10 before | Expand all | Expand 10 after
4005 OS::SNPrint(chars, len, format, cname); 4005 OS::SNPrint(chars, len, format, cname);
4006 return chars; 4006 return chars;
4007 } 4007 }
4008 4008
4009 4009
4010 void UnresolvedClass::PrintToJSONStream(JSONStream* stream, bool ref) const { 4010 void UnresolvedClass::PrintToJSONStream(JSONStream* stream, bool ref) const {
4011 Object::PrintToJSONStream(stream, ref); 4011 Object::PrintToJSONStream(stream, ref);
4012 } 4012 }
4013 4013
4014 4014
4015 static intptr_t FinalizeHash(uword hash) { 4015 static uint32_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 uint32_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 uint32_t result = 0;
4028 AbstractType& type = AbstractType::Handle(); 4036 AbstractType& type = AbstractType::Handle();
4029 for (intptr_t i = 0; i < num_types; i++) { 4037 for (intptr_t i = 0; i < num_types; i++) {
4030 type = TypeAt(i); 4038 type = TypeAt(i);
4031 result += type.Hash(); 4039 result = CombineHashes(result, type.Hash());
4032 result += result << 10;
4033 result ^= result >> 6;
4034 } 4040 }
4035 return FinalizeHash(result); 4041 return FinalizeHash(result);
4036 } 4042 }
4037 4043
4038 4044
4039 RawString* TypeArguments::SubvectorName(intptr_t from_index, 4045 RawString* TypeArguments::SubvectorName(intptr_t from_index,
4040 intptr_t len, 4046 intptr_t len,
4041 NameVisibility name_visibility) const { 4047 NameVisibility name_visibility) const {
4042 ASSERT(from_index + len <= Length()); 4048 ASSERT(from_index + len <= Length());
4043 String& name = String::Handle(); 4049 String& name = String::Handle();
(...skipping 10 matching lines...) Expand all
4054 strings.SetAt(s++, Symbols::CommaSpace()); 4060 strings.SetAt(s++, Symbols::CommaSpace());
4055 } 4061 }
4056 } 4062 }
4057 strings.SetAt(s++, Symbols::RAngleBracket()); 4063 strings.SetAt(s++, Symbols::RAngleBracket());
4058 ASSERT(s == num_strings); 4064 ASSERT(s == num_strings);
4059 name = String::ConcatAll(strings); 4065 name = String::ConcatAll(strings);
4060 return Symbols::New(name); 4066 return Symbols::New(name);
4061 } 4067 }
4062 4068
4063 4069
4064 bool TypeArguments::IsEquivalent(const TypeArguments& other, 4070 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other,
4065 GrowableObjectArray* trail) const { 4071 intptr_t from_index,
4072 intptr_t len,
4073 GrowableObjectArray* trail) const {
4066 if (this->raw() == other.raw()) { 4074 if (this->raw() == other.raw()) {
4067 return true; 4075 return true;
4068 } 4076 }
4069 if (IsNull() || other.IsNull()) { 4077 if (IsNull() || other.IsNull()) {
4070 return false; 4078 return false;
4071 } 4079 }
4072 const intptr_t num_types = Length(); 4080 const intptr_t num_types = Length();
4073 if (num_types != other.Length()) { 4081 if (num_types != other.Length()) {
4074 return false; 4082 return false;
4075 } 4083 }
4076 AbstractType& type = AbstractType::Handle(); 4084 AbstractType& type = AbstractType::Handle();
4077 AbstractType& other_type = AbstractType::Handle(); 4085 AbstractType& other_type = AbstractType::Handle();
4078 for (intptr_t i = 0; i < num_types; i++) { 4086 for (intptr_t i = from_index; i < from_index + len; i++) {
4079 type = TypeAt(i); 4087 type = TypeAt(i);
4080 other_type = other.TypeAt(i); 4088 other_type = other.TypeAt(i);
4081 if (!type.IsEquivalent(other_type, trail)) { 4089 if (!type.IsEquivalent(other_type, trail)) {
4082 return false; 4090 return false;
4083 } 4091 }
4084 } 4092 }
4085 return true; 4093 return true;
4086 } 4094 }
4087 4095
4088 4096
4097 bool TypeArguments::IsRecursive() const {
4098 if (IsNull()) return false;
4099 const intptr_t num_types = Length();
4100 AbstractType& type = AbstractType::Handle();
4101 for (intptr_t i = 0; i < num_types; i++) {
4102 type = TypeAt(i);
4103 if (type.IsRecursive()) {
4104 return true;
4105 }
4106 }
4107 return false;
4108 }
4109
4110
4089 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, 4111 bool TypeArguments::IsDynamicTypes(bool raw_instantiated,
4090 intptr_t from_index, 4112 intptr_t from_index,
4091 intptr_t len) const { 4113 intptr_t len) const {
4092 ASSERT(Length() >= (from_index + len)); 4114 ASSERT(Length() >= (from_index + len));
4093 AbstractType& type = AbstractType::Handle(); 4115 AbstractType& type = AbstractType::Handle();
4094 Class& type_class = Class::Handle(); 4116 Class& type_class = Class::Handle();
4095 for (intptr_t i = 0; i < len; i++) { 4117 for (intptr_t i = 0; i < len; i++) {
4096 type = TypeAt(from_index + i); 4118 type = TypeAt(from_index + i);
4097 ASSERT(!type.IsNull());
4098 if (!type.HasResolvedTypeClass()) { 4119 if (!type.HasResolvedTypeClass()) {
4099 if (raw_instantiated && type.IsTypeParameter()) { 4120 if (raw_instantiated && type.IsTypeParameter()) {
4100 // An uninstantiated type parameter is equivalent to dynamic (even in 4121 // An uninstantiated type parameter is equivalent to dynamic (even in
4101 // the presence of a malformed bound in checked mode). 4122 // the presence of a malformed bound in checked mode).
4102 continue; 4123 continue;
4103 } 4124 }
4104 return false; 4125 return false;
4105 } 4126 }
4106 type_class = type.type_class(); 4127 type_class = type.type_class();
4107 if (!type_class.IsDynamicClass()) { 4128 if (!type_class.IsDynamicClass()) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
4255 for (intptr_t i = 0; i < num_types; i++) { 4276 for (intptr_t i = 0; i < num_types; i++) {
4256 type = TypeAt(i); 4277 type = TypeAt(i);
4257 if (!type.IsResolved()) { 4278 if (!type.IsResolved()) {
4258 return false; 4279 return false;
4259 } 4280 }
4260 } 4281 }
4261 return true; 4282 return true;
4262 } 4283 }
4263 4284
4264 4285
4265 bool TypeArguments::IsInstantiated(GrowableObjectArray* trail) const { 4286 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index,
4287 intptr_t len,
4288 GrowableObjectArray* trail) const {
4289 ASSERT(!IsNull());
4266 AbstractType& type = AbstractType::Handle(); 4290 AbstractType& type = AbstractType::Handle();
4267 const intptr_t num_types = Length(); 4291 for (intptr_t i = 0; i < len; i++) {
4268 for (intptr_t i = 0; i < num_types; i++) { 4292 type = TypeAt(from_index + i);
4269 type = TypeAt(i); 4293 if (!type.IsInstantiated(trail)) {
4270 if (!type.IsBeingFinalized() && !type.IsInstantiated(trail)) {
4271 return false; 4294 return false;
4272 } 4295 }
4273 } 4296 }
4274 return true; 4297 return true;
4275 } 4298 }
4276 4299
4277 4300
4278 bool TypeArguments::IsUninstantiatedIdentity() const { 4301 bool TypeArguments::IsUninstantiatedIdentity() const {
4279 ASSERT(!IsInstantiated()); 4302 ASSERT(!IsInstantiated());
4280 AbstractType& type = AbstractType::Handle(); 4303 AbstractType& type = AbstractType::Handle();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
4424 IsUninstantiatedIdentity() && 4447 IsUninstantiatedIdentity() &&
4425 (instantiator_type_arguments.Length() == Length())) { 4448 (instantiator_type_arguments.Length() == Length())) {
4426 return instantiator_type_arguments.raw(); 4449 return instantiator_type_arguments.raw();
4427 } 4450 }
4428 const intptr_t num_types = Length(); 4451 const intptr_t num_types = Length();
4429 TypeArguments& instantiated_array = 4452 TypeArguments& instantiated_array =
4430 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); 4453 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew));
4431 AbstractType& type = AbstractType::Handle(); 4454 AbstractType& type = AbstractType::Handle();
4432 for (intptr_t i = 0; i < num_types; i++) { 4455 for (intptr_t i = 0; i < num_types; i++) {
4433 type = TypeAt(i); 4456 type = TypeAt(i);
4434 if (!type.IsBeingFinalized() && !type.IsInstantiated()) { 4457 if (!type.IsInstantiated()) {
4435 type = type.InstantiateFrom(instantiator_type_arguments, 4458 type = type.InstantiateFrom(instantiator_type_arguments,
4436 bound_error, 4459 bound_error,
4437 trail); 4460 trail);
4438 } 4461 }
4439 instantiated_array.SetTypeAt(i, type); 4462 instantiated_array.SetTypeAt(i, type);
4440 } 4463 }
4441 return instantiated_array.raw(); 4464 return instantiated_array.raw();
4442 } 4465 }
4443 4466
4444 4467
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4540 const intptr_t table_size = table.Length() - 1; 4563 const intptr_t table_size = table.Length() - 1;
4541 const intptr_t new_table_size = table_size * 2; 4564 const intptr_t new_table_size = table_size * 2;
4542 Array& new_table = Array::Handle(isolate, Array::New(new_table_size + 1)); 4565 Array& new_table = Array::Handle(isolate, Array::New(new_table_size + 1));
4543 // Copy all elements from the original table to the newly allocated 4566 // Copy all elements from the original table to the newly allocated
4544 // array. 4567 // array.
4545 TypeArguments& element = TypeArguments::Handle(isolate); 4568 TypeArguments& element = TypeArguments::Handle(isolate);
4546 Object& new_element = Object::Handle(isolate); 4569 Object& new_element = Object::Handle(isolate);
4547 for (intptr_t i = 0; i < table_size; i++) { 4570 for (intptr_t i = 0; i < table_size; i++) {
4548 element ^= table.At(i); 4571 element ^= table.At(i);
4549 if (!element.IsNull()) { 4572 if (!element.IsNull()) {
4550 intptr_t hash = element.Hash(); 4573 const intptr_t hash = element.Hash();
4551 ASSERT(Utils::IsPowerOfTwo(new_table_size)); 4574 ASSERT(Utils::IsPowerOfTwo(new_table_size));
4552 intptr_t index = hash & (new_table_size - 1); 4575 intptr_t index = hash & (new_table_size - 1);
4553 new_element = new_table.At(index); 4576 new_element = new_table.At(index);
4554 while (!new_element.IsNull()) { 4577 while (!new_element.IsNull()) {
4555 index = (index + 1) & (new_table_size - 1); // Move to next element. 4578 index = (index + 1) & (new_table_size - 1); // Move to next element.
4556 new_element = new_table.At(index); 4579 new_element = new_table.At(index);
4557 } 4580 }
4558 new_table.SetAt(index, element); 4581 new_table.SetAt(index, element);
4559 } 4582 }
4560 } 4583 }
(...skipping 12 matching lines...) Expand all
4573 arguments.SetCanonical(); // Mark object as being canonical. 4596 arguments.SetCanonical(); // Mark object as being canonical.
4574 table.SetAt(index, arguments); // Remember the new element. 4597 table.SetAt(index, arguments); // Remember the new element.
4575 // Update used count. 4598 // Update used count.
4576 // Last element of the array is the number of used elements. 4599 // Last element of the array is the number of used elements.
4577 const intptr_t table_size = table.Length() - 1; 4600 const intptr_t table_size = table.Length() - 1;
4578 const intptr_t used_elements = 4601 const intptr_t used_elements =
4579 Smi::Value(Smi::RawCast(table.At(table_size))) + 1; 4602 Smi::Value(Smi::RawCast(table.At(table_size))) + 1;
4580 const Smi& used = Smi::Handle(isolate, Smi::New(used_elements)); 4603 const Smi& used = Smi::Handle(isolate, Smi::New(used_elements));
4581 table.SetAt(table_size, used); 4604 table.SetAt(table_size, used);
4582 4605
4606 #ifdef DEBUG
4607 // Verify that there are no duplicates.
4608 // Duplicates could appear if hash values are not kept constant across
4609 // snapshots, e.g. if class ids are not preserved by the snapshots.
4610 TypeArguments& other_arguments = TypeArguments::Handle();
4611 for (intptr_t i = 0; i < table_size; i++) {
4612 if ((i != index) && (table.At(i) != TypeArguments::null())) {
4613 other_arguments ^= table.At(i);
4614 if (arguments.Equals(other_arguments)) {
4615 // Recursive types may be equal, but have different hashes.
4616 ASSERT(arguments.IsRecursive());
4617 ASSERT(other_arguments.IsRecursive());
4618 ASSERT(arguments.Hash() != other_arguments.Hash());
4619 }
4620 }
4621 }
4622 #endif
4623
4583 // Rehash if table is 75% full. 4624 // Rehash if table is 75% full.
4584 if (used_elements > ((table_size / 4) * 3)) { 4625 if (used_elements > ((table_size / 4) * 3)) {
4585 GrowCanonicalTypeArguments(isolate, table); 4626 GrowCanonicalTypeArguments(isolate, table);
4586 } 4627 }
4587 } 4628 }
4588 4629
4589 4630
4590 static intptr_t FindIndexInCanonicalTypeArguments( 4631 static intptr_t FindIndexInCanonicalTypeArguments(
4591 Isolate* isolate, 4632 Isolate* isolate,
4592 const Array& table, 4633 const Array& table,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4634 } 4675 }
4635 const intptr_t num_types = Length(); 4676 const intptr_t num_types = Length();
4636 if (IsRaw(0, num_types)) { 4677 if (IsRaw(0, num_types)) {
4637 return TypeArguments::null(); 4678 return TypeArguments::null();
4638 } 4679 }
4639 Isolate* isolate = Isolate::Current(); 4680 Isolate* isolate = Isolate::Current();
4640 ObjectStore* object_store = isolate->object_store(); 4681 ObjectStore* object_store = isolate->object_store();
4641 Array& table = Array::Handle(isolate, 4682 Array& table = Array::Handle(isolate,
4642 object_store->canonical_type_arguments()); 4683 object_store->canonical_type_arguments());
4643 // Last element of the array is the number of used elements. 4684 // Last element of the array is the number of used elements.
4644 const intptr_t used_elements = 4685 const intptr_t num_used =
4645 Smi::Value(Smi::RawCast(table.At(table.Length() - 1))); 4686 Smi::Value(Smi::RawCast(table.At(table.Length() - 1)));
4646 const intptr_t hash = Hash(); 4687 const intptr_t hash = Hash();
4647 intptr_t index = 4688 intptr_t index =
4648 FindIndexInCanonicalTypeArguments(isolate, table, *this, hash); 4689 FindIndexInCanonicalTypeArguments(isolate, table, *this, hash);
4649 TypeArguments& result = TypeArguments::Handle(isolate); 4690 TypeArguments& result = TypeArguments::Handle(isolate);
4650 result ^= table.At(index); 4691 result ^= table.At(index);
4651 if (result.IsNull()) { 4692 if (result.IsNull()) {
4652 // Canonicalize each type argument. 4693 // Canonicalize each type argument.
4653 AbstractType& type_arg = AbstractType::Handle(isolate); 4694 AbstractType& type_arg = AbstractType::Handle(isolate);
4654 for (intptr_t i = 0; i < num_types; i++) { 4695 for (intptr_t i = 0; i < num_types; i++) {
4655 type_arg = TypeAt(i); 4696 type_arg = TypeAt(i);
4656 type_arg = type_arg.Canonicalize(trail); 4697 type_arg = type_arg.Canonicalize(trail);
4657 SetTypeAt(i, type_arg); 4698 SetTypeAt(i, type_arg);
4658 } 4699 }
4659 // Canonicalization of a recursive type may change its hash. 4700 // Canonicalization of a type should not change its hash. Verify.
4660 const intptr_t new_hash = Hash(); 4701 ASSERT(Hash() == hash);
4661 // Canonicalization of the type argument's own type arguments may add an 4702 // Canonicalization of the type argument's own type arguments may add an
4662 // entry to the table, or even grow the table, and thereby change the 4703 // entry to the table, or even grow the table, and thereby change the
4663 // previously calculated index. 4704 // previously calculated index.
4664 table = object_store->canonical_type_arguments(); 4705 table = object_store->canonical_type_arguments();
4665 if ((new_hash != hash) || 4706 if (Smi::Value(Smi::RawCast(table.At(table.Length() - 1))) != num_used) {
4666 (Smi::Value(Smi::RawCast(table.At(table.Length() - 1))) 4707 index = FindIndexInCanonicalTypeArguments(isolate, table, *this, hash);
4667 != used_elements)) {
4668 index =
4669 FindIndexInCanonicalTypeArguments(isolate, table, *this, new_hash);
4670 result ^= table.At(index); 4708 result ^= table.At(index);
4671 } 4709 }
4672 if (result.IsNull()) { 4710 if (result.IsNull()) {
4673 // Make sure we have an old space object and add it to the table. 4711 // Make sure we have an old space object and add it to the table.
4674 if (this->IsNew()) { 4712 if (this->IsNew()) {
4675 result ^= Object::Clone(*this, Heap::kOld); 4713 result ^= Object::Clone(*this, Heap::kOld);
4676 } else { 4714 } else {
4677 result ^= this->raw(); 4715 result ^= this->raw();
4678 } 4716 }
4679 ASSERT(result.IsOld()); 4717 ASSERT(result.IsOld());
(...skipping 7979 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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 uint32_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
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
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 uint32_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
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
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 uint32_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
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
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 uint32_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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698