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 1721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1732 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); | 1732 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); |
| 1733 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); | 1733 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); |
| 1734 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw()); | 1734 StorePointer(&raw_ptr()->canonical_types_, Object::empty_array().raw()); |
| 1735 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); | 1735 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |
| 1736 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); | 1736 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); |
| 1737 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, | 1737 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, |
| 1738 Object::empty_array().raw()); | 1738 Object::empty_array().raw()); |
| 1739 } | 1739 } |
| 1740 | 1740 |
| 1741 | 1741 |
| 1742 RawArray* Class::OffsetToFieldMap() const { | |
| 1743 Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_); | |
| 1744 if (array.IsNull()) { | |
| 1745 ASSERT(is_finalized()); | |
| 1746 const intptr_t length = raw_ptr()->instance_size_in_words_; | |
| 1747 array = Array::New(length); | |
|
Ivan Posva
2013/11/01 04:50:05
This array should be allocated in old space. It wi
Florian Schneider
2013/11/01 10:39:27
Done.
| |
| 1748 Class& cls = Class::Handle(this->raw()); | |
| 1749 Array& fields = Array::Handle(); | |
| 1750 Field& f = Field::Handle(); | |
| 1751 while (!cls.IsNull()) { | |
| 1752 fields = cls.fields(); | |
| 1753 for (intptr_t i = 0; i < fields.Length(); ++i) { | |
| 1754 f ^= fields.At(i); | |
| 1755 if (!f.is_static()) { | |
| 1756 array.SetAt(f.Offset() / kWordSize, f); | |
|
Ivan Posva
2013/11/01 04:50:05
f.Offset() >> kWordSizeLog2
Florian Schneider
2013/11/01 10:39:27
Done.
| |
| 1757 } | |
| 1758 } | |
| 1759 cls = cls.SuperClass(); | |
| 1760 } | |
| 1761 StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw()); | |
| 1762 } | |
| 1763 return array.raw(); | |
| 1764 } | |
| 1765 | |
| 1766 | |
| 1742 bool Class::HasInstanceFields() const { | 1767 bool Class::HasInstanceFields() const { |
| 1743 const Array& field_array = Array::Handle(fields()); | 1768 const Array& field_array = Array::Handle(fields()); |
| 1744 Field& field = Field::Handle(); | 1769 Field& field = Field::Handle(); |
| 1745 for (intptr_t i = 0; i < field_array.Length(); ++i) { | 1770 for (intptr_t i = 0; i < field_array.Length(); ++i) { |
| 1746 field ^= field_array.At(i); | 1771 field ^= field_array.At(i); |
| 1747 if (!field.is_static()) { | 1772 if (!field.is_static()) { |
| 1748 return true; | 1773 return true; |
| 1749 } | 1774 } |
| 1750 } | 1775 } |
| 1751 return false; | 1776 return false; |
| (...skipping 4201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5953 } | 5978 } |
| 5954 | 5979 |
| 5955 | 5980 |
| 5956 bool Field::IsUninitialized() const { | 5981 bool Field::IsUninitialized() const { |
| 5957 const Instance& value = Instance::Handle(raw_ptr()->value_); | 5982 const Instance& value = Instance::Handle(raw_ptr()->value_); |
| 5958 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 5983 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
| 5959 return value.raw() == Object::sentinel().raw(); | 5984 return value.raw() == Object::sentinel().raw(); |
| 5960 } | 5985 } |
| 5961 | 5986 |
| 5962 | 5987 |
| 5963 void Field::UpdateCid(intptr_t cid) const { | 5988 static intptr_t GetListLength(const Object& value) { |
| 5989 const intptr_t cid = value.GetClassId(); | |
| 5990 ASSERT(RawObject::IsBuiltinListClassId(cid)); | |
| 5991 // Extract list length. | |
| 5992 if (value.IsTypedData()) { | |
| 5993 const TypedData& list = TypedData::Cast(value); | |
| 5994 return list.Length(); | |
| 5995 } else if (value.IsArray()) { | |
| 5996 const Array& list = Array::Cast(value); | |
| 5997 return list.Length(); | |
| 5998 } else if (value.IsGrowableObjectArray()) { | |
| 5999 // List length is variable. | |
| 6000 return Field::kNoFixedLength; | |
| 6001 } else if (value.IsExternalTypedData()) { | |
| 6002 // TODO(johnmccutchan): Enable for external typed data. | |
| 6003 return Field::kNoFixedLength; | |
| 6004 } else if (RawObject::IsTypedDataViewClassId(cid)) { | |
| 6005 // TODO(johnmccutchan): Enable for typed data views. | |
| 6006 return Field::kNoFixedLength; | |
| 6007 } | |
| 6008 UNIMPLEMENTED(); | |
| 6009 return Field::kNoFixedLength; | |
| 6010 } | |
| 6011 | |
| 6012 | |
| 6013 bool Field::UpdateGuardedCidAndLength(const Object& value) const { | |
| 6014 const intptr_t cid = value.GetClassId(); | |
| 6015 bool deoptimize = UpdateCid(cid); | |
| 6016 intptr_t list_length = Field::kNoFixedLength; | |
| 6017 if ((guarded_cid() != kDynamicCid) && | |
| 6018 is_final() && RawObject::IsBuiltinListClassId(cid)) { | |
| 6019 list_length = GetListLength(value); | |
| 6020 } | |
| 6021 deoptimize = UpdateLength(list_length) || deoptimize; | |
| 6022 if (deoptimize) { | |
| 6023 DeoptimizeDependentCode(); | |
| 6024 } | |
| 6025 return deoptimize; | |
| 6026 } | |
| 6027 | |
| 6028 | |
| 6029 bool Field::UpdateCid(intptr_t cid) const { | |
| 5964 if (guarded_cid() == kIllegalCid) { | 6030 if (guarded_cid() == kIllegalCid) { |
| 5965 // Field is assigned first time. | 6031 // Field is assigned first time. |
| 5966 set_guarded_cid(cid); | 6032 set_guarded_cid(cid); |
| 5967 set_is_nullable(cid == kNullCid); | 6033 set_is_nullable(cid == kNullCid); |
| 5968 return; | 6034 return false; |
| 5969 } | 6035 } |
| 5970 | 6036 |
| 5971 if ((cid == guarded_cid()) || ((cid == kNullCid) && is_nullable())) { | 6037 if ((cid == guarded_cid()) || ((cid == kNullCid) && is_nullable())) { |
| 5972 // Class id of the assigned value matches expected class id and nullability. | 6038 // Class id of the assigned value matches expected class id and nullability. |
| 5973 return; | 6039 return false; |
| 5974 } | 6040 } |
| 5975 | 6041 |
| 5976 if ((cid == kNullCid) && !is_nullable()) { | 6042 if ((cid == kNullCid) && !is_nullable()) { |
| 5977 // Assigning null value to a non-nullable field makes it nullable. | 6043 // Assigning null value to a non-nullable field makes it nullable. |
| 5978 set_is_nullable(true); | 6044 set_is_nullable(true); |
| 5979 } else if ((cid != kNullCid) && (guarded_cid() == kNullCid)) { | 6045 } else if ((cid != kNullCid) && (guarded_cid() == kNullCid)) { |
| 5980 // Assigning non-null value to a field that previously contained only null | 6046 // Assigning non-null value to a field that previously contained only null |
| 5981 // turns it into a nullable field with the given class id. | 6047 // turns it into a nullable field with the given class id. |
| 5982 ASSERT(is_nullable()); | 6048 ASSERT(is_nullable()); |
| 5983 set_guarded_cid(cid); | 6049 set_guarded_cid(cid); |
| 5984 } else { | 6050 } else { |
| 5985 // Give up on tracking class id of values contained in this field. | 6051 // Give up on tracking class id of values contained in this field. |
| 5986 ASSERT(guarded_cid() != cid); | 6052 ASSERT(guarded_cid() != cid); |
| 5987 set_guarded_cid(kDynamicCid); | 6053 set_guarded_cid(kDynamicCid); |
| 5988 set_is_nullable(true); | 6054 set_is_nullable(true); |
| 5989 } | 6055 } |
| 5990 | 6056 |
| 5991 // Expected class id or nullability of the field changed. | 6057 // Expected class id or nullability of the field changed. |
| 5992 DeoptimizeDependentCode(); | 6058 return true; |
| 5993 } | 6059 } |
| 5994 | 6060 |
| 5995 | 6061 |
| 5996 void Field::UpdateLength(intptr_t list_length) const { | 6062 bool Field::UpdateLength(intptr_t list_length) const { |
| 5997 ASSERT(is_final() || (!is_final() && | 6063 ASSERT(is_final() || (!is_final() && |
| 5998 (list_length < Field::kUnknownFixedLength))); | 6064 (list_length < Field::kUnknownFixedLength))); |
| 5999 ASSERT((list_length == Field::kNoFixedLength) || | 6065 ASSERT((list_length == Field::kNoFixedLength) || |
| 6000 (list_length > Field::kUnknownFixedLength)); | 6066 (list_length > Field::kUnknownFixedLength)); |
| 6001 ASSERT(guarded_cid() != kIllegalCid); | 6067 ASSERT(guarded_cid() != kIllegalCid); |
| 6002 | 6068 |
| 6003 const bool force_invalidate = (guarded_cid() == kDynamicCid) && | 6069 const bool force_invalidate = (guarded_cid() == kDynamicCid) && |
| 6004 (list_length != Field::kNoFixedLength); | 6070 (list_length != Field::kNoFixedLength); |
| 6005 | 6071 |
| 6006 const bool list_length_unknown = | 6072 const bool list_length_unknown = |
| 6007 (guarded_list_length() == Field::kUnknownFixedLength); | 6073 (guarded_list_length() == Field::kUnknownFixedLength); |
| 6008 const bool list_length_changed = (guarded_list_length() != list_length); | 6074 const bool list_length_changed = (guarded_list_length() != list_length); |
| 6009 | 6075 |
| 6010 if (list_length_unknown && list_length_changed && !force_invalidate) { | 6076 if (list_length_unknown && list_length_changed && !force_invalidate) { |
| 6011 // List length set for first time. | 6077 // List length set for first time. |
| 6012 set_guarded_list_length(list_length); | 6078 set_guarded_list_length(list_length); |
| 6013 return; | 6079 return false; |
| 6014 } | 6080 } |
| 6015 | 6081 |
| 6016 if (!list_length_changed && !force_invalidate) { | 6082 if (!list_length_changed && !force_invalidate) { |
| 6017 // List length unchanged. | 6083 // List length unchanged. |
| 6018 return; | 6084 return false; |
| 6019 } | 6085 } |
| 6020 // Multiple list lengths assigned here, stop tracking length. | 6086 // Multiple list lengths assigned here, stop tracking length. |
| 6021 set_guarded_list_length(Field::kNoFixedLength); | 6087 set_guarded_list_length(Field::kNoFixedLength); |
| 6022 DeoptimizeDependentCode(); | 6088 return true; |
| 6023 } | 6089 } |
| 6024 | 6090 |
| 6025 | 6091 |
| 6026 void LiteralToken::set_literal(const String& literal) const { | 6092 void LiteralToken::set_literal(const String& literal) const { |
| 6027 StorePointer(&raw_ptr()->literal_, literal.raw()); | 6093 StorePointer(&raw_ptr()->literal_, literal.raw()); |
| 6028 } | 6094 } |
| 6029 | 6095 |
| 6030 | 6096 |
| 6031 void LiteralToken::set_value(const Object& value) const { | 6097 void LiteralToken::set_value(const Object& value) const { |
| 6032 StorePointer(&raw_ptr()->value_, value.raw()); | 6098 StorePointer(&raw_ptr()->value_, value.raw()); |
| (...skipping 9563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15596 return "_MirrorReference"; | 15662 return "_MirrorReference"; |
| 15597 } | 15663 } |
| 15598 | 15664 |
| 15599 | 15665 |
| 15600 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 15666 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 15601 JSONObject jsobj(stream); | 15667 JSONObject jsobj(stream); |
| 15602 } | 15668 } |
| 15603 | 15669 |
| 15604 | 15670 |
| 15605 } // namespace dart | 15671 } // namespace dart |
| OLD | NEW |