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 |