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/messages.h" | 10 #include "src/messages.h" |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 for (int i = 0; i < copy_size; i++) { | 421 for (int i = 0; i < copy_size; i++) { |
422 int entry = from->FindEntry(i + from_start); | 422 int entry = from->FindEntry(i + from_start); |
423 if (entry != SeededNumberDictionary::kNotFound) { | 423 if (entry != SeededNumberDictionary::kNotFound) { |
424 to->set(i + to_start, from->ValueAt(entry)->Number()); | 424 to->set(i + to_start, from->ValueAt(entry)->Number()); |
425 } else { | 425 } else { |
426 to->set_the_hole(i + to_start); | 426 to->set_the_hole(i + to_start); |
427 } | 427 } |
428 } | 428 } |
429 } | 429 } |
430 | 430 |
431 | |
432 static void TraceTopFrame(Isolate* isolate) { | 431 static void TraceTopFrame(Isolate* isolate) { |
433 StackFrameIterator it(isolate); | 432 StackFrameIterator it(isolate); |
434 if (it.done()) { | 433 if (it.done()) { |
435 PrintF("unknown location (no JavaScript frames present)"); | 434 PrintF("unknown location (no JavaScript frames present)"); |
436 return; | 435 return; |
437 } | 436 } |
438 StackFrame* raw_frame = it.frame(); | 437 StackFrame* raw_frame = it.frame(); |
439 if (raw_frame->is_internal()) { | 438 if (raw_frame->is_internal()) { |
440 Code* apply_builtin = | 439 Code* apply_builtin = |
441 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); | 440 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 } else { | 722 } else { |
724 // Check whether the backing store should be expanded. | 723 // Check whether the backing store should be expanded. |
725 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 724 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
726 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); | 725 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); |
727 } | 726 } |
728 | 727 |
729 array->set_length(Smi::FromInt(length)); | 728 array->set_length(Smi::FromInt(length)); |
730 JSObject::ValidateElements(array); | 729 JSObject::ValidateElements(array); |
731 } | 730 } |
732 | 731 |
| 732 static uint32_t GetIterationLength(JSObject* receiver, |
| 733 FixedArrayBase* elements) { |
| 734 if (receiver->IsJSArray()) { |
| 735 return static_cast<uint32_t>( |
| 736 Smi::cast(JSArray::cast(receiver)->length())->value()); |
| 737 } else { |
| 738 return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements); |
| 739 } |
| 740 } |
| 741 |
733 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 742 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
734 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 743 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
735 ElementsKind from_kind, uint32_t capacity) { | 744 ElementsKind from_kind, uint32_t capacity) { |
736 return ConvertElementsWithCapacity( | 745 return ConvertElementsWithCapacity( |
737 object, old_elements, from_kind, capacity, 0, 0, | 746 object, old_elements, from_kind, capacity, 0, 0, |
738 ElementsAccessor::kCopyToEndAndInitializeToHole); | 747 ElementsAccessor::kCopyToEndAndInitializeToHole); |
739 } | 748 } |
740 | 749 |
741 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 750 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
742 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 751 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 // intentionally to avoid ArrayConcat() builtin performance degradation. | 848 // intentionally to avoid ArrayConcat() builtin performance degradation. |
840 // | 849 // |
841 // Details: The idea is that allocations actually happen only in case of | 850 // Details: The idea is that allocations actually happen only in case of |
842 // copying from object with fast double elements to object with object | 851 // copying from object with fast double elements to object with object |
843 // elements. In all the other cases there are no allocations performed and | 852 // elements. In all the other cases there are no allocations performed and |
844 // handle creation causes noticeable performance degradation of the builtin. | 853 // handle creation causes noticeable performance degradation of the builtin. |
845 ElementsAccessorSubclass::CopyElementsImpl( | 854 ElementsAccessorSubclass::CopyElementsImpl( |
846 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 855 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
847 } | 856 } |
848 | 857 |
| 858 void CollectElementIndices(Handle<JSObject> object, |
| 859 Handle<FixedArrayBase> backing_store, |
| 860 KeyAccumulator* keys, uint32_t range, |
| 861 PropertyFilter filter, uint32_t offset) final { |
| 862 ElementsAccessorSubclass::CollectElementIndicesImpl( |
| 863 object, backing_store, keys, range, filter, offset); |
| 864 } |
| 865 |
849 static void CollectElementIndicesImpl(Handle<JSObject> object, | 866 static void CollectElementIndicesImpl(Handle<JSObject> object, |
850 Handle<FixedArrayBase> backing_store, | 867 Handle<FixedArrayBase> backing_store, |
851 KeyAccumulator* keys, uint32_t range, | 868 KeyAccumulator* keys, uint32_t range, |
852 PropertyFilter filter, | 869 PropertyFilter filter, |
853 uint32_t offset) { | 870 uint32_t offset) { |
854 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 871 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
855 if (filter & ONLY_ALL_CAN_READ) { | 872 if (filter & ONLY_ALL_CAN_READ) { |
856 // Non-dictionary elements can't have all-can-read accessors. | 873 // Non-dictionary elements can't have all-can-read accessors. |
857 return; | 874 return; |
858 } | 875 } |
859 uint32_t length = 0; | 876 uint32_t length = GetIterationLength(*object, *backing_store); |
860 if (object->IsJSArray()) { | |
861 length = Smi::cast(JSArray::cast(*object)->length())->value(); | |
862 } else { | |
863 length = | |
864 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); | |
865 } | |
866 if (range < length) length = range; | 877 if (range < length) length = range; |
867 for (uint32_t i = offset; i < length; i++) { | 878 for (uint32_t i = offset; i < length; i++) { |
868 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | 879 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
869 filter)) { | 880 filter)) { |
870 continue; | 881 keys->AddKey(i); |
871 } | 882 } |
872 keys->AddKey(i); | |
873 } | 883 } |
874 } | 884 } |
875 | 885 |
876 void CollectElementIndices(Handle<JSObject> object, | 886 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
877 Handle<FixedArrayBase> backing_store, | 887 Isolate* isolate, Handle<JSObject> object, |
878 KeyAccumulator* keys, uint32_t range, | 888 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
879 PropertyFilter filter, uint32_t offset) final { | 889 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { |
880 ElementsAccessorSubclass::CollectElementIndicesImpl( | 890 uint32_t length = |
881 object, backing_store, keys, range, filter, offset); | 891 ElementsAccessorSubclass::GetIterationLength(*object, *backing_store); |
882 }; | 892 uint32_t insertion_index = 0; |
| 893 for (uint32_t i = 0; i < length; i++) { |
| 894 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
| 895 filter)) { |
| 896 if (convert == CONVERT_TO_STRING) { |
| 897 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
| 898 list->set(insertion_index, *index_string); |
| 899 } else { |
| 900 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
| 901 } |
| 902 insertion_index++; |
| 903 } |
| 904 } |
| 905 *nof_indices = insertion_index; |
| 906 return list; |
| 907 } |
| 908 |
| 909 Handle<FixedArray> PrependElementIndices(Handle<JSObject> object, |
| 910 Handle<FixedArrayBase> backing_store, |
| 911 Handle<FixedArray> keys, |
| 912 GetKeysConversion convert, |
| 913 PropertyFilter filter) final { |
| 914 return ElementsAccessorSubclass::PrependElementIndicesImpl( |
| 915 object, backing_store, keys, convert, filter); |
| 916 } |
| 917 |
| 918 static Handle<FixedArray> PrependElementIndicesImpl( |
| 919 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, |
| 920 Handle<FixedArray> keys, GetKeysConversion convert, |
| 921 PropertyFilter filter) { |
| 922 Isolate* isolate = object->GetIsolate(); |
| 923 uint32_t nof_property_keys = keys->length(); |
| 924 uint32_t initial_list_length = |
| 925 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); |
| 926 initial_list_length += nof_property_keys; |
| 927 |
| 928 // Collect the element indices into a new list. |
| 929 uint32_t nof_indices = 0; |
| 930 Handle<FixedArray> combined_keys = |
| 931 isolate->factory()->NewFixedArray(initial_list_length); |
| 932 combined_keys = ElementsAccessorSubclass::DirectCollectElementIndicesImpl( |
| 933 isolate, object, backing_store, convert, filter, combined_keys, |
| 934 &nof_indices); |
| 935 |
| 936 // Sort the indices list if necessary. |
| 937 if (IsDictionaryElementsKind(kind())) { |
| 938 struct { |
| 939 bool operator()(Object* a, Object* b) { |
| 940 if (!a->IsUndefined()) { |
| 941 if (b->IsUndefined()) return true; |
| 942 return a->Number() < b->Number(); |
| 943 } |
| 944 return !b->IsUndefined(); |
| 945 } |
| 946 } cmp; |
| 947 Object** start = |
| 948 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress()); |
| 949 std::sort(start, start + nof_indices, cmp); |
| 950 // Indices from dictionary elements should only be converted after |
| 951 // sorting. |
| 952 if (convert == CONVERT_TO_STRING) { |
| 953 for (uint32_t i = 0; i < nof_indices; i++) { |
| 954 Handle<Object> index_string = isolate->factory()->Uint32ToString( |
| 955 combined_keys->get(i)->Number()); |
| 956 combined_keys->set(i, *index_string); |
| 957 } |
| 958 } |
| 959 } |
| 960 |
| 961 // Copy over the passed-in property keys. |
| 962 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, |
| 963 FAST_ELEMENTS, nof_indices, nof_property_keys); |
| 964 |
| 965 if (IsHoleyElementsKind(kind())) { |
| 966 // Shrink combined_keys to the final size. |
| 967 int final_size = nof_indices + nof_property_keys; |
| 968 DCHECK_LE(final_size, combined_keys->length()); |
| 969 combined_keys->Shrink(final_size); |
| 970 } |
| 971 |
| 972 return combined_keys; |
| 973 } |
883 | 974 |
884 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, | 975 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
885 KeyAccumulator* accumulator, | 976 KeyAccumulator* accumulator, |
886 AddKeyConversion convert) final { | 977 AddKeyConversion convert) final { |
887 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl( | 978 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl( |
888 receiver, accumulator, convert); | 979 receiver, accumulator, convert); |
889 } | 980 } |
890 | 981 |
891 static uint32_t GetCapacityImpl(JSObject* holder, | 982 static uint32_t GetCapacityImpl(JSObject* holder, |
892 FixedArrayBase* backing_store) { | 983 FixedArrayBase* backing_store) { |
(...skipping 12 matching lines...) Expand all Loading... |
905 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 996 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
906 FixedArrayBase* backing_store, | 997 FixedArrayBase* backing_store, |
907 uint32_t index, PropertyFilter filter) { | 998 uint32_t index, PropertyFilter filter) { |
908 if (IsHoleyElementsKind(kind())) { | 999 if (IsHoleyElementsKind(kind())) { |
909 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, | 1000 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, |
910 backing_store) && | 1001 backing_store) && |
911 !BackingStore::cast(backing_store)->is_the_hole(index) | 1002 !BackingStore::cast(backing_store)->is_the_hole(index) |
912 ? index | 1003 ? index |
913 : kMaxUInt32; | 1004 : kMaxUInt32; |
914 } else { | 1005 } else { |
915 uint32_t length = | 1006 uint32_t length = GetIterationLength(holder, backing_store); |
916 holder->IsJSArray() | |
917 ? static_cast<uint32_t>( | |
918 Smi::cast(JSArray::cast(holder)->length())->value()) | |
919 : ElementsAccessorSubclass::GetCapacityImpl(holder, | |
920 backing_store); | |
921 return index < length ? index : kMaxUInt32; | 1007 return index < length ? index : kMaxUInt32; |
922 } | 1008 } |
923 } | 1009 } |
924 | 1010 |
925 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, | 1011 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, |
926 uint32_t index) final { | 1012 uint32_t index) final { |
927 return ElementsAccessorSubclass::GetEntryForIndexImpl( | 1013 return ElementsAccessorSubclass::GetEntryForIndexImpl( |
928 holder, backing_store, index, ALL_PROPERTIES); | 1014 holder, backing_store, index, ALL_PROPERTIES); |
929 } | 1015 } |
930 | 1016 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 | 1198 |
1113 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 1199 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
1114 return GetDetailsImpl(holder->elements(), entry); | 1200 return GetDetailsImpl(holder->elements(), entry); |
1115 } | 1201 } |
1116 | 1202 |
1117 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1203 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
1118 uint32_t entry) { | 1204 uint32_t entry) { |
1119 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); | 1205 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
1120 } | 1206 } |
1121 | 1207 |
| 1208 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, |
| 1209 int entry, PropertyFilter filter) { |
| 1210 DisallowHeapAllocation no_gc; |
| 1211 Object* raw_key = dictionary->KeyAt(entry); |
| 1212 if (!dictionary->IsKey(raw_key)) return kMaxUInt32; |
| 1213 if (raw_key->FilterKey(filter)) return kMaxUInt32; |
| 1214 if (dictionary->IsDeleted(entry)) return kMaxUInt32; |
| 1215 DCHECK(raw_key->IsNumber()); |
| 1216 DCHECK_LE(raw_key->Number(), kMaxUInt32); |
| 1217 uint32_t key = static_cast<uint32_t>(raw_key->Number()); |
| 1218 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1219 if (filter & ONLY_ALL_CAN_READ) { |
| 1220 if (details.kind() != kAccessor) return kMaxUInt32; |
| 1221 Object* accessors = dictionary->ValueAt(entry); |
| 1222 if (!accessors->IsAccessorInfo()) return kMaxUInt32; |
| 1223 if (!AccessorInfo::cast(accessors)->all_can_read()) return kMaxUInt32; |
| 1224 } |
| 1225 PropertyAttributes attr = details.attributes(); |
| 1226 if ((attr & filter) != 0) return kMaxUInt32; |
| 1227 return key; |
| 1228 } |
| 1229 |
1122 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1230 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1123 Handle<FixedArrayBase> backing_store, | 1231 Handle<FixedArrayBase> backing_store, |
1124 KeyAccumulator* keys, uint32_t range, | 1232 KeyAccumulator* keys, uint32_t range, |
1125 PropertyFilter filter, | 1233 PropertyFilter filter, |
1126 uint32_t offset) { | 1234 uint32_t offset) { |
1127 Handle<SeededNumberDictionary> dictionary = | 1235 Handle<SeededNumberDictionary> dictionary = |
1128 Handle<SeededNumberDictionary>::cast(backing_store); | 1236 Handle<SeededNumberDictionary>::cast(backing_store); |
1129 int capacity = dictionary->Capacity(); | 1237 int capacity = dictionary->Capacity(); |
1130 for (int i = 0; i < capacity; i++) { | 1238 for (int i = 0; i < capacity; i++) { |
1131 Object* k = dictionary->KeyAt(i); | 1239 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
1132 if (!dictionary->IsKey(k)) continue; | 1240 if (key == kMaxUInt32) continue; |
1133 if (k->FilterKey(filter)) continue; | 1241 keys->AddKey(key); |
1134 if (dictionary->IsDeleted(i)) continue; | |
1135 DCHECK(k->IsNumber()); | |
1136 DCHECK_LE(k->Number(), kMaxUInt32); | |
1137 uint32_t index = static_cast<uint32_t>(k->Number()); | |
1138 if (index < offset) continue; | |
1139 PropertyDetails details = dictionary->DetailsAt(i); | |
1140 if (filter & ONLY_ALL_CAN_READ) { | |
1141 if (details.kind() != kAccessor) continue; | |
1142 Object* accessors = dictionary->ValueAt(i); | |
1143 if (!accessors->IsAccessorInfo()) continue; | |
1144 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; | |
1145 } | |
1146 PropertyAttributes attr = details.attributes(); | |
1147 if ((attr & filter) != 0) continue; | |
1148 keys->AddKey(index); | |
1149 } | 1242 } |
1150 | 1243 |
1151 keys->SortCurrentElementsList(); | 1244 keys->SortCurrentElementsList(); |
1152 } | 1245 } |
1153 | 1246 |
| 1247 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
| 1248 Isolate* isolate, Handle<JSObject> object, |
| 1249 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
| 1250 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { |
| 1251 Handle<SeededNumberDictionary> dictionary = |
| 1252 Handle<SeededNumberDictionary>::cast(backing_store); |
| 1253 uint32_t capacity = dictionary->Capacity(); |
| 1254 uint32_t insertion_index = 0; |
| 1255 for (uint32_t i = 0; i < capacity; i++) { |
| 1256 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
| 1257 if (key == kMaxUInt32) continue; |
| 1258 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); |
| 1259 list->set(insertion_index, *index); |
| 1260 insertion_index++; |
| 1261 } |
| 1262 *nof_indices = insertion_index; |
| 1263 return list; |
| 1264 } |
| 1265 |
1154 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1266 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1155 KeyAccumulator* accumulator, | 1267 KeyAccumulator* accumulator, |
1156 AddKeyConversion convert) { | 1268 AddKeyConversion convert) { |
1157 SeededNumberDictionary* dictionary = | 1269 SeededNumberDictionary* dictionary = |
1158 SeededNumberDictionary::cast(receiver->elements()); | 1270 SeededNumberDictionary::cast(receiver->elements()); |
1159 int capacity = dictionary->Capacity(); | 1271 int capacity = dictionary->Capacity(); |
1160 for (int i = 0; i < capacity; i++) { | 1272 for (int i = 0; i < capacity; i++) { |
1161 Object* k = dictionary->KeyAt(i); | 1273 Object* k = dictionary->KeyAt(i); |
1162 if (!dictionary->IsKey(k)) continue; | 1274 if (!dictionary->IsKey(k)) continue; |
1163 if (dictionary->IsDeleted(i)) continue; | 1275 if (dictionary->IsDeleted(i)) continue; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 DeleteCommon(obj, entry, handle(obj->elements())); | 1420 DeleteCommon(obj, entry, handle(obj->elements())); |
1309 } | 1421 } |
1310 | 1422 |
1311 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 1423 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
1312 return !BackingStore::cast(backing_store)->is_the_hole(entry); | 1424 return !BackingStore::cast(backing_store)->is_the_hole(entry); |
1313 } | 1425 } |
1314 | 1426 |
1315 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1427 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1316 KeyAccumulator* accumulator, | 1428 KeyAccumulator* accumulator, |
1317 AddKeyConversion convert) { | 1429 AddKeyConversion convert) { |
1318 uint32_t length = 0; | |
1319 Handle<FixedArrayBase> elements(receiver->elements(), | 1430 Handle<FixedArrayBase> elements(receiver->elements(), |
1320 receiver->GetIsolate()); | 1431 receiver->GetIsolate()); |
1321 if (receiver->IsJSArray()) { | 1432 uint32_t length = |
1322 length = Smi::cast(JSArray::cast(*receiver)->length())->value(); | 1433 FastElementsAccessorSubclass::GetIterationLength(*receiver, *elements); |
1323 } else { | |
1324 length = | |
1325 FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements); | |
1326 } | |
1327 for (uint32_t i = 0; i < length; i++) { | 1434 for (uint32_t i = 0; i < length; i++) { |
1328 if (IsFastPackedElementsKind(KindTraits::Kind) || | 1435 if (IsFastPackedElementsKind(KindTraits::Kind) || |
1329 HasEntryImpl(*elements, i)) { | 1436 HasEntryImpl(*elements, i)) { |
1330 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i), | 1437 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i), |
1331 convert); | 1438 convert); |
1332 } | 1439 } |
1333 } | 1440 } |
1334 } | 1441 } |
1335 | 1442 |
1336 static void ValidateContents(Handle<JSObject> holder, int length) { | 1443 static void ValidateContents(Handle<JSObject> holder, int length) { |
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2680 } | 2787 } |
2681 } | 2788 } |
2682 | 2789 |
2683 DCHECK(j == result_len); | 2790 DCHECK(j == result_len); |
2684 return result_array; | 2791 return result_array; |
2685 } | 2792 } |
2686 | 2793 |
2687 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2794 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2688 } // namespace internal | 2795 } // namespace internal |
2689 } // namespace v8 | 2796 } // namespace v8 |
OLD | NEW |