Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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( | |
| 449 Handle<FixedArray> indices, uint32_t sort_size, | |
| 450 WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER) { | |
| 451 struct { | |
| 452 bool operator()(Object* a, Object* b) { | |
| 453 if (!a->IsUndefined()) { | |
| 454 if (b->IsUndefined()) return true; | |
| 455 return a->Number() < b->Number(); | |
| 456 } | |
| 457 return b->IsUndefined(); | |
| 458 } | |
| 459 } cmp; | |
| 460 Object** start = | |
| 461 reinterpret_cast<Object**>(indices->GetFirstElementAddress()); | |
| 462 std::sort(start, start + sort_size, cmp); | |
| 463 if (write_barrier_mode != SKIP_WRITE_BARRIER) { | |
| 464 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices, | |
| 465 0, sort_size); | |
| 466 } | |
| 467 } | |
| 448 | 468 |
| 449 // Base class for element handler implementations. Contains the | 469 // Base class for element handler implementations. Contains the |
| 450 // the common logic for objects with different ElementsKinds. | 470 // the common logic for objects with different ElementsKinds. |
| 451 // Subclasses must specialize method for which the element | 471 // Subclasses must specialize method for which the element |
| 452 // implementation differs from the base class implementation. | 472 // implementation differs from the base class implementation. |
| 453 // | 473 // |
| 454 // This class is intended to be used in the following way: | 474 // This class is intended to be used in the following way: |
| 455 // | 475 // |
| 456 // class SomeElementsAccessor : | 476 // class SomeElementsAccessor : |
| 457 // public ElementsAccessorBase<SomeElementsAccessor, | 477 // public ElementsAccessorBase<SomeElementsAccessor, |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 } else { | 722 } else { |
| 703 // Check whether the backing store should be expanded. | 723 // Check whether the backing store should be expanded. |
| 704 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 724 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
| 705 Subclass::GrowCapacityAndConvertImpl(array, capacity); | 725 Subclass::GrowCapacityAndConvertImpl(array, capacity); |
| 706 } | 726 } |
| 707 | 727 |
| 708 array->set_length(Smi::FromInt(length)); | 728 array->set_length(Smi::FromInt(length)); |
| 709 JSObject::ValidateElements(array); | 729 JSObject::ValidateElements(array); |
| 710 } | 730 } |
| 711 | 731 |
| 712 static uint32_t GetIterationLength(JSObject* receiver, | 732 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
| 713 FixedArrayBase* elements) { | |
| 714 if (receiver->IsJSArray()) { | 733 if (receiver->IsJSArray()) { |
| 715 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); | 734 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); |
| 716 return static_cast<uint32_t>( | 735 return static_cast<uint32_t>( |
| 717 Smi::cast(JSArray::cast(receiver)->length())->value()); | 736 Smi::cast(JSArray::cast(receiver)->length())->value()); |
| 718 } | 737 } |
| 719 return Subclass::GetCapacityImpl(receiver, elements); | 738 return Subclass::GetCapacityImpl(receiver, elements); |
| 720 } | 739 } |
| 721 | 740 |
| 741 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, | |
| 742 FixedArrayBase* elements) { | |
| 743 return Subclass::GetMaxIndex(receiver, elements); | |
| 744 } | |
| 745 | |
| 722 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 746 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
| 723 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 747 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
| 724 ElementsKind from_kind, uint32_t capacity) { | 748 ElementsKind from_kind, uint32_t capacity) { |
| 725 return ConvertElementsWithCapacity( | 749 return ConvertElementsWithCapacity( |
| 726 object, old_elements, from_kind, capacity, 0, 0, | 750 object, old_elements, from_kind, capacity, 0, 0, |
| 727 ElementsAccessor::kCopyToEndAndInitializeToHole); | 751 ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 728 } | 752 } |
| 729 | 753 |
| 730 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 754 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
| 731 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 755 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 856 return Subclass::CollectValuesOrEntriesImpl( | 880 return Subclass::CollectValuesOrEntriesImpl( |
| 857 isolate, object, values_or_entries, get_entries, nof_items, filter); | 881 isolate, object, values_or_entries, get_entries, nof_items, filter); |
| 858 } | 882 } |
| 859 | 883 |
| 860 static Maybe<bool> CollectValuesOrEntriesImpl( | 884 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 861 Isolate* isolate, Handle<JSObject> object, | 885 Isolate* isolate, Handle<JSObject> object, |
| 862 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, | 886 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 863 PropertyFilter filter) { | 887 PropertyFilter filter) { |
| 864 int count = 0; | 888 int count = 0; |
| 865 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); | 889 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
| 866 accumulator.NextPrototype(); | |
| 867 Subclass::CollectElementIndicesImpl( | 890 Subclass::CollectElementIndicesImpl( |
| 868 object, handle(object->elements(), isolate), &accumulator); | 891 object, handle(object->elements(), isolate), &accumulator); |
| 869 Handle<FixedArray> keys = accumulator.GetKeys(); | 892 Handle<FixedArray> keys = accumulator.GetKeys(); |
| 870 | 893 |
| 871 for (int i = 0; i < keys->length(); ++i) { | 894 for (int i = 0; i < keys->length(); ++i) { |
| 872 Handle<Object> key(keys->get(i), isolate); | 895 Handle<Object> key(keys->get(i), isolate); |
| 873 Handle<Object> value; | 896 Handle<Object> value; |
| 874 uint32_t index; | 897 uint32_t index; |
| 875 if (!key->ToUint32(&index)) continue; | 898 if (!key->ToUint32(&index)) continue; |
| 876 | 899 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 902 KeyAccumulator* keys) final { | 925 KeyAccumulator* keys) final { |
| 903 if (keys->filter() & ONLY_ALL_CAN_READ) return; | 926 if (keys->filter() & ONLY_ALL_CAN_READ) return; |
| 904 Subclass::CollectElementIndicesImpl(object, backing_store, keys); | 927 Subclass::CollectElementIndicesImpl(object, backing_store, keys); |
| 905 } | 928 } |
| 906 | 929 |
| 907 static void CollectElementIndicesImpl(Handle<JSObject> object, | 930 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 908 Handle<FixedArrayBase> backing_store, | 931 Handle<FixedArrayBase> backing_store, |
| 909 KeyAccumulator* keys) { | 932 KeyAccumulator* keys) { |
| 910 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 933 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
| 911 // Non-dictionary elements can't have all-can-read accessors. | 934 // Non-dictionary elements can't have all-can-read accessors. |
| 912 uint32_t length = GetIterationLength(*object, *backing_store); | 935 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
| 913 PropertyFilter filter = keys->filter(); | 936 PropertyFilter filter = keys->filter(); |
| 937 Factory* factory = keys->isolate()->factory(); | |
| 914 for (uint32_t i = 0; i < length; i++) { | 938 for (uint32_t i = 0; i < length; i++) { |
| 915 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 939 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
| 916 keys->AddKey(i); | 940 keys->AddKey(factory->NewNumberFromUint(i)); |
| 917 } | 941 } |
| 918 } | 942 } |
| 919 } | 943 } |
| 920 | 944 |
| 921 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 945 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
| 922 Isolate* isolate, Handle<JSObject> object, | 946 Isolate* isolate, Handle<JSObject> object, |
| 923 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 947 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
| 924 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 948 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 925 uint32_t insertion_index = 0) { | 949 uint32_t insertion_index = 0) { |
| 926 uint32_t length = Subclass::GetIterationLength(*object, *backing_store); | 950 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
| 927 for (uint32_t i = 0; i < length; i++) { | 951 for (uint32_t i = 0; i < length; i++) { |
| 928 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 952 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
| 929 if (convert == CONVERT_TO_STRING) { | 953 if (convert == CONVERT_TO_STRING) { |
| 930 Handle<String> index_string = isolate->factory()->Uint32ToString(i); | 954 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
| 931 list->set(insertion_index, *index_string); | 955 list->set(insertion_index, *index_string); |
| 932 } else { | 956 } else { |
| 933 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); | 957 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
| 934 } | 958 } |
| 935 insertion_index++; | 959 insertion_index++; |
| 936 } | 960 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 961 // Collect the element indices into a new list. | 985 // Collect the element indices into a new list. |
| 962 uint32_t nof_indices = 0; | 986 uint32_t nof_indices = 0; |
| 963 Handle<FixedArray> combined_keys = | 987 Handle<FixedArray> combined_keys = |
| 964 isolate->factory()->NewFixedArray(initial_list_length); | 988 isolate->factory()->NewFixedArray(initial_list_length); |
| 965 combined_keys = Subclass::DirectCollectElementIndicesImpl( | 989 combined_keys = Subclass::DirectCollectElementIndicesImpl( |
| 966 isolate, object, backing_store, convert, filter, combined_keys, | 990 isolate, object, backing_store, convert, filter, combined_keys, |
| 967 &nof_indices); | 991 &nof_indices); |
| 968 | 992 |
| 969 // Sort the indices list if necessary. | 993 // Sort the indices list if necessary. |
| 970 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { | 994 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { |
| 971 struct { | 995 SortIndices(combined_keys, nof_indices, SKIP_WRITE_BARRIER); |
| 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; | 996 uint32_t array_length = 0; |
| 984 // Indices from dictionary elements should only be converted after | 997 // Indices from dictionary elements should only be converted after |
| 985 // sorting. | 998 // sorting. |
| 986 if (convert == CONVERT_TO_STRING) { | 999 if (convert == CONVERT_TO_STRING) { |
| 987 for (uint32_t i = 0; i < nof_indices; i++) { | 1000 for (uint32_t i = 0; i < nof_indices; i++) { |
| 988 Handle<Object> index_string = isolate->factory()->Uint32ToString( | 1001 Handle<Object> index_string = isolate->factory()->Uint32ToString( |
| 989 combined_keys->get(i)->Number()); | 1002 combined_keys->get(i)->Number()); |
| 990 combined_keys->set(i, *index_string); | 1003 combined_keys->set(i, *index_string); |
| 991 } | 1004 } |
| 992 } else if (!(object->IsJSArray() && | 1005 } else if (!(object->IsJSArray() && |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 | 1050 |
| 1038 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1051 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
| 1039 FixedArrayBase* backing_store, | 1052 FixedArrayBase* backing_store, |
| 1040 uint32_t index, PropertyFilter filter) { | 1053 uint32_t index, PropertyFilter filter) { |
| 1041 if (IsHoleyElementsKind(kind())) { | 1054 if (IsHoleyElementsKind(kind())) { |
| 1042 return index < Subclass::GetCapacityImpl(holder, backing_store) && | 1055 return index < Subclass::GetCapacityImpl(holder, backing_store) && |
| 1043 !BackingStore::cast(backing_store)->is_the_hole(index) | 1056 !BackingStore::cast(backing_store)->is_the_hole(index) |
| 1044 ? index | 1057 ? index |
| 1045 : kMaxUInt32; | 1058 : kMaxUInt32; |
| 1046 } else { | 1059 } else { |
| 1047 uint32_t length = GetIterationLength(holder, backing_store); | 1060 uint32_t length = Subclass::GetMaxIndex(holder, backing_store); |
| 1048 return index < length ? index : kMaxUInt32; | 1061 return index < length ? index : kMaxUInt32; |
| 1049 } | 1062 } |
| 1050 } | 1063 } |
| 1051 | 1064 |
| 1052 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, | 1065 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, |
| 1053 uint32_t index) final { | 1066 uint32_t index) final { |
| 1054 return Subclass::GetEntryForIndexImpl(holder, backing_store, index, | 1067 return Subclass::GetEntryForIndexImpl(holder, backing_store, index, |
| 1055 ALL_PROPERTIES); | 1068 ALL_PROPERTIES); |
| 1056 } | 1069 } |
| 1057 | 1070 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1074 | 1087 |
| 1075 | 1088 |
| 1076 class DictionaryElementsAccessor | 1089 class DictionaryElementsAccessor |
| 1077 : public ElementsAccessorBase<DictionaryElementsAccessor, | 1090 : public ElementsAccessorBase<DictionaryElementsAccessor, |
| 1078 ElementsKindTraits<DICTIONARY_ELEMENTS> > { | 1091 ElementsKindTraits<DICTIONARY_ELEMENTS> > { |
| 1079 public: | 1092 public: |
| 1080 explicit DictionaryElementsAccessor(const char* name) | 1093 explicit DictionaryElementsAccessor(const char* name) |
| 1081 : ElementsAccessorBase<DictionaryElementsAccessor, | 1094 : ElementsAccessorBase<DictionaryElementsAccessor, |
| 1082 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} | 1095 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
| 1083 | 1096 |
| 1084 static uint32_t GetIterationLength(JSObject* receiver, | 1097 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
| 1085 FixedArrayBase* elements) { | |
| 1086 uint32_t length; | |
| 1087 if (receiver->IsJSArray()) { | 1098 if (receiver->IsJSArray()) { |
| 1088 // Special-case GetIterationLength for dictionary elements since the | 1099 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); |
|
Jakob Kummerow
2016/05/24 13:19:58
Nope! Dictionary arrays can have heap number lengt
| |
| 1089 // length of the array might be a HeapNumber. | 1100 return static_cast<uint32_t>( |
| 1090 JSArray::cast(receiver)->length()->ToArrayLength(&length); | 1101 Smi::cast(JSArray::cast(receiver)->length())->value()); |
| 1091 } else { | |
| 1092 length = GetCapacityImpl(receiver, elements); | |
| 1093 } | 1102 } |
| 1094 return length; | 1103 // We don't properly estimate the MaxIndex for dictionaries. |
| 1104 return kMaxUInt32; | |
| 1105 } | |
| 1106 | |
| 1107 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, | |
| 1108 FixedArrayBase* backing_store) { | |
| 1109 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); | |
| 1110 return dict->NumberOfElements(); | |
| 1095 } | 1111 } |
| 1096 | 1112 |
| 1097 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 1113 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
| 1098 uint32_t length, | 1114 uint32_t length, |
| 1099 Handle<FixedArrayBase> backing_store) { | 1115 Handle<FixedArrayBase> backing_store) { |
| 1100 Handle<SeededNumberDictionary> dict = | 1116 Handle<SeededNumberDictionary> dict = |
| 1101 Handle<SeededNumberDictionary>::cast(backing_store); | 1117 Handle<SeededNumberDictionary>::cast(backing_store); |
| 1102 int capacity = dict->Capacity(); | 1118 int capacity = dict->Capacity(); |
| 1103 uint32_t old_length = 0; | 1119 uint32_t old_length = 0; |
| 1104 CHECK(array->length()->ToArrayLength(&old_length)); | 1120 CHECK(array->length()->ToArrayLength(&old_length)); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1306 if (raw_key == undefined || raw_key == the_hole) { | 1322 if (raw_key == undefined || raw_key == the_hole) { |
| 1307 return kMaxUInt32; | 1323 return kMaxUInt32; |
| 1308 } | 1324 } |
| 1309 return FilterKey(dictionary, entry, raw_key, filter); | 1325 return FilterKey(dictionary, entry, raw_key, filter); |
| 1310 } | 1326 } |
| 1311 | 1327 |
| 1312 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1328 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 1313 Handle<FixedArrayBase> backing_store, | 1329 Handle<FixedArrayBase> backing_store, |
| 1314 KeyAccumulator* keys) { | 1330 KeyAccumulator* keys) { |
| 1315 if (keys->filter() & SKIP_STRINGS) return; | 1331 if (keys->filter() & SKIP_STRINGS) return; |
| 1316 Isolate* isolate = keys->isolate(); | 1332 Factory* factory = keys->isolate()->factory(); |
| 1317 Handle<Object> undefined = isolate->factory()->undefined_value(); | 1333 Handle<Object> undefined = factory->undefined_value(); |
| 1318 Handle<Object> the_hole = isolate->factory()->the_hole_value(); | 1334 Handle<Object> the_hole = factory->the_hole_value(); |
| 1319 Handle<SeededNumberDictionary> dictionary = | 1335 Handle<SeededNumberDictionary> dictionary = |
| 1320 Handle<SeededNumberDictionary>::cast(backing_store); | 1336 Handle<SeededNumberDictionary>::cast(backing_store); |
| 1321 int capacity = dictionary->Capacity(); | 1337 int capacity = dictionary->Capacity(); |
| 1338 Handle<FixedArray> elements = | |
| 1339 factory->NewFixedArray(GetMaxNumberOfEntries(*object, *backing_store)); | |
| 1340 int insertion_index = 0; | |
| 1322 PropertyFilter filter = keys->filter(); | 1341 PropertyFilter filter = keys->filter(); |
| 1323 for (int i = 0; i < capacity; i++) { | 1342 for (int i = 0; i < capacity; i++) { |
| 1324 uint32_t key = | 1343 uint32_t key = |
| 1325 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); | 1344 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); |
| 1326 if (key == kMaxUInt32) continue; | 1345 if (key == kMaxUInt32) continue; |
| 1327 keys->AddKey(key); | 1346 elements->set(insertion_index, *factory->NewNumberFromUint(key)); |
| 1347 insertion_index++; | |
| 1328 } | 1348 } |
| 1329 | 1349 SortIndices(elements, insertion_index); |
| 1330 keys->SortCurrentElementsList(); | 1350 for (int i = 0; i < insertion_index; i++) { |
| 1351 keys->AddKey(elements->get(i)); | |
| 1352 } | |
| 1331 } | 1353 } |
| 1332 | 1354 |
| 1333 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 1355 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
| 1334 Isolate* isolate, Handle<JSObject> object, | 1356 Isolate* isolate, Handle<JSObject> object, |
| 1335 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 1357 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
| 1336 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 1358 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 1337 uint32_t insertion_index = 0) { | 1359 uint32_t insertion_index = 0) { |
| 1338 if (filter & SKIP_STRINGS) return list; | 1360 if (filter & SKIP_STRINGS) return list; |
| 1339 if (filter & ONLY_ALL_CAN_READ) return list; | 1361 if (filter & ONLY_ALL_CAN_READ) return list; |
| 1340 | 1362 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1545 } | 1567 } |
| 1546 | 1568 |
| 1547 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 1569 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
| 1548 return !BackingStore::cast(backing_store)->is_the_hole(entry); | 1570 return !BackingStore::cast(backing_store)->is_the_hole(entry); |
| 1549 } | 1571 } |
| 1550 | 1572 |
| 1551 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1573 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
| 1552 KeyAccumulator* accumulator, | 1574 KeyAccumulator* accumulator, |
| 1553 AddKeyConversion convert) { | 1575 AddKeyConversion convert) { |
| 1554 Handle<FixedArrayBase> elements(receiver->elements(), | 1576 Handle<FixedArrayBase> elements(receiver->elements(), |
| 1555 receiver->GetIsolate()); | 1577 accumulator->isolate()); |
| 1556 uint32_t length = Subclass::GetIterationLength(*receiver, *elements); | 1578 uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); |
| 1557 for (uint32_t i = 0; i < length; i++) { | 1579 for (uint32_t i = 0; i < length; i++) { |
| 1558 if (IsFastPackedElementsKind(KindTraits::Kind) || | 1580 if (IsFastPackedElementsKind(KindTraits::Kind) || |
| 1559 HasEntryImpl(*elements, i)) { | 1581 HasEntryImpl(*elements, i)) { |
| 1560 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); | 1582 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); |
| 1561 } | 1583 } |
| 1562 } | 1584 } |
| 1563 } | 1585 } |
| 1564 | 1586 |
| 1565 static void ValidateContents(Handle<JSObject> holder, int length) { | 1587 static void ValidateContents(Handle<JSObject> holder, int length) { |
| 1566 #if DEBUG | 1588 #if DEBUG |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2379 // would enable GC of the context. | 2401 // would enable GC of the context. |
| 2380 parameter_map->set_the_hole(entry + 2); | 2402 parameter_map->set_the_hole(entry + 2); |
| 2381 } else { | 2403 } else { |
| 2382 Subclass::DeleteFromArguments(obj, entry - length); | 2404 Subclass::DeleteFromArguments(obj, entry - length); |
| 2383 } | 2405 } |
| 2384 } | 2406 } |
| 2385 | 2407 |
| 2386 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2408 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 2387 Handle<FixedArrayBase> backing_store, | 2409 Handle<FixedArrayBase> backing_store, |
| 2388 KeyAccumulator* keys) { | 2410 KeyAccumulator* keys) { |
| 2389 FixedArray* parameter_map = FixedArray::cast(*backing_store); | 2411 Isolate* isolate = keys->isolate(); |
| 2390 uint32_t length = parameter_map->length() - 2; | 2412 uint32_t nof_indices = 0; |
| 2391 for (uint32_t i = 0; i < length; ++i) { | 2413 Handle<FixedArray> indices = isolate->factory()->NewFixedArray( |
| 2392 if (!parameter_map->get(i + 2)->IsTheHole()) { | 2414 GetCapacityImpl(*object, *backing_store)); |
| 2393 keys->AddKey(i); | 2415 DirectCollectElementIndicesImpl(isolate, object, backing_store, |
| 2394 } | 2416 KEEP_NUMBERS, ENUMERABLE_STRINGS, indices, |
| 2395 } | 2417 &nof_indices); |
| 2396 | 2418 SortIndices(indices, nof_indices); |
| 2397 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); | 2419 for (uint32_t i = 0; i < nof_indices; i++) { |
| 2398 ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys); | 2420 keys->AddKey(indices->get(i)); |
| 2399 if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { | |
| 2400 keys->SortCurrentElementsList(); | |
| 2401 } | 2421 } |
| 2402 } | 2422 } |
| 2403 | 2423 |
| 2404 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 2424 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
| 2405 Isolate* isolate, Handle<JSObject> object, | 2425 Isolate* isolate, Handle<JSObject> object, |
| 2406 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 2426 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
| 2407 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 2427 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 2408 uint32_t insertion_index = 0) { | 2428 uint32_t insertion_index = 0) { |
| 2409 FixedArray* parameter_map = FixedArray::cast(*backing_store); | 2429 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
| 2410 uint32_t length = parameter_map->length() - 2; | 2430 uint32_t length = parameter_map->length() - 2; |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2738 convert); | 2758 convert); |
| 2739 } | 2759 } |
| 2740 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, | 2760 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, |
| 2741 convert); | 2761 convert); |
| 2742 } | 2762 } |
| 2743 | 2763 |
| 2744 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2764 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 2745 Handle<FixedArrayBase> backing_store, | 2765 Handle<FixedArrayBase> backing_store, |
| 2746 KeyAccumulator* keys) { | 2766 KeyAccumulator* keys) { |
| 2747 uint32_t length = GetString(*object)->length(); | 2767 uint32_t length = GetString(*object)->length(); |
| 2768 Factory* factory = keys->isolate()->factory(); | |
| 2748 for (uint32_t i = 0; i < length; i++) { | 2769 for (uint32_t i = 0; i < length; i++) { |
| 2749 keys->AddKey(i); | 2770 keys->AddKey(factory->NewNumberFromUint(i)); |
| 2750 } | 2771 } |
| 2751 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, | 2772 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, |
| 2752 keys); | 2773 keys); |
| 2753 } | 2774 } |
| 2754 | 2775 |
| 2755 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, | 2776 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, |
| 2756 uint32_t capacity) { | 2777 uint32_t capacity) { |
| 2757 Handle<FixedArrayBase> old_elements(object->elements()); | 2778 Handle<FixedArrayBase> old_elements(object->elements()); |
| 2758 ElementsKind from_kind = object->GetElementsKind(); | 2779 ElementsKind from_kind = object->GetElementsKind(); |
| 2759 // This method should only be called if there's a reason to update the | 2780 // 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 Loading... | |
| 3024 insertion_index += len; | 3045 insertion_index += len; |
| 3025 } | 3046 } |
| 3026 | 3047 |
| 3027 DCHECK_EQ(insertion_index, result_len); | 3048 DCHECK_EQ(insertion_index, result_len); |
| 3028 return result_array; | 3049 return result_array; |
| 3029 } | 3050 } |
| 3030 | 3051 |
| 3031 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3052 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 3032 } // namespace internal | 3053 } // namespace internal |
| 3033 } // namespace v8 | 3054 } // namespace v8 |
| OLD | NEW |