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