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 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1077 object_store->set_empty_context(context); | 1077 object_store->set_empty_context(context); |
| 1078 | 1078 |
| 1079 // Now that the symbol table is initialized and that the core dictionary as | 1079 // Now that the symbol table is initialized and that the core dictionary as |
| 1080 // well as the core implementation dictionary have been setup, preallocate | 1080 // well as the core implementation dictionary have been setup, preallocate |
| 1081 // remaining classes and register them by name in the dictionaries. | 1081 // remaining classes and register them by name in the dictionaries. |
| 1082 String& name = String::Handle(isolate); | 1082 String& name = String::Handle(isolate); |
| 1083 cls = object_store->array_class(); // Was allocated above. | 1083 cls = object_store->array_class(); // Was allocated above. |
| 1084 RegisterPrivateClass(cls, Symbols::_List(), core_lib); | 1084 RegisterPrivateClass(cls, Symbols::_List(), core_lib); |
| 1085 pending_classes.Add(cls); | 1085 pending_classes.Add(cls); |
| 1086 // We cannot use NewNonParameterizedType(cls), because Array is parameterized. | 1086 // We cannot use NewNonParameterizedType(cls), because Array is parameterized. |
| 1087 // Warning: class _List has not been patched yet. Its declared number of type | |
| 1088 // parameters is still 0. It will become 1 after patching. The array type | |
| 1089 // allocated below represents the raw type _List and not _List<E> as we | |
| 1090 // could expect. Use with caution. | |
| 1087 type ^= Type::New(Object::Handle(isolate, cls.raw()), | 1091 type ^= Type::New(Object::Handle(isolate, cls.raw()), |
| 1088 TypeArguments::Handle(isolate), | 1092 TypeArguments::Handle(isolate), |
| 1089 Scanner::kNoSourcePos); | 1093 Scanner::kNoSourcePos); |
| 1090 type.SetIsFinalized(); | 1094 type.SetIsFinalized(); |
| 1091 type ^= type.Canonicalize(); | 1095 type ^= type.Canonicalize(); |
| 1092 object_store->set_array_type(type); | 1096 object_store->set_array_type(type); |
| 1093 | 1097 |
| 1094 cls = object_store->growable_object_array_class(); // Was allocated above. | 1098 cls = object_store->growable_object_array_class(); // Was allocated above. |
| 1095 RegisterPrivateClass(cls, Symbols::_GrowableList(), core_lib); | 1099 RegisterPrivateClass(cls, Symbols::_GrowableList(), core_lib); |
| 1096 pending_classes.Add(cls); | 1100 pending_classes.Add(cls); |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1867 const Function& function = Function::Handle(signature_function()); | 1871 const Function& function = Function::Handle(signature_function()); |
| 1868 ASSERT(!function.IsNull()); | 1872 ASSERT(!function.IsNull()); |
| 1869 if (function.signature_class() != raw()) { | 1873 if (function.signature_class() != raw()) { |
| 1870 // This class is a function type alias. Return the canonical signature type. | 1874 // This class is a function type alias. Return the canonical signature type. |
| 1871 const Class& canonical_class = Class::Handle(function.signature_class()); | 1875 const Class& canonical_class = Class::Handle(function.signature_class()); |
| 1872 return canonical_class.SignatureType(); | 1876 return canonical_class.SignatureType(); |
| 1873 } | 1877 } |
| 1874 // Return the first canonical signature type if already computed at class | 1878 // Return the first canonical signature type if already computed at class |
| 1875 // finalization time. The optimizer may canonicalize instantiated function | 1879 // finalization time. The optimizer may canonicalize instantiated function |
| 1876 // types of the same signature class, but these will be added after the | 1880 // types of the same signature class, but these will be added after the |
| 1877 // uninstantiated signature class at index 0. | 1881 // uninstantiated signature class at index 1. |
| 1878 Array& signature_types = Array::Handle(); | 1882 Array& signature_types = Array::Handle(); |
| 1879 signature_types ^= canonical_types(); | 1883 signature_types ^= canonical_types(); |
| 1880 if (signature_types.IsNull()) { | 1884 if (signature_types.IsNull()) { |
| 1881 set_canonical_types(empty_array()); | 1885 set_canonical_types(empty_array()); |
| 1882 signature_types ^= canonical_types(); | 1886 signature_types ^= canonical_types(); |
| 1883 } | 1887 } |
| 1884 // The canonical_types array is initialized to the empty array. | 1888 // The canonical_types array is initialized to the empty array. |
| 1885 ASSERT(!signature_types.IsNull()); | 1889 ASSERT(!signature_types.IsNull()); |
| 1886 if (signature_types.Length() > 0) { | 1890 if (signature_types.Length() > 0) { |
| 1891 ASSERT(signature_types.Length() > 1); | |
| 1887 Type& signature_type = Type::Handle(); | 1892 Type& signature_type = Type::Handle(); |
| 1888 signature_type ^= signature_types.At(0); | 1893 signature_type ^= signature_types.At(1); |
| 1889 ASSERT(!signature_type.IsNull()); | 1894 ASSERT(!signature_type.IsNull()); |
| 1890 return signature_type.raw(); | 1895 return signature_type.raw(); |
| 1891 } | 1896 } |
| 1892 // A signature class extends class Instance and is parameterized in the same | 1897 // A signature class extends class Instance and is parameterized in the same |
| 1893 // way as the owner class of its non-static signature function. | 1898 // way as the owner class of its non-static signature function. |
| 1894 // It is not type parameterized if its signature function is static. | 1899 // It is not type parameterized if its signature function is static. |
| 1895 // See Class::NewSignatureClass() for the setup of its type parameters. | 1900 // See Class::NewSignatureClass() for the setup of its type parameters. |
| 1896 // During type finalization, the type arguments of the super class of the | 1901 // During type finalization, the type arguments of the super class of the |
| 1897 // owner class of its signature function will be prepended to the type | 1902 // owner class of its signature function will be prepended to the type |
| 1898 // argument vector. Therefore, we only need to set the type arguments | 1903 // argument vector. Therefore, we only need to set the type arguments |
| (...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3596 return raw_ptr()->canonical_types_; | 3601 return raw_ptr()->canonical_types_; |
| 3597 } | 3602 } |
| 3598 | 3603 |
| 3599 | 3604 |
| 3600 void Class::set_canonical_types(const Object& value) const { | 3605 void Class::set_canonical_types(const Object& value) const { |
| 3601 ASSERT(!value.IsNull()); | 3606 ASSERT(!value.IsNull()); |
| 3602 StorePointer(&raw_ptr()->canonical_types_, value.raw()); | 3607 StorePointer(&raw_ptr()->canonical_types_, value.raw()); |
| 3603 } | 3608 } |
| 3604 | 3609 |
| 3605 | 3610 |
| 3606 intptr_t Class::NumCanonicalTypes() const { | 3611 RawType* Class::CanonicalType() const { |
| 3607 if (CanonicalType() != Type::null()) { | 3612 if ((NumTypeArguments() == 0) && !IsSignatureClass()) { |
| 3608 return 1; | 3613 return reinterpret_cast<RawType*>(raw_ptr()->canonical_types_); |
| 3609 } | 3614 } |
| 3610 const Object& types = Object::Handle(canonical_types()); | 3615 Array& types = Array::Handle(); |
| 3611 if (types.IsNull()) { | 3616 types ^= canonical_types(); |
| 3612 return 0; | 3617 if (!types.IsNull() && types.Length() > 0) { |
|
srdjan
2015/08/21 05:02:20
Add parenthesis.
regis
2015/08/21 15:38:21
Done.
| |
| 3618 return reinterpret_cast<RawType*>(types.At(0)); | |
| 3613 } | 3619 } |
| 3614 intptr_t num_types = Array::Cast(types).Length(); | 3620 return reinterpret_cast<RawType*>(Object::null()); |
| 3615 while ((num_types > 0) && | |
| 3616 (Array::Cast(types).At(num_types - 1) == Type::null())) { | |
| 3617 num_types--; | |
| 3618 } | |
| 3619 return num_types; | |
| 3620 } | 3621 } |
| 3621 | 3622 |
| 3622 | 3623 |
| 3624 void Class::SetCanonicalType(const Type& type) const { | |
| 3625 ASSERT(type.IsCanonical()); | |
| 3626 if ((NumTypeArguments() == 0) && !IsSignatureClass()) { | |
|
srdjan
2015/08/21 05:02:20
Should we factor out this test? Only if we can com
regis
2015/08/21 15:38:21
I cannot think of a good name :-)
In any case, I t
| |
| 3627 ASSERT((canonical_types() == Object::null() || | |
| 3628 (canonical_types() == type.raw()))); // Set during own finalization. | |
| 3629 set_canonical_types(type); | |
|
srdjan
2015/08/21 05:02:20
Can we clear it ever, i.e., type -> null ? If it i
regis
2015/08/21 15:38:21
No, we cannot clear it. However, from the time we
| |
| 3630 } else { | |
| 3631 Array& types = Array::Handle(); | |
| 3632 types ^= canonical_types(); | |
| 3633 ASSERT(!types.IsNull() && (types.Length() > 1)); | |
| 3634 ASSERT((types.At(0) == Object::null()) || (types.At(0) == type.raw())); | |
| 3635 types.SetAt(0, type); | |
| 3636 } | |
| 3637 } | |
| 3638 | |
| 3639 | |
| 3623 intptr_t Class::FindCanonicalTypeIndex(const Type& needle) const { | 3640 intptr_t Class::FindCanonicalTypeIndex(const Type& needle) const { |
| 3624 Isolate* isolate = Isolate::Current(); | 3641 Isolate* isolate = Isolate::Current(); |
| 3625 if (EnsureIsFinalized(isolate) != Error::null()) { | 3642 if (EnsureIsFinalized(isolate) != Error::null()) { |
| 3626 return -1; | 3643 return -1; |
| 3627 } | 3644 } |
| 3628 if (needle.raw() == CanonicalType()) { | 3645 if (needle.raw() == CanonicalType()) { |
| 3646 // For a generic type or signature type, there exists another index with the | |
| 3647 // same type. It will never be returned by this function. | |
| 3629 return 0; | 3648 return 0; |
| 3630 } | 3649 } |
| 3631 REUSABLE_OBJECT_HANDLESCOPE(isolate); | 3650 REUSABLE_OBJECT_HANDLESCOPE(isolate); |
| 3632 Object& types = isolate->ObjectHandle(); | 3651 Object& types = isolate->ObjectHandle(); |
| 3633 types = canonical_types(); | 3652 types = canonical_types(); |
| 3634 if (types.IsNull()) { | 3653 if (types.IsNull()) { |
| 3635 return -1; | 3654 return -1; |
| 3636 } | 3655 } |
| 3637 const intptr_t len = Array::Cast(types).Length(); | 3656 const intptr_t len = Array::Cast(types).Length(); |
| 3638 REUSABLE_ABSTRACT_TYPE_HANDLESCOPE(isolate); | 3657 REUSABLE_ABSTRACT_TYPE_HANDLESCOPE(isolate); |
| (...skipping 10745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14384 result.SetCanonical(); | 14403 result.SetCanonical(); |
| 14385 return result.raw(); | 14404 return result.raw(); |
| 14386 } | 14405 } |
| 14387 | 14406 |
| 14388 | 14407 |
| 14389 RawType* Instance::GetType() const { | 14408 RawType* Instance::GetType() const { |
| 14390 if (IsNull()) { | 14409 if (IsNull()) { |
| 14391 return Type::NullType(); | 14410 return Type::NullType(); |
| 14392 } | 14411 } |
| 14393 const Class& cls = Class::Handle(clazz()); | 14412 const Class& cls = Class::Handle(clazz()); |
| 14394 Type& type = Type::Handle(cls.CanonicalType()); | 14413 Type& type = Type::Handle(); |
| 14414 if (cls.NumTypeArguments() == 0) { | |
| 14415 type = cls.CanonicalType(); | |
| 14416 } | |
| 14395 if (type.IsNull()) { | 14417 if (type.IsNull()) { |
| 14396 TypeArguments& type_arguments = TypeArguments::Handle(); | 14418 TypeArguments& type_arguments = TypeArguments::Handle(); |
| 14397 if (cls.NumTypeArguments() > 0) { | 14419 if (cls.NumTypeArguments() > 0) { |
| 14398 type_arguments = GetTypeArguments(); | 14420 type_arguments = GetTypeArguments(); |
| 14399 } | 14421 } |
| 14400 type = Type::New(cls, type_arguments, Scanner::kNoSourcePos); | 14422 type = Type::New(cls, type_arguments, Scanner::kNoSourcePos); |
| 14401 type.SetIsFinalized(); | 14423 type.SetIsFinalized(); |
| 14402 type ^= type.Canonicalize(); | 14424 type ^= type.Canonicalize(); |
| 14403 } | 14425 } |
| 14404 return type.raw(); | 14426 return type.raw(); |
| (...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15659 Array& canonical_types = Array::Handle(isolate); | 15681 Array& canonical_types = Array::Handle(isolate); |
| 15660 canonical_types ^= cls.canonical_types(); | 15682 canonical_types ^= cls.canonical_types(); |
| 15661 if (canonical_types.IsNull()) { | 15683 if (canonical_types.IsNull()) { |
| 15662 canonical_types = empty_array().raw(); | 15684 canonical_types = empty_array().raw(); |
| 15663 } | 15685 } |
| 15664 intptr_t length = canonical_types.Length(); | 15686 intptr_t length = canonical_types.Length(); |
| 15665 // Linear search to see whether this type is already present in the | 15687 // Linear search to see whether this type is already present in the |
| 15666 // list of canonicalized types. | 15688 // list of canonicalized types. |
| 15667 // TODO(asiva): Try to re-factor this lookup code to make sharing | 15689 // TODO(asiva): Try to re-factor this lookup code to make sharing |
| 15668 // easy between the 4 versions of this loop. | 15690 // easy between the 4 versions of this loop. |
| 15669 intptr_t index = 0; | 15691 intptr_t index = 1; // Slot 0 is reserved for CanonicalType(). |
| 15670 while (index < length) { | 15692 while (index < length) { |
| 15671 type ^= canonical_types.At(index); | 15693 type ^= canonical_types.At(index); |
| 15672 if (type.IsNull()) { | 15694 if (type.IsNull()) { |
| 15673 break; | 15695 break; |
| 15674 } | 15696 } |
| 15675 ASSERT(type.IsFinalized()); | 15697 ASSERT(type.IsFinalized()); |
| 15676 if (this->Equals(type)) { | 15698 if (this->Equals(type)) { |
| 15677 ASSERT(type.IsCanonical()); | 15699 ASSERT(type.IsCanonical()); |
| 15678 return type.raw(); | 15700 return type.raw(); |
| 15679 } | 15701 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 15703 } | 15725 } |
| 15704 ASSERT(type.IsFinalized()); | 15726 ASSERT(type.IsFinalized()); |
| 15705 if (this->Equals(type)) { | 15727 if (this->Equals(type)) { |
| 15706 ASSERT(type.IsCanonical()); | 15728 ASSERT(type.IsCanonical()); |
| 15707 return type.raw(); | 15729 return type.raw(); |
| 15708 } | 15730 } |
| 15709 index++; | 15731 index++; |
| 15710 } | 15732 } |
| 15711 | 15733 |
| 15712 // The type needs to be added to the list. Grow the list if it is full. | 15734 // The type needs to be added to the list. Grow the list if it is full. |
| 15713 if (index == length) { | 15735 if (index >= length) { |
| 15736 ASSERT((index == length) || ((index == 1) && (length == 0))); | |
| 15714 const intptr_t new_length = (length > 64) ? | 15737 const intptr_t new_length = (length > 64) ? |
| 15715 (length + 64) : | 15738 (length + 64) : |
| 15716 ((length == 0) ? 1 : (length * 2)); | 15739 ((length == 0) ? 2 : (length * 2)); |
| 15717 const Array& new_canonical_types = Array::Handle( | 15740 const Array& new_canonical_types = Array::Handle( |
| 15718 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); | 15741 isolate, Array::Grow(canonical_types, new_length, Heap::kOld)); |
| 15719 cls.set_canonical_types(new_canonical_types); | 15742 cls.set_canonical_types(new_canonical_types); |
| 15720 new_canonical_types.SetAt(index, *this); | 15743 new_canonical_types.SetAt(index, *this); |
| 15721 } else { | 15744 } else { |
| 15722 canonical_types.SetAt(index, *this); | 15745 canonical_types.SetAt(index, *this); |
| 15723 } | 15746 } |
| 15724 #ifdef DEBUG | 15747 #ifdef DEBUG |
| 15725 if ((index == 0) && cls.IsCanonicalSignatureClass()) { | 15748 if ((index == 1) && cls.IsCanonicalSignatureClass()) { |
| 15726 // Verify that the first canonical type is the signature type by checking | 15749 // Verify that the first canonical type is the signature type by checking |
| 15727 // that the type argument vector of the canonical type ends with the | 15750 // that the type argument vector of the canonical type ends with the |
| 15728 // uninstantiated type parameters of the signature class. Note that these | 15751 // uninstantiated type parameters of the signature class. Note that these |
| 15729 // type parameters may be bounded if the super class of the owner class | 15752 // type parameters may be bounded if the super class of the owner class |
| 15730 // declares bounds. | 15753 // declares bounds. |
| 15731 // The signature type is finalized during class finalization, before the | 15754 // The signature type is finalized during class finalization, before the |
| 15732 // optimizer may canonicalize instantiated function types of the same | 15755 // optimizer may canonicalize instantiated function types of the same |
| 15733 // signature class. | 15756 // signature class. |
| 15734 // Although the signature class extends class Instance, the type arguments | 15757 // Although the signature class extends class Instance, the type arguments |
| 15735 // of the super class of the owner class of its signature function will be | 15758 // of the super class of the owner class of its signature function will be |
| (...skipping 5679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 21415 return tag_label.ToCString(); | 21438 return tag_label.ToCString(); |
| 21416 } | 21439 } |
| 21417 | 21440 |
| 21418 | 21441 |
| 21419 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21442 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 21420 Instance::PrintJSONImpl(stream, ref); | 21443 Instance::PrintJSONImpl(stream, ref); |
| 21421 } | 21444 } |
| 21422 | 21445 |
| 21423 | 21446 |
| 21424 } // namespace dart | 21447 } // namespace dart |
| OLD | NEW |