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 |