| 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 |