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

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

Issue 102053010: - Use canonicalized type of non-parameterized classes when (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 136 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
137 RawClass* Object::megamorphic_cache_class_ = 137 RawClass* Object::megamorphic_cache_class_ =
138 reinterpret_cast<RawClass*>(RAW_NULL); 138 reinterpret_cast<RawClass*>(RAW_NULL);
139 RawClass* Object::subtypetestcache_class_ = 139 RawClass* Object::subtypetestcache_class_ =
140 reinterpret_cast<RawClass*>(RAW_NULL); 140 reinterpret_cast<RawClass*>(RAW_NULL);
141 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 141 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
142 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 142 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
143 RawClass* Object::unhandled_exception_class_ = 143 RawClass* Object::unhandled_exception_class_ =
144 reinterpret_cast<RawClass*>(RAW_NULL); 144 reinterpret_cast<RawClass*>(RAW_NULL);
145 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 145 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
146 #undef RAW_NULL
147 146
148 147
149 const double MegamorphicCache::kLoadFactor = 0.75; 148 const double MegamorphicCache::kLoadFactor = 0.75;
150 149
151 150
152 // The following functions are marked as invisible, meaning they will be hidden 151 // The following functions are marked as invisible, meaning they will be hidden
153 // in the stack trace and will be hidden from reflective access. 152 // in the stack trace and will be hidden from reflective access.
154 // (Library, class name, method name) 153 // (Library, class name, method name)
155 #define INVISIBLE_LIST(V) \ 154 #define INVISIBLE_LIST(V) \
156 V(CoreLibrary, Object, _noSuchMethod) \ 155 V(CoreLibrary, Object, _noSuchMethod) \
(...skipping 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 ASSERT(!function.IsNull()); 1604 ASSERT(!function.IsNull());
1606 if (function.signature_class() != raw()) { 1605 if (function.signature_class() != raw()) {
1607 // This class is a function type alias. Return the canonical signature type. 1606 // This class is a function type alias. Return the canonical signature type.
1608 const Class& canonical_class = Class::Handle(function.signature_class()); 1607 const Class& canonical_class = Class::Handle(function.signature_class());
1609 return canonical_class.SignatureType(); 1608 return canonical_class.SignatureType();
1610 } 1609 }
1611 // Return the first canonical signature type if already computed at class 1610 // Return the first canonical signature type if already computed at class
1612 // finalization time. The optimizer may canonicalize instantiated function 1611 // finalization time. The optimizer may canonicalize instantiated function
1613 // types of the same signature class, but these will be added after the 1612 // types of the same signature class, but these will be added after the
1614 // uninstantiated signature class at index 0. 1613 // uninstantiated signature class at index 0.
1615 const Array& signature_types = Array::Handle(canonical_types()); 1614 Array& signature_types = Array::Handle();
1615 signature_types ^= canonical_types();
1616 if (signature_types.IsNull()) {
1617 set_canonical_types(empty_array());
1618 signature_types ^= canonical_types();
1619 }
1616 // The canonical_types array is initialized to the empty array. 1620 // The canonical_types array is initialized to the empty array.
1617 ASSERT(!signature_types.IsNull()); 1621 ASSERT(!signature_types.IsNull());
1618 if (signature_types.Length() > 0) { 1622 if (signature_types.Length() > 0) {
1619 Type& signature_type = Type::Handle(); 1623 Type& signature_type = Type::Handle();
1620 signature_type ^= signature_types.At(0); 1624 signature_type ^= signature_types.At(0);
1621 ASSERT(!signature_type.IsNull()); 1625 ASSERT(!signature_type.IsNull());
1622 return signature_type.raw(); 1626 return signature_type.raw();
1623 } 1627 }
1624 // A signature class extends class Instance and is parameterized in the same 1628 // A signature class extends class Instance and is parameterized in the same
1625 // way as the owner class of its non-static signature function. 1629 // way as the owner class of its non-static signature function.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 1733
1730 1734
1731 // Initialize class fields of type Array with empty array. 1735 // Initialize class fields of type Array with empty array.
1732 void Class::InitEmptyFields() { 1736 void Class::InitEmptyFields() {
1733 if (Object::empty_array().raw() == Array::null()) { 1737 if (Object::empty_array().raw() == Array::null()) {
1734 // The empty array has not been initialized yet. 1738 // The empty array has not been initialized yet.
1735 return; 1739 return;
1736 } 1740 }
1737 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); 1741 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw());
1738 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); 1742 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw());
1739 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw());
1740 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); 1743 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
1741 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); 1744 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw());
1742 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, 1745 StorePointer(&raw_ptr()->invocation_dispatcher_cache_,
1743 Object::empty_array().raw()); 1746 Object::empty_array().raw());
1744 } 1747 }
1745 1748
1746 1749
1747 RawArray* Class::OffsetToFieldMap() const { 1750 RawArray* Class::OffsetToFieldMap() const {
1748 Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_); 1751 Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_);
1749 if (array.IsNull()) { 1752 if (array.IsNull()) {
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 RawArray* Class::constants() const { 2715 RawArray* Class::constants() const {
2713 return raw_ptr()->constants_; 2716 return raw_ptr()->constants_;
2714 } 2717 }
2715 2718
2716 void Class::set_constants(const Array& value) const { 2719 void Class::set_constants(const Array& value) const {
2717 ASSERT(!value.IsNull()); 2720 ASSERT(!value.IsNull());
2718 StorePointer(&raw_ptr()->constants_, value.raw()); 2721 StorePointer(&raw_ptr()->constants_, value.raw());
2719 } 2722 }
2720 2723
2721 2724
2722 RawArray* Class::canonical_types() const { 2725 RawObject* Class::canonical_types() const {
2723 return raw_ptr()->canonical_types_; 2726 return raw_ptr()->canonical_types_;
2724 } 2727 }
2725 2728
2726 void Class::set_canonical_types(const Array& value) const { 2729 void Class::set_canonical_types(const Object& value) const {
2727 ASSERT(!value.IsNull()); 2730 ASSERT(!value.IsNull());
2728 StorePointer(&raw_ptr()->canonical_types_, value.raw()); 2731 StorePointer(&raw_ptr()->canonical_types_, value.raw());
2729 } 2732 }
2730 2733
2731 2734
2732 void Class::set_allocation_stub(const Code& value) const { 2735 void Class::set_allocation_stub(const Code& value) const {
2733 ASSERT(!value.IsNull()); 2736 ASSERT(!value.IsNull());
2734 ASSERT(raw_ptr()->allocation_stub_ == Code::null()); 2737 ASSERT(raw_ptr()->allocation_stub_ == Code::null());
2735 StorePointer(&raw_ptr()->allocation_stub_, value.raw()); 2738 StorePointer(&raw_ptr()->allocation_stub_, value.raw());
2736 } 2739 }
(...skipping 8485 matching lines...) Expand 10 before | Expand all | Expand 10 after
11222 result.SetCanonical(); 11225 result.SetCanonical();
11223 return result.raw(); 11226 return result.raw();
11224 } 11227 }
11225 11228
11226 11229
11227 RawType* Instance::GetType() const { 11230 RawType* Instance::GetType() const {
11228 if (IsNull()) { 11231 if (IsNull()) {
11229 return Type::NullType(); 11232 return Type::NullType();
11230 } 11233 }
11231 const Class& cls = Class::Handle(clazz()); 11234 const Class& cls = Class::Handle(clazz());
11232 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); 11235 Type& type = Type::Handle(cls.CanonicalType());
11233 if (cls.NumTypeArguments() > 0) { 11236 if (type.IsNull()) {
11234 type_arguments = GetTypeArguments(); 11237 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
11238 if (cls.NumTypeArguments() > 0) {
11239 type_arguments = GetTypeArguments();
11240 }
11241 type = Type::New(cls, type_arguments, Scanner::kDummyTokenIndex);
11242 type.SetIsFinalized();
11243 type ^= type.Canonicalize();
11235 } 11244 }
11236 const Type& type = Type::Handle(
11237 Type::New(cls, type_arguments, Scanner::kDummyTokenIndex));
11238 type.SetIsFinalized();
11239 return type.raw(); 11245 return type.raw();
11240 } 11246 }
11241 11247
11242 11248
11243 RawAbstractTypeArguments* Instance::GetTypeArguments() const { 11249 RawAbstractTypeArguments* Instance::GetTypeArguments() const {
11244 const Class& cls = Class::Handle(clazz()); 11250 const Class& cls = Class::Handle(clazz());
11245 intptr_t field_offset = cls.type_arguments_field_offset(); 11251 intptr_t field_offset = cls.type_arguments_field_offset();
11246 ASSERT(field_offset != Class::kNoTypeArguments); 11252 ASSERT(field_offset != Class::kNoTypeArguments);
11247 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); 11253 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
11248 type_arguments ^= *FieldAddrAtOffset(field_offset); 11254 type_arguments ^= *FieldAddrAtOffset(field_offset);
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
11952 } 11958 }
11953 11959
11954 11960
11955 RawType* Type::Function() { 11961 RawType* Type::Function() {
11956 return Isolate::Current()->object_store()->function_type(); 11962 return Isolate::Current()->object_store()->function_type();
11957 } 11963 }
11958 11964
11959 11965
11960 RawType* Type::NewNonParameterizedType(const Class& type_class) { 11966 RawType* Type::NewNonParameterizedType(const Class& type_class) {
11961 ASSERT(type_class.NumTypeArguments() == 0); 11967 ASSERT(type_class.NumTypeArguments() == 0);
11962 const TypeArguments& no_type_arguments = TypeArguments::Handle(); 11968 if (type_class.raw() == Object::dynamic_class()) {
11963 Type& type = Type::Handle(); 11969 // If the dynamic type has not been setup in the VM isolate, then we need
11964 type ^= Type::New(Object::Handle(type_class.raw()), 11970 // to allocate it here.
11965 no_type_arguments, 11971 if (Object::dynamic_type() != reinterpret_cast<RawType*>(RAW_NULL)) {
11966 Scanner::kDummyTokenIndex); 11972 return Object::dynamic_type();
11967 type.SetIsFinalized(); 11973 }
11968 type ^= type.Canonicalize(); 11974 ASSERT(Isolate::Current() == Dart::vm_isolate());
11975 }
11976 Type& type = Type::Handle(type_class.CanonicalType());
11977 if (type.IsNull()) {
11978 const TypeArguments& no_type_arguments = TypeArguments::Handle();
11979 type ^= Type::New(Object::Handle(type_class.raw()),
11980 no_type_arguments,
11981 Scanner::kDummyTokenIndex);
11982 type.SetIsFinalized();
11983 type ^= type.Canonicalize();
11984 }
11969 return type.raw(); 11985 return type.raw();
11970 } 11986 }
11971 11987
Florian Schneider 2013/12/17 10:39:23 #undef RAW_NULL?
Ivan Posva 2013/12/17 16:58:04 I expect to get more of these kinds of tests in th
11972 11988
11973 void Type::SetIsFinalized() const { 11989 void Type::SetIsFinalized() const {
11974 ASSERT(!IsFinalized()); 11990 ASSERT(!IsFinalized());
11975 if (IsInstantiated()) { 11991 if (IsInstantiated()) {
11976 set_type_state(RawType::kFinalizedInstantiated); 11992 set_type_state(RawType::kFinalizedInstantiated);
11977 } else { 11993 } else {
11978 set_type_state(RawType::kFinalizedUninstantiated); 11994 set_type_state(RawType::kFinalizedUninstantiated);
11979 } 11995 }
11980 } 11996 }
11981 11997
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
12195 return Type::New(type_cls, type_args, token_pos()); 12211 return Type::New(type_cls, type_args, token_pos());
12196 } 12212 }
12197 12213
12198 12214
12199 RawAbstractType* Type::Canonicalize() const { 12215 RawAbstractType* Type::Canonicalize() const {
12200 ASSERT(IsFinalized()); 12216 ASSERT(IsFinalized());
12201 if (IsCanonical() || IsMalformed()) { 12217 if (IsCanonical() || IsMalformed()) {
12202 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); 12218 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld());
12203 return this->raw(); 12219 return this->raw();
12204 } 12220 }
12205 const Class& cls = Class::Handle(type_class()); 12221 Isolate* isolate = Isolate::Current();
12206 Array& canonical_types = Array::Handle(cls.canonical_types()); 12222 Type& type = Type::Handle(isolate);
12223 const Class& cls = Class::Handle(isolate, type_class());
12224 if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
12225 return Object::dynamic_type();
12226 }
12227 // Fast canonical lookup/registry for simple types.
12228 if ((cls.NumTypeArguments() == 0) && !cls.IsSignatureClass()) {
12229 type = cls.CanonicalType();
12230 if (type.IsNull()) {
12231 ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate()));
12232 cls.set_canonical_types(*this);
12233 SetCanonical();
12234 return this->raw();
12235 }
12236 ASSERT(this->Equals(type));
12237 return type.raw();
12238 }
12239
12240 Array& canonical_types = Array::Handle(isolate);
12241 canonical_types ^= cls.canonical_types();
12207 if (canonical_types.IsNull()) { 12242 if (canonical_types.IsNull()) {
12208 // Types defined in the VM isolate are canonicalized via the object store. 12243 canonical_types = empty_array().raw();
12209 return this->raw();
12210 } 12244 }
12211 const intptr_t canonical_types_len = canonical_types.Length(); 12245 const intptr_t canonical_types_len = canonical_types.Length();
12212 // Linear search to see whether this type is already present in the 12246 // Linear search to see whether this type is already present in the
12213 // list of canonicalized types. 12247 // list of canonicalized types.
12214 // TODO(asiva): Try to re-factor this lookup code to make sharing 12248 // TODO(asiva): Try to re-factor this lookup code to make sharing
12215 // easy between the 4 versions of this loop. 12249 // easy between the 4 versions of this loop.
12216 Type& type = Type::Handle();
12217 intptr_t index = 0; 12250 intptr_t index = 0;
12218 while (index < canonical_types_len) { 12251 while (index < canonical_types_len) {
12219 type ^= canonical_types.At(index); 12252 type ^= canonical_types.At(index);
12220 if (type.IsNull()) { 12253 if (type.IsNull()) {
12221 break; 12254 break;
12222 } 12255 }
12223 ASSERT(type.IsFinalized()); 12256 ASSERT(type.IsFinalized());
12224 if (this->Equals(type)) { 12257 if (this->Equals(type)) {
12225 return type.raw(); 12258 return type.raw();
12226 } 12259 }
12227 index++; 12260 index++;
12228 } 12261 }
12229 // Canonicalize the type arguments. 12262 // Canonicalize the type arguments.
12230 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); 12263 AbstractTypeArguments& type_args =
12264 AbstractTypeArguments::Handle(isolate, arguments());
12231 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments())); 12265 ASSERT(type_args.IsNull() || (type_args.Length() == cls.NumTypeArguments()));
12232 type_args = type_args.Canonicalize(); 12266 type_args = type_args.Canonicalize();
12233 set_arguments(type_args); 12267 set_arguments(type_args);
12234 // The type needs to be added to the list. Grow the list if it is full. 12268 // The type needs to be added to the list. Grow the list if it is full.
12235 if (index == canonical_types_len) { 12269 if (index == canonical_types_len) {
12236 const intptr_t kLengthIncrement = 2; // Raw and parameterized. 12270 const intptr_t kLengthIncrement = 2; // Raw and parameterized.
12237 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; 12271 const intptr_t new_length = canonical_types.Length() + kLengthIncrement;
12238 const Array& new_canonical_types = 12272 const Array& new_canonical_types = Array::Handle(
12239 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); 12273 isolate, Array::Grow(canonical_types, new_length, Heap::kOld));
12240 cls.set_canonical_types(new_canonical_types); 12274 cls.set_canonical_types(new_canonical_types);
12241 new_canonical_types.SetAt(index, *this); 12275 new_canonical_types.SetAt(index, *this);
12242 } else { 12276 } else {
12243 canonical_types.SetAt(index, *this); 12277 canonical_types.SetAt(index, *this);
12244 } 12278 }
12245 #ifdef DEBUG 12279 #ifdef DEBUG
12246 if ((index == 0) && cls.IsCanonicalSignatureClass()) { 12280 if ((index == 0) && cls.IsCanonicalSignatureClass()) {
12247 // Verify that the first canonical type is the signature type by checking 12281 // Verify that the first canonical type is the signature type by checking
12248 // that the type argument vector of the canonical type ends with the 12282 // that the type argument vector of the canonical type ends with the
12249 // uninstantiated type parameters of the signature class. 12283 // uninstantiated type parameters of the signature class.
12250 // The signature type is finalized during class finalization, before the 12284 // The signature type is finalized during class finalization, before the
12251 // optimizer may canonicalize instantiated function types of the same 12285 // optimizer may canonicalize instantiated function types of the same
12252 // signature class. 12286 // signature class.
12253 // Although the signature class extends class Instance, the type arguments 12287 // Although the signature class extends class Instance, the type arguments
12254 // of the super class of the owner class of its signature function will be 12288 // of the super class of the owner class of its signature function will be
12255 // prepended to the type argument vector during class finalization. 12289 // prepended to the type argument vector during class finalization.
12256 const TypeArguments& type_params = 12290 const TypeArguments& type_params =
12257 TypeArguments::Handle(cls.type_parameters()); 12291 TypeArguments::Handle(isolate, cls.type_parameters());
12258 const intptr_t num_type_params = cls.NumTypeParameters(); 12292 const intptr_t num_type_params = cls.NumTypeParameters();
12259 const intptr_t num_type_args = cls.NumTypeArguments(); 12293 const intptr_t num_type_args = cls.NumTypeArguments();
12260 TypeParameter& type_arg = TypeParameter::Handle(); 12294 TypeParameter& type_arg = TypeParameter::Handle(isolate);
12261 TypeParameter& type_param = TypeParameter::Handle(); 12295 TypeParameter& type_param = TypeParameter::Handle(isolate);
12262 for (intptr_t i = 0; i < num_type_params; i++) { 12296 for (intptr_t i = 0; i < num_type_params; i++) {
12263 type_arg ^= type_args.TypeAt(num_type_args - num_type_params + i); 12297 type_arg ^= type_args.TypeAt(num_type_args - num_type_params + i);
12264 type_param ^= type_params.TypeAt(i); 12298 type_param ^= type_params.TypeAt(i);
12265 ASSERT(type_arg.Equals(type_param)); 12299 ASSERT(type_arg.Equals(type_param));
12266 } 12300 }
12267 } 12301 }
12268 #endif 12302 #endif
12269 ASSERT(IsOld()); 12303 ASSERT(IsOld());
12270 SetCanonical(); 12304 SetCanonical();
12271 return this->raw(); 12305 return this->raw();
(...skipping 4187 matching lines...) Expand 10 before | Expand all | Expand 10 after
16459 return "_MirrorReference"; 16493 return "_MirrorReference";
16460 } 16494 }
16461 16495
16462 16496
16463 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 16497 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
16464 Instance::PrintToJSONStream(stream, ref); 16498 Instance::PrintToJSONStream(stream, ref);
16465 } 16499 }
16466 16500
16467 16501
16468 } // namespace dart 16502 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698