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

Side by Side Diff: src/js/array.js

Issue 2013873002: [array] speed up array.forEach and friends by directly using in-operator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « no previous file | src/js/macros.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 (function(global, utils, extrasUtils) { 5 (function(global, utils, extrasUtils) {
6 6
7 "use strict"; 7 "use strict";
8 8
9 %CheckIsBootstrapping(); 9 %CheckIsBootstrapping();
10 10
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 array[key] = new_array[key]; 321 array[key] = new_array[key];
322 } 322 }
323 } 323 }
324 } 324 }
325 325
326 326
327 // This is part of the old simple-minded splice. We are using it either 327 // This is part of the old simple-minded splice. We are using it either
328 // because the receiver is not an array (so we have no choice) or because we 328 // because the receiver is not an array (so we have no choice) or because we
329 // know we are not deleting or moving a lot of elements. 329 // know we are not deleting or moving a lot of elements.
330 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { 330 function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
331 var is_array = IS_ARRAY(array);
332 for (var i = 0; i < del_count; i++) { 331 for (var i = 0; i < del_count; i++) {
333 var index = start_i + i; 332 var index = start_i + i;
334 if (HAS_INDEX(array, index, is_array)) { 333 if (HAS_INDEX(array, index)) {
335 var current = array[index]; 334 var current = array[index];
336 %CreateDataProperty(deleted_elements, i, current); 335 %CreateDataProperty(deleted_elements, i, current);
337 } 336 }
338 } 337 }
339 } 338 }
340 339
341 340
342 function SimpleMove(array, start_i, del_count, len, num_additional_args) { 341 function SimpleMove(array, start_i, del_count, len, num_additional_args) {
343 var is_array = IS_ARRAY(array);
344 if (num_additional_args !== del_count) { 342 if (num_additional_args !== del_count) {
345 // Move the existing elements after the elements to be deleted 343 // Move the existing elements after the elements to be deleted
346 // to the right position in the resulting array. 344 // to the right position in the resulting array.
347 if (num_additional_args > del_count) { 345 if (num_additional_args > del_count) {
348 for (var i = len - del_count; i > start_i; i--) { 346 for (var i = len - del_count; i > start_i; i--) {
349 var from_index = i + del_count - 1; 347 var from_index = i + del_count - 1;
350 var to_index = i + num_additional_args - 1; 348 var to_index = i + num_additional_args - 1;
351 if (HAS_INDEX(array, from_index, is_array)) { 349 if (HAS_INDEX(array, from_index)) {
352 array[to_index] = array[from_index]; 350 array[to_index] = array[from_index];
353 } else { 351 } else {
354 delete array[to_index]; 352 delete array[to_index];
355 } 353 }
356 } 354 }
357 } else { 355 } else {
358 for (var i = start_i; i < len - del_count; i++) { 356 for (var i = start_i; i < len - del_count; i++) {
359 var from_index = i + del_count; 357 var from_index = i + del_count;
360 var to_index = i + num_additional_args; 358 var to_index = i + num_additional_args;
361 if (HAS_INDEX(array, from_index, is_array)) { 359 if (HAS_INDEX(array, from_index)) {
362 array[to_index] = array[from_index]; 360 array[to_index] = array[from_index];
363 } else { 361 } else {
364 delete array[to_index]; 362 delete array[to_index];
365 } 363 }
366 } 364 }
367 for (var i = len; i > len - del_count + num_additional_args; i--) { 365 for (var i = len; i > len - del_count + num_additional_args; i--) {
368 delete array[i - 1]; 366 delete array[i - 1];
369 } 367 }
370 } 368 }
371 } 369 }
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 var length = TO_LENGTH(array.length); 1046 var length = TO_LENGTH(array.length);
1049 return InnerArraySort(array, length, comparefn); 1047 return InnerArraySort(array, length, comparefn);
1050 } 1048 }
1051 1049
1052 1050
1053 // The following functions cannot be made efficient on sparse arrays while 1051 // The following functions cannot be made efficient on sparse arrays while
1054 // preserving the semantics, since the calls to the receiver function can add 1052 // preserving the semantics, since the calls to the receiver function can add
1055 // or delete elements from the array. 1053 // or delete elements from the array.
1056 function InnerArrayFilter(f, receiver, array, length, result) { 1054 function InnerArrayFilter(f, receiver, array, length, result) {
1057 var result_length = 0; 1055 var result_length = 0;
1058 var is_array = IS_ARRAY(array);
1059 for (var i = 0; i < length; i++) { 1056 for (var i = 0; i < length; i++) {
1060 if (HAS_INDEX(array, i, is_array)) { 1057 if (HAS_INDEX(array, i)) {
1061 var element = array[i]; 1058 var element = array[i];
1062 if (%_Call(f, receiver, element, i, array)) { 1059 if (%_Call(f, receiver, element, i, array)) {
1063 %CreateDataProperty(result, result_length, element); 1060 %CreateDataProperty(result, result_length, element);
1064 result_length++; 1061 result_length++;
1065 } 1062 }
1066 } 1063 }
1067 } 1064 }
1068 return result; 1065 return result;
1069 } 1066 }
1070 1067
1071 1068
1072 1069
1073 function ArrayFilter(f, receiver) { 1070 function ArrayFilter(f, receiver) {
1074 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter"); 1071 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter");
1075 1072
1076 // Pull out the length so that modifications to the length in the 1073 // Pull out the length so that modifications to the length in the
1077 // loop will not affect the looping and side effects are visible. 1074 // loop will not affect the looping and side effects are visible.
1078 var array = TO_OBJECT(this); 1075 var array = TO_OBJECT(this);
1079 var length = TO_LENGTH(array.length); 1076 var length = TO_LENGTH(array.length);
1080 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1077 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1081 var result = ArraySpeciesCreate(array, 0); 1078 var result = ArraySpeciesCreate(array, 0);
1082 return InnerArrayFilter(f, receiver, array, length, result); 1079 return InnerArrayFilter(f, receiver, array, length, result);
1083 } 1080 }
1084 1081
1085 1082
1086 function InnerArrayForEach(f, receiver, array, length) { 1083 function InnerArrayForEach(f, receiver, array, length) {
1087 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1084 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1088 1085
1089 var is_array = IS_ARRAY(array);
1090 if (IS_UNDEFINED(receiver)) { 1086 if (IS_UNDEFINED(receiver)) {
1091 for (var i = 0; i < length; i++) { 1087 for (var i = 0; i < length; i++) {
1092 if (HAS_INDEX(array, i, is_array)) { 1088 if (HAS_INDEX(array, i)) {
1093 var element = array[i]; 1089 var element = array[i];
1094 f(element, i, array); 1090 f(element, i, array);
1095 } 1091 }
1096 } 1092 }
1097 } else { 1093 } else {
1098 for (var i = 0; i < length; i++) { 1094 for (var i = 0; i < length; i++) {
1099 if (HAS_INDEX(array, i, is_array)) { 1095 if (HAS_INDEX(array, i)) {
1100 var element = array[i]; 1096 var element = array[i];
1101 %_Call(f, receiver, element, i, array); 1097 %_Call(f, receiver, element, i, array);
1102 } 1098 }
1103 } 1099 }
1104 } 1100 }
1105 } 1101 }
1106 1102
1107 1103
1108 function ArrayForEach(f, receiver) { 1104 function ArrayForEach(f, receiver) {
1109 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach"); 1105 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach");
1110 1106
1111 // Pull out the length so that modifications to the length in the 1107 // Pull out the length so that modifications to the length in the
1112 // loop will not affect the looping and side effects are visible. 1108 // loop will not affect the looping and side effects are visible.
1113 var array = TO_OBJECT(this); 1109 var array = TO_OBJECT(this);
1114 var length = TO_LENGTH(array.length); 1110 var length = TO_LENGTH(array.length);
1115 InnerArrayForEach(f, receiver, array, length); 1111 InnerArrayForEach(f, receiver, array, length);
1116 } 1112 }
1117 1113
1118 1114
1119 function InnerArraySome(f, receiver, array, length) { 1115 function InnerArraySome(f, receiver, array, length) {
1120 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1116 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1121 1117
1122 var is_array = IS_ARRAY(array);
1123 for (var i = 0; i < length; i++) { 1118 for (var i = 0; i < length; i++) {
1124 if (HAS_INDEX(array, i, is_array)) { 1119 if (HAS_INDEX(array, i)) {
1125 var element = array[i]; 1120 var element = array[i];
1126 if (%_Call(f, receiver, element, i, array)) return true; 1121 if (%_Call(f, receiver, element, i, array)) return true;
1127 } 1122 }
1128 } 1123 }
1129 return false; 1124 return false;
1130 } 1125 }
1131 1126
1132 1127
1133 // Executes the function once for each element present in the 1128 // Executes the function once for each element present in the
1134 // array until it finds one where callback returns true. 1129 // array until it finds one where callback returns true.
1135 function ArraySome(f, receiver) { 1130 function ArraySome(f, receiver) {
1136 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some"); 1131 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some");
1137 1132
1138 // Pull out the length so that modifications to the length in the 1133 // Pull out the length so that modifications to the length in the
1139 // loop will not affect the looping and side effects are visible. 1134 // loop will not affect the looping and side effects are visible.
1140 var array = TO_OBJECT(this); 1135 var array = TO_OBJECT(this);
1141 var length = TO_LENGTH(array.length); 1136 var length = TO_LENGTH(array.length);
1142 return InnerArraySome(f, receiver, array, length); 1137 return InnerArraySome(f, receiver, array, length);
1143 } 1138 }
1144 1139
1145 1140
1146 function InnerArrayEvery(f, receiver, array, length) { 1141 function InnerArrayEvery(f, receiver, array, length) {
1147 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1142 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1148 1143
1149 var is_array = IS_ARRAY(array);
1150 for (var i = 0; i < length; i++) { 1144 for (var i = 0; i < length; i++) {
1151 if (HAS_INDEX(array, i, is_array)) { 1145 if (HAS_INDEX(array, i)) {
1152 var element = array[i]; 1146 var element = array[i];
1153 if (!%_Call(f, receiver, element, i, array)) return false; 1147 if (!%_Call(f, receiver, element, i, array)) return false;
1154 } 1148 }
1155 } 1149 }
1156 return true; 1150 return true;
1157 } 1151 }
1158 1152
1159 function ArrayEvery(f, receiver) { 1153 function ArrayEvery(f, receiver) {
1160 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every"); 1154 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every");
1161 1155
1162 // Pull out the length so that modifications to the length in the 1156 // Pull out the length so that modifications to the length in the
1163 // loop will not affect the looping and side effects are visible. 1157 // loop will not affect the looping and side effects are visible.
1164 var array = TO_OBJECT(this); 1158 var array = TO_OBJECT(this);
1165 var length = TO_LENGTH(array.length); 1159 var length = TO_LENGTH(array.length);
1166 return InnerArrayEvery(f, receiver, array, length); 1160 return InnerArrayEvery(f, receiver, array, length);
1167 } 1161 }
1168 1162
1169 1163
1170 function ArrayMap(f, receiver) { 1164 function ArrayMap(f, receiver) {
1171 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map"); 1165 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
1172 1166
1173 // Pull out the length so that modifications to the length in the 1167 // Pull out the length so that modifications to the length in the
1174 // loop will not affect the looping and side effects are visible. 1168 // loop will not affect the looping and side effects are visible.
1175 var array = TO_OBJECT(this); 1169 var array = TO_OBJECT(this);
1176 var length = TO_LENGTH(array.length); 1170 var length = TO_LENGTH(array.length);
1177 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1171 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1178 var result = ArraySpeciesCreate(array, length); 1172 var result = ArraySpeciesCreate(array, length);
1179 var is_array = IS_ARRAY(array);
1180 for (var i = 0; i < length; i++) { 1173 for (var i = 0; i < length; i++) {
1181 if (HAS_INDEX(array, i, is_array)) { 1174 if (HAS_INDEX(array, i)) {
1182 var element = array[i]; 1175 var element = array[i];
1183 %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array)); 1176 %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array));
1184 } 1177 }
1185 } 1178 }
1186 return result; 1179 return result;
1187 } 1180 }
1188 1181
1189 1182
1190 // For .indexOf, we don't need to pass in the number of arguments 1183 // For .indexOf, we don't need to pass in the number of arguments
1191 // at the callsite since ToInteger(undefined) == 0; however, for 1184 // at the callsite since ToInteger(undefined) == 0; however, for
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 return InnerArrayLastIndexOf(this, element, index, length, 1303 return InnerArrayLastIndexOf(this, element, index, length,
1311 arguments.length); 1304 arguments.length);
1312 } 1305 }
1313 1306
1314 1307
1315 function InnerArrayReduce(callback, current, array, length, argumentsLength) { 1308 function InnerArrayReduce(callback, current, array, length, argumentsLength) {
1316 if (!IS_CALLABLE(callback)) { 1309 if (!IS_CALLABLE(callback)) {
1317 throw MakeTypeError(kCalledNonCallable, callback); 1310 throw MakeTypeError(kCalledNonCallable, callback);
1318 } 1311 }
1319 1312
1320 var is_array = IS_ARRAY(array);
1321 var i = 0; 1313 var i = 0;
1322 find_initial: if (argumentsLength < 2) { 1314 find_initial: if (argumentsLength < 2) {
1323 for (; i < length; i++) { 1315 for (; i < length; i++) {
1324 if (HAS_INDEX(array, i, is_array)) { 1316 if (HAS_INDEX(array, i)) {
1325 current = array[i++]; 1317 current = array[i++];
1326 break find_initial; 1318 break find_initial;
1327 } 1319 }
1328 } 1320 }
1329 throw MakeTypeError(kReduceNoInitial); 1321 throw MakeTypeError(kReduceNoInitial);
1330 } 1322 }
1331 1323
1332 for (; i < length; i++) { 1324 for (; i < length; i++) {
1333 if (HAS_INDEX(array, i, is_array)) { 1325 if (HAS_INDEX(array, i)) {
1334 var element = array[i]; 1326 var element = array[i];
1335 current = callback(current, element, i, array); 1327 current = callback(current, element, i, array);
1336 } 1328 }
1337 } 1329 }
1338 return current; 1330 return current;
1339 } 1331 }
1340 1332
1341 1333
1342 function ArrayReduce(callback, current) { 1334 function ArrayReduce(callback, current) {
1343 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce"); 1335 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce");
1344 1336
1345 // Pull out the length so that modifications to the length in the 1337 // Pull out the length so that modifications to the length in the
1346 // loop will not affect the looping and side effects are visible. 1338 // loop will not affect the looping and side effects are visible.
1347 var array = TO_OBJECT(this); 1339 var array = TO_OBJECT(this);
1348 var length = TO_LENGTH(array.length); 1340 var length = TO_LENGTH(array.length);
1349 return InnerArrayReduce(callback, current, array, length, 1341 return InnerArrayReduce(callback, current, array, length,
1350 arguments.length); 1342 arguments.length);
1351 } 1343 }
1352 1344
1353 1345
1354 function InnerArrayReduceRight(callback, current, array, length, 1346 function InnerArrayReduceRight(callback, current, array, length,
1355 argumentsLength) { 1347 argumentsLength) {
1356 if (!IS_CALLABLE(callback)) { 1348 if (!IS_CALLABLE(callback)) {
1357 throw MakeTypeError(kCalledNonCallable, callback); 1349 throw MakeTypeError(kCalledNonCallable, callback);
1358 } 1350 }
1359 1351
1360 var is_array = IS_ARRAY(array);
1361 var i = length - 1; 1352 var i = length - 1;
1362 find_initial: if (argumentsLength < 2) { 1353 find_initial: if (argumentsLength < 2) {
1363 for (; i >= 0; i--) { 1354 for (; i >= 0; i--) {
1364 if (HAS_INDEX(array, i, is_array)) { 1355 if (HAS_INDEX(array, i)) {
1365 current = array[i--]; 1356 current = array[i--];
1366 break find_initial; 1357 break find_initial;
1367 } 1358 }
1368 } 1359 }
1369 throw MakeTypeError(kReduceNoInitial); 1360 throw MakeTypeError(kReduceNoInitial);
1370 } 1361 }
1371 1362
1372 for (; i >= 0; i--) { 1363 for (; i >= 0; i--) {
1373 if (HAS_INDEX(array, i, is_array)) { 1364 if (HAS_INDEX(array, i)) {
1374 var element = array[i]; 1365 var element = array[i];
1375 current = callback(current, element, i, array); 1366 current = callback(current, element, i, array);
1376 } 1367 }
1377 } 1368 }
1378 return current; 1369 return current;
1379 } 1370 }
1380 1371
1381 1372
1382 function ArrayReduceRight(callback, current) { 1373 function ArrayReduceRight(callback, current) {
1383 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight"); 1374 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight");
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1789 %InstallToContext([ 1780 %InstallToContext([
1790 "array_pop", ArrayPop, 1781 "array_pop", ArrayPop,
1791 "array_push", ArrayPush, 1782 "array_push", ArrayPush,
1792 "array_shift", ArrayShift, 1783 "array_shift", ArrayShift,
1793 "array_splice", ArraySplice, 1784 "array_splice", ArraySplice,
1794 "array_slice", ArraySlice, 1785 "array_slice", ArraySlice,
1795 "array_unshift", ArrayUnshift, 1786 "array_unshift", ArrayUnshift,
1796 ]); 1787 ]);
1797 1788
1798 }); 1789 });
OLDNEW
« no previous file with comments | « no previous file | src/js/macros.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698