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 3190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3201 // Compute the new index for new field. | 3201 // Compute the new index for new field. |
3202 int index = map->NextFreePropertyIndex(); | 3202 int index = map->NextFreePropertyIndex(); |
3203 | 3203 |
3204 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { | 3204 if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) { |
3205 representation = Representation::Tagged(); | 3205 representation = Representation::Tagged(); |
3206 type = FieldType::Any(isolate); | 3206 type = FieldType::Any(isolate); |
3207 } | 3207 } |
3208 | 3208 |
3209 Handle<Object> wrapped_type(WrapType(type)); | 3209 Handle<Object> wrapped_type(WrapType(type)); |
3210 | 3210 |
3211 DataDescriptor new_field_desc(name, index, wrapped_type, attributes, | 3211 Descriptor d = Descriptor::DataField(name, index, wrapped_type, attributes, |
3212 representation); | 3212 representation); |
3213 Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); | 3213 Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag); |
3214 int unused_property_fields = new_map->unused_property_fields() - 1; | 3214 int unused_property_fields = new_map->unused_property_fields() - 1; |
3215 if (unused_property_fields < 0) { | 3215 if (unused_property_fields < 0) { |
3216 unused_property_fields += JSObject::kFieldsAdded; | 3216 unused_property_fields += JSObject::kFieldsAdded; |
3217 } | 3217 } |
3218 new_map->set_unused_property_fields(unused_property_fields); | 3218 new_map->set_unused_property_fields(unused_property_fields); |
3219 return new_map; | 3219 return new_map; |
3220 } | 3220 } |
3221 | 3221 |
3222 | 3222 |
3223 MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map, | 3223 MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map, |
3224 Handle<Name> name, | 3224 Handle<Name> name, |
3225 Handle<Object> constant, | 3225 Handle<Object> constant, |
3226 PropertyAttributes attributes, | 3226 PropertyAttributes attributes, |
3227 TransitionFlag flag) { | 3227 TransitionFlag flag) { |
3228 // Ensure the descriptor array does not get too big. | 3228 // Ensure the descriptor array does not get too big. |
3229 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 3229 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
3230 return MaybeHandle<Map>(); | 3230 return MaybeHandle<Map>(); |
3231 } | 3231 } |
3232 | 3232 |
3233 // Allocate new instance descriptors with (name, constant) added. | 3233 // Allocate new instance descriptors with (name, constant) added. |
3234 DataConstantDescriptor new_constant_desc(name, constant, attributes); | 3234 Descriptor d = Descriptor::DataConstant(name, constant, attributes); |
3235 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); | 3235 return Map::CopyAddDescriptor(map, &d, flag); |
3236 } | 3236 } |
3237 | 3237 |
3238 const char* Representation::Mnemonic() const { | 3238 const char* Representation::Mnemonic() const { |
3239 switch (kind_) { | 3239 switch (kind_) { |
3240 case kNone: return "v"; | 3240 case kNone: return "v"; |
3241 case kTagged: return "t"; | 3241 case kTagged: return "t"; |
3242 case kSmi: return "s"; | 3242 case kSmi: return "s"; |
3243 case kDouble: return "d"; | 3243 case kDouble: return "d"; |
3244 case kInteger32: return "i"; | 3244 case kInteger32: return "i"; |
3245 case kHeapObject: return "h"; | 3245 case kHeapObject: return "h"; |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3764 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, | 3764 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, |
3765 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); | 3765 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); |
3766 | 3766 |
3767 // Unless the instance is being migrated, ensure that modify_index is a field. | 3767 // Unless the instance is being migrated, ensure that modify_index is a field. |
3768 if (modify_index >= 0) { | 3768 if (modify_index >= 0) { |
3769 PropertyDetails details = descriptors->GetDetails(modify_index); | 3769 PropertyDetails details = descriptors->GetDetails(modify_index); |
3770 if (store_mode == FORCE_FIELD && | 3770 if (store_mode == FORCE_FIELD && |
3771 (details.type() != DATA || details.attributes() != attributes)) { | 3771 (details.type() != DATA || details.attributes() != attributes)) { |
3772 int field_index = details.type() == DATA ? details.field_index() | 3772 int field_index = details.type() == DATA ? details.field_index() |
3773 : new_map->NumberOfFields(); | 3773 : new_map->NumberOfFields(); |
3774 DataDescriptor d(handle(descriptors->GetKey(modify_index), isolate), | 3774 Descriptor d = Descriptor::DataField( |
3775 field_index, attributes, Representation::Tagged()); | 3775 handle(descriptors->GetKey(modify_index), isolate), field_index, |
| 3776 attributes, Representation::Tagged()); |
3776 descriptors->Replace(modify_index, &d); | 3777 descriptors->Replace(modify_index, &d); |
3777 if (details.type() != DATA) { | 3778 if (details.type() != DATA) { |
3778 int unused_property_fields = new_map->unused_property_fields() - 1; | 3779 int unused_property_fields = new_map->unused_property_fields() - 1; |
3779 if (unused_property_fields < 0) { | 3780 if (unused_property_fields < 0) { |
3780 unused_property_fields += JSObject::kFieldsAdded; | 3781 unused_property_fields += JSObject::kFieldsAdded; |
3781 } | 3782 } |
3782 new_map->set_unused_property_fields(unused_property_fields); | 3783 new_map->set_unused_property_fields(unused_property_fields); |
3783 } | 3784 } |
3784 } else { | 3785 } else { |
3785 DCHECK(details.attributes() == attributes); | 3786 DCHECK(details.attributes() == attributes); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3950 } | 3951 } |
3951 DescriptorArray* descriptors = current->instance_descriptors(); | 3952 DescriptorArray* descriptors = current->instance_descriptors(); |
3952 PropertyDetails details = descriptors->GetDetails(descriptor); | 3953 PropertyDetails details = descriptors->GetDetails(descriptor); |
3953 | 3954 |
3954 // It is allowed to change representation here only from None to something. | 3955 // It is allowed to change representation here only from None to something. |
3955 DCHECK(details.representation().Equals(new_representation) || | 3956 DCHECK(details.representation().Equals(new_representation) || |
3956 details.representation().IsNone()); | 3957 details.representation().IsNone()); |
3957 | 3958 |
3958 // Skip if already updated the shared descriptor. | 3959 // Skip if already updated the shared descriptor. |
3959 if (descriptors->GetValue(descriptor) != *new_wrapped_type) { | 3960 if (descriptors->GetValue(descriptor) != *new_wrapped_type) { |
3960 DataDescriptor d(name, descriptors->GetFieldIndex(descriptor), | 3961 Descriptor d = Descriptor::DataField( |
3961 new_wrapped_type, details.attributes(), | 3962 name, descriptors->GetFieldIndex(descriptor), new_wrapped_type, |
3962 new_representation); | 3963 details.attributes(), new_representation); |
3963 descriptors->Replace(descriptor, &d); | 3964 descriptors->Replace(descriptor, &d); |
3964 } | 3965 } |
3965 } | 3966 } |
3966 } | 3967 } |
3967 | 3968 |
3968 bool FieldTypeIsCleared(Representation rep, FieldType* type) { | 3969 bool FieldTypeIsCleared(Representation rep, FieldType* type) { |
3969 return type->IsNone() && rep.IsHeapObject(); | 3970 return type->IsNone() && rep.IsHeapObject(); |
3970 } | 3971 } |
3971 | 3972 |
3972 | 3973 |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4425 } | 4426 } |
4426 } else { | 4427 } else { |
4427 Handle<FieldType> old_field_type = | 4428 Handle<FieldType> old_field_type = |
4428 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 4429 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
4429 next_representation); | 4430 next_representation); |
4430 next_field_type = GeneralizeFieldType( | 4431 next_field_type = GeneralizeFieldType( |
4431 old_details.representation(), old_field_type, next_representation, | 4432 old_details.representation(), old_field_type, next_representation, |
4432 target_field_type, isolate); | 4433 target_field_type, isolate); |
4433 } | 4434 } |
4434 Handle<Object> wrapped_type(WrapType(next_field_type)); | 4435 Handle<Object> wrapped_type(WrapType(next_field_type)); |
4435 DataDescriptor d(target_key, current_offset, wrapped_type, | 4436 Descriptor d = |
4436 next_attributes, next_representation); | 4437 Descriptor::DataField(target_key, current_offset, wrapped_type, |
| 4438 next_attributes, next_representation); |
4437 current_offset += d.GetDetails().field_width_in_words(); | 4439 current_offset += d.GetDetails().field_width_in_words(); |
4438 new_descriptors->Set(i, &d); | 4440 new_descriptors->Set(i, &d); |
4439 } else { | 4441 } else { |
4440 UNIMPLEMENTED(); // TODO(ishell): implement. | 4442 UNIMPLEMENTED(); // TODO(ishell): implement. |
4441 } | 4443 } |
4442 } else { | 4444 } else { |
4443 PropertyDetails details(next_attributes, next_kind, next_location, | 4445 PropertyDetails details(next_attributes, next_kind, next_location, |
4444 next_representation); | 4446 next_representation); |
4445 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), | 4447 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), |
4446 details); | 4448 details); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4496 } | 4498 } |
4497 } else { | 4499 } else { |
4498 Handle<FieldType> old_field_type = | 4500 Handle<FieldType> old_field_type = |
4499 GetFieldType(isolate, old_descriptors, i, old_details.location(), | 4501 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
4500 next_representation); | 4502 next_representation); |
4501 next_field_type = old_field_type; | 4503 next_field_type = old_field_type; |
4502 } | 4504 } |
4503 | 4505 |
4504 Handle<Object> wrapped_type(WrapType(next_field_type)); | 4506 Handle<Object> wrapped_type(WrapType(next_field_type)); |
4505 | 4507 |
4506 DataDescriptor d(old_key, current_offset, wrapped_type, next_attributes, | 4508 Descriptor d = |
4507 next_representation); | 4509 Descriptor::DataField(old_key, current_offset, wrapped_type, |
| 4510 next_attributes, next_representation); |
4508 current_offset += d.GetDetails().field_width_in_words(); | 4511 current_offset += d.GetDetails().field_width_in_words(); |
4509 new_descriptors->Set(i, &d); | 4512 new_descriptors->Set(i, &d); |
4510 } else { | 4513 } else { |
4511 UNIMPLEMENTED(); // TODO(ishell): implement. | 4514 UNIMPLEMENTED(); // TODO(ishell): implement. |
4512 } | 4515 } |
4513 } else { | 4516 } else { |
4514 PropertyDetails details(next_attributes, next_kind, next_location, | 4517 PropertyDetails details(next_attributes, next_kind, next_location, |
4515 next_representation); | 4518 next_representation); |
4516 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), | 4519 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), |
4517 details); | 4520 details); |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5199 int valid_descriptors, | 5202 int valid_descriptors, |
5200 Handle<DescriptorArray> array) { | 5203 Handle<DescriptorArray> array) { |
5201 DisallowHeapAllocation no_gc; | 5204 DisallowHeapAllocation no_gc; |
5202 return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound; | 5205 return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound; |
5203 } | 5206 } |
5204 static void Insert(Handle<Name> key, | 5207 static void Insert(Handle<Name> key, |
5205 Handle<AccessorInfo> entry, | 5208 Handle<AccessorInfo> entry, |
5206 int valid_descriptors, | 5209 int valid_descriptors, |
5207 Handle<DescriptorArray> array) { | 5210 Handle<DescriptorArray> array) { |
5208 DisallowHeapAllocation no_gc; | 5211 DisallowHeapAllocation no_gc; |
5209 AccessorConstantDescriptor desc(key, entry, entry->property_attributes()); | 5212 Descriptor d = |
5210 array->Append(&desc); | 5213 Descriptor::AccessorConstant(key, entry, entry->property_attributes()); |
| 5214 array->Append(&d); |
5211 } | 5215 } |
5212 }; | 5216 }; |
5213 | 5217 |
5214 | 5218 |
5215 struct FixedArrayAppender { | 5219 struct FixedArrayAppender { |
5216 typedef FixedArray Array; | 5220 typedef FixedArray Array; |
5217 static bool Contains(Handle<Name> key, | 5221 static bool Contains(Handle<Name> key, |
5218 Handle<AccessorInfo> entry, | 5222 Handle<AccessorInfo> entry, |
5219 int valid_descriptors, | 5223 int valid_descriptors, |
5220 Handle<FixedArray> array) { | 5224 Handle<FixedArray> array) { |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6166 CHECK(k->IsUniqueName()); | 6170 CHECK(k->IsUniqueName()); |
6167 Handle<Name> key(Name::cast(k), isolate); | 6171 Handle<Name> key(Name::cast(k), isolate); |
6168 | 6172 |
6169 Object* value = dictionary->ValueAt(index); | 6173 Object* value = dictionary->ValueAt(index); |
6170 | 6174 |
6171 PropertyDetails details = dictionary->DetailsAt(index); | 6175 PropertyDetails details = dictionary->DetailsAt(index); |
6172 int enumeration_index = details.dictionary_index(); | 6176 int enumeration_index = details.dictionary_index(); |
6173 PropertyType type = details.type(); | 6177 PropertyType type = details.type(); |
6174 | 6178 |
6175 if (value->IsJSFunction()) { | 6179 if (value->IsJSFunction()) { |
6176 DataConstantDescriptor d(key, handle(value, isolate), | 6180 Descriptor d = Descriptor::DataConstant(key, handle(value, isolate), |
6177 details.attributes()); | 6181 details.attributes()); |
6178 descriptors->Set(enumeration_index - 1, &d); | 6182 descriptors->Set(enumeration_index - 1, &d); |
6179 } else if (type == DATA) { | 6183 } else if (type == DATA) { |
6180 if (current_offset < inobject_props) { | 6184 if (current_offset < inobject_props) { |
6181 object->InObjectPropertyAtPut(current_offset, value, | 6185 object->InObjectPropertyAtPut(current_offset, value, |
6182 UPDATE_WRITE_BARRIER); | 6186 UPDATE_WRITE_BARRIER); |
6183 } else { | 6187 } else { |
6184 int offset = current_offset - inobject_props; | 6188 int offset = current_offset - inobject_props; |
6185 fields->set(offset, value); | 6189 fields->set(offset, value); |
6186 } | 6190 } |
6187 DataDescriptor d(key, current_offset, details.attributes(), | 6191 Descriptor d = Descriptor::DataField( |
6188 // TODO(verwaest): value->OptimalRepresentation(); | 6192 key, current_offset, details.attributes(), |
6189 Representation::Tagged()); | 6193 // TODO(verwaest): value->OptimalRepresentation(); |
| 6194 Representation::Tagged()); |
6190 current_offset += d.GetDetails().field_width_in_words(); | 6195 current_offset += d.GetDetails().field_width_in_words(); |
6191 descriptors->Set(enumeration_index - 1, &d); | 6196 descriptors->Set(enumeration_index - 1, &d); |
6192 } else if (type == ACCESSOR_CONSTANT) { | 6197 } else if (type == ACCESSOR_CONSTANT) { |
6193 AccessorConstantDescriptor d(key, handle(value, isolate), | 6198 Descriptor d = Descriptor::AccessorConstant(key, handle(value, isolate), |
6194 details.attributes()); | 6199 details.attributes()); |
6195 descriptors->Set(enumeration_index - 1, &d); | 6200 descriptors->Set(enumeration_index - 1, &d); |
6196 } else { | 6201 } else { |
6197 UNREACHABLE(); | 6202 UNREACHABLE(); |
6198 } | 6203 } |
6199 } | 6204 } |
6200 DCHECK(current_offset == number_of_fields); | 6205 DCHECK(current_offset == number_of_fields); |
6201 | 6206 |
6202 descriptors->Sort(); | 6207 descriptors->Sort(); |
6203 | 6208 |
6204 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( | 6209 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( |
(...skipping 3584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9789 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || | 9794 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || |
9790 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { | 9795 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { |
9791 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); | 9796 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); |
9792 } else { | 9797 } else { |
9793 pair = isolate->factory()->NewAccessorPair(); | 9798 pair = isolate->factory()->NewAccessorPair(); |
9794 } | 9799 } |
9795 | 9800 |
9796 pair->SetComponents(*getter, *setter); | 9801 pair->SetComponents(*getter, *setter); |
9797 | 9802 |
9798 TransitionFlag flag = INSERT_TRANSITION; | 9803 TransitionFlag flag = INSERT_TRANSITION; |
9799 AccessorConstantDescriptor new_desc(name, pair, attributes); | 9804 Descriptor d = Descriptor::AccessorConstant(name, pair, attributes); |
9800 return Map::CopyInsertDescriptor(map, &new_desc, flag); | 9805 return Map::CopyInsertDescriptor(map, &d, flag); |
9801 } | 9806 } |
9802 | 9807 |
9803 | 9808 |
9804 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, | 9809 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
9805 Descriptor* descriptor, | 9810 Descriptor* descriptor, |
9806 TransitionFlag flag) { | 9811 TransitionFlag flag) { |
9807 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 9812 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
9808 | 9813 |
9809 // Share descriptors only if map owns descriptors and it not an initial map. | 9814 // Share descriptors only if map owns descriptors and it not an initial map. |
9810 if (flag == INSERT_TRANSITION && map->owns_descriptors() && | 9815 if (flag == INSERT_TRANSITION && map->owns_descriptors() && |
(...skipping 10634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20445 // depend on this. | 20450 // depend on this. |
20446 return DICTIONARY_ELEMENTS; | 20451 return DICTIONARY_ELEMENTS; |
20447 } | 20452 } |
20448 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20453 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20449 return kind; | 20454 return kind; |
20450 } | 20455 } |
20451 } | 20456 } |
20452 | 20457 |
20453 } // namespace internal | 20458 } // namespace internal |
20454 } // namespace v8 | 20459 } // namespace v8 |
OLD | NEW |