Chromium Code Reviews| 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 <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 8725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8736 Isolate* isolate = object->GetIsolate(); | 8736 Isolate* isolate = object->GetIsolate(); |
| 8737 KeyAccumulator accumulator(isolate, type, filter); | 8737 KeyAccumulator accumulator(isolate, type, filter); |
| 8738 MAYBE_RETURN( | 8738 MAYBE_RETURN( |
| 8739 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), | 8739 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), |
| 8740 MaybeHandle<FixedArray>()); | 8740 MaybeHandle<FixedArray>()); |
| 8741 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); | 8741 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
| 8742 DCHECK(ContainsOnlyValidKeys(keys)); | 8742 DCHECK(ContainsOnlyValidKeys(keys)); |
| 8743 return keys; | 8743 return keys; |
| 8744 } | 8744 } |
| 8745 | 8745 |
| 8746 Handle<Object> MakeEntryPair(Isolate* isolate, uint32_t index, Object* value) { | |
| 8747 AllowHeapAllocation allow_allocation; | |
| 8748 Handle<Object> key = isolate->factory()->Uint32ToString(index); | |
| 8749 Handle<FixedArray> entry_storage = | |
| 8750 isolate->factory()->NewUninitializedFixedArray(2); | |
|
Camillo Bruni
2016/03/15 13:36:14
That's unsafe here, value is still a raw pointer.
Camillo Bruni
2016/03/15 13:36:14
That's unsafe here, value is still a raw pointer.
| |
| 8751 { | |
| 8752 DisallowHeapAllocation no_allocation; | |
| 8753 entry_storage->set(0, *key); | |
| 8754 entry_storage->set(1, value); | |
| 8755 } | |
| 8756 return isolate->factory()->NewJSArrayWithElements(entry_storage, | |
| 8757 FAST_ELEMENTS, 2); | |
| 8758 } | |
| 8759 | |
| 8760 Handle<Object> MakeEntryPair(Isolate* isolate, Handle<Name> key, | |
| 8761 Object* value) { | |
| 8762 AllowHeapAllocation allow_allocation; | |
| 8763 Handle<FixedArray> entry_storage = | |
| 8764 isolate->factory()->NewUninitializedFixedArray(2); | |
|
Camillo Bruni
2016/03/15 13:36:14
same here.
| |
| 8765 { | |
| 8766 DisallowHeapAllocation no_allocation; | |
| 8767 entry_storage->set(0, *key); | |
| 8768 entry_storage->set(1, value); | |
| 8769 } | |
| 8770 return isolate->factory()->NewJSArrayWithElements(entry_storage, | |
| 8771 FAST_ELEMENTS, 2); | |
| 8772 } | |
| 8773 | |
| 8746 MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries( | 8774 MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries( |
| 8747 Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries, | 8775 Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries, |
| 8748 Handle<FixedArray>* result) { | 8776 Handle<FixedArray>* result) { |
| 8749 Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate); | 8777 Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate); |
| 8750 | 8778 |
| 8751 if (!map->IsJSObjectMap()) return Just(false); | 8779 if (!map->IsJSObjectMap()) return Just(false); |
| 8752 if (!map->OnlyHasSimpleProperties()) return Just(false); | 8780 if (!map->OnlyHasSimpleProperties()) return Just(false); |
| 8753 | 8781 |
| 8754 Handle<JSObject> object(JSObject::cast(*receiver)); | 8782 Handle<JSObject> object(JSObject::cast(*receiver)); |
| 8755 if (object->elements() != isolate->heap()->empty_fixed_array()) { | |
| 8756 return Just(false); | |
| 8757 } | |
| 8758 | 8783 |
| 8759 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); | 8784 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); |
| 8760 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 8785 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 8761 Handle<FixedArray> values_or_entries = | 8786 int number_of_own_elements = object->NumberOfOwnElements(ALL_PROPERTIES); |
| 8762 isolate->factory()->NewFixedArray(number_of_own_descriptors); | 8787 Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray( |
| 8788 number_of_own_descriptors + number_of_own_elements); | |
| 8763 int count = 0; | 8789 int count = 0; |
| 8764 | 8790 |
| 8765 bool stable = true; | 8791 bool stable = true; |
| 8766 | 8792 |
| 8793 if (object->elements() != isolate->heap()->empty_fixed_array()) { | |
| 8794 ElementsKind kind = object->GetElementsKind(); | |
|
Camillo Bruni
2016/03/15 13:36:14
I would feel more comfortable if this where in ele
caitp (gmail)
2016/03/15 15:55:09
I've moved it
| |
| 8795 switch (kind) { | |
| 8796 case FAST_SMI_ELEMENTS: | |
| 8797 case FAST_HOLEY_SMI_ELEMENTS: | |
| 8798 case FAST_ELEMENTS: | |
| 8799 case FAST_HOLEY_ELEMENTS: { | |
| 8800 DisallowHeapAllocation no_allocation; | |
|
Camillo Bruni
2016/03/15 13:36:14
again doens't hold... MakeEntryPair allocates an a
| |
| 8801 FixedArray* elements = FixedArray::cast(object->elements()); | |
| 8802 for (int i = 0; i < elements->length(); ++i) { | |
| 8803 Object* value = elements->get(i); | |
| 8804 if (!value->IsTheHole()) { | |
| 8805 if (get_entries) { | |
| 8806 value = *MakeEntryPair(isolate, i, value); | |
| 8807 } | |
| 8808 values_or_entries->set(count++, value); | |
| 8809 } | |
| 8810 } | |
| 8811 DCHECK_EQ(object->map(), *map); | |
| 8812 break; | |
| 8813 } | |
| 8814 | |
| 8815 case FAST_DOUBLE_ELEMENTS: | |
| 8816 case FAST_HOLEY_DOUBLE_ELEMENTS: { | |
| 8817 FixedDoubleArray* elements = FixedDoubleArray::cast(object->elements()); | |
| 8818 for (int i = 0; i < elements->length(); ++i) { | |
| 8819 if (!elements->is_the_hole(i)) { | |
| 8820 Handle<Object> value = FixedDoubleArray::get(elements, i, isolate); | |
| 8821 if (get_entries) { | |
| 8822 value = MakeEntryPair(isolate, i, *value); | |
| 8823 } | |
| 8824 values_or_entries->set(count++, *value); | |
| 8825 } | |
| 8826 } | |
| 8827 DCHECK_EQ(object->map(), *map); | |
| 8828 break; | |
| 8829 } | |
| 8830 | |
| 8831 case NO_ELEMENTS: | |
| 8832 break; | |
| 8833 | |
| 8834 default: { | |
| 8835 bool is_slow_elements = IsDictionaryElementsKind(kind) || | |
| 8836 IsSloppyArgumentsElements(kind) || | |
| 8837 IsStringWrapperElementsKind(kind); | |
| 8838 ElementsAccessor* accessor = object->GetElementsAccessor(); | |
| 8839 PropertyFilter filter = | |
| 8840 is_slow_elements ? ALL_PROPERTIES : ENUMERABLE_STRINGS; | |
| 8841 KeyAccumulator accumulator(isolate, OWN_ONLY, filter); | |
| 8842 accumulator.NextPrototype(); | |
| 8843 accessor->CollectElementIndices(object, &accumulator, kMaxUInt32, | |
| 8844 filter); | |
| 8845 Handle<FixedArray> keys = accumulator.GetKeys(); | |
| 8846 | |
| 8847 if (is_slow_elements) { | |
|
Camillo Bruni
2016/03/15 13:36:14
I think this would be automatically cleaner when p
caitp (gmail)
2016/03/15 15:55:09
The fast elements case definitely makes a big diff
| |
| 8848 for (int i = 0; i < keys->length(); ++i) { | |
| 8849 Handle<Object> key(keys->get(i), isolate); | |
| 8850 uint32_t index = key->Number(); | |
| 8851 LookupIterator it(isolate, object, index, LookupIterator::OWN); | |
| 8852 if (it.property_attributes() & ENUMERABLE_STRINGS) continue; | |
| 8853 if (it.property_details().kind() == kData) { | |
| 8854 Handle<Object> value = it.GetDataValue(); | |
| 8855 if (get_entries) { | |
| 8856 value = MakeEntryPair(isolate, index, *value); | |
| 8857 } | |
| 8858 values_or_entries->set(count++, *value); | |
| 8859 } else { | |
| 8860 Handle<Object> value; | |
| 8861 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 8862 isolate, value, Object::GetProperty(&it), Nothing<bool>()); | |
| 8863 if (get_entries) { | |
| 8864 value = MakeEntryPair(isolate, index, *value); | |
| 8865 } | |
| 8866 values_or_entries->set(count++, *value); | |
| 8867 stable = object->map() == *map; | |
|
Camillo Bruni
2016/03/15 13:36:14
That's not used anywhere...
caitp (gmail)
2016/03/15 15:55:09
It's used when walking instance_descriptors() belo
| |
| 8868 } | |
| 8869 } | |
| 8870 } else { | |
| 8871 for (int i = 0; i < keys->length(); ++i) { | |
| 8872 Handle<Object> key(keys->get(i), isolate); | |
| 8873 int entry = key->Number(); | |
| 8874 Handle<Object> value = accessor->Get(object, entry); | |
| 8875 if (get_entries) { | |
| 8876 value = MakeEntryPair(isolate, entry, *value); | |
| 8877 } | |
| 8878 values_or_entries->set(count++, *value); | |
| 8879 } | |
| 8880 } | |
| 8881 break; | |
| 8882 } | |
| 8883 } | |
| 8884 } | |
| 8885 | |
| 8767 for (int index = 0; index < number_of_own_descriptors; index++) { | 8886 for (int index = 0; index < number_of_own_descriptors; index++) { |
| 8768 Handle<Name> next_key(descriptors->GetKey(index), isolate); | 8887 Handle<Name> next_key(descriptors->GetKey(index), isolate); |
| 8769 if (!next_key->IsString()) continue; | 8888 if (!next_key->IsString()) continue; |
| 8770 Handle<Object> prop_value; | 8889 Handle<Object> prop_value; |
| 8771 | 8890 |
| 8772 // Directly decode from the descriptor array if |from| did not change shape. | 8891 // Directly decode from the descriptor array if |from| did not change shape. |
| 8773 if (stable) { | 8892 if (stable) { |
| 8774 PropertyDetails details = descriptors->GetDetails(index); | 8893 PropertyDetails details = descriptors->GetDetails(index); |
| 8775 if (!details.IsEnumerable()) continue; | 8894 if (!details.IsEnumerable()) continue; |
| 8776 if (details.kind() == kData) { | 8895 if (details.kind() == kData) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 8794 LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR); | 8913 LookupIterator it(object, next_key, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 8795 if (!it.IsFound()) continue; | 8914 if (!it.IsFound()) continue; |
| 8796 DCHECK(it.state() == LookupIterator::DATA || | 8915 DCHECK(it.state() == LookupIterator::DATA || |
| 8797 it.state() == LookupIterator::ACCESSOR); | 8916 it.state() == LookupIterator::ACCESSOR); |
| 8798 if (!it.IsEnumerable()) continue; | 8917 if (!it.IsEnumerable()) continue; |
| 8799 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 8918 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8800 isolate, prop_value, Object::GetProperty(&it), Nothing<bool>()); | 8919 isolate, prop_value, Object::GetProperty(&it), Nothing<bool>()); |
| 8801 } | 8920 } |
| 8802 | 8921 |
| 8803 if (get_entries) { | 8922 if (get_entries) { |
| 8804 Handle<FixedArray> entry_storage = | 8923 prop_value = MakeEntryPair(isolate, next_key, *prop_value); |
| 8805 isolate->factory()->NewUninitializedFixedArray(2); | |
| 8806 entry_storage->set(0, *next_key); | |
| 8807 entry_storage->set(1, *prop_value); | |
| 8808 prop_value = isolate->factory()->NewJSArrayWithElements(entry_storage, | |
| 8809 FAST_ELEMENTS, 2); | |
| 8810 } | 8924 } |
| 8811 | 8925 |
| 8812 values_or_entries->set(count, *prop_value); | 8926 values_or_entries->set(count, *prop_value); |
| 8813 count++; | 8927 count++; |
| 8814 } | 8928 } |
| 8815 | 8929 |
| 8816 if (count < values_or_entries->length()) values_or_entries->Shrink(count); | 8930 if (count < values_or_entries->length()) values_or_entries->Shrink(count); |
| 8817 *result = values_or_entries; | 8931 *result = values_or_entries; |
| 8818 return Just(true); | 8932 return Just(true); |
| 8819 } | 8933 } |
| (...skipping 10947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 19767 if (cell->value() != *new_value) { | 19881 if (cell->value() != *new_value) { |
| 19768 cell->set_value(*new_value); | 19882 cell->set_value(*new_value); |
| 19769 Isolate* isolate = cell->GetIsolate(); | 19883 Isolate* isolate = cell->GetIsolate(); |
| 19770 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19884 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19771 isolate, DependentCode::kPropertyCellChangedGroup); | 19885 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19772 } | 19886 } |
| 19773 } | 19887 } |
| 19774 | 19888 |
| 19775 } // namespace internal | 19889 } // namespace internal |
| 19776 } // namespace v8 | 19890 } // namespace v8 |
| OLD | NEW |