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

Side by Side Diff: src/elements.cc

Issue 1995263002: [keys] Simplify KeyAccumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebasing Created 4 years, 7 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/elements.h" 5 #include "src/elements.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/isolate-inl.h" 10 #include "src/isolate-inl.h"
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); 438 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply);
439 if (raw_frame->unchecked_code() == apply_builtin) { 439 if (raw_frame->unchecked_code() == apply_builtin) {
440 PrintF("apply from "); 440 PrintF("apply from ");
441 it.Advance(); 441 it.Advance();
442 raw_frame = it.frame(); 442 raw_frame = it.frame();
443 } 443 }
444 } 444 }
445 JavaScriptFrame::PrintTop(isolate, stdout, false, true); 445 JavaScriptFrame::PrintTop(isolate, stdout, false, true);
446 } 446 }
447 447
448 static void SortIndices(Handle<FixedArray> indices, uint32_t sort_size,
449 bool emit_write_barrier = true) {
Jakob Kummerow 2016/05/23 16:25:21 Consider using the existing enum WriteBarrierMode
Camillo Bruni 2016/05/23 19:10:13 updated.
450 struct {
451 bool operator()(Object* a, Object* b) {
452 if (!a->IsUndefined()) {
453 if (b->IsUndefined()) return true;
454 return a->Number() < b->Number();
455 }
456 return !b->IsUndefined();
Jakob Kummerow 2016/05/23 16:25:21 I'm pretty sure this condition is inverted, i.e. y
Camillo Bruni 2016/05/23 19:10:13 good catch! you're right, if b is smaller than a r
457 }
458 } cmp;
459 Object** start =
460 reinterpret_cast<Object**>(indices->GetFirstElementAddress());
461 std::sort(start, start + sort_size, cmp);
462 if (emit_write_barrier) {
463 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices,
464 0, sort_size);
465 }
466 }
448 467
449 // Base class for element handler implementations. Contains the 468 // Base class for element handler implementations. Contains the
450 // the common logic for objects with different ElementsKinds. 469 // the common logic for objects with different ElementsKinds.
451 // Subclasses must specialize method for which the element 470 // Subclasses must specialize method for which the element
452 // implementation differs from the base class implementation. 471 // implementation differs from the base class implementation.
453 // 472 //
454 // This class is intended to be used in the following way: 473 // This class is intended to be used in the following way:
455 // 474 //
456 // class SomeElementsAccessor : 475 // class SomeElementsAccessor :
457 // public ElementsAccessorBase<SomeElementsAccessor, 476 // public ElementsAccessorBase<SomeElementsAccessor,
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 return Subclass::CollectValuesOrEntriesImpl( 875 return Subclass::CollectValuesOrEntriesImpl(
857 isolate, object, values_or_entries, get_entries, nof_items, filter); 876 isolate, object, values_or_entries, get_entries, nof_items, filter);
858 } 877 }
859 878
860 static Maybe<bool> CollectValuesOrEntriesImpl( 879 static Maybe<bool> CollectValuesOrEntriesImpl(
861 Isolate* isolate, Handle<JSObject> object, 880 Isolate* isolate, Handle<JSObject> object,
862 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, 881 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items,
863 PropertyFilter filter) { 882 PropertyFilter filter) {
864 int count = 0; 883 int count = 0;
865 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); 884 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES);
866 accumulator.NextPrototype();
867 Subclass::CollectElementIndicesImpl( 885 Subclass::CollectElementIndicesImpl(
868 object, handle(object->elements(), isolate), &accumulator); 886 object, handle(object->elements(), isolate), &accumulator);
869 Handle<FixedArray> keys = accumulator.GetKeys(); 887 Handle<FixedArray> keys = accumulator.GetKeys();
870 888
871 for (int i = 0; i < keys->length(); ++i) { 889 for (int i = 0; i < keys->length(); ++i) {
872 Handle<Object> key(keys->get(i), isolate); 890 Handle<Object> key(keys->get(i), isolate);
873 Handle<Object> value; 891 Handle<Object> value;
874 uint32_t index; 892 uint32_t index;
875 if (!key->ToUint32(&index)) continue; 893 if (!key->ToUint32(&index)) continue;
876 894
(...skipping 27 matching lines...) Expand all
904 Subclass::CollectElementIndicesImpl(object, backing_store, keys); 922 Subclass::CollectElementIndicesImpl(object, backing_store, keys);
905 } 923 }
906 924
907 static void CollectElementIndicesImpl(Handle<JSObject> object, 925 static void CollectElementIndicesImpl(Handle<JSObject> object,
908 Handle<FixedArrayBase> backing_store, 926 Handle<FixedArrayBase> backing_store,
909 KeyAccumulator* keys) { 927 KeyAccumulator* keys) {
910 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); 928 DCHECK_NE(DICTIONARY_ELEMENTS, kind());
911 // Non-dictionary elements can't have all-can-read accessors. 929 // Non-dictionary elements can't have all-can-read accessors.
912 uint32_t length = GetIterationLength(*object, *backing_store); 930 uint32_t length = GetIterationLength(*object, *backing_store);
913 PropertyFilter filter = keys->filter(); 931 PropertyFilter filter = keys->filter();
932 Factory* factory = keys->isolate()->factory();
914 for (uint32_t i = 0; i < length; i++) { 933 for (uint32_t i = 0; i < length; i++) {
915 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { 934 if (Subclass::HasElementImpl(object, i, backing_store, filter)) {
916 keys->AddKey(i); 935 keys->AddKey(factory->NewNumberFromUint(i));
917 } 936 }
918 } 937 }
919 } 938 }
920 939
921 static Handle<FixedArray> DirectCollectElementIndicesImpl( 940 static Handle<FixedArray> DirectCollectElementIndicesImpl(
922 Isolate* isolate, Handle<JSObject> object, 941 Isolate* isolate, Handle<JSObject> object,
923 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 942 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
924 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 943 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
925 uint32_t insertion_index = 0) { 944 uint32_t insertion_index = 0) {
926 uint32_t length = Subclass::GetIterationLength(*object, *backing_store); 945 uint32_t length = Subclass::GetIterationLength(*object, *backing_store);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 // Collect the element indices into a new list. 980 // Collect the element indices into a new list.
962 uint32_t nof_indices = 0; 981 uint32_t nof_indices = 0;
963 Handle<FixedArray> combined_keys = 982 Handle<FixedArray> combined_keys =
964 isolate->factory()->NewFixedArray(initial_list_length); 983 isolate->factory()->NewFixedArray(initial_list_length);
965 combined_keys = Subclass::DirectCollectElementIndicesImpl( 984 combined_keys = Subclass::DirectCollectElementIndicesImpl(
966 isolate, object, backing_store, convert, filter, combined_keys, 985 isolate, object, backing_store, convert, filter, combined_keys,
967 &nof_indices); 986 &nof_indices);
968 987
969 // Sort the indices list if necessary. 988 // Sort the indices list if necessary.
970 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { 989 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) {
971 struct { 990 SortIndices(combined_keys, nof_indices, false);
972 bool operator()(Object* a, Object* b) {
973 if (!a->IsUndefined()) {
974 if (b->IsUndefined()) return true;
975 return a->Number() < b->Number();
976 }
977 return !b->IsUndefined();
978 }
979 } cmp;
980 Object** start =
981 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress());
982 std::sort(start, start + nof_indices, cmp);
983 uint32_t array_length = 0; 991 uint32_t array_length = 0;
984 // Indices from dictionary elements should only be converted after 992 // Indices from dictionary elements should only be converted after
985 // sorting. 993 // sorting.
986 if (convert == CONVERT_TO_STRING) { 994 if (convert == CONVERT_TO_STRING) {
987 for (uint32_t i = 0; i < nof_indices; i++) { 995 for (uint32_t i = 0; i < nof_indices; i++) {
988 Handle<Object> index_string = isolate->factory()->Uint32ToString( 996 Handle<Object> index_string = isolate->factory()->Uint32ToString(
989 combined_keys->get(i)->Number()); 997 combined_keys->get(i)->Number());
990 combined_keys->set(i, *index_string); 998 combined_keys->set(i, *index_string);
991 } 999 }
992 } else if (!(object->IsJSArray() && 1000 } else if (!(object->IsJSArray() &&
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 1083
1076 class DictionaryElementsAccessor 1084 class DictionaryElementsAccessor
1077 : public ElementsAccessorBase<DictionaryElementsAccessor, 1085 : public ElementsAccessorBase<DictionaryElementsAccessor,
1078 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1086 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1079 public: 1087 public:
1080 explicit DictionaryElementsAccessor(const char* name) 1088 explicit DictionaryElementsAccessor(const char* name)
1081 : ElementsAccessorBase<DictionaryElementsAccessor, 1089 : ElementsAccessorBase<DictionaryElementsAccessor,
1082 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1090 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1083 1091
1084 static uint32_t GetIterationLength(JSObject* receiver, 1092 static uint32_t GetIterationLength(JSObject* receiver,
1085 FixedArrayBase* elements) { 1093 FixedArrayBase* backing_store) {
1086 uint32_t length; 1094 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
1087 if (receiver->IsJSArray()) { 1095 return dict->NumberOfElements();
Jakob Kummerow 2016/05/23 16:25:21 In existing code, GetIterationLength is clearly ex
Camillo Bruni 2016/05/23 19:10:13 Renamed to GetMaxNumberOfElements, though the rest
1088 // Special-case GetIterationLength for dictionary elements since the
1089 // length of the array might be a HeapNumber.
1090 JSArray::cast(receiver)->length()->ToArrayLength(&length);
1091 } else {
1092 length = GetCapacityImpl(receiver, elements);
1093 }
1094 return length;
1095 } 1096 }
1096 1097
1097 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 1098 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
1098 uint32_t length, 1099 uint32_t length,
1099 Handle<FixedArrayBase> backing_store) { 1100 Handle<FixedArrayBase> backing_store) {
1100 Handle<SeededNumberDictionary> dict = 1101 Handle<SeededNumberDictionary> dict =
1101 Handle<SeededNumberDictionary>::cast(backing_store); 1102 Handle<SeededNumberDictionary>::cast(backing_store);
1102 int capacity = dict->Capacity(); 1103 int capacity = dict->Capacity();
1103 uint32_t old_length = 0; 1104 uint32_t old_length = 0;
1104 CHECK(array->length()->ToArrayLength(&old_length)); 1105 CHECK(array->length()->ToArrayLength(&old_length));
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 if (raw_key == undefined || raw_key == the_hole) { 1307 if (raw_key == undefined || raw_key == the_hole) {
1307 return kMaxUInt32; 1308 return kMaxUInt32;
1308 } 1309 }
1309 return FilterKey(dictionary, entry, raw_key, filter); 1310 return FilterKey(dictionary, entry, raw_key, filter);
1310 } 1311 }
1311 1312
1312 static void CollectElementIndicesImpl(Handle<JSObject> object, 1313 static void CollectElementIndicesImpl(Handle<JSObject> object,
1313 Handle<FixedArrayBase> backing_store, 1314 Handle<FixedArrayBase> backing_store,
1314 KeyAccumulator* keys) { 1315 KeyAccumulator* keys) {
1315 if (keys->filter() & SKIP_STRINGS) return; 1316 if (keys->filter() & SKIP_STRINGS) return;
1316 Isolate* isolate = keys->isolate(); 1317 Factory* factory = keys->isolate()->factory();
1317 Handle<Object> undefined = isolate->factory()->undefined_value(); 1318 Handle<Object> undefined = factory->undefined_value();
1318 Handle<Object> the_hole = isolate->factory()->the_hole_value(); 1319 Handle<Object> the_hole = factory->the_hole_value();
1319 Handle<SeededNumberDictionary> dictionary = 1320 Handle<SeededNumberDictionary> dictionary =
1320 Handle<SeededNumberDictionary>::cast(backing_store); 1321 Handle<SeededNumberDictionary>::cast(backing_store);
1321 int capacity = dictionary->Capacity(); 1322 int capacity = dictionary->Capacity();
1323 Handle<FixedArray> elements =
1324 factory->NewFixedArray(GetIterationLength(*object, *backing_store));
1325 int insertion_index = 0;
1322 PropertyFilter filter = keys->filter(); 1326 PropertyFilter filter = keys->filter();
1323 for (int i = 0; i < capacity; i++) { 1327 for (int i = 0; i < capacity; i++) {
1324 uint32_t key = 1328 uint32_t key =
1325 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); 1329 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
1326 if (key == kMaxUInt32) continue; 1330 if (key == kMaxUInt32) continue;
1327 keys->AddKey(key); 1331 elements->set(insertion_index, *factory->NewNumberFromUint(key));
1332 insertion_index++;
1328 } 1333 }
1329 1334 SortIndices(elements, insertion_index);
1330 keys->SortCurrentElementsList(); 1335 for (int i = 0; i < insertion_index; i++) {
1336 keys->AddKey(elements->get(i));
1337 }
1331 } 1338 }
1332 1339
1333 static Handle<FixedArray> DirectCollectElementIndicesImpl( 1340 static Handle<FixedArray> DirectCollectElementIndicesImpl(
1334 Isolate* isolate, Handle<JSObject> object, 1341 Isolate* isolate, Handle<JSObject> object,
1335 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 1342 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
1336 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 1343 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
1337 uint32_t insertion_index = 0) { 1344 uint32_t insertion_index = 0) {
1338 if (filter & SKIP_STRINGS) return list; 1345 if (filter & SKIP_STRINGS) return list;
1339 if (filter & ONLY_ALL_CAN_READ) return list; 1346 if (filter & ONLY_ALL_CAN_READ) return list;
1340 1347
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 // would enable GC of the context. 2386 // would enable GC of the context.
2380 parameter_map->set_the_hole(entry + 2); 2387 parameter_map->set_the_hole(entry + 2);
2381 } else { 2388 } else {
2382 Subclass::DeleteFromArguments(obj, entry - length); 2389 Subclass::DeleteFromArguments(obj, entry - length);
2383 } 2390 }
2384 } 2391 }
2385 2392
2386 static void CollectElementIndicesImpl(Handle<JSObject> object, 2393 static void CollectElementIndicesImpl(Handle<JSObject> object,
2387 Handle<FixedArrayBase> backing_store, 2394 Handle<FixedArrayBase> backing_store,
2388 KeyAccumulator* keys) { 2395 KeyAccumulator* keys) {
2389 FixedArray* parameter_map = FixedArray::cast(*backing_store); 2396 Isolate* isolate = keys->isolate();
2390 uint32_t length = parameter_map->length() - 2; 2397 uint32_t nof_indices = 0;
2391 for (uint32_t i = 0; i < length; ++i) { 2398 Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
2392 if (!parameter_map->get(i + 2)->IsTheHole()) { 2399 GetCapacityImpl(*object, *backing_store));
2393 keys->AddKey(i); 2400 DirectCollectElementIndicesImpl(isolate, object, backing_store,
2394 } 2401 KEEP_NUMBERS, ENUMERABLE_STRINGS, indices,
2395 } 2402 &nof_indices);
2396 2403 SortIndices(indices, nof_indices);
2397 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); 2404 for (uint32_t i = 0; i < nof_indices; i++) {
2398 ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys); 2405 keys->AddKey(indices->get(i));
2399 if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
2400 keys->SortCurrentElementsList();
2401 } 2406 }
2402 } 2407 }
2403 2408
2404 static Handle<FixedArray> DirectCollectElementIndicesImpl( 2409 static Handle<FixedArray> DirectCollectElementIndicesImpl(
2405 Isolate* isolate, Handle<JSObject> object, 2410 Isolate* isolate, Handle<JSObject> object,
2406 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 2411 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
2407 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 2412 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
2408 uint32_t insertion_index = 0) { 2413 uint32_t insertion_index = 0) {
2409 FixedArray* parameter_map = FixedArray::cast(*backing_store); 2414 FixedArray* parameter_map = FixedArray::cast(*backing_store);
2410 uint32_t length = parameter_map->length() - 2; 2415 uint32_t length = parameter_map->length() - 2;
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
2738 convert); 2743 convert);
2739 } 2744 }
2740 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, 2745 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator,
2741 convert); 2746 convert);
2742 } 2747 }
2743 2748
2744 static void CollectElementIndicesImpl(Handle<JSObject> object, 2749 static void CollectElementIndicesImpl(Handle<JSObject> object,
2745 Handle<FixedArrayBase> backing_store, 2750 Handle<FixedArrayBase> backing_store,
2746 KeyAccumulator* keys) { 2751 KeyAccumulator* keys) {
2747 uint32_t length = GetString(*object)->length(); 2752 uint32_t length = GetString(*object)->length();
2753 Factory* factory = keys->isolate()->factory();
2748 for (uint32_t i = 0; i < length; i++) { 2754 for (uint32_t i = 0; i < length; i++) {
2749 keys->AddKey(i); 2755 keys->AddKey(factory->NewNumberFromUint(i));
2750 } 2756 }
2751 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, 2757 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store,
2752 keys); 2758 keys);
2753 } 2759 }
2754 2760
2755 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 2761 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
2756 uint32_t capacity) { 2762 uint32_t capacity) {
2757 Handle<FixedArrayBase> old_elements(object->elements()); 2763 Handle<FixedArrayBase> old_elements(object->elements());
2758 ElementsKind from_kind = object->GetElementsKind(); 2764 ElementsKind from_kind = object->GetElementsKind();
2759 // This method should only be called if there's a reason to update the 2765 // This method should only be called if there's a reason to update the
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 insertion_index += len; 3030 insertion_index += len;
3025 } 3031 }
3026 3032
3027 DCHECK_EQ(insertion_index, result_len); 3033 DCHECK_EQ(insertion_index, result_len);
3028 return result_array; 3034 return result_array;
3029 } 3035 }
3030 3036
3031 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3037 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
3032 } // namespace internal 3038 } // namespace internal
3033 } // namespace v8 3039 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug-scopes.cc ('k') | src/json-stringifier.cc » ('j') | src/keys.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698