| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 3350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3361 // Compute the new index for new field. | 3361 // Compute the new index for new field. |
| 3362 int index = map->NextFreePropertyIndex(); | 3362 int index = map->NextFreePropertyIndex(); |
| 3363 | 3363 |
| 3364 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | 3364 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
| 3365 representation = Representation::Tagged(); | 3365 representation = Representation::Tagged(); |
| 3366 type = FieldType::Any(isolate); | 3366 type = FieldType::Any(isolate); |
| 3367 } | 3367 } |
| 3368 | 3368 |
| 3369 Handle<Object> wrapped_type(WrapFieldType(type)); | 3369 Handle<Object> wrapped_type(WrapFieldType(type)); |
| 3370 | 3370 |
| 3371 Descriptor d = Descriptor::DataField(name, index, wrapped_type, attributes, | 3371 Descriptor d = Descriptor::DataField(name, index, attributes, kMutable, |
| 3372 representation); | 3372 representation, wrapped_type); |
| 3373 Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag); | 3373 Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag); |
| 3374 int unused_property_fields = new_map->unused_property_fields() - 1; | 3374 int unused_property_fields = new_map->unused_property_fields() - 1; |
| 3375 if (unused_property_fields < 0) { | 3375 if (unused_property_fields < 0) { |
| 3376 unused_property_fields += JSObject::kFieldsAdded; | 3376 unused_property_fields += JSObject::kFieldsAdded; |
| 3377 } | 3377 } |
| 3378 new_map->set_unused_property_fields(unused_property_fields); | 3378 new_map->set_unused_property_fields(unused_property_fields); |
| 3379 return new_map; | 3379 return new_map; |
| 3380 } | 3380 } |
| 3381 | 3381 |
| 3382 | 3382 |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4063 DescriptorArray* descriptors = current->instance_descriptors(); | 4063 DescriptorArray* descriptors = current->instance_descriptors(); |
| 4064 PropertyDetails details = descriptors->GetDetails(descriptor); | 4064 PropertyDetails details = descriptors->GetDetails(descriptor); |
| 4065 | 4065 |
| 4066 // It is allowed to change representation here only from None to something. | 4066 // It is allowed to change representation here only from None to something. |
| 4067 DCHECK(details.representation().Equals(new_representation) || | 4067 DCHECK(details.representation().Equals(new_representation) || |
| 4068 details.representation().IsNone()); | 4068 details.representation().IsNone()); |
| 4069 | 4069 |
| 4070 // Skip if already updated the shared descriptor. | 4070 // Skip if already updated the shared descriptor. |
| 4071 if (descriptors->GetValue(descriptor) != *new_wrapped_type) { | 4071 if (descriptors->GetValue(descriptor) != *new_wrapped_type) { |
| 4072 Descriptor d = Descriptor::DataField( | 4072 Descriptor d = Descriptor::DataField( |
| 4073 name, descriptors->GetFieldIndex(descriptor), new_wrapped_type, | 4073 name, descriptors->GetFieldIndex(descriptor), details.attributes(), |
| 4074 details.attributes(), new_representation); | 4074 kMutable, new_representation, new_wrapped_type); |
| 4075 descriptors->Replace(descriptor, &d); | 4075 descriptors->Replace(descriptor, &d); |
| 4076 } | 4076 } |
| 4077 } | 4077 } |
| 4078 } | 4078 } |
| 4079 | 4079 |
| 4080 bool FieldTypeIsCleared(Representation rep, FieldType* type) { | 4080 bool FieldTypeIsCleared(Representation rep, FieldType* type) { |
| 4081 return type->IsNone() && rep.IsHeapObject(); | 4081 return type->IsNone() && rep.IsHeapObject(); |
| 4082 } | 4082 } |
| 4083 | 4083 |
| 4084 | 4084 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4231 Map* transition = TransitionArray::SearchTransition( | 4231 Map* transition = TransitionArray::SearchTransition( |
| 4232 new_map, old_details.kind(), old_descriptors->GetKey(i), | 4232 new_map, old_details.kind(), old_descriptors->GetKey(i), |
| 4233 old_details.attributes()); | 4233 old_details.attributes()); |
| 4234 if (transition == NULL) return nullptr; | 4234 if (transition == NULL) return nullptr; |
| 4235 new_map = transition; | 4235 new_map = transition; |
| 4236 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 4236 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
| 4237 | 4237 |
| 4238 PropertyDetails new_details = new_descriptors->GetDetails(i); | 4238 PropertyDetails new_details = new_descriptors->GetDetails(i); |
| 4239 DCHECK_EQ(old_details.kind(), new_details.kind()); | 4239 DCHECK_EQ(old_details.kind(), new_details.kind()); |
| 4240 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 4240 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
| 4241 if (!IsGeneralizableTo(old_details.constness(), new_details.constness())) { |
| 4242 return nullptr; |
| 4243 } |
| 4244 DCHECK(IsGeneralizableTo(old_details.location(), new_details.location())); |
| 4241 if (!old_details.representation().fits_into(new_details.representation())) { | 4245 if (!old_details.representation().fits_into(new_details.representation())) { |
| 4242 return nullptr; | 4246 return nullptr; |
| 4243 } | 4247 } |
| 4244 if (new_details.location() == kField) { | 4248 if (new_details.location() == kField) { |
| 4245 if (new_details.kind() == kData) { | 4249 if (new_details.kind() == kData) { |
| 4246 FieldType* new_type = new_descriptors->GetFieldType(i); | 4250 FieldType* new_type = new_descriptors->GetFieldType(i); |
| 4247 // Cleared field types need special treatment. They represent lost | 4251 // Cleared field types need special treatment. They represent lost |
| 4248 // knowledge, so we must first generalize the new_type to "Any". | 4252 // knowledge, so we must first generalize the new_type to "Any". |
| 4249 if (FieldTypeIsCleared(new_details.representation(), new_type)) { | 4253 if (FieldTypeIsCleared(new_details.representation(), new_type)) { |
| 4250 return nullptr; | 4254 return nullptr; |
| (...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5748 Object* k = dictionary->KeyAt(index); | 5752 Object* k = dictionary->KeyAt(index); |
| 5749 DCHECK(dictionary->IsKey(k)); | 5753 DCHECK(dictionary->IsKey(k)); |
| 5750 // Dictionary keys are internalized upon insertion. | 5754 // Dictionary keys are internalized upon insertion. |
| 5751 // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild. | 5755 // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild. |
| 5752 CHECK(k->IsUniqueName()); | 5756 CHECK(k->IsUniqueName()); |
| 5753 Handle<Name> key(Name::cast(k), isolate); | 5757 Handle<Name> key(Name::cast(k), isolate); |
| 5754 | 5758 |
| 5755 Object* value = dictionary->ValueAt(index); | 5759 Object* value = dictionary->ValueAt(index); |
| 5756 | 5760 |
| 5757 PropertyDetails details = dictionary->DetailsAt(index); | 5761 PropertyDetails details = dictionary->DetailsAt(index); |
| 5762 DCHECK_EQ(kField, details.location()); |
| 5763 DCHECK_EQ(kMutable, details.constness()); |
| 5758 int enumeration_index = details.dictionary_index(); | 5764 int enumeration_index = details.dictionary_index(); |
| 5759 | 5765 |
| 5760 Descriptor d; | 5766 Descriptor d; |
| 5761 if (details.kind() == kData) { | 5767 if (details.kind() == kData) { |
| 5762 if (value->IsJSFunction()) { | 5768 if (value->IsJSFunction()) { |
| 5763 d = Descriptor::DataConstant(key, handle(value, isolate), | 5769 d = Descriptor::DataConstant(key, handle(value, isolate), |
| 5764 details.attributes()); | 5770 details.attributes()); |
| 5765 } else { | 5771 } else { |
| 5766 d = Descriptor::DataField( | 5772 d = Descriptor::DataField( |
| 5767 key, current_offset, details.attributes(), | 5773 key, current_offset, details.attributes(), |
| (...skipping 3358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9126 new_map->set_elements_kind(new_kind); | 9132 new_map->set_elements_kind(new_kind); |
| 9127 } | 9133 } |
| 9128 return new_map; | 9134 return new_map; |
| 9129 } | 9135 } |
| 9130 | 9136 |
| 9131 namespace { | 9137 namespace { |
| 9132 | 9138 |
| 9133 bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) { | 9139 bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) { |
| 9134 PropertyDetails details = descriptors->GetDetails(descriptor); | 9140 PropertyDetails details = descriptors->GetDetails(descriptor); |
| 9135 if (details.location() == kField) { | 9141 if (details.location() == kField) { |
| 9142 DCHECK_EQ(kMutable, details.constness()); |
| 9136 if (details.kind() == kData) { | 9143 if (details.kind() == kData) { |
| 9137 return value->FitsRepresentation(details.representation()) && | 9144 return value->FitsRepresentation(details.representation()) && |
| 9138 descriptors->GetFieldType(descriptor)->NowContains(value); | 9145 descriptors->GetFieldType(descriptor)->NowContains(value); |
| 9139 } else { | 9146 } else { |
| 9140 DCHECK_EQ(kAccessor, details.kind()); | 9147 DCHECK_EQ(kAccessor, details.kind()); |
| 9141 UNREACHABLE(); | 9148 UNREACHABLE(); |
| 9142 return false; | 9149 return false; |
| 9143 } | 9150 } |
| 9144 | 9151 |
| 9145 } else { | 9152 } else { |
| 9146 DCHECK_EQ(kDescriptor, details.location()); | 9153 DCHECK_EQ(kDescriptor, details.location()); |
| 9154 DCHECK_EQ(kConst, details.constness()); |
| 9147 if (details.kind() == kData) { | 9155 if (details.kind() == kData) { |
| 9148 DCHECK(descriptors->GetValue(descriptor) != value || | 9156 DCHECK(descriptors->GetValue(descriptor) != value || |
| 9149 value->FitsRepresentation(details.representation())); | 9157 value->FitsRepresentation(details.representation())); |
| 9150 return descriptors->GetValue(descriptor) == value; | 9158 return descriptors->GetValue(descriptor) == value; |
| 9151 } else { | 9159 } else { |
| 9152 DCHECK_EQ(kAccessor, details.kind()); | 9160 DCHECK_EQ(kAccessor, details.kind()); |
| 9153 return false; | 9161 return false; |
| 9154 } | 9162 } |
| 9155 } | 9163 } |
| 9156 UNREACHABLE(); | 9164 UNREACHABLE(); |
| (...skipping 10740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19897 // depend on this. | 19905 // depend on this. |
| 19898 return DICTIONARY_ELEMENTS; | 19906 return DICTIONARY_ELEMENTS; |
| 19899 } | 19907 } |
| 19900 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 19908 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 19901 return kind; | 19909 return kind; |
| 19902 } | 19910 } |
| 19903 } | 19911 } |
| 19904 | 19912 |
| 19905 } // namespace internal | 19913 } // namespace internal |
| 19906 } // namespace v8 | 19914 } // namespace v8 |
| OLD | NEW |