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 4019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4030 | 4030 |
4031 | 4031 |
4032 intptr_t TypeArguments::Hash() const { | 4032 intptr_t TypeArguments::Hash() const { |
4033 if (IsNull()) return 0; | 4033 if (IsNull()) return 0; |
4034 const intptr_t num_types = Length(); | 4034 const intptr_t num_types = Length(); |
4035 if (IsRaw(0, num_types)) return 0; | 4035 if (IsRaw(0, num_types)) return 0; |
4036 uint32_t result = 0; | 4036 uint32_t result = 0; |
4037 AbstractType& type = AbstractType::Handle(); | 4037 AbstractType& type = AbstractType::Handle(); |
4038 for (intptr_t i = 0; i < num_types; i++) { | 4038 for (intptr_t i = 0; i < num_types; i++) { |
4039 type = TypeAt(i); | 4039 type = TypeAt(i); |
4040 result = CombineHashes(result, type.Hash()); | 4040 // The hash may be calculated during type finalization (for debugging |
| 4041 // purposes only) while a type argument is still temporarily null. |
| 4042 result = CombineHashes(result, type.IsNull() ? 0 : type.Hash()); |
4041 } | 4043 } |
4042 return FinalizeHash(result); | 4044 return FinalizeHash(result); |
4043 } | 4045 } |
4044 | 4046 |
4045 | 4047 |
4046 RawString* TypeArguments::SubvectorName(intptr_t from_index, | 4048 RawString* TypeArguments::SubvectorName(intptr_t from_index, |
4047 intptr_t len, | 4049 intptr_t len, |
4048 NameVisibility name_visibility) const { | 4050 NameVisibility name_visibility) const { |
4049 ASSERT(from_index + len <= Length()); | 4051 ASSERT(from_index + len <= Length()); |
4050 String& name = String::Handle(); | 4052 String& name = String::Handle(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4094 return true; | 4096 return true; |
4095 } | 4097 } |
4096 | 4098 |
4097 | 4099 |
4098 bool TypeArguments::IsRecursive() const { | 4100 bool TypeArguments::IsRecursive() const { |
4099 if (IsNull()) return false; | 4101 if (IsNull()) return false; |
4100 const intptr_t num_types = Length(); | 4102 const intptr_t num_types = Length(); |
4101 AbstractType& type = AbstractType::Handle(); | 4103 AbstractType& type = AbstractType::Handle(); |
4102 for (intptr_t i = 0; i < num_types; i++) { | 4104 for (intptr_t i = 0; i < num_types; i++) { |
4103 type = TypeAt(i); | 4105 type = TypeAt(i); |
4104 if (type.IsRecursive()) { | 4106 // If this type argument is null, the type parameterized with this type |
| 4107 // argument is still being finalized and is definitely recursive. The null |
| 4108 // type argument will be replaced by a non-null type before the type is |
| 4109 // marked as finalized. |
| 4110 if (type.IsNull() || type.IsRecursive()) { |
4105 return true; | 4111 return true; |
4106 } | 4112 } |
4107 } | 4113 } |
4108 return false; | 4114 return false; |
4109 } | 4115 } |
4110 | 4116 |
4111 | 4117 |
4112 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, | 4118 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, |
4113 intptr_t from_index, | 4119 intptr_t from_index, |
4114 intptr_t len) const { | 4120 intptr_t len) const { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4246 ASSERT(!IsNull()); | 4252 ASSERT(!IsNull()); |
4247 return Smi::Value(raw_ptr()->length_); | 4253 return Smi::Value(raw_ptr()->length_); |
4248 } | 4254 } |
4249 | 4255 |
4250 | 4256 |
4251 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 4257 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |
4252 return *TypeAddr(index); | 4258 return *TypeAddr(index); |
4253 } | 4259 } |
4254 | 4260 |
4255 | 4261 |
4256 void TypeArguments::set_type_at(intptr_t index, | 4262 void TypeArguments::SetTypeAt(intptr_t index, |
4257 const AbstractType& value) const { | 4263 const AbstractType& value) const { |
4258 StorePointer(TypeAddr(index), value.raw()); | 4264 StorePointer(TypeAddr(index), value.raw()); |
4259 } | 4265 } |
4260 | 4266 |
4261 | 4267 |
4262 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { | |
4263 const AbstractType& type_arg = AbstractType::Handle(TypeAt(index)); | |
4264 if (type_arg.IsTypeRef()) { | |
4265 if (value.raw() != type_arg.raw()) { | |
4266 TypeRef::Cast(type_arg).set_type(value); | |
4267 } | |
4268 } else { | |
4269 set_type_at(index, value); | |
4270 } | |
4271 } | |
4272 | |
4273 | |
4274 bool TypeArguments::IsResolved() const { | 4268 bool TypeArguments::IsResolved() const { |
4275 AbstractType& type = AbstractType::Handle(); | 4269 AbstractType& type = AbstractType::Handle(); |
4276 const intptr_t num_types = Length(); | 4270 const intptr_t num_types = Length(); |
4277 for (intptr_t i = 0; i < num_types; i++) { | 4271 for (intptr_t i = 0; i < num_types; i++) { |
4278 type = TypeAt(i); | 4272 type = TypeAt(i); |
4279 if (!type.IsResolved()) { | 4273 if (!type.IsResolved()) { |
4280 return false; | 4274 return false; |
4281 } | 4275 } |
4282 } | 4276 } |
4283 return true; | 4277 return true; |
4284 } | 4278 } |
4285 | 4279 |
4286 | 4280 |
4287 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index, | 4281 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index, |
4288 intptr_t len, | 4282 intptr_t len, |
4289 GrowableObjectArray* trail) const { | 4283 GrowableObjectArray* trail) const { |
4290 ASSERT(!IsNull()); | 4284 ASSERT(!IsNull()); |
4291 AbstractType& type = AbstractType::Handle(); | 4285 AbstractType& type = AbstractType::Handle(); |
4292 for (intptr_t i = 0; i < len; i++) { | 4286 for (intptr_t i = 0; i < len; i++) { |
4293 type = TypeAt(from_index + i); | 4287 type = TypeAt(from_index + i); |
4294 if (!type.IsInstantiated(trail)) { | 4288 // If the type argument is null, the type parameterized with this type |
| 4289 // argument is still being finalized. Skip this null type argument. |
| 4290 if (!type.IsNull() && !type.IsInstantiated(trail)) { |
4295 return false; | 4291 return false; |
4296 } | 4292 } |
4297 } | 4293 } |
4298 return true; | 4294 return true; |
4299 } | 4295 } |
4300 | 4296 |
4301 | 4297 |
4302 bool TypeArguments::IsUninstantiatedIdentity() const { | 4298 bool TypeArguments::IsUninstantiatedIdentity() const { |
4303 ASSERT(!IsInstantiated()); | 4299 ASSERT(!IsInstantiated()); |
4304 AbstractType& type = AbstractType::Handle(); | 4300 AbstractType& type = AbstractType::Handle(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4448 IsUninstantiatedIdentity() && | 4444 IsUninstantiatedIdentity() && |
4449 (instantiator_type_arguments.Length() == Length())) { | 4445 (instantiator_type_arguments.Length() == Length())) { |
4450 return instantiator_type_arguments.raw(); | 4446 return instantiator_type_arguments.raw(); |
4451 } | 4447 } |
4452 const intptr_t num_types = Length(); | 4448 const intptr_t num_types = Length(); |
4453 TypeArguments& instantiated_array = | 4449 TypeArguments& instantiated_array = |
4454 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); | 4450 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); |
4455 AbstractType& type = AbstractType::Handle(); | 4451 AbstractType& type = AbstractType::Handle(); |
4456 for (intptr_t i = 0; i < num_types; i++) { | 4452 for (intptr_t i = 0; i < num_types; i++) { |
4457 type = TypeAt(i); | 4453 type = TypeAt(i); |
4458 if (!type.IsInstantiated()) { | 4454 // If this type argument T is null, the type A containing T in its flattened |
| 4455 // type argument vector V is recursive and is still being finalized. |
| 4456 // T is the type argument of a super type of A. T is being instantiated |
| 4457 // during finalization of V, which is also the instantiator. T depends |
| 4458 // solely on the type parameters of A and will be replaced by a non-null |
| 4459 // type before A is marked as finalized. |
| 4460 if (!type.IsNull() && !type.IsInstantiated()) { |
4459 type = type.InstantiateFrom(instantiator_type_arguments, | 4461 type = type.InstantiateFrom(instantiator_type_arguments, |
4460 bound_error, | 4462 bound_error, |
4461 trail); | 4463 trail); |
4462 } | 4464 } |
4463 instantiated_array.SetTypeAt(i, type); | 4465 instantiated_array.SetTypeAt(i, type); |
4464 } | 4466 } |
4465 return instantiated_array.raw(); | 4467 return instantiated_array.raw(); |
4466 } | 4468 } |
4467 | 4469 |
4468 | 4470 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4691 TypeArguments& result = TypeArguments::Handle(isolate); | 4693 TypeArguments& result = TypeArguments::Handle(isolate); |
4692 result ^= table.At(index); | 4694 result ^= table.At(index); |
4693 if (result.IsNull()) { | 4695 if (result.IsNull()) { |
4694 // Canonicalize each type argument. | 4696 // Canonicalize each type argument. |
4695 AbstractType& type_arg = AbstractType::Handle(isolate); | 4697 AbstractType& type_arg = AbstractType::Handle(isolate); |
4696 for (intptr_t i = 0; i < num_types; i++) { | 4698 for (intptr_t i = 0; i < num_types; i++) { |
4697 type_arg = TypeAt(i); | 4699 type_arg = TypeAt(i); |
4698 type_arg = type_arg.Canonicalize(trail); | 4700 type_arg = type_arg.Canonicalize(trail); |
4699 SetTypeAt(i, type_arg); | 4701 SetTypeAt(i, type_arg); |
4700 } | 4702 } |
4701 // Canonicalization of a type should not change its hash. Verify. | 4703 // Canonicalization of a recursive type may change its hash. |
4702 ASSERT(Hash() == hash); | 4704 intptr_t canonical_hash = hash; |
| 4705 if (IsRecursive()) { |
| 4706 canonical_hash = Hash(); |
| 4707 } |
4703 // Canonicalization of the type argument's own type arguments may add an | 4708 // Canonicalization of the type argument's own type arguments may add an |
4704 // entry to the table, or even grow the table, and thereby change the | 4709 // entry to the table, or even grow the table, and thereby change the |
4705 // previously calculated index. | 4710 // previously calculated index. |
4706 table = object_store->canonical_type_arguments(); | 4711 table = object_store->canonical_type_arguments(); |
4707 if (Smi::Value(Smi::RawCast(table.At(table.Length() - 1))) != num_used) { | 4712 if ((canonical_hash != hash) || |
4708 index = FindIndexInCanonicalTypeArguments(isolate, table, *this, hash); | 4713 (Smi::Value(Smi::RawCast(table.At(table.Length() - 1))) != num_used)) { |
| 4714 index = FindIndexInCanonicalTypeArguments( |
| 4715 isolate, table, *this, canonical_hash); |
4709 result ^= table.At(index); | 4716 result ^= table.At(index); |
4710 } | 4717 } |
4711 if (result.IsNull()) { | 4718 if (result.IsNull()) { |
4712 // Make sure we have an old space object and add it to the table. | 4719 // Make sure we have an old space object and add it to the table. |
4713 if (this->IsNew()) { | 4720 if (this->IsNew()) { |
4714 result ^= Object::Clone(*this, Heap::kOld); | 4721 result ^= Object::Clone(*this, Heap::kOld); |
4715 } else { | 4722 } else { |
4716 result ^= this->raw(); | 4723 result ^= this->raw(); |
4717 } | 4724 } |
4718 ASSERT(result.IsOld()); | 4725 ASSERT(result.IsOld()); |
(...skipping 8771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13490 RawAbstractType* Type::InstantiateFrom( | 13497 RawAbstractType* Type::InstantiateFrom( |
13491 const TypeArguments& instantiator_type_arguments, | 13498 const TypeArguments& instantiator_type_arguments, |
13492 Error* bound_error, | 13499 Error* bound_error, |
13493 GrowableObjectArray* trail) const { | 13500 GrowableObjectArray* trail) const { |
13494 ASSERT(IsFinalized() || IsBeingFinalized()); | 13501 ASSERT(IsFinalized() || IsBeingFinalized()); |
13495 ASSERT(!IsInstantiated()); | 13502 ASSERT(!IsInstantiated()); |
13496 // Return the uninstantiated type unchanged if malformed. No copy needed. | 13503 // Return the uninstantiated type unchanged if malformed. No copy needed. |
13497 if (IsMalformed()) { | 13504 if (IsMalformed()) { |
13498 return raw(); | 13505 return raw(); |
13499 } | 13506 } |
| 13507 // Instantiating this type with its own type arguments as instantiator can |
| 13508 // occur during finalization and bounds checking. Return the type unchanged. |
| 13509 if (arguments() == instantiator_type_arguments.raw()) { |
| 13510 return raw(); |
| 13511 } |
| 13512 // If this type is recursive, we may already be instantiating it. |
| 13513 Type& instantiated_type = Type::Handle(); |
| 13514 instantiated_type ^= OnlyBuddyInTrail(trail); |
| 13515 if (!instantiated_type.IsNull()) { |
| 13516 ASSERT(IsRecursive()); |
| 13517 return instantiated_type.raw(); |
| 13518 } |
13500 // Note that the type class has to be resolved at this time, but not | 13519 // Note that the type class has to be resolved at this time, but not |
13501 // necessarily finalized yet. We may be checking bounds at compile time or | 13520 // necessarily finalized yet. We may be checking bounds at compile time or |
13502 // finalizing the type argument vector of a recursive type. | 13521 // finalizing the type argument vector of a recursive type. |
13503 const Class& cls = Class::Handle(type_class()); | 13522 const Class& cls = Class::Handle(type_class()); |
| 13523 |
13504 // This uninstantiated type is not modified, as it can be instantiated | 13524 // This uninstantiated type is not modified, as it can be instantiated |
13505 // with different instantiators. | 13525 // with different instantiators. Allocate a new instantiated version of it. |
13506 Type& instantiated_type = Type::Handle( | 13526 instantiated_type = Type::New(cls, TypeArguments::Handle(), token_pos()); |
13507 Type::New(cls, TypeArguments::Handle(), token_pos())); | 13527 TypeArguments& type_arguments = TypeArguments::Handle(arguments()); |
13508 if (arguments() != TypeArguments::null()) { | 13528 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); |
13509 TypeArguments& type_arguments = TypeArguments::Handle(arguments()); | 13529 if (type_arguments.IsRecursive()) { |
13510 ASSERT(type_arguments.Length() == cls.NumTypeArguments()); | 13530 AddOnlyBuddyToTrail(&trail, instantiated_type); |
13511 if (type_arguments.IsRecursive()) { | |
13512 AddOnlyBuddyToTrail(&trail, instantiated_type); | |
13513 } | |
13514 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, | |
13515 bound_error, | |
13516 trail); | |
13517 instantiated_type.set_arguments(type_arguments); | |
13518 } | 13531 } |
13519 instantiated_type.SetIsFinalized(); | 13532 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
| 13533 bound_error, |
| 13534 trail); |
| 13535 instantiated_type.set_arguments(type_arguments); |
| 13536 if (IsFinalized()) { |
| 13537 instantiated_type.SetIsFinalized(); |
| 13538 } else { |
| 13539 instantiated_type.set_is_resolved(); |
| 13540 } |
13520 // Canonicalization is not part of instantiation. | 13541 // Canonicalization is not part of instantiation. |
13521 return instantiated_type.raw(); | 13542 return instantiated_type.raw(); |
13522 } | 13543 } |
13523 | 13544 |
13524 | 13545 |
13525 bool Type::IsEquivalent(const Instance& other, | 13546 bool Type::IsEquivalent(const Instance& other, |
13526 GrowableObjectArray* trail) const { | 13547 GrowableObjectArray* trail) const { |
13527 ASSERT(!IsNull()); | 13548 ASSERT(!IsNull()); |
13528 if (raw() == other.raw()) { | 13549 if (raw() == other.raw()) { |
13529 return true; | 13550 return true; |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13871 if (raw() == other.raw()) { | 13892 if (raw() == other.raw()) { |
13872 return true; | 13893 return true; |
13873 } | 13894 } |
13874 if (TestAndAddBuddyToTrail(&trail, other)) { | 13895 if (TestAndAddBuddyToTrail(&trail, other)) { |
13875 return true; | 13896 return true; |
13876 } | 13897 } |
13877 return AbstractType::Handle(type()).IsEquivalent(other, trail); | 13898 return AbstractType::Handle(type()).IsEquivalent(other, trail); |
13878 } | 13899 } |
13879 | 13900 |
13880 | 13901 |
13881 RawAbstractType* TypeRef::InstantiateFrom( | 13902 RawTypeRef* TypeRef::InstantiateFrom( |
13882 const TypeArguments& instantiator_type_arguments, | 13903 const TypeArguments& instantiator_type_arguments, |
13883 Error* bound_error, | 13904 Error* bound_error, |
13884 GrowableObjectArray* trail) const { | 13905 GrowableObjectArray* trail) const { |
| 13906 TypeRef& instantiated_type_ref = TypeRef::Handle(); |
| 13907 instantiated_type_ref ^= OnlyBuddyInTrail(trail); |
| 13908 if (!instantiated_type_ref.IsNull()) { |
| 13909 return instantiated_type_ref.raw(); |
| 13910 } |
13885 AbstractType& ref_type = AbstractType::Handle(type()); | 13911 AbstractType& ref_type = AbstractType::Handle(type()); |
13886 ASSERT(!ref_type.IsTypeRef()); | 13912 ASSERT(!ref_type.IsTypeRef()); |
13887 AbstractType& instantiated_ref_type = AbstractType::Handle(); | 13913 AbstractType& instantiated_ref_type = AbstractType::Handle(); |
13888 instantiated_ref_type ^= ref_type.OnlyBuddyInTrail(trail); | 13914 instantiated_ref_type = ref_type.InstantiateFrom( |
13889 if (instantiated_ref_type.IsNull()) { | |
13890 // The referenced type is first encountered here during instantiation. | |
13891 instantiated_ref_type = ref_type.InstantiateFrom( | |
13892 instantiator_type_arguments, bound_error, trail); | 13915 instantiator_type_arguments, bound_error, trail); |
13893 } | |
13894 ASSERT(!instantiated_ref_type.IsTypeRef()); | 13916 ASSERT(!instantiated_ref_type.IsTypeRef()); |
13895 return TypeRef::New(instantiated_ref_type); | 13917 instantiated_type_ref = TypeRef::New(instantiated_ref_type); |
| 13918 AddOnlyBuddyToTrail(&trail, instantiated_type_ref); |
| 13919 return instantiated_type_ref.raw(); |
13896 } | 13920 } |
13897 | 13921 |
13898 | 13922 |
13899 void TypeRef::set_type(const AbstractType& value) const { | 13923 void TypeRef::set_type(const AbstractType& value) const { |
13900 ASSERT(value.HasResolvedTypeClass()); | 13924 ASSERT(value.HasResolvedTypeClass()); |
| 13925 ASSERT(!value.IsTypeRef()); |
13901 StorePointer(&raw_ptr()->type_, value.raw()); | 13926 StorePointer(&raw_ptr()->type_, value.raw()); |
13902 } | 13927 } |
13903 | 13928 |
13904 | 13929 |
13905 // A TypeRef cannot be canonical by definition. Only its referenced type can be. | 13930 // A TypeRef cannot be canonical by definition. Only its referenced type can be. |
13906 // Consider the type Derived, where class Derived extends Base<Derived>. | 13931 // Consider the type Derived, where class Derived extends Base<Derived>. |
13907 // The first type argument of its flattened type argument vector is Derived, | 13932 // The first type argument of its flattened type argument vector is Derived, |
13908 // represented by a TypeRef pointing to itself. | 13933 // represented by a TypeRef pointing to itself. |
13909 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { | 13934 RawAbstractType* TypeRef::Canonicalize(GrowableObjectArray* trail) const { |
13910 if (TestAndAddToTrail(&trail)) { | 13935 if (TestAndAddToTrail(&trail)) { |
13911 return raw(); | 13936 return raw(); |
13912 } | 13937 } |
| 13938 // TODO(regis): Try to reduce the number of nodes required to represent the |
| 13939 // referenced recursive type. |
13913 AbstractType& ref_type = AbstractType::Handle(type()); | 13940 AbstractType& ref_type = AbstractType::Handle(type()); |
13914 ref_type = ref_type.Canonicalize(trail); | 13941 ref_type = ref_type.Canonicalize(trail); |
13915 set_type(ref_type); | 13942 set_type(ref_type); |
13916 return raw(); | 13943 return raw(); |
13917 } | 13944 } |
13918 | 13945 |
13919 | 13946 |
13920 intptr_t TypeRef::Hash() const { | 13947 intptr_t TypeRef::Hash() const { |
13921 // Do not calculate the hash of the referenced type to avoid divergence. | 13948 // Do not calculate the hash of the referenced type to avoid divergence. |
13922 const uint32_t result = | 13949 const uint32_t result = |
(...skipping 4310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18233 return "_MirrorReference"; | 18260 return "_MirrorReference"; |
18234 } | 18261 } |
18235 | 18262 |
18236 | 18263 |
18237 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 18264 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
18238 Instance::PrintToJSONStream(stream, ref); | 18265 Instance::PrintToJSONStream(stream, ref); |
18239 } | 18266 } |
18240 | 18267 |
18241 | 18268 |
18242 } // namespace dart | 18269 } // namespace dart |
OLD | NEW |