Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: src/objects.cc

Issue 1767113004: [esnext] handle elements in FastObjectValuesOrEntries() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handle element properties Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/harmony/object-entries.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/harmony/object-entries.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698