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 2844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2855 os << "{symbol " << static_cast<void*>(name) << "}"; | 2855 os << "{symbol " << static_cast<void*>(name) << "}"; |
2856 } | 2856 } |
2857 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; | 2857 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; |
2858 os << attributes << " ["; | 2858 os << attributes << " ["; |
2859 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | 2859 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
2860 os << "]\n"; | 2860 os << "]\n"; |
2861 } | 2861 } |
2862 | 2862 |
2863 void Map::PrintGeneralization( | 2863 void Map::PrintGeneralization( |
2864 FILE* file, const char* reason, int modify_index, int split, | 2864 FILE* file, const char* reason, int modify_index, int split, |
2865 int descriptors, bool constant_to_field, Representation old_representation, | 2865 int descriptors, bool descriptor_to_field, |
2866 Representation new_representation, MaybeHandle<FieldType> old_field_type, | 2866 Representation old_representation, Representation new_representation, |
2867 MaybeHandle<Object> old_value, MaybeHandle<FieldType> new_field_type, | 2867 MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value, |
2868 MaybeHandle<Object> new_value) { | 2868 MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value) { |
2869 OFStream os(file); | 2869 OFStream os(file); |
2870 os << "[generalizing]"; | 2870 os << "[generalizing]"; |
2871 Name* name = instance_descriptors()->GetKey(modify_index); | 2871 Name* name = instance_descriptors()->GetKey(modify_index); |
2872 if (name->IsString()) { | 2872 if (name->IsString()) { |
2873 String::cast(name)->PrintOn(file); | 2873 String::cast(name)->PrintOn(file); |
2874 } else { | 2874 } else { |
2875 os << "{symbol " << static_cast<void*>(name) << "}"; | 2875 os << "{symbol " << static_cast<void*>(name) << "}"; |
2876 } | 2876 } |
2877 os << ":"; | 2877 os << ":"; |
2878 if (constant_to_field) { | 2878 if (descriptor_to_field) { |
2879 os << "c"; | 2879 os << "c"; |
2880 } else { | 2880 } else { |
2881 os << old_representation.Mnemonic() << "{"; | 2881 os << old_representation.Mnemonic() << "{"; |
2882 if (old_field_type.is_null()) { | 2882 if (old_field_type.is_null()) { |
2883 os << Brief(*(old_value.ToHandleChecked())); | 2883 os << Brief(*(old_value.ToHandleChecked())); |
2884 } else { | 2884 } else { |
2885 old_field_type.ToHandleChecked()->PrintTo(os); | 2885 old_field_type.ToHandleChecked()->PrintTo(os); |
2886 } | 2886 } |
2887 os << "}"; | 2887 os << "}"; |
2888 } | 2888 } |
(...skipping 20 matching lines...) Expand all Loading... |
2909 Map* new_map) { | 2909 Map* new_map) { |
2910 PrintF(file, "[migrating]"); | 2910 PrintF(file, "[migrating]"); |
2911 DescriptorArray* o = original_map->instance_descriptors(); | 2911 DescriptorArray* o = original_map->instance_descriptors(); |
2912 DescriptorArray* n = new_map->instance_descriptors(); | 2912 DescriptorArray* n = new_map->instance_descriptors(); |
2913 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { | 2913 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { |
2914 Representation o_r = o->GetDetails(i).representation(); | 2914 Representation o_r = o->GetDetails(i).representation(); |
2915 Representation n_r = n->GetDetails(i).representation(); | 2915 Representation n_r = n->GetDetails(i).representation(); |
2916 if (!o_r.Equals(n_r)) { | 2916 if (!o_r.Equals(n_r)) { |
2917 String::cast(o->GetKey(i))->PrintOn(file); | 2917 String::cast(o->GetKey(i))->PrintOn(file); |
2918 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); | 2918 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); |
2919 } else if (o->GetDetails(i).type() == DATA_CONSTANT && | 2919 } else if (o->GetDetails(i).location() == kDescriptor && |
2920 n->GetDetails(i).type() == DATA) { | 2920 n->GetDetails(i).location() == kField) { |
2921 Name* name = o->GetKey(i); | 2921 Name* name = o->GetKey(i); |
2922 if (name->IsString()) { | 2922 if (name->IsString()) { |
2923 String::cast(name)->PrintOn(file); | 2923 String::cast(name)->PrintOn(file); |
2924 } else { | 2924 } else { |
2925 PrintF(file, "{symbol %p}", static_cast<void*>(name)); | 2925 PrintF(file, "{symbol %p}", static_cast<void*>(name)); |
2926 } | 2926 } |
2927 PrintF(file, " "); | 2927 PrintF(file, " "); |
2928 } | 2928 } |
2929 } | 2929 } |
2930 PrintF(file, "\n"); | 2930 PrintF(file, "\n"); |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3532 Handle<FixedArray> new_storage = | 3532 Handle<FixedArray> new_storage = |
3533 isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by); | 3533 isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by); |
3534 | 3534 |
3535 // Properly initialize newly added property. | 3535 // Properly initialize newly added property. |
3536 Handle<Object> value; | 3536 Handle<Object> value; |
3537 if (details.representation().IsDouble()) { | 3537 if (details.representation().IsDouble()) { |
3538 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3538 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
3539 } else { | 3539 } else { |
3540 value = isolate->factory()->uninitialized_value(); | 3540 value = isolate->factory()->uninitialized_value(); |
3541 } | 3541 } |
3542 DCHECK_EQ(DATA, details.type()); | 3542 DCHECK_EQ(kField, details.location()); |
3543 int target_index = details.field_index() - new_map->GetInObjectProperties(); | 3543 int target_index = details.field_index() - new_map->GetInObjectProperties(); |
3544 DCHECK(target_index >= 0); // Must be a backing store index. | 3544 DCHECK(target_index >= 0); // Must be a backing store index. |
3545 new_storage->set(target_index, *value); | 3545 new_storage->set(target_index, *value); |
3546 | 3546 |
3547 // From here on we cannot fail and we shouldn't GC anymore. | 3547 // From here on we cannot fail and we shouldn't GC anymore. |
3548 DisallowHeapAllocation no_allocation; | 3548 DisallowHeapAllocation no_allocation; |
3549 | 3549 |
3550 // Set the new property value and do the map transition. | 3550 // Set the new property value and do the map transition. |
3551 object->set_properties(*new_storage); | 3551 object->set_properties(*new_storage); |
3552 object->synchronized_set_map(*new_map); | 3552 object->synchronized_set_map(*new_map); |
(...skipping 22 matching lines...) Expand all Loading... |
3575 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); | 3575 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); |
3576 int old_nof = old_map->NumberOfOwnDescriptors(); | 3576 int old_nof = old_map->NumberOfOwnDescriptors(); |
3577 int new_nof = new_map->NumberOfOwnDescriptors(); | 3577 int new_nof = new_map->NumberOfOwnDescriptors(); |
3578 | 3578 |
3579 // This method only supports generalizing instances to at least the same | 3579 // This method only supports generalizing instances to at least the same |
3580 // number of properties. | 3580 // number of properties. |
3581 DCHECK(old_nof <= new_nof); | 3581 DCHECK(old_nof <= new_nof); |
3582 | 3582 |
3583 for (int i = 0; i < old_nof; i++) { | 3583 for (int i = 0; i < old_nof; i++) { |
3584 PropertyDetails details = new_descriptors->GetDetails(i); | 3584 PropertyDetails details = new_descriptors->GetDetails(i); |
3585 if (details.type() != DATA) continue; | 3585 if (details.location() != kField) continue; |
3586 PropertyDetails old_details = old_descriptors->GetDetails(i); | 3586 PropertyDetails old_details = old_descriptors->GetDetails(i); |
3587 Representation old_representation = old_details.representation(); | 3587 Representation old_representation = old_details.representation(); |
3588 Representation representation = details.representation(); | 3588 Representation representation = details.representation(); |
3589 Handle<Object> value; | 3589 Handle<Object> value; |
3590 if (old_details.type() == ACCESSOR_CONSTANT) { | 3590 if (old_details.location() == kDescriptor) { |
3591 // In case of kAccessor -> kData property reconfiguration, the property | 3591 if (old_details.kind() == kAccessor) { |
3592 // must already be prepared for data or certain type. | 3592 // In case of kAccessor -> kData property reconfiguration, the property |
3593 DCHECK(!details.representation().IsNone()); | 3593 // must already be prepared for data of certain type. |
3594 if (details.representation().IsDouble()) { | 3594 DCHECK(!details.representation().IsNone()); |
3595 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3595 if (details.representation().IsDouble()) { |
| 3596 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 3597 } else { |
| 3598 value = isolate->factory()->uninitialized_value(); |
| 3599 } |
3596 } else { | 3600 } else { |
3597 value = isolate->factory()->uninitialized_value(); | 3601 DCHECK_EQ(kData, old_details.kind()); |
| 3602 value = handle(old_descriptors->GetValue(i), isolate); |
| 3603 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); |
3598 } | 3604 } |
3599 } else if (old_details.type() == DATA_CONSTANT) { | |
3600 value = handle(old_descriptors->GetValue(i), isolate); | |
3601 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); | |
3602 } else { | 3605 } else { |
| 3606 DCHECK_EQ(kField, old_details.location()); |
3603 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); | 3607 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); |
3604 if (object->IsUnboxedDoubleField(index)) { | 3608 if (object->IsUnboxedDoubleField(index)) { |
3605 double old = object->RawFastDoublePropertyAt(index); | 3609 double old = object->RawFastDoublePropertyAt(index); |
3606 value = isolate->factory()->NewHeapNumber( | 3610 value = isolate->factory()->NewHeapNumber( |
3607 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); | 3611 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); |
3608 | 3612 |
3609 } else { | 3613 } else { |
3610 value = handle(object->RawFastPropertyAt(index), isolate); | 3614 value = handle(object->RawFastPropertyAt(index), isolate); |
3611 if (!old_representation.IsDouble() && representation.IsDouble()) { | 3615 if (!old_representation.IsDouble() && representation.IsDouble()) { |
3612 if (old_representation.IsNone()) { | 3616 if (old_representation.IsNone()) { |
3613 value = handle(Smi::kZero, isolate); | 3617 value = handle(Smi::kZero, isolate); |
3614 } | 3618 } |
3615 value = Object::NewStorageFor(isolate, value, representation); | 3619 value = Object::NewStorageFor(isolate, value, representation); |
3616 } else if (old_representation.IsDouble() && | 3620 } else if (old_representation.IsDouble() && |
3617 !representation.IsDouble()) { | 3621 !representation.IsDouble()) { |
3618 value = Object::WrapForRead(isolate, value, old_representation); | 3622 value = Object::WrapForRead(isolate, value, old_representation); |
3619 } | 3623 } |
3620 } | 3624 } |
3621 } | 3625 } |
3622 DCHECK(!(representation.IsDouble() && value->IsSmi())); | 3626 DCHECK(!(representation.IsDouble() && value->IsSmi())); |
3623 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 3627 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
3624 if (target_index < 0) target_index += total_size; | 3628 if (target_index < 0) target_index += total_size; |
3625 array->set(target_index, *value); | 3629 array->set(target_index, *value); |
3626 } | 3630 } |
3627 | 3631 |
3628 for (int i = old_nof; i < new_nof; i++) { | 3632 for (int i = old_nof; i < new_nof; i++) { |
3629 PropertyDetails details = new_descriptors->GetDetails(i); | 3633 PropertyDetails details = new_descriptors->GetDetails(i); |
3630 if (details.type() != DATA) continue; | 3634 if (details.location() != kField) continue; |
3631 Handle<Object> value; | 3635 Handle<Object> value; |
3632 if (details.representation().IsDouble()) { | 3636 if (details.representation().IsDouble()) { |
3633 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3637 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
3634 } else { | 3638 } else { |
3635 value = isolate->factory()->uninitialized_value(); | 3639 value = isolate->factory()->uninitialized_value(); |
3636 } | 3640 } |
3637 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 3641 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
3638 if (target_index < 0) target_index += total_size; | 3642 if (target_index < 0) target_index += total_size; |
3639 array->set(target_index, *value); | 3643 array->set(target_index, *value); |
3640 } | 3644 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3714 // Make space for two more properties. | 3718 // Make space for two more properties. |
3715 property_count += NameDictionary::kInitialCapacity; | 3719 property_count += NameDictionary::kInitialCapacity; |
3716 } | 3720 } |
3717 Handle<NameDictionary> dictionary = | 3721 Handle<NameDictionary> dictionary = |
3718 NameDictionary::New(isolate, property_count); | 3722 NameDictionary::New(isolate, property_count); |
3719 | 3723 |
3720 Handle<DescriptorArray> descs(map->instance_descriptors()); | 3724 Handle<DescriptorArray> descs(map->instance_descriptors()); |
3721 for (int i = 0; i < real_size; i++) { | 3725 for (int i = 0; i < real_size; i++) { |
3722 PropertyDetails details = descs->GetDetails(i); | 3726 PropertyDetails details = descs->GetDetails(i); |
3723 Handle<Name> key(descs->GetKey(i)); | 3727 Handle<Name> key(descs->GetKey(i)); |
3724 switch (details.type()) { | 3728 // TODO(ishell): Simplify the below code. |
3725 case DATA_CONSTANT: { | 3729 if (details.location() == kField) { |
3726 Handle<Object> value(descs->GetConstant(i), isolate); | 3730 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
3727 PropertyDetails d(details.attributes(), DATA, i + 1, | 3731 if (details.kind() == kData) { |
3728 PropertyCellType::kNoCell); | |
3729 dictionary = NameDictionary::Add(dictionary, key, value, d); | |
3730 break; | |
3731 } | |
3732 case DATA: { | |
3733 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | |
3734 Handle<Object> value; | 3732 Handle<Object> value; |
3735 if (object->IsUnboxedDoubleField(index)) { | 3733 if (object->IsUnboxedDoubleField(index)) { |
3736 double old_value = object->RawFastDoublePropertyAt(index); | 3734 double old_value = object->RawFastDoublePropertyAt(index); |
3737 value = isolate->factory()->NewHeapNumber(old_value); | 3735 value = isolate->factory()->NewHeapNumber(old_value); |
3738 } else { | 3736 } else { |
3739 value = handle(object->RawFastPropertyAt(index), isolate); | 3737 value = handle(object->RawFastPropertyAt(index), isolate); |
3740 if (details.representation().IsDouble()) { | 3738 if (details.representation().IsDouble()) { |
3741 DCHECK(value->IsMutableHeapNumber()); | 3739 DCHECK(value->IsMutableHeapNumber()); |
3742 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | 3740 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
3743 value = isolate->factory()->NewHeapNumber(old->value()); | 3741 value = isolate->factory()->NewHeapNumber(old->value()); |
3744 } | 3742 } |
3745 } | 3743 } |
3746 PropertyDetails d(details.attributes(), DATA, i + 1, | 3744 PropertyDetails d(details.attributes(), DATA, i + 1, |
3747 PropertyCellType::kNoCell); | 3745 PropertyCellType::kNoCell); |
3748 dictionary = NameDictionary::Add(dictionary, key, value, d); | 3746 dictionary = NameDictionary::Add(dictionary, key, value, d); |
3749 break; | 3747 |
3750 } | 3748 } else { |
3751 case ACCESSOR: { | 3749 DCHECK_EQ(kAccessor, details.kind()); |
3752 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | |
3753 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 3750 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
3754 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, | 3751 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, |
3755 PropertyCellType::kNoCell); | 3752 PropertyCellType::kNoCell); |
3756 dictionary = NameDictionary::Add(dictionary, key, value, d); | 3753 dictionary = NameDictionary::Add(dictionary, key, value, d); |
3757 break; | |
3758 } | 3754 } |
3759 case ACCESSOR_CONSTANT: { | 3755 |
| 3756 } else { |
| 3757 DCHECK_EQ(kDescriptor, details.location()); |
| 3758 if (details.kind() == kData) { |
| 3759 Handle<Object> value(descs->GetConstant(i), isolate); |
| 3760 PropertyDetails d(details.attributes(), DATA, i + 1, |
| 3761 PropertyCellType::kNoCell); |
| 3762 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 3763 |
| 3764 } else { |
| 3765 DCHECK_EQ(kAccessor, details.kind()); |
3760 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | 3766 Handle<Object> value(descs->GetCallbacksObject(i), isolate); |
3761 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, | 3767 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, |
3762 PropertyCellType::kNoCell); | 3768 PropertyCellType::kNoCell); |
3763 dictionary = NameDictionary::Add(dictionary, key, value, d); | 3769 dictionary = NameDictionary::Add(dictionary, key, value, d); |
3764 break; | |
3765 } | 3770 } |
3766 } | 3771 } |
3767 } | 3772 } |
3768 | 3773 |
3769 // Copy the next enumeration index from instance descriptor. | 3774 // Copy the next enumeration index from instance descriptor. |
3770 dictionary->SetNextEnumerationIndex(real_size + 1); | 3775 dictionary->SetNextEnumerationIndex(real_size + 1); |
3771 | 3776 |
3772 // From here on we cannot fail and we shouldn't GC anymore. | 3777 // From here on we cannot fail and we shouldn't GC anymore. |
3773 DisallowHeapAllocation no_allocation; | 3778 DisallowHeapAllocation no_allocation; |
3774 | 3779 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3896 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes, | 3901 StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes, |
3897 const char* reason) { | 3902 const char* reason) { |
3898 Isolate* isolate = map->GetIsolate(); | 3903 Isolate* isolate = map->GetIsolate(); |
3899 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 3904 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
3900 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 3905 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
3901 Handle<DescriptorArray> descriptors = | 3906 Handle<DescriptorArray> descriptors = |
3902 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 3907 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
3903 | 3908 |
3904 for (int i = 0; i < number_of_own_descriptors; i++) { | 3909 for (int i = 0; i < number_of_own_descriptors; i++) { |
3905 descriptors->SetRepresentation(i, Representation::Tagged()); | 3910 descriptors->SetRepresentation(i, Representation::Tagged()); |
3906 if (descriptors->GetDetails(i).type() == DATA) { | 3911 if (descriptors->GetDetails(i).location() == kField) { |
3907 descriptors->SetValue(i, FieldType::Any()); | 3912 descriptors->SetValue(i, FieldType::Any()); |
3908 } | 3913 } |
3909 } | 3914 } |
3910 | 3915 |
3911 Handle<LayoutDescriptor> new_layout_descriptor( | 3916 Handle<LayoutDescriptor> new_layout_descriptor( |
3912 LayoutDescriptor::FastPointerLayout(), isolate); | 3917 LayoutDescriptor::FastPointerLayout(), isolate); |
3913 Handle<Map> new_map = CopyReplaceDescriptors( | 3918 Handle<Map> new_map = CopyReplaceDescriptors( |
3914 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, | 3919 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, |
3915 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); | 3920 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); |
3916 | 3921 |
3917 // Unless the instance is being migrated, ensure that modify_index is a field. | 3922 // Unless the instance is being migrated, ensure that modify_index is a field. |
3918 if (modify_index >= 0) { | 3923 if (modify_index >= 0) { |
3919 PropertyDetails details = descriptors->GetDetails(modify_index); | 3924 PropertyDetails details = descriptors->GetDetails(modify_index); |
3920 if (store_mode == FORCE_FIELD && | 3925 if (store_mode == FORCE_FIELD && |
3921 (details.type() != DATA || details.attributes() != attributes)) { | 3926 (details.location() != kField || details.attributes() != attributes)) { |
3922 int field_index = details.type() == DATA ? details.field_index() | 3927 int field_index = details.location() == kField |
3923 : new_map->NumberOfFields(); | 3928 ? details.field_index() |
| 3929 : new_map->NumberOfFields(); |
3924 Descriptor d = Descriptor::DataField( | 3930 Descriptor d = Descriptor::DataField( |
3925 handle(descriptors->GetKey(modify_index), isolate), field_index, | 3931 handle(descriptors->GetKey(modify_index), isolate), field_index, |
3926 attributes, Representation::Tagged()); | 3932 attributes, Representation::Tagged()); |
3927 descriptors->Replace(modify_index, &d); | 3933 descriptors->Replace(modify_index, &d); |
3928 if (details.type() != DATA) { | 3934 if (details.location() != kField) { |
3929 int unused_property_fields = new_map->unused_property_fields() - 1; | 3935 int unused_property_fields = new_map->unused_property_fields() - 1; |
3930 if (unused_property_fields < 0) { | 3936 if (unused_property_fields < 0) { |
3931 unused_property_fields += JSObject::kFieldsAdded; | 3937 unused_property_fields += JSObject::kFieldsAdded; |
3932 } | 3938 } |
3933 new_map->set_unused_property_fields(unused_property_fields); | 3939 new_map->set_unused_property_fields(unused_property_fields); |
3934 } | 3940 } |
3935 } else { | 3941 } else { |
3936 DCHECK(details.attributes() == attributes); | 3942 DCHECK(details.attributes() == attributes); |
3937 } | 3943 } |
3938 | 3944 |
3939 if (FLAG_trace_generalization) { | 3945 if (FLAG_trace_generalization) { |
3940 MaybeHandle<FieldType> field_type = FieldType::None(isolate); | 3946 MaybeHandle<FieldType> field_type = FieldType::None(isolate); |
3941 if (details.type() == DATA) { | 3947 if (details.location() == kField) { |
3942 field_type = handle( | 3948 field_type = handle( |
3943 map->instance_descriptors()->GetFieldType(modify_index), isolate); | 3949 map->instance_descriptors()->GetFieldType(modify_index), isolate); |
3944 } | 3950 } |
3945 map->PrintGeneralization( | 3951 map->PrintGeneralization( |
3946 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 3952 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
3947 new_map->NumberOfOwnDescriptors(), | 3953 new_map->NumberOfOwnDescriptors(), |
3948 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 3954 details.location() == kDescriptor && store_mode == FORCE_FIELD, |
3949 details.representation(), Representation::Tagged(), field_type, | 3955 details.representation(), Representation::Tagged(), field_type, |
3950 MaybeHandle<Object>(), FieldType::Any(isolate), | 3956 MaybeHandle<Object>(), FieldType::Any(isolate), |
3951 MaybeHandle<Object>()); | 3957 MaybeHandle<Object>()); |
3952 } | 3958 } |
3953 } | 3959 } |
3954 new_map->set_elements_kind(elements_kind); | 3960 new_map->set_elements_kind(elements_kind); |
3955 return new_map; | 3961 return new_map; |
3956 } | 3962 } |
3957 | 3963 |
3958 | 3964 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4007 result->instance_descriptors()->number_of_descriptors()); | 4013 result->instance_descriptors()->number_of_descriptors()); |
4008 return result; | 4014 return result; |
4009 } | 4015 } |
4010 result = Map::cast(back); | 4016 result = Map::cast(back); |
4011 } | 4017 } |
4012 } | 4018 } |
4013 | 4019 |
4014 | 4020 |
4015 Map* Map::FindFieldOwner(int descriptor) { | 4021 Map* Map::FindFieldOwner(int descriptor) { |
4016 DisallowHeapAllocation no_allocation; | 4022 DisallowHeapAllocation no_allocation; |
4017 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); | 4023 DCHECK_EQ(kField, instance_descriptors()->GetDetails(descriptor).location()); |
4018 Map* result = this; | 4024 Map* result = this; |
4019 Isolate* isolate = GetIsolate(); | 4025 Isolate* isolate = GetIsolate(); |
4020 while (true) { | 4026 while (true) { |
4021 Object* back = result->GetBackPointer(); | 4027 Object* back = result->GetBackPointer(); |
4022 if (back->IsUndefined(isolate)) break; | 4028 if (back->IsUndefined(isolate)) break; |
4023 Map* parent = Map::cast(back); | 4029 Map* parent = Map::cast(back); |
4024 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | 4030 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
4025 result = parent; | 4031 result = parent; |
4026 } | 4032 } |
4027 return result; | 4033 return result; |
4028 } | 4034 } |
4029 | 4035 |
4030 | 4036 |
4031 void Map::UpdateFieldType(int descriptor, Handle<Name> name, | 4037 void Map::UpdateFieldType(int descriptor, Handle<Name> name, |
4032 Representation new_representation, | 4038 Representation new_representation, |
4033 Handle<Object> new_wrapped_type) { | 4039 Handle<Object> new_wrapped_type) { |
4034 DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell()); | 4040 DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell()); |
4035 // We store raw pointers in the queue, so no allocations are allowed. | 4041 // We store raw pointers in the queue, so no allocations are allowed. |
4036 DisallowHeapAllocation no_allocation; | 4042 DisallowHeapAllocation no_allocation; |
4037 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); | 4043 PropertyDetails details = instance_descriptors()->GetDetails(descriptor); |
4038 if (details.type() != DATA) return; | 4044 if (details.location() != kField) return; |
4039 | 4045 |
4040 Zone zone(GetIsolate()->allocator(), ZONE_NAME); | 4046 Zone zone(GetIsolate()->allocator(), ZONE_NAME); |
4041 ZoneQueue<Map*> backlog(&zone); | 4047 ZoneQueue<Map*> backlog(&zone); |
4042 backlog.push(this); | 4048 backlog.push(this); |
4043 | 4049 |
4044 while (!backlog.empty()) { | 4050 while (!backlog.empty()) { |
4045 Map* current = backlog.front(); | 4051 Map* current = backlog.front(); |
4046 backlog.pop(); | 4052 backlog.pop(); |
4047 | 4053 |
4048 Object* transitions = current->raw_transitions(); | 4054 Object* transitions = current->raw_transitions(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4167 | 4173 |
4168 // Generalize the representation of all DATA descriptors. | 4174 // Generalize the representation of all DATA descriptors. |
4169 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 4175 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
4170 Handle<Map> map) { | 4176 Handle<Map> map) { |
4171 Isolate* isolate = map->GetIsolate(); | 4177 Isolate* isolate = map->GetIsolate(); |
4172 Handle<FieldType> any_type = FieldType::Any(isolate); | 4178 Handle<FieldType> any_type = FieldType::Any(isolate); |
4173 | 4179 |
4174 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 4180 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
4175 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { | 4181 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
4176 PropertyDetails details = descriptors->GetDetails(i); | 4182 PropertyDetails details = descriptors->GetDetails(i); |
4177 if (details.type() == DATA) { | 4183 if (details.location() == kField) { |
4178 MapUpdater mu(isolate, map); | 4184 MapUpdater mu(isolate, map); |
4179 map = mu.ReconfigureToDataField(i, details.attributes(), | 4185 map = mu.ReconfigureToDataField(i, details.attributes(), |
4180 Representation::Tagged(), any_type); | 4186 Representation::Tagged(), any_type); |
4181 } | 4187 } |
4182 } | 4188 } |
4183 return map; | 4189 return map; |
4184 } | 4190 } |
4185 | 4191 |
4186 | 4192 |
4187 // static | 4193 // static |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4226 if (transition == NULL) return nullptr; | 4232 if (transition == NULL) return nullptr; |
4227 new_map = transition; | 4233 new_map = transition; |
4228 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 4234 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
4229 | 4235 |
4230 PropertyDetails new_details = new_descriptors->GetDetails(i); | 4236 PropertyDetails new_details = new_descriptors->GetDetails(i); |
4231 DCHECK_EQ(old_details.kind(), new_details.kind()); | 4237 DCHECK_EQ(old_details.kind(), new_details.kind()); |
4232 DCHECK_EQ(old_details.attributes(), new_details.attributes()); | 4238 DCHECK_EQ(old_details.attributes(), new_details.attributes()); |
4233 if (!old_details.representation().fits_into(new_details.representation())) { | 4239 if (!old_details.representation().fits_into(new_details.representation())) { |
4234 return nullptr; | 4240 return nullptr; |
4235 } | 4241 } |
4236 switch (new_details.type()) { | 4242 if (new_details.location() == kField) { |
4237 case DATA: { | 4243 if (new_details.kind() == kData) { |
4238 FieldType* new_type = new_descriptors->GetFieldType(i); | 4244 FieldType* new_type = new_descriptors->GetFieldType(i); |
4239 // Cleared field types need special treatment. They represent lost | 4245 // Cleared field types need special treatment. They represent lost |
4240 // knowledge, so we must first generalize the new_type to "Any". | 4246 // knowledge, so we must first generalize the new_type to "Any". |
4241 if (FieldTypeIsCleared(new_details.representation(), new_type)) { | 4247 if (FieldTypeIsCleared(new_details.representation(), new_type)) { |
4242 return nullptr; | 4248 return nullptr; |
4243 } | 4249 } |
4244 PropertyType old_property_type = old_details.type(); | 4250 DCHECK_EQ(kData, old_details.kind()); |
4245 if (old_property_type == DATA) { | 4251 if (old_details.location() == kField) { |
4246 FieldType* old_type = old_descriptors->GetFieldType(i); | 4252 FieldType* old_type = old_descriptors->GetFieldType(i); |
4247 if (FieldTypeIsCleared(old_details.representation(), old_type) || | 4253 if (FieldTypeIsCleared(old_details.representation(), old_type) || |
4248 !old_type->NowIs(new_type)) { | 4254 !old_type->NowIs(new_type)) { |
4249 return nullptr; | 4255 return nullptr; |
4250 } | 4256 } |
4251 } else { | 4257 } else { |
4252 DCHECK(old_property_type == DATA_CONSTANT); | 4258 DCHECK_EQ(kDescriptor, old_details.location()); |
4253 Object* old_value = old_descriptors->GetValue(i); | 4259 Object* old_value = old_descriptors->GetValue(i); |
4254 if (!new_type->NowContains(old_value)) { | 4260 if (!new_type->NowContains(old_value)) { |
4255 return nullptr; | 4261 return nullptr; |
4256 } | 4262 } |
4257 } | 4263 } |
4258 break; | 4264 |
4259 } | 4265 } else { |
4260 case ACCESSOR: { | 4266 DCHECK_EQ(kAccessor, new_details.kind()); |
4261 #ifdef DEBUG | 4267 #ifdef DEBUG |
4262 FieldType* new_type = new_descriptors->GetFieldType(i); | 4268 FieldType* new_type = new_descriptors->GetFieldType(i); |
4263 DCHECK(new_type->IsAny()); | 4269 DCHECK(new_type->IsAny()); |
4264 #endif | 4270 #endif |
4265 break; | 4271 UNREACHABLE(); |
4266 } | 4272 } |
4267 | 4273 } else { |
4268 case DATA_CONSTANT: | 4274 DCHECK_EQ(kDescriptor, new_details.location()); |
4269 case ACCESSOR_CONSTANT: { | 4275 Object* old_value = old_descriptors->GetValue(i); |
4270 Object* old_value = old_descriptors->GetValue(i); | 4276 Object* new_value = new_descriptors->GetValue(i); |
4271 Object* new_value = new_descriptors->GetValue(i); | 4277 if (old_details.location() == kField || old_value != new_value) { |
4272 if (old_details.location() == kField || old_value != new_value) { | 4278 return nullptr; |
4273 return nullptr; | |
4274 } | |
4275 break; | |
4276 } | 4279 } |
4277 } | 4280 } |
4278 } | 4281 } |
4279 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; | 4282 if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr; |
4280 return new_map; | 4283 return new_map; |
4281 } | 4284 } |
4282 | 4285 |
4283 | 4286 |
4284 // static | 4287 // static |
4285 Handle<Map> Map::Update(Handle<Map> map) { | 4288 Handle<Map> Map::Update(Handle<Map> map) { |
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5644 } | 5647 } |
5645 | 5648 |
5646 int instance_descriptor_length = iteration_order->length(); | 5649 int instance_descriptor_length = iteration_order->length(); |
5647 int number_of_fields = 0; | 5650 int number_of_fields = 0; |
5648 | 5651 |
5649 // Compute the length of the instance descriptor. | 5652 // Compute the length of the instance descriptor. |
5650 for (int i = 0; i < instance_descriptor_length; i++) { | 5653 for (int i = 0; i < instance_descriptor_length; i++) { |
5651 int index = Smi::cast(iteration_order->get(i))->value(); | 5654 int index = Smi::cast(iteration_order->get(i))->value(); |
5652 DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index))); | 5655 DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index))); |
5653 | 5656 |
5654 Object* value = dictionary->ValueAt(index); | 5657 PropertyKind kind = dictionary->DetailsAt(index).kind(); |
5655 PropertyType type = dictionary->DetailsAt(index).type(); | 5658 if (kind == kData) { |
5656 if (type == DATA && !value->IsJSFunction()) { | 5659 Object* value = dictionary->ValueAt(index); |
5657 number_of_fields += 1; | 5660 if (!value->IsJSFunction()) { |
| 5661 number_of_fields += 1; |
| 5662 } |
5658 } | 5663 } |
5659 } | 5664 } |
5660 | 5665 |
5661 Handle<Map> old_map(object->map(), isolate); | 5666 Handle<Map> old_map(object->map(), isolate); |
5662 | 5667 |
5663 int inobject_props = old_map->GetInObjectProperties(); | 5668 int inobject_props = old_map->GetInObjectProperties(); |
5664 | 5669 |
5665 // Allocate new map. | 5670 // Allocate new map. |
5666 Handle<Map> new_map = Map::CopyDropDescriptors(old_map); | 5671 Handle<Map> new_map = Map::CopyDropDescriptors(old_map); |
5667 new_map->set_dictionary_map(false); | 5672 new_map->set_dictionary_map(false); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5712 DCHECK(dictionary->IsKey(k)); | 5717 DCHECK(dictionary->IsKey(k)); |
5713 // Dictionary keys are internalized upon insertion. | 5718 // Dictionary keys are internalized upon insertion. |
5714 // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild. | 5719 // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild. |
5715 CHECK(k->IsUniqueName()); | 5720 CHECK(k->IsUniqueName()); |
5716 Handle<Name> key(Name::cast(k), isolate); | 5721 Handle<Name> key(Name::cast(k), isolate); |
5717 | 5722 |
5718 Object* value = dictionary->ValueAt(index); | 5723 Object* value = dictionary->ValueAt(index); |
5719 | 5724 |
5720 PropertyDetails details = dictionary->DetailsAt(index); | 5725 PropertyDetails details = dictionary->DetailsAt(index); |
5721 int enumeration_index = details.dictionary_index(); | 5726 int enumeration_index = details.dictionary_index(); |
5722 PropertyType type = details.type(); | |
5723 | 5727 |
5724 if (value->IsJSFunction()) { | 5728 Descriptor d; |
5725 Descriptor d = Descriptor::DataConstant(key, handle(value, isolate), | 5729 if (details.kind() == kData) { |
5726 details.attributes()); | 5730 if (value->IsJSFunction()) { |
5727 descriptors->Set(enumeration_index - 1, &d); | 5731 d = Descriptor::DataConstant(key, handle(value, isolate), |
5728 } else if (type == DATA) { | 5732 details.attributes()); |
| 5733 } else { |
| 5734 d = Descriptor::DataField( |
| 5735 key, current_offset, details.attributes(), |
| 5736 // TODO(verwaest): value->OptimalRepresentation(); |
| 5737 Representation::Tagged()); |
| 5738 } |
| 5739 } else { |
| 5740 DCHECK_EQ(kDescriptor, details.location()); |
| 5741 d = Descriptor::AccessorConstant(key, handle(value, isolate), |
| 5742 details.attributes()); |
| 5743 } |
| 5744 details = d.GetDetails(); |
| 5745 if (details.location() == kField) { |
5729 if (current_offset < inobject_props) { | 5746 if (current_offset < inobject_props) { |
5730 object->InObjectPropertyAtPut(current_offset, value, | 5747 object->InObjectPropertyAtPut(current_offset, value, |
5731 UPDATE_WRITE_BARRIER); | 5748 UPDATE_WRITE_BARRIER); |
5732 } else { | 5749 } else { |
5733 int offset = current_offset - inobject_props; | 5750 int offset = current_offset - inobject_props; |
5734 fields->set(offset, value); | 5751 fields->set(offset, value); |
5735 } | 5752 } |
5736 Descriptor d = Descriptor::DataField( | 5753 current_offset += details.field_width_in_words(); |
5737 key, current_offset, details.attributes(), | |
5738 // TODO(verwaest): value->OptimalRepresentation(); | |
5739 Representation::Tagged()); | |
5740 current_offset += d.GetDetails().field_width_in_words(); | |
5741 descriptors->Set(enumeration_index - 1, &d); | |
5742 } else if (type == ACCESSOR_CONSTANT) { | |
5743 Descriptor d = Descriptor::AccessorConstant(key, handle(value, isolate), | |
5744 details.attributes()); | |
5745 descriptors->Set(enumeration_index - 1, &d); | |
5746 } else { | |
5747 UNREACHABLE(); | |
5748 } | 5754 } |
| 5755 descriptors->Set(enumeration_index - 1, &d); |
5749 } | 5756 } |
5750 DCHECK(current_offset == number_of_fields); | 5757 DCHECK(current_offset == number_of_fields); |
5751 | 5758 |
5752 descriptors->Sort(); | 5759 descriptors->Sort(); |
5753 | 5760 |
5754 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( | 5761 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( |
5755 new_map, descriptors, descriptors->number_of_descriptors()); | 5762 new_map, descriptors, descriptors->number_of_descriptors()); |
5756 | 5763 |
5757 DisallowHeapAllocation no_gc; | 5764 DisallowHeapAllocation no_gc; |
5758 new_map->InitializeDescriptors(*descriptors, *layout_descriptor); | 5765 new_map->InitializeDescriptors(*descriptors, *layout_descriptor); |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7630 Handle<Dictionary> dictionary, | 7637 Handle<Dictionary> dictionary, |
7631 const PropertyAttributes attributes) { | 7638 const PropertyAttributes attributes) { |
7632 int capacity = dictionary->Capacity(); | 7639 int capacity = dictionary->Capacity(); |
7633 for (int i = 0; i < capacity; i++) { | 7640 for (int i = 0; i < capacity; i++) { |
7634 Object* k = dictionary->KeyAt(i); | 7641 Object* k = dictionary->KeyAt(i); |
7635 if (dictionary->IsKey(isolate, k) && | 7642 if (dictionary->IsKey(isolate, k) && |
7636 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { | 7643 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { |
7637 PropertyDetails details = dictionary->DetailsAt(i); | 7644 PropertyDetails details = dictionary->DetailsAt(i); |
7638 int attrs = attributes; | 7645 int attrs = attributes; |
7639 // READ_ONLY is an invalid attribute for JS setters/getters. | 7646 // READ_ONLY is an invalid attribute for JS setters/getters. |
7640 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { | 7647 if ((attributes & READ_ONLY) && details.kind() == kAccessor) { |
7641 Object* v = dictionary->ValueAt(i); | 7648 Object* v = dictionary->ValueAt(i); |
7642 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); | 7649 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); |
7643 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; | 7650 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; |
7644 } | 7651 } |
7645 details = details.CopyAddAttributes( | 7652 details = details.CopyAddAttributes( |
7646 static_cast<PropertyAttributes>(attrs)); | 7653 static_cast<PropertyAttributes>(attrs)); |
7647 DictionaryDetailsAtPut<Dictionary>(isolate, dictionary, i, details); | 7654 DictionaryDetailsAtPut<Dictionary>(isolate, dictionary, i, details); |
7648 } | 7655 } |
7649 } | 7656 } |
7650 } | 7657 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7870 | 7877 |
7871 if (!shallow) { | 7878 if (!shallow) { |
7872 HandleScope scope(isolate); | 7879 HandleScope scope(isolate); |
7873 | 7880 |
7874 // Deep copy own properties. | 7881 // Deep copy own properties. |
7875 if (copy->HasFastProperties()) { | 7882 if (copy->HasFastProperties()) { |
7876 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 7883 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
7877 int limit = copy->map()->NumberOfOwnDescriptors(); | 7884 int limit = copy->map()->NumberOfOwnDescriptors(); |
7878 for (int i = 0; i < limit; i++) { | 7885 for (int i = 0; i < limit; i++) { |
7879 PropertyDetails details = descriptors->GetDetails(i); | 7886 PropertyDetails details = descriptors->GetDetails(i); |
7880 if (details.type() != DATA) continue; | 7887 if (details.location() != kField) continue; |
7881 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); | 7888 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); |
7882 if (object->IsUnboxedDoubleField(index)) { | 7889 if (object->IsUnboxedDoubleField(index)) { |
7883 if (copying) { | 7890 if (copying) { |
7884 double value = object->RawFastDoublePropertyAt(index); | 7891 double value = object->RawFastDoublePropertyAt(index); |
7885 copy->RawFastDoublePropertyAtPut(index, value); | 7892 copy->RawFastDoublePropertyAtPut(index, value); |
7886 } | 7893 } |
7887 } else { | 7894 } else { |
7888 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 7895 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
7889 if (value->IsJSObject()) { | 7896 if (value->IsJSObject()) { |
7890 ASSIGN_RETURN_ON_EXCEPTION( | 7897 ASSIGN_RETURN_ON_EXCEPTION( |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8464 | 8471 |
8465 return object; | 8472 return object; |
8466 } | 8473 } |
8467 | 8474 |
8468 Object* JSObject::SlowReverseLookup(Object* value) { | 8475 Object* JSObject::SlowReverseLookup(Object* value) { |
8469 if (HasFastProperties()) { | 8476 if (HasFastProperties()) { |
8470 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 8477 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
8471 DescriptorArray* descs = map()->instance_descriptors(); | 8478 DescriptorArray* descs = map()->instance_descriptors(); |
8472 bool value_is_number = value->IsNumber(); | 8479 bool value_is_number = value->IsNumber(); |
8473 for (int i = 0; i < number_of_own_descriptors; i++) { | 8480 for (int i = 0; i < number_of_own_descriptors; i++) { |
8474 if (descs->GetType(i) == DATA) { | 8481 PropertyDetails details = descs->GetDetails(i); |
| 8482 if (details.location() == kField) { |
| 8483 DCHECK_EQ(kData, details.kind()); |
8475 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); | 8484 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); |
8476 if (IsUnboxedDoubleField(field_index)) { | 8485 if (IsUnboxedDoubleField(field_index)) { |
8477 if (value_is_number) { | 8486 if (value_is_number) { |
8478 double property = RawFastDoublePropertyAt(field_index); | 8487 double property = RawFastDoublePropertyAt(field_index); |
8479 if (property == value->Number()) { | 8488 if (property == value->Number()) { |
8480 return descs->GetKey(i); | 8489 return descs->GetKey(i); |
8481 } | 8490 } |
8482 } | 8491 } |
8483 } else { | 8492 } else { |
8484 Object* property = RawFastPropertyAt(field_index); | 8493 Object* property = RawFastPropertyAt(field_index); |
8485 if (field_index.is_double()) { | 8494 if (field_index.is_double()) { |
8486 DCHECK(property->IsMutableHeapNumber()); | 8495 DCHECK(property->IsMutableHeapNumber()); |
8487 if (value_is_number && property->Number() == value->Number()) { | 8496 if (value_is_number && property->Number() == value->Number()) { |
8488 return descs->GetKey(i); | 8497 return descs->GetKey(i); |
8489 } | 8498 } |
8490 } else if (property == value) { | 8499 } else if (property == value) { |
8491 return descs->GetKey(i); | 8500 return descs->GetKey(i); |
8492 } | 8501 } |
8493 } | 8502 } |
8494 } else if (descs->GetType(i) == DATA_CONSTANT) { | 8503 } else { |
8495 if (descs->GetConstant(i) == value) { | 8504 DCHECK_EQ(kDescriptor, details.location()); |
8496 return descs->GetKey(i); | 8505 if (details.kind() == kData) { |
| 8506 if (descs->GetConstant(i) == value) { |
| 8507 return descs->GetKey(i); |
| 8508 } |
8497 } | 8509 } |
8498 } | 8510 } |
8499 } | 8511 } |
8500 return GetHeap()->undefined_value(); | 8512 return GetHeap()->undefined_value(); |
8501 } else if (IsJSGlobalObject()) { | 8513 } else if (IsJSGlobalObject()) { |
8502 return global_dictionary()->SlowReverseLookup(value); | 8514 return global_dictionary()->SlowReverseLookup(value); |
8503 } else { | 8515 } else { |
8504 return property_dictionary()->SlowReverseLookup(value); | 8516 return property_dictionary()->SlowReverseLookup(value); |
8505 } | 8517 } |
8506 } | 8518 } |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8797 TransitionArray::CanHaveMoreTransitions(map)) { | 8809 TransitionArray::CanHaveMoreTransitions(map)) { |
8798 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 8810 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
8799 | 8811 |
8800 Handle<Name> name; | 8812 Handle<Name> name; |
8801 CHECK(maybe_name.ToHandle(&name)); | 8813 CHECK(maybe_name.ToHandle(&name)); |
8802 ConnectTransition(map, result, name, simple_flag); | 8814 ConnectTransition(map, result, name, simple_flag); |
8803 } else { | 8815 } else { |
8804 int length = descriptors->number_of_descriptors(); | 8816 int length = descriptors->number_of_descriptors(); |
8805 for (int i = 0; i < length; i++) { | 8817 for (int i = 0; i < length; i++) { |
8806 descriptors->SetRepresentation(i, Representation::Tagged()); | 8818 descriptors->SetRepresentation(i, Representation::Tagged()); |
8807 if (descriptors->GetDetails(i).type() == DATA) { | 8819 if (descriptors->GetDetails(i).location() == kField) { |
8808 descriptors->SetValue(i, FieldType::Any()); | 8820 descriptors->SetValue(i, FieldType::Any()); |
8809 } | 8821 } |
8810 } | 8822 } |
8811 result->InitializeDescriptors(*descriptors, | 8823 result->InitializeDescriptors(*descriptors, |
8812 LayoutDescriptor::FastPointerLayout()); | 8824 LayoutDescriptor::FastPointerLayout()); |
8813 } | 8825 } |
8814 } else { | 8826 } else { |
8815 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 8827 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
8816 } | 8828 } |
8817 #if TRACE_MAPS | 8829 #if TRACE_MAPS |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9096 if (WeakCell::cast(value)->cleared()) return FieldType::None(); | 9108 if (WeakCell::cast(value)->cleared()) return FieldType::None(); |
9097 value = WeakCell::cast(value)->value(); | 9109 value = WeakCell::cast(value)->value(); |
9098 } | 9110 } |
9099 return FieldType::cast(value); | 9111 return FieldType::cast(value); |
9100 } | 9112 } |
9101 | 9113 |
9102 namespace { | 9114 namespace { |
9103 | 9115 |
9104 bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) { | 9116 bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) { |
9105 PropertyDetails details = descriptors->GetDetails(descriptor); | 9117 PropertyDetails details = descriptors->GetDetails(descriptor); |
9106 switch (details.type()) { | 9118 if (details.location() == kField) { |
9107 case DATA: | 9119 if (details.kind() == kData) { |
9108 return value->FitsRepresentation(details.representation()) && | 9120 return value->FitsRepresentation(details.representation()) && |
9109 descriptors->GetFieldType(descriptor)->NowContains(value); | 9121 descriptors->GetFieldType(descriptor)->NowContains(value); |
| 9122 } else { |
| 9123 DCHECK_EQ(kAccessor, details.kind()); |
| 9124 UNREACHABLE(); |
| 9125 return false; |
| 9126 } |
9110 | 9127 |
9111 case DATA_CONSTANT: | 9128 } else { |
| 9129 DCHECK_EQ(kDescriptor, details.location()); |
| 9130 if (details.kind() == kData) { |
9112 DCHECK(descriptors->GetConstant(descriptor) != value || | 9131 DCHECK(descriptors->GetConstant(descriptor) != value || |
9113 value->FitsRepresentation(details.representation())); | 9132 value->FitsRepresentation(details.representation())); |
9114 return descriptors->GetConstant(descriptor) == value; | 9133 return descriptors->GetConstant(descriptor) == value; |
9115 | 9134 } else { |
9116 case ACCESSOR: | 9135 DCHECK_EQ(kAccessor, details.kind()); |
9117 case ACCESSOR_CONSTANT: | |
9118 return false; | 9136 return false; |
| 9137 } |
9119 } | 9138 } |
9120 | |
9121 UNREACHABLE(); | 9139 UNREACHABLE(); |
9122 return false; | 9140 return false; |
9123 } | 9141 } |
9124 | 9142 |
9125 Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, | 9143 Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, |
9126 Handle<Object> value) { | 9144 Handle<Object> value) { |
9127 if (CanHoldValue(map->instance_descriptors(), descriptor, *value)) return map; | 9145 if (CanHoldValue(map->instance_descriptors(), descriptor, *value)) return map; |
9128 | 9146 |
9129 Isolate* isolate = map->GetIsolate(); | 9147 Isolate* isolate = map->GetIsolate(); |
9130 PropertyAttributes attributes = | 9148 PropertyAttributes attributes = |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9284 return transition; | 9302 return transition; |
9285 } | 9303 } |
9286 | 9304 |
9287 Handle<AccessorPair> pair; | 9305 Handle<AccessorPair> pair; |
9288 DescriptorArray* old_descriptors = map->instance_descriptors(); | 9306 DescriptorArray* old_descriptors = map->instance_descriptors(); |
9289 if (descriptor != DescriptorArray::kNotFound) { | 9307 if (descriptor != DescriptorArray::kNotFound) { |
9290 if (descriptor != map->LastAdded()) { | 9308 if (descriptor != map->LastAdded()) { |
9291 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); | 9309 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); |
9292 } | 9310 } |
9293 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); | 9311 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); |
9294 if (old_details.type() != ACCESSOR_CONSTANT) { | 9312 if (old_details.kind() != kAccessor) { |
9295 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); | 9313 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); |
9296 } | 9314 } |
9297 | 9315 |
9298 if (old_details.attributes() != attributes) { | 9316 if (old_details.attributes() != attributes) { |
9299 return Map::Normalize(map, mode, "AccessorsWithAttributes"); | 9317 return Map::Normalize(map, mode, "AccessorsWithAttributes"); |
9300 } | 9318 } |
9301 | 9319 |
9302 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); | 9320 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); |
9303 if (!maybe_pair->IsAccessorPair()) { | 9321 if (!maybe_pair->IsAccessorPair()) { |
9304 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); | 9322 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9406 | 9424 |
9407 if (attributes != NONE) { | 9425 if (attributes != NONE) { |
9408 for (int i = 0; i < size; ++i) { | 9426 for (int i = 0; i < size; ++i) { |
9409 Object* value = desc->GetValue(i); | 9427 Object* value = desc->GetValue(i); |
9410 Name* key = desc->GetKey(i); | 9428 Name* key = desc->GetKey(i); |
9411 PropertyDetails details = desc->GetDetails(i); | 9429 PropertyDetails details = desc->GetDetails(i); |
9412 // Bulk attribute changes never affect private properties. | 9430 // Bulk attribute changes never affect private properties. |
9413 if (!key->IsPrivate()) { | 9431 if (!key->IsPrivate()) { |
9414 int mask = DONT_DELETE | DONT_ENUM; | 9432 int mask = DONT_DELETE | DONT_ENUM; |
9415 // READ_ONLY is an invalid attribute for JS setters/getters. | 9433 // READ_ONLY is an invalid attribute for JS setters/getters. |
9416 if (details.type() != ACCESSOR_CONSTANT || !value->IsAccessorPair()) { | 9434 if (details.kind() != kAccessor || !value->IsAccessorPair()) { |
9417 mask |= READ_ONLY; | 9435 mask |= READ_ONLY; |
9418 } | 9436 } |
9419 details = details.CopyAddAttributes( | 9437 details = details.CopyAddAttributes( |
9420 static_cast<PropertyAttributes>(attributes & mask)); | 9438 static_cast<PropertyAttributes>(attributes & mask)); |
9421 } | 9439 } |
9422 Descriptor inner_desc( | 9440 Descriptor inner_desc( |
9423 handle(key), handle(value, desc->GetIsolate()), details); | 9441 handle(key), handle(value, desc->GetIsolate()), details); |
9424 descriptors->SetDescriptor(i, &inner_desc); | 9442 descriptors->SetDescriptor(i, &inner_desc); |
9425 } | 9443 } |
9426 } else { | 9444 } else { |
(...skipping 7332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16759 if (!dict->IsKey(isolate, k)) continue; | 16777 if (!dict->IsKey(isolate, k)) continue; |
16760 | 16778 |
16761 DCHECK(k->IsNumber()); | 16779 DCHECK(k->IsNumber()); |
16762 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); | 16780 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
16763 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); | 16781 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
16764 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); | 16782 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
16765 | 16783 |
16766 HandleScope scope(isolate); | 16784 HandleScope scope(isolate); |
16767 Handle<Object> value(dict->ValueAt(i), isolate); | 16785 Handle<Object> value(dict->ValueAt(i), isolate); |
16768 PropertyDetails details = dict->DetailsAt(i); | 16786 PropertyDetails details = dict->DetailsAt(i); |
16769 if (details.type() == ACCESSOR_CONSTANT || details.IsReadOnly()) { | 16787 if (details.kind() == kAccessor || details.IsReadOnly()) { |
16770 // Bail out and do the sorting of undefineds and array holes in JS. | 16788 // Bail out and do the sorting of undefineds and array holes in JS. |
16771 // Also bail out if the element is not supposed to be moved. | 16789 // Also bail out if the element is not supposed to be moved. |
16772 return bailout; | 16790 return bailout; |
16773 } | 16791 } |
16774 | 16792 |
16775 uint32_t key = NumberToUint32(k); | 16793 uint32_t key = NumberToUint32(k); |
16776 if (key < limit) { | 16794 if (key < limit) { |
16777 if (value->IsUndefined(isolate)) { | 16795 if (value->IsUndefined(isolate)) { |
16778 undefs++; | 16796 undefs++; |
16779 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 16797 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17677 | 17695 |
17678 bool SeededNumberDictionary::HasComplexElements() { | 17696 bool SeededNumberDictionary::HasComplexElements() { |
17679 if (!requires_slow_elements()) return false; | 17697 if (!requires_slow_elements()) return false; |
17680 Isolate* isolate = this->GetIsolate(); | 17698 Isolate* isolate = this->GetIsolate(); |
17681 int capacity = this->Capacity(); | 17699 int capacity = this->Capacity(); |
17682 for (int i = 0; i < capacity; i++) { | 17700 for (int i = 0; i < capacity; i++) { |
17683 Object* k = this->KeyAt(i); | 17701 Object* k = this->KeyAt(i); |
17684 if (!this->IsKey(isolate, k)) continue; | 17702 if (!this->IsKey(isolate, k)) continue; |
17685 DCHECK(!IsDeleted(i)); | 17703 DCHECK(!IsDeleted(i)); |
17686 PropertyDetails details = this->DetailsAt(i); | 17704 PropertyDetails details = this->DetailsAt(i); |
17687 if (details.type() == ACCESSOR_CONSTANT) return true; | 17705 if (details.kind() == kAccessor) return true; |
17688 PropertyAttributes attr = details.attributes(); | 17706 PropertyAttributes attr = details.attributes(); |
17689 if (attr & ALL_ATTRIBUTES_MASK) return true; | 17707 if (attr & ALL_ATTRIBUTES_MASK) return true; |
17690 } | 17708 } |
17691 return false; | 17709 return false; |
17692 } | 17710 } |
17693 | 17711 |
17694 void SeededNumberDictionary::UpdateMaxNumberKey( | 17712 void SeededNumberDictionary::UpdateMaxNumberKey( |
17695 uint32_t key, Handle<JSObject> dictionary_holder) { | 17713 uint32_t key, Handle<JSObject> dictionary_holder) { |
17696 DisallowHeapAllocation no_allocation; | 17714 DisallowHeapAllocation no_allocation; |
17697 // If the dictionary requires slow elements an element has already | 17715 // If the dictionary requires slow elements an element has already |
(...skipping 2255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19953 // depend on this. | 19971 // depend on this. |
19954 return DICTIONARY_ELEMENTS; | 19972 return DICTIONARY_ELEMENTS; |
19955 } | 19973 } |
19956 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 19974 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
19957 return kind; | 19975 return kind; |
19958 } | 19976 } |
19959 } | 19977 } |
19960 | 19978 |
19961 } // namespace internal | 19979 } // namespace internal |
19962 } // namespace v8 | 19980 } // namespace v8 |
OLD | NEW |