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 |