| 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 3720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3731 // Make space for two more properties. | 3731 // Make space for two more properties. |
| 3732 property_count += NameDictionary::kInitialCapacity; | 3732 property_count += NameDictionary::kInitialCapacity; |
| 3733 } | 3733 } |
| 3734 Handle<NameDictionary> dictionary = | 3734 Handle<NameDictionary> dictionary = |
| 3735 NameDictionary::New(isolate, property_count); | 3735 NameDictionary::New(isolate, property_count); |
| 3736 | 3736 |
| 3737 Handle<DescriptorArray> descs(map->instance_descriptors()); | 3737 Handle<DescriptorArray> descs(map->instance_descriptors()); |
| 3738 for (int i = 0; i < real_size; i++) { | 3738 for (int i = 0; i < real_size; i++) { |
| 3739 PropertyDetails details = descs->GetDetails(i); | 3739 PropertyDetails details = descs->GetDetails(i); |
| 3740 Handle<Name> key(descs->GetKey(i)); | 3740 Handle<Name> key(descs->GetKey(i)); |
| 3741 // TODO(ishell): Simplify the below code. | 3741 Handle<Object> value; |
| 3742 if (details.location() == kField) { | 3742 if (details.location() == kField) { |
| 3743 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 3743 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
| 3744 if (details.kind() == kData) { | 3744 if (details.kind() == kData) { |
| 3745 Handle<Object> value; | |
| 3746 if (object->IsUnboxedDoubleField(index)) { | 3745 if (object->IsUnboxedDoubleField(index)) { |
| 3747 double old_value = object->RawFastDoublePropertyAt(index); | 3746 double old_value = object->RawFastDoublePropertyAt(index); |
| 3748 value = isolate->factory()->NewHeapNumber(old_value); | 3747 value = isolate->factory()->NewHeapNumber(old_value); |
| 3749 } else { | 3748 } else { |
| 3750 value = handle(object->RawFastPropertyAt(index), isolate); | 3749 value = handle(object->RawFastPropertyAt(index), isolate); |
| 3751 if (details.representation().IsDouble()) { | 3750 if (details.representation().IsDouble()) { |
| 3752 DCHECK(value->IsMutableHeapNumber()); | 3751 DCHECK(value->IsMutableHeapNumber()); |
| 3753 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | 3752 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
| 3754 value = isolate->factory()->NewHeapNumber(old->value()); | 3753 value = isolate->factory()->NewHeapNumber(old->value()); |
| 3755 } | 3754 } |
| 3756 } | 3755 } |
| 3757 PropertyDetails d(kData, details.attributes(), i + 1, | |
| 3758 PropertyCellType::kNoCell); | |
| 3759 dictionary = NameDictionary::Add(dictionary, key, value, d); | |
| 3760 | |
| 3761 } else { | 3756 } else { |
| 3762 DCHECK_EQ(kAccessor, details.kind()); | 3757 DCHECK_EQ(kAccessor, details.kind()); |
| 3763 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 3758 value = handle(object->RawFastPropertyAt(index), isolate); |
| 3764 PropertyDetails d(kAccessor, details.attributes(), i + 1, | |
| 3765 PropertyCellType::kNoCell); | |
| 3766 dictionary = NameDictionary::Add(dictionary, key, value, d); | |
| 3767 } | 3759 } |
| 3768 | 3760 |
| 3769 } else { | 3761 } else { |
| 3770 DCHECK_EQ(kDescriptor, details.location()); | 3762 DCHECK_EQ(kDescriptor, details.location()); |
| 3771 if (details.kind() == kData) { | 3763 value = handle(descs->GetValue(i), isolate); |
| 3772 Handle<Object> value(descs->GetConstant(i), isolate); | |
| 3773 PropertyDetails d(kData, details.attributes(), i + 1, | |
| 3774 PropertyCellType::kNoCell); | |
| 3775 dictionary = NameDictionary::Add(dictionary, key, value, d); | |
| 3776 | |
| 3777 } else { | |
| 3778 DCHECK_EQ(kAccessor, details.kind()); | |
| 3779 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | |
| 3780 PropertyDetails d(kAccessor, details.attributes(), i + 1, | |
| 3781 PropertyCellType::kNoCell); | |
| 3782 dictionary = NameDictionary::Add(dictionary, key, value, d); | |
| 3783 } | |
| 3784 } | 3764 } |
| 3765 DCHECK(!value.is_null()); |
| 3766 PropertyDetails d(details.kind(), details.attributes(), i + 1, |
| 3767 PropertyCellType::kNoCell); |
| 3768 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 3785 } | 3769 } |
| 3786 | 3770 |
| 3787 // Copy the next enumeration index from instance descriptor. | 3771 // Copy the next enumeration index from instance descriptor. |
| 3788 dictionary->SetNextEnumerationIndex(real_size + 1); | 3772 dictionary->SetNextEnumerationIndex(real_size + 1); |
| 3789 | 3773 |
| 3790 // From here on we cannot fail and we shouldn't GC anymore. | 3774 // From here on we cannot fail and we shouldn't GC anymore. |
| 3791 DisallowHeapAllocation no_allocation; | 3775 DisallowHeapAllocation no_allocation; |
| 3792 | 3776 |
| 3793 // Resize the object in the heap if necessary. | 3777 // Resize the object in the heap if necessary. |
| 3794 int new_instance_size = new_map->instance_size(); | 3778 int new_instance_size = new_map->instance_size(); |
| (...skipping 4718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8513 if (value_is_number && property->Number() == value->Number()) { | 8497 if (value_is_number && property->Number() == value->Number()) { |
| 8514 return descs->GetKey(i); | 8498 return descs->GetKey(i); |
| 8515 } | 8499 } |
| 8516 } else if (property == value) { | 8500 } else if (property == value) { |
| 8517 return descs->GetKey(i); | 8501 return descs->GetKey(i); |
| 8518 } | 8502 } |
| 8519 } | 8503 } |
| 8520 } else { | 8504 } else { |
| 8521 DCHECK_EQ(kDescriptor, details.location()); | 8505 DCHECK_EQ(kDescriptor, details.location()); |
| 8522 if (details.kind() == kData) { | 8506 if (details.kind() == kData) { |
| 8523 if (descs->GetConstant(i) == value) { | 8507 if (descs->GetValue(i) == value) { |
| 8524 return descs->GetKey(i); | 8508 return descs->GetKey(i); |
| 8525 } | 8509 } |
| 8526 } | 8510 } |
| 8527 } | 8511 } |
| 8528 } | 8512 } |
| 8529 return GetHeap()->undefined_value(); | 8513 return GetHeap()->undefined_value(); |
| 8530 } else if (IsJSGlobalObject()) { | 8514 } else if (IsJSGlobalObject()) { |
| 8531 return global_dictionary()->SlowReverseLookup(value); | 8515 return global_dictionary()->SlowReverseLookup(value); |
| 8532 } else { | 8516 } else { |
| 8533 return property_dictionary()->SlowReverseLookup(value); | 8517 return property_dictionary()->SlowReverseLookup(value); |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9129 descriptors->GetFieldType(descriptor)->NowContains(value); | 9113 descriptors->GetFieldType(descriptor)->NowContains(value); |
| 9130 } else { | 9114 } else { |
| 9131 DCHECK_EQ(kAccessor, details.kind()); | 9115 DCHECK_EQ(kAccessor, details.kind()); |
| 9132 UNREACHABLE(); | 9116 UNREACHABLE(); |
| 9133 return false; | 9117 return false; |
| 9134 } | 9118 } |
| 9135 | 9119 |
| 9136 } else { | 9120 } else { |
| 9137 DCHECK_EQ(kDescriptor, details.location()); | 9121 DCHECK_EQ(kDescriptor, details.location()); |
| 9138 if (details.kind() == kData) { | 9122 if (details.kind() == kData) { |
| 9139 DCHECK(descriptors->GetConstant(descriptor) != value || | 9123 DCHECK(descriptors->GetValue(descriptor) != value || |
| 9140 value->FitsRepresentation(details.representation())); | 9124 value->FitsRepresentation(details.representation())); |
| 9141 return descriptors->GetConstant(descriptor) == value; | 9125 return descriptors->GetValue(descriptor) == value; |
| 9142 } else { | 9126 } else { |
| 9143 DCHECK_EQ(kAccessor, details.kind()); | 9127 DCHECK_EQ(kAccessor, details.kind()); |
| 9144 return false; | 9128 return false; |
| 9145 } | 9129 } |
| 9146 } | 9130 } |
| 9147 UNREACHABLE(); | 9131 UNREACHABLE(); |
| 9148 return false; | 9132 return false; |
| 9149 } | 9133 } |
| 9150 | 9134 |
| 9151 Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, | 9135 Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor, |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9438 // Bulk attribute changes never affect private properties. | 9422 // Bulk attribute changes never affect private properties. |
| 9439 if (!key->IsPrivate()) { | 9423 if (!key->IsPrivate()) { |
| 9440 int mask = DONT_DELETE | DONT_ENUM; | 9424 int mask = DONT_DELETE | DONT_ENUM; |
| 9441 // READ_ONLY is an invalid attribute for JS setters/getters. | 9425 // READ_ONLY is an invalid attribute for JS setters/getters. |
| 9442 if (details.kind() != kAccessor || !value->IsAccessorPair()) { | 9426 if (details.kind() != kAccessor || !value->IsAccessorPair()) { |
| 9443 mask |= READ_ONLY; | 9427 mask |= READ_ONLY; |
| 9444 } | 9428 } |
| 9445 details = details.CopyAddAttributes( | 9429 details = details.CopyAddAttributes( |
| 9446 static_cast<PropertyAttributes>(attributes & mask)); | 9430 static_cast<PropertyAttributes>(attributes & mask)); |
| 9447 } | 9431 } |
| 9448 Descriptor inner_desc( | 9432 descriptors->Set(i, key, value, details); |
| 9449 handle(key), handle(value, desc->GetIsolate()), details); | |
| 9450 descriptors->SetDescriptor(i, &inner_desc); | |
| 9451 } | 9433 } |
| 9452 } else { | 9434 } else { |
| 9453 for (int i = 0; i < size; ++i) { | 9435 for (int i = 0; i < size; ++i) { |
| 9454 descriptors->CopyFrom(i, *desc); | 9436 descriptors->CopyFrom(i, *desc); |
| 9455 } | 9437 } |
| 9456 } | 9438 } |
| 9457 | 9439 |
| 9458 if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort(); | 9440 if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort(); |
| 9459 | 9441 |
| 9460 return descriptors; | 9442 return descriptors; |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10103 } | 10085 } |
| 10104 bridge_storage->set(kEnumCacheBridgeCacheIndex, *new_cache); | 10086 bridge_storage->set(kEnumCacheBridgeCacheIndex, *new_cache); |
| 10105 bridge_storage->set( | 10087 bridge_storage->set( |
| 10106 kEnumCacheBridgeIndicesCacheIndex, | 10088 kEnumCacheBridgeIndicesCacheIndex, |
| 10107 new_index_cache.is_null() ? Object::cast(Smi::kZero) : *new_index_cache); | 10089 new_index_cache.is_null() ? Object::cast(Smi::kZero) : *new_index_cache); |
| 10108 if (needs_new_enum_cache) { | 10090 if (needs_new_enum_cache) { |
| 10109 descriptors->set(kEnumCacheIndex, bridge_storage); | 10091 descriptors->set(kEnumCacheIndex, bridge_storage); |
| 10110 } | 10092 } |
| 10111 } | 10093 } |
| 10112 | 10094 |
| 10113 | |
| 10114 void DescriptorArray::CopyFrom(int index, DescriptorArray* src) { | 10095 void DescriptorArray::CopyFrom(int index, DescriptorArray* src) { |
| 10115 Object* value = src->GetValue(index); | |
| 10116 PropertyDetails details = src->GetDetails(index); | 10096 PropertyDetails details = src->GetDetails(index); |
| 10117 Descriptor desc(handle(src->GetKey(index)), | 10097 Set(index, src->GetKey(index), src->GetValue(index), details); |
| 10118 handle(value, src->GetIsolate()), | |
| 10119 details); | |
| 10120 SetDescriptor(index, &desc); | |
| 10121 } | 10098 } |
| 10122 | 10099 |
| 10123 | |
| 10124 void DescriptorArray::Sort() { | 10100 void DescriptorArray::Sort() { |
| 10125 // In-place heap sort. | 10101 // In-place heap sort. |
| 10126 int len = number_of_descriptors(); | 10102 int len = number_of_descriptors(); |
| 10127 // Reset sorting since the descriptor array might contain invalid pointers. | 10103 // Reset sorting since the descriptor array might contain invalid pointers. |
| 10128 for (int i = 0; i < len; ++i) SetSortedKey(i, i); | 10104 for (int i = 0; i < len; ++i) SetSortedKey(i, i); |
| 10129 // Bottom-up max-heap construction. | 10105 // Bottom-up max-heap construction. |
| 10130 // Index of the last node with children | 10106 // Index of the last node with children |
| 10131 const int max_parent_index = (len / 2) - 1; | 10107 const int max_parent_index = (len / 2) - 1; |
| 10132 for (int i = max_parent_index; i >= 0; --i) { | 10108 for (int i = max_parent_index; i >= 0; --i) { |
| 10133 int parent_index = i; | 10109 int parent_index = i; |
| (...skipping 9759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19893 // depend on this. | 19869 // depend on this. |
| 19894 return DICTIONARY_ELEMENTS; | 19870 return DICTIONARY_ELEMENTS; |
| 19895 } | 19871 } |
| 19896 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 19872 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 19897 return kind; | 19873 return kind; |
| 19898 } | 19874 } |
| 19899 } | 19875 } |
| 19900 | 19876 |
| 19901 } // namespace internal | 19877 } // namespace internal |
| 19902 } // namespace v8 | 19878 } // namespace v8 |
| OLD | NEW |