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