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

Side by Side Diff: src/elements.cc

Issue 1707743002: [key-accumulator] Starting to reimplement the key-accumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: WIP fast path for collecting receiver-only elements Created 4 years, 10 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/messages.h" 10 #include "src/messages.h"
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 Handle<FixedArray> EnsureSize(Isolate* isolate, Handle<FixedArray> array,
432 int size) {
433 int length = array->length();
434 if (size < length) return array;
435 int new_capacity = length + length / 2;
436 int grow_by = new_capacity - length;
437 return isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
438 }
431 439
432 static void TraceTopFrame(Isolate* isolate) { 440 static void TraceTopFrame(Isolate* isolate) {
433 StackFrameIterator it(isolate); 441 StackFrameIterator it(isolate);
434 if (it.done()) { 442 if (it.done()) {
435 PrintF("unknown location (no JavaScript frames present)"); 443 PrintF("unknown location (no JavaScript frames present)");
436 return; 444 return;
437 } 445 }
438 StackFrame* raw_frame = it.frame(); 446 StackFrame* raw_frame = it.frame();
439 if (raw_frame->is_internal()) { 447 if (raw_frame->is_internal()) {
440 Code* apply_builtin = 448 Code* apply_builtin =
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 } else { 728 } else {
721 // Check whether the backing store should be expanded. 729 // Check whether the backing store should be expanded.
722 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); 730 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
723 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); 731 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
724 } 732 }
725 733
726 array->set_length(Smi::FromInt(length)); 734 array->set_length(Smi::FromInt(length));
727 JSObject::ValidateElements(array); 735 JSObject::ValidateElements(array);
728 } 736 }
729 737
738 static uint32_t GetIterationLength(JSObject* receiver,
739 FixedArrayBase* elements) {
740 if (receiver->IsJSArray()) {
741 return static_cast<uint32_t>(
742 Smi::cast(JSArray::cast(receiver)->length())->value());
743 } else {
744 return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements);
745 }
746 }
747
730 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 748 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
731 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 749 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
732 ElementsKind from_kind, uint32_t capacity) { 750 ElementsKind from_kind, uint32_t capacity) {
733 return ConvertElementsWithCapacity( 751 return ConvertElementsWithCapacity(
734 object, old_elements, from_kind, capacity, 0, 0, 752 object, old_elements, from_kind, capacity, 0, 0,
735 ElementsAccessor::kCopyToEndAndInitializeToHole); 753 ElementsAccessor::kCopyToEndAndInitializeToHole);
736 } 754 }
737 755
738 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 756 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
739 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 757 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 // intentionally to avoid ArrayConcat() builtin performance degradation. 854 // intentionally to avoid ArrayConcat() builtin performance degradation.
837 // 855 //
838 // Details: The idea is that allocations actually happen only in case of 856 // Details: The idea is that allocations actually happen only in case of
839 // copying from object with fast double elements to object with object 857 // copying from object with fast double elements to object with object
840 // elements. In all the other cases there are no allocations performed and 858 // elements. In all the other cases there are no allocations performed and
841 // handle creation causes noticeable performance degradation of the builtin. 859 // handle creation causes noticeable performance degradation of the builtin.
842 ElementsAccessorSubclass::CopyElementsImpl( 860 ElementsAccessorSubclass::CopyElementsImpl(
843 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 861 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
844 } 862 }
845 863
864 void CollectElementIndices(Handle<JSObject> object,
865 Handle<FixedArrayBase> backing_store,
866 KeyAccumulator* keys, uint32_t range,
867 PropertyFilter filter, uint32_t offset) final {
868 ElementsAccessorSubclass::CollectElementIndicesImpl(
869 object, backing_store, keys, range, filter, offset);
870 }
871
846 static void CollectElementIndicesImpl(Handle<JSObject> object, 872 static void CollectElementIndicesImpl(Handle<JSObject> object,
847 Handle<FixedArrayBase> backing_store, 873 Handle<FixedArrayBase> backing_store,
848 KeyAccumulator* keys, uint32_t range, 874 KeyAccumulator* keys, uint32_t range,
849 PropertyFilter filter, 875 PropertyFilter filter,
850 uint32_t offset) { 876 uint32_t offset) {
851 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); 877 DCHECK_NE(DICTIONARY_ELEMENTS, kind());
852 if (filter & ONLY_ALL_CAN_READ) { 878 if (filter & ONLY_ALL_CAN_READ) {
853 // Non-dictionary elements can't have all-can-read accessors. 879 // Non-dictionary elements can't have all-can-read accessors.
854 return; 880 return;
855 } 881 }
856 uint32_t length = 0; 882 uint32_t length = GetIterationLength(*object, *backing_store);
857 if (object->IsJSArray()) {
858 length = Smi::cast(JSArray::cast(*object)->length())->value();
859 } else {
860 length =
861 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store);
862 }
863 if (range < length) length = range; 883 if (range < length) length = range;
864 for (uint32_t i = offset; i < length; i++) { 884 for (uint32_t i = offset; i < length; i++) {
865 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, 885 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
866 filter)) { 886 filter)) {
867 continue; 887 keys->AddKey(i);
868 } 888 }
869 keys->AddKey(i);
870 } 889 }
871 } 890 }
872 891
873 void CollectElementIndices(Handle<JSObject> object, 892 static Handle<FixedArray> FastCollectElementIndicesImpl(
874 Handle<FixedArrayBase> backing_store, 893 Isolate* isolate, Handle<JSObject> object,
875 KeyAccumulator* keys, uint32_t range, 894 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
876 PropertyFilter filter, uint32_t offset) final { 895 PropertyFilter filter, Handle<FixedArray> list, int* nof_indices) {
877 ElementsAccessorSubclass::CollectElementIndicesImpl( 896 uint32_t length =
878 object, backing_store, keys, range, filter, offset); 897 ElementsAccessorSubclass::GetIterationLength(*object, *backing_store);
879 }; 898 int insertion_index = 0;
899 for (uint32_t i = 0; i < length; i++) {
900 if (IsFastPackedElementsKind(kind())) {
Toon Verwaest 2016/02/24 15:07:06 HasElementImpl should just return true for packed
901 if (convert == CONVERT_TO_STRING) {
902 list->set(insertion_index++, *isolate->factory()->Uint32ToString(i));
903 } else {
904 list->set(insertion_index++, Smi::FromInt(i), SKIP_WRITE_BARRIER);
905 }
906 } else {
907 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
908 filter)) {
909 list = EnsureSize(isolate, list, insertion_index);
910 if (convert == CONVERT_TO_STRING) {
911 list->set(insertion_index++,
912 *isolate->factory()->Uint32ToString(i));
913 } else {
914 list->set(insertion_index++, Smi::FromInt(i), SKIP_WRITE_BARRIER);
915 }
916 }
917 }
918 }
919 *nof_indices = insertion_index;
920 return list;
921 }
922
923 Handle<FixedArray> PrependElementIndices(Handle<JSObject> object,
924 Handle<FixedArrayBase> backing_store,
925 Handle<FixedArray> keys,
926 GetKeysConversion convert,
927 PropertyFilter filter) final {
928 return ElementsAccessorSubclass::PrependElementIndicesImpl(
929 object, backing_store, keys, convert, filter);
930 }
931
932 Handle<FixedArray> PrependElementIndicesImpl(
933 Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
934 Handle<FixedArray> keys, GetKeysConversion convert,
935 PropertyFilter filter) {
936 if (!IsDictionaryElementsKind(kind()) && filter & ONLY_ALL_CAN_READ) {
Toon Verwaest 2016/02/24 15:07:06 There are no ALL_CAN_READ indexed properties that
937 // Non-dictionary elements can't have all-can-read accessors.
938 return keys;
939 }
940
941 Isolate* isolate = object->GetIsolate();
942 int nof_property_keys = keys->length();
943
944 // Calculate the initial list size depending on the object at hand.
945 int initial_list_length = 10;
Toon Verwaest 2016/02/24 15:07:06 Why not immediately use Capacity + nof_property_ke
946 if (IsFastPackedElementsKind(kind())) {
947 initial_list_length =
948 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store);
949 initial_list_length += nof_property_keys;
950 }
951
952 // Collect the element indices into a new list.
953 int nof_indices = 0;
954 Handle<FixedArray> combined_keys =
955 isolate->factory()->NewFixedArray(initial_list_length);
956 combined_keys = ElementsAccessorSubclass::FastCollectElementIndicesImpl(
957 isolate, object, backing_store, convert, filter, combined_keys,
958 &nof_indices);
959
960 // Sort the indices list if necessary.
961 if (kind() == DICTIONARY_ELEMENTS) {
962 struct {
963 bool operator()(Object* a, Object* b) {
Toon Verwaest 2016/02/24 15:07:06 return a->Number() < b->Number()? Seems like doub
964 if (a->IsSmi()) {
965 if (!b->IsSmi()) return true;
966 return Smi::cast(a)->value() < Smi::cast(b)->value();
967 }
968 return !b->IsSmi();
969 }
970 } cmp;
971 Object** start =
972 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress());
973 std::sort(start, start + nof_indices, cmp);
974 }
975
976 // Shrink/Grow the combined_keys to the final size.
977 int final_size = nof_indices + nof_property_keys;
978 if (combined_keys->length() < final_size) {
979 combined_keys = isolate->factory()->CopyFixedArrayAndGrow(
980 combined_keys, final_size - combined_keys->length());
981 } else {
982 combined_keys->Shrink(final_size);
983 }
984
985 // Copy over the property keys.
986 ElementsKind kind = FAST_HOLEY_ELEMENTS;
Toon Verwaest 2016/02/24 15:07:06 I guess it doesn't change anything, but this shoul
987 CopyObjectToObjectElements(*keys, kind, 0, *combined_keys, kind,
988 nof_indices, nof_property_keys);
989 return combined_keys;
990 }
880 991
881 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, 992 void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
882 KeyAccumulator* accumulator, 993 KeyAccumulator* accumulator,
883 AddKeyConversion convert) final { 994 AddKeyConversion convert) final {
884 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl( 995 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl(
885 receiver, accumulator, convert); 996 receiver, accumulator, convert);
886 } 997 }
887 998
888 static uint32_t GetCapacityImpl(JSObject* holder, 999 static uint32_t GetCapacityImpl(JSObject* holder,
889 FixedArrayBase* backing_store) { 1000 FixedArrayBase* backing_store) {
(...skipping 12 matching lines...) Expand all
902 static uint32_t GetEntryForIndexImpl(JSObject* holder, 1013 static uint32_t GetEntryForIndexImpl(JSObject* holder,
903 FixedArrayBase* backing_store, 1014 FixedArrayBase* backing_store,
904 uint32_t index, PropertyFilter filter) { 1015 uint32_t index, PropertyFilter filter) {
905 if (IsHoleyElementsKind(kind())) { 1016 if (IsHoleyElementsKind(kind())) {
906 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, 1017 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
907 backing_store) && 1018 backing_store) &&
908 !BackingStore::cast(backing_store)->is_the_hole(index) 1019 !BackingStore::cast(backing_store)->is_the_hole(index)
909 ? index 1020 ? index
910 : kMaxUInt32; 1021 : kMaxUInt32;
911 } else { 1022 } else {
912 uint32_t length = 1023 uint32_t length = GetIterationLength(holder, backing_store);
913 holder->IsJSArray()
914 ? static_cast<uint32_t>(
915 Smi::cast(JSArray::cast(holder)->length())->value())
916 : ElementsAccessorSubclass::GetCapacityImpl(holder,
917 backing_store);
918 return index < length ? index : kMaxUInt32; 1024 return index < length ? index : kMaxUInt32;
919 } 1025 }
920 } 1026 }
921 1027
922 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, 1028 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store,
923 uint32_t index) final { 1029 uint32_t index) final {
924 return ElementsAccessorSubclass::GetEntryForIndexImpl( 1030 return ElementsAccessorSubclass::GetEntryForIndexImpl(
925 holder, backing_store, index, ALL_PROPERTIES); 1031 holder, backing_store, index, ALL_PROPERTIES);
926 } 1032 }
927 1033
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 1215
1110 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1216 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1111 return GetDetailsImpl(holder->elements(), entry); 1217 return GetDetailsImpl(holder->elements(), entry);
1112 } 1218 }
1113 1219
1114 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1220 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1115 uint32_t entry) { 1221 uint32_t entry) {
1116 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1222 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1117 } 1223 }
1118 1224
1225 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
1226 int entry, PropertyFilter filter) {
1227 Object* raw_key = dictionary->KeyAt(entry);
1228 if (!dictionary->IsKey(raw_key)) return kMaxUInt32;
1229 if (raw_key->FilterKey(filter)) return kMaxUInt32;
1230 if (dictionary->IsDeleted(entry)) return kMaxUInt32;
1231 DCHECK(raw_key->IsNumber());
1232 DCHECK_LE(raw_key->Number(), kMaxUInt32);
1233 uint32_t key = static_cast<uint32_t>(raw_key->Number());
1234 PropertyDetails details = dictionary->DetailsAt(entry);
1235 if (filter & ONLY_ALL_CAN_READ) {
1236 if (details.kind() != kAccessor) return kMaxUInt32;
1237 Object* accessors = dictionary->ValueAt(entry);
1238 if (!accessors->IsAccessorInfo()) return kMaxUInt32;
1239 if (!AccessorInfo::cast(accessors)->all_can_read()) return kMaxUInt32;
1240 }
1241 PropertyAttributes attr = details.attributes();
1242 if ((attr & filter) != 0) return kMaxUInt32;
1243 return key;
1244 }
1245
1119 static void CollectElementIndicesImpl(Handle<JSObject> object, 1246 static void CollectElementIndicesImpl(Handle<JSObject> object,
1120 Handle<FixedArrayBase> backing_store, 1247 Handle<FixedArrayBase> backing_store,
1121 KeyAccumulator* keys, uint32_t range, 1248 KeyAccumulator* keys, uint32_t range,
1122 PropertyFilter filter, 1249 PropertyFilter filter,
1123 uint32_t offset) { 1250 uint32_t offset) {
1124 Handle<SeededNumberDictionary> dictionary = 1251 Handle<SeededNumberDictionary> dictionary =
1125 Handle<SeededNumberDictionary>::cast(backing_store); 1252 Handle<SeededNumberDictionary>::cast(backing_store);
1126 int capacity = dictionary->Capacity(); 1253 int capacity = dictionary->Capacity();
1127 for (int i = 0; i < capacity; i++) { 1254 for (int i = 0; i < capacity; i++) {
1128 Object* k = dictionary->KeyAt(i); 1255 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter);
1129 if (!dictionary->IsKey(k)) continue; 1256 if (key == kMaxUInt32) continue;
1130 if (k->FilterKey(filter)) continue; 1257 keys->AddKey(key);
1131 if (dictionary->IsDeleted(i)) continue;
1132 DCHECK(k->IsNumber());
1133 DCHECK_LE(k->Number(), kMaxUInt32);
1134 uint32_t index = static_cast<uint32_t>(k->Number());
1135 if (index < offset) continue;
1136 PropertyDetails details = dictionary->DetailsAt(i);
1137 if (filter & ONLY_ALL_CAN_READ) {
1138 if (details.kind() != kAccessor) continue;
1139 Object* accessors = dictionary->ValueAt(i);
1140 if (!accessors->IsAccessorInfo()) continue;
1141 if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
1142 }
1143 PropertyAttributes attr = details.attributes();
1144 if ((attr & filter) != 0) continue;
1145 keys->AddKey(index);
1146 } 1258 }
1147 1259
1148 keys->SortCurrentElementsList(); 1260 keys->SortCurrentElementsList();
1149 } 1261 }
1150 1262
1263 static Handle<FixedArray> FastCollectElementIndicesImpl(
1264 Isolate* isolate, Handle<JSObject> object,
1265 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
1266 PropertyFilter filter, Handle<FixedArray> list, int* nof_indices) {
1267 Handle<SeededNumberDictionary> dictionary =
1268 Handle<SeededNumberDictionary>::cast(backing_store);
1269
1270 int capacity = dictionary->Capacity();
1271 int insertion_index = 0;
1272 for (uint32_t i = 0; i < capacity; i++) {
1273 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter);
1274 if (key == kMaxUInt32) continue;
1275 list = EnsureSize(isolate, list, insertion_index);
1276 if (convert == CONVERT_TO_STRING) {
1277 list->set(insertion_index++, *isolate->factory()->Uint32ToString(key));
1278 } else {
1279 list->set(insertion_index++, Smi::FromInt(key), SKIP_WRITE_BARRIER);
1280 }
1281 }
1282 *nof_indices = insertion_index;
1283 return list;
1284 }
1285
1151 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1286 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1152 KeyAccumulator* accumulator, 1287 KeyAccumulator* accumulator,
1153 AddKeyConversion convert) { 1288 AddKeyConversion convert) {
1154 SeededNumberDictionary* dictionary = 1289 SeededNumberDictionary* dictionary =
1155 SeededNumberDictionary::cast(receiver->elements()); 1290 SeededNumberDictionary::cast(receiver->elements());
1156 int capacity = dictionary->Capacity(); 1291 int capacity = dictionary->Capacity();
1157 for (int i = 0; i < capacity; i++) { 1292 for (int i = 0; i < capacity; i++) {
1158 Object* k = dictionary->KeyAt(i); 1293 Object* k = dictionary->KeyAt(i);
1159 if (!dictionary->IsKey(k)) continue; 1294 if (!dictionary->IsKey(k)) continue;
1160 if (dictionary->IsDeleted(i)) continue; 1295 if (dictionary->IsDeleted(i)) continue;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 DeleteCommon(obj, entry, handle(obj->elements())); 1440 DeleteCommon(obj, entry, handle(obj->elements()));
1306 } 1441 }
1307 1442
1308 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { 1443 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
1309 return !BackingStore::cast(backing_store)->is_the_hole(entry); 1444 return !BackingStore::cast(backing_store)->is_the_hole(entry);
1310 } 1445 }
1311 1446
1312 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1447 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1313 KeyAccumulator* accumulator, 1448 KeyAccumulator* accumulator,
1314 AddKeyConversion convert) { 1449 AddKeyConversion convert) {
1315 uint32_t length = 0;
1316 Handle<FixedArrayBase> elements(receiver->elements(), 1450 Handle<FixedArrayBase> elements(receiver->elements(),
1317 receiver->GetIsolate()); 1451 receiver->GetIsolate());
1318 if (receiver->IsJSArray()) { 1452 uint32_t length =
1319 length = Smi::cast(JSArray::cast(*receiver)->length())->value(); 1453 FastElementsAccessorSubclass::GetIterationLength(*receiver, *elements);
1320 } else {
1321 length =
1322 FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements);
1323 }
1324 for (uint32_t i = 0; i < length; i++) { 1454 for (uint32_t i = 0; i < length; i++) {
1325 if (IsFastPackedElementsKind(KindTraits::Kind) || 1455 if (IsFastPackedElementsKind(KindTraits::Kind) ||
1326 HasEntryImpl(*elements, i)) { 1456 HasEntryImpl(*elements, i)) {
1327 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i), 1457 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i),
1328 convert); 1458 convert);
1329 } 1459 }
1330 } 1460 }
1331 } 1461 }
1332 1462
1333 static void ValidateContents(Handle<JSObject> holder, int length) { 1463 static void ValidateContents(Handle<JSObject> holder, int length) {
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2677 } 2807 }
2678 } 2808 }
2679 2809
2680 DCHECK(j == result_len); 2810 DCHECK(j == result_len);
2681 return result_array; 2811 return result_array;
2682 } 2812 }
2683 2813
2684 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2814 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2685 } // namespace internal 2815 } // namespace internal
2686 } // namespace v8 2816 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/key-accumulator.h » ('j') | src/key-accumulator.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698