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

Side by Side Diff: src/array.js

Issue 1326263002: Avoid using %_CallFunction if the receiver doesn't change. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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/harmony-typedarray.js » ('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) { 5 (function(global, utils) {
6 6
7 "use strict"; 7 "use strict";
8 8
9 %CheckIsBootstrapping(); 9 %CheckIsBootstrapping();
10 10
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 var length = indices.length; 59 var length = indices.length;
60 for (var k = 0; k < length; ++k) { 60 for (var k = 0; k < length; ++k) {
61 var key = indices[k]; 61 var key = indices[k];
62 if (!IS_UNDEFINED(key)) { 62 if (!IS_UNDEFINED(key)) {
63 var e = array[key]; 63 var e = array[key];
64 if (!IS_UNDEFINED(e) || key in array) { 64 if (!IS_UNDEFINED(e) || key in array) {
65 keys.push(key); 65 keys.push(key);
66 } 66 }
67 } 67 }
68 } 68 }
69 %_CallFunction(keys, function(a, b) { return a - b; }, ArraySort); 69 keys.sort(function(a, b) { return a - b; });
70 } 70 }
71 return keys; 71 return keys;
72 } 72 }
73 73
74 74
75 function SparseJoinWithSeparatorJS(array, len, convert, separator) { 75 function SparseJoinWithSeparatorJS(array, len, convert, separator) {
76 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); 76 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
77 var totalLength = 0; 77 var totalLength = 0;
78 var elements = new InternalArray(keys.length * 2); 78 var elements = new InternalArray(keys.length * 2);
79 var previousKey = -1; 79 var previousKey = -1;
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 while (arguments_index < arguments_length) { 893 while (arguments_index < arguments_length) {
894 array[i++] = %_Arguments(arguments_index++); 894 array[i++] = %_Arguments(arguments_index++);
895 } 895 }
896 array.length = len - del_count + num_elements_to_add; 896 array.length = len - del_count + num_elements_to_add;
897 897
898 // Return the deleted elements. 898 // Return the deleted elements.
899 return deleted_elements; 899 return deleted_elements;
900 } 900 }
901 901
902 902
903 function InnerArraySort(length, comparefn) { 903 function InnerArraySort(array, length, comparefn) {
904 // In-place QuickSort algorithm. 904 // In-place QuickSort algorithm.
905 // For short (length <= 22) arrays, insertion sort is used for efficiency. 905 // For short (length <= 22) arrays, insertion sort is used for efficiency.
906 906
907 if (!IS_CALLABLE(comparefn)) { 907 if (!IS_CALLABLE(comparefn)) {
908 comparefn = function (x, y) { 908 comparefn = function (x, y) {
909 if (x === y) return 0; 909 if (x === y) return 0;
910 if (%_IsSmi(x) && %_IsSmi(y)) { 910 if (%_IsSmi(x) && %_IsSmi(y)) {
911 return %SmiLexicographicCompare(x, y); 911 return %SmiLexicographicCompare(x, y);
912 } 912 }
913 x = ToString(x); 913 x = ToString(x);
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 obj[i] = UNDEFINED; 1138 obj[i] = UNDEFINED;
1139 } else { 1139 } else {
1140 delete obj[i]; 1140 delete obj[i];
1141 } 1141 }
1142 } 1142 }
1143 1143
1144 // Return the number of defined elements. 1144 // Return the number of defined elements.
1145 return first_undefined; 1145 return first_undefined;
1146 }; 1146 };
1147 1147
1148 if (length < 2) return this; 1148 if (length < 2) return array;
1149 1149
1150 var is_array = IS_ARRAY(this); 1150 var is_array = IS_ARRAY(array);
1151 var max_prototype_element; 1151 var max_prototype_element;
1152 if (!is_array) { 1152 if (!is_array) {
1153 // For compatibility with JSC, we also sort elements inherited from 1153 // For compatibility with JSC, we also sort elements inherited from
1154 // the prototype chain on non-Array objects. 1154 // the prototype chain on non-Array objects.
1155 // We do this by copying them to this object and sorting only 1155 // We do this by copying them to this object and sorting only
1156 // own elements. This is not very efficient, but sorting with 1156 // own elements. This is not very efficient, but sorting with
1157 // inherited elements happens very, very rarely, if at all. 1157 // inherited elements happens very, very rarely, if at all.
1158 // The specification allows "implementation dependent" behavior 1158 // The specification allows "implementation dependent" behavior
1159 // if an element on the prototype chain has an element that 1159 // if an element on the prototype chain has an element that
1160 // might interact with sorting. 1160 // might interact with sorting.
1161 max_prototype_element = CopyFromPrototype(this, length); 1161 max_prototype_element = CopyFromPrototype(array, length);
1162 } 1162 }
1163 1163
1164 // %RemoveArrayHoles returns -1 if fast removal is not supported. 1164 // %RemoveArrayHoles returns -1 if fast removal is not supported.
1165 var num_non_undefined = %RemoveArrayHoles(this, length); 1165 var num_non_undefined = %RemoveArrayHoles(array, length);
1166 1166
1167 if (num_non_undefined == -1) { 1167 if (num_non_undefined == -1) {
1168 // The array is observed, or there were indexed accessors in the array. 1168 // The array is observed, or there were indexed accessors in the array.
1169 // Move array holes and undefineds to the end using a Javascript function 1169 // Move array holes and undefineds to the end using a Javascript function
1170 // that is safe in the presence of accessors and is observable. 1170 // that is safe in the presence of accessors and is observable.
1171 num_non_undefined = SafeRemoveArrayHoles(this); 1171 num_non_undefined = SafeRemoveArrayHoles(array);
1172 } 1172 }
1173 1173
1174 QuickSort(this, 0, num_non_undefined); 1174 QuickSort(array, 0, num_non_undefined);
1175 1175
1176 if (!is_array && (num_non_undefined + 1 < max_prototype_element)) { 1176 if (!is_array && (num_non_undefined + 1 < max_prototype_element)) {
1177 // For compatibility with JSC, we shadow any elements in the prototype 1177 // For compatibility with JSC, we shadow any elements in the prototype
1178 // chain that has become exposed by sort moving a hole to its position. 1178 // chain that has become exposed by sort moving a hole to its position.
1179 ShadowPrototypeElements(this, num_non_undefined, max_prototype_element); 1179 ShadowPrototypeElements(array, num_non_undefined, max_prototype_element);
1180 } 1180 }
1181 1181
1182 return this; 1182 return array;
1183 } 1183 }
1184 1184
1185 1185
1186 function ArraySort(comparefn) { 1186 function ArraySort(comparefn) {
1187 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort"); 1187 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.sort");
1188 1188
1189 var array = TO_OBJECT(this); 1189 var array = TO_OBJECT(this);
1190 var length = TO_UINT32(array.length); 1190 var length = TO_UINT32(array.length);
1191 return %_CallFunction(array, length, comparefn, InnerArraySort); 1191 return InnerArraySort(array, length, comparefn);
1192 } 1192 }
1193 1193
1194 1194
1195 // The following functions cannot be made efficient on sparse arrays while 1195 // The following functions cannot be made efficient on sparse arrays while
1196 // preserving the semantics, since the calls to the receiver function can add 1196 // preserving the semantics, since the calls to the receiver function can add
1197 // or delete elements from the array. 1197 // or delete elements from the array.
1198 function InnerArrayFilter(f, receiver, array, length) { 1198 function InnerArrayFilter(f, receiver, array, length) {
1199 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f); 1199 if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
1200 var needs_wrapper = false; 1200 var needs_wrapper = false;
1201 if (IS_NULL(receiver)) { 1201 if (IS_NULL(receiver)) {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 var result = new GlobalArray(); 1375 var result = new GlobalArray();
1376 %MoveArrayContents(accumulator, result); 1376 %MoveArrayContents(accumulator, result);
1377 return result; 1377 return result;
1378 } 1378 }
1379 1379
1380 1380
1381 // For .indexOf, we don't need to pass in the number of arguments 1381 // For .indexOf, we don't need to pass in the number of arguments
1382 // at the callsite since ToInteger(undefined) == 0; however, for 1382 // at the callsite since ToInteger(undefined) == 0; however, for
1383 // .lastIndexOf, we need to pass it, since the behavior for passing 1383 // .lastIndexOf, we need to pass it, since the behavior for passing
1384 // undefined is 0 but for not including the argument is length-1. 1384 // undefined is 0 but for not including the argument is length-1.
1385 function InnerArrayIndexOf(element, index, length) { 1385 function InnerArrayIndexOf(array, element, index, length) {
1386 if (length == 0) return -1; 1386 if (length == 0) return -1;
1387 if (IS_UNDEFINED(index)) { 1387 if (IS_UNDEFINED(index)) {
1388 index = 0; 1388 index = 0;
1389 } else { 1389 } else {
1390 index = TO_INTEGER(index); 1390 index = TO_INTEGER(index);
1391 // If index is negative, index from the end of the array. 1391 // If index is negative, index from the end of the array.
1392 if (index < 0) { 1392 if (index < 0) {
1393 index = length + index; 1393 index = length + index;
1394 // If index is still negative, search the entire array. 1394 // If index is still negative, search the entire array.
1395 if (index < 0) index = 0; 1395 if (index < 0) index = 0;
1396 } 1396 }
1397 } 1397 }
1398 var min = index; 1398 var min = index;
1399 var max = length; 1399 var max = length;
1400 if (UseSparseVariant(this, length, IS_ARRAY(this), max - min)) { 1400 if (UseSparseVariant(array, length, IS_ARRAY(array), max - min)) {
1401 %NormalizeElements(this); 1401 %NormalizeElements(array);
1402 var indices = %GetArrayKeys(this, length); 1402 var indices = %GetArrayKeys(array, length);
1403 if (IS_NUMBER(indices)) { 1403 if (IS_NUMBER(indices)) {
1404 // It's an interval. 1404 // It's an interval.
1405 max = indices; // Capped by length already. 1405 max = indices; // Capped by length already.
1406 // Fall through to loop below. 1406 // Fall through to loop below.
1407 } else { 1407 } else {
1408 if (indices.length == 0) return -1; 1408 if (indices.length == 0) return -1;
1409 // Get all the keys in sorted order. 1409 // Get all the keys in sorted order.
1410 var sortedKeys = GetSortedArrayKeys(this, indices); 1410 var sortedKeys = GetSortedArrayKeys(array, indices);
1411 var n = sortedKeys.length; 1411 var n = sortedKeys.length;
1412 var i = 0; 1412 var i = 0;
1413 while (i < n && sortedKeys[i] < index) i++; 1413 while (i < n && sortedKeys[i] < index) i++;
1414 while (i < n) { 1414 while (i < n) {
1415 var key = sortedKeys[i]; 1415 var key = sortedKeys[i];
1416 if (!IS_UNDEFINED(key) && this[key] === element) return key; 1416 if (!IS_UNDEFINED(key) && array[key] === element) return key;
1417 i++; 1417 i++;
1418 } 1418 }
1419 return -1; 1419 return -1;
1420 } 1420 }
1421 } 1421 }
1422 // Lookup through the array. 1422 // Lookup through the array.
1423 if (!IS_UNDEFINED(element)) { 1423 if (!IS_UNDEFINED(element)) {
1424 for (var i = min; i < max; i++) { 1424 for (var i = min; i < max; i++) {
1425 if (this[i] === element) return i; 1425 if (array[i] === element) return i;
1426 } 1426 }
1427 return -1; 1427 return -1;
1428 } 1428 }
1429 // Lookup through the array. 1429 // Lookup through the array.
1430 for (var i = min; i < max; i++) { 1430 for (var i = min; i < max; i++) {
1431 if (IS_UNDEFINED(this[i]) && i in this) { 1431 if (IS_UNDEFINED(array[i]) && i in array) {
1432 return i; 1432 return i;
1433 } 1433 }
1434 } 1434 }
1435 return -1; 1435 return -1;
1436 } 1436 }
1437 1437
1438 1438
1439 function ArrayIndexOf(element, index) { 1439 function ArrayIndexOf(element, index) {
1440 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf"); 1440 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf");
1441 1441
1442 var length = TO_UINT32(this.length); 1442 var length = TO_UINT32(this.length);
1443 return %_CallFunction(this, element, index, length, InnerArrayIndexOf); 1443 return InnerArrayIndexOf(this, element, index, length);
1444 } 1444 }
1445 1445
1446 1446
1447 function InnerArrayLastIndexOf(element, index, length, argumentsLength) { 1447 function InnerArrayLastIndexOf(array, element, index, length, argumentsLength) {
1448 if (length == 0) return -1; 1448 if (length == 0) return -1;
1449 if (argumentsLength < 2) { 1449 if (argumentsLength < 2) {
1450 index = length - 1; 1450 index = length - 1;
1451 } else { 1451 } else {
1452 index = TO_INTEGER(index); 1452 index = TO_INTEGER(index);
1453 // If index is negative, index from end of the array. 1453 // If index is negative, index from end of the array.
1454 if (index < 0) index += length; 1454 if (index < 0) index += length;
1455 // If index is still negative, do not search the array. 1455 // If index is still negative, do not search the array.
1456 if (index < 0) return -1; 1456 if (index < 0) return -1;
1457 else if (index >= length) index = length - 1; 1457 else if (index >= length) index = length - 1;
1458 } 1458 }
1459 var min = 0; 1459 var min = 0;
1460 var max = index; 1460 var max = index;
1461 if (UseSparseVariant(this, length, IS_ARRAY(this), index)) { 1461 if (UseSparseVariant(array, length, IS_ARRAY(array), index)) {
1462 %NormalizeElements(this); 1462 %NormalizeElements(array);
1463 var indices = %GetArrayKeys(this, index + 1); 1463 var indices = %GetArrayKeys(array, index + 1);
1464 if (IS_NUMBER(indices)) { 1464 if (IS_NUMBER(indices)) {
1465 // It's an interval. 1465 // It's an interval.
1466 max = indices; // Capped by index already. 1466 max = indices; // Capped by index already.
1467 // Fall through to loop below. 1467 // Fall through to loop below.
1468 } else { 1468 } else {
1469 if (indices.length == 0) return -1; 1469 if (indices.length == 0) return -1;
1470 // Get all the keys in sorted order. 1470 // Get all the keys in sorted order.
1471 var sortedKeys = GetSortedArrayKeys(this, indices); 1471 var sortedKeys = GetSortedArrayKeys(array, indices);
1472 var i = sortedKeys.length - 1; 1472 var i = sortedKeys.length - 1;
1473 while (i >= 0) { 1473 while (i >= 0) {
1474 var key = sortedKeys[i]; 1474 var key = sortedKeys[i];
1475 if (!IS_UNDEFINED(key) && this[key] === element) return key; 1475 if (!IS_UNDEFINED(key) && array[key] === element) return key;
1476 i--; 1476 i--;
1477 } 1477 }
1478 return -1; 1478 return -1;
1479 } 1479 }
1480 } 1480 }
1481 // Lookup through the array. 1481 // Lookup through the array.
1482 if (!IS_UNDEFINED(element)) { 1482 if (!IS_UNDEFINED(element)) {
1483 for (var i = max; i >= min; i--) { 1483 for (var i = max; i >= min; i--) {
1484 if (this[i] === element) return i; 1484 if (array[i] === element) return i;
1485 } 1485 }
1486 return -1; 1486 return -1;
1487 } 1487 }
1488 for (var i = max; i >= min; i--) { 1488 for (var i = max; i >= min; i--) {
1489 if (IS_UNDEFINED(this[i]) && i in this) { 1489 if (IS_UNDEFINED(array[i]) && i in array) {
1490 return i; 1490 return i;
1491 } 1491 }
1492 } 1492 }
1493 return -1; 1493 return -1;
1494 } 1494 }
1495 1495
1496 1496
1497 function ArrayLastIndexOf(element, index) { 1497 function ArrayLastIndexOf(element, index) {
1498 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf"); 1498 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.lastIndexOf");
1499 1499
1500 var length = TO_UINT32(this.length); 1500 var length = TO_UINT32(this.length);
1501 return %_CallFunction(this, element, index, length, 1501 return InnerArrayLastIndexOf(this, element, index, length,
1502 %_ArgumentsLength(), InnerArrayLastIndexOf); 1502 %_ArgumentsLength());
1503 } 1503 }
1504 1504
1505 1505
1506 function InnerArrayReduce(callback, current, array, length, argumentsLength) { 1506 function InnerArrayReduce(callback, current, array, length, argumentsLength) {
1507 if (!IS_CALLABLE(callback)) { 1507 if (!IS_CALLABLE(callback)) {
1508 throw MakeTypeError(kCalledNonCallable, callback); 1508 throw MakeTypeError(kCalledNonCallable, callback);
1509 } 1509 }
1510 1510
1511 var is_array = IS_ARRAY(array); 1511 var is_array = IS_ARRAY(array);
1512 var i = 0; 1512 var i = 0;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 // The internal Array prototype doesn't need to be fancy, since it's never 1665 // The internal Array prototype doesn't need to be fancy, since it's never
1666 // exposed to user code. 1666 // exposed to user code.
1667 // Adding only the functions that are actually used. 1667 // Adding only the functions that are actually used.
1668 utils.SetUpLockedPrototype(InternalArray, GlobalArray(), [ 1668 utils.SetUpLockedPrototype(InternalArray, GlobalArray(), [
1669 "concat", getFunction("concat", ArrayConcatJS), 1669 "concat", getFunction("concat", ArrayConcatJS),
1670 "indexOf", getFunction("indexOf", ArrayIndexOf), 1670 "indexOf", getFunction("indexOf", ArrayIndexOf),
1671 "join", getFunction("join", ArrayJoin), 1671 "join", getFunction("join", ArrayJoin),
1672 "pop", getFunction("pop", ArrayPop), 1672 "pop", getFunction("pop", ArrayPop),
1673 "push", getFunction("push", ArrayPush), 1673 "push", getFunction("push", ArrayPush),
1674 "shift", getFunction("shift", ArrayShift), 1674 "shift", getFunction("shift", ArrayShift),
1675 "sort", getFunction("sort", ArraySort),
1675 "splice", getFunction("splice", ArraySplice) 1676 "splice", getFunction("splice", ArraySplice)
1676 ]); 1677 ]);
1677 1678
1678 utils.SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [ 1679 utils.SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [
1679 "join", getFunction("join", ArrayJoin), 1680 "join", getFunction("join", ArrayJoin),
1680 "pop", getFunction("pop", ArrayPop), 1681 "pop", getFunction("pop", ArrayPop),
1681 "push", getFunction("push", ArrayPush), 1682 "push", getFunction("push", ArrayPush),
1682 "shift", getFunction("shift", ArrayShift) 1683 "shift", getFunction("shift", ArrayShift)
1683 ]); 1684 ]);
1684 1685
(...skipping 24 matching lines...) Expand all
1709 "array_concat", ArrayConcatJS, 1710 "array_concat", ArrayConcatJS,
1710 "array_pop", ArrayPop, 1711 "array_pop", ArrayPop,
1711 "array_push", ArrayPush, 1712 "array_push", ArrayPush,
1712 "array_shift", ArrayShift, 1713 "array_shift", ArrayShift,
1713 "array_splice", ArraySplice, 1714 "array_splice", ArraySplice,
1714 "array_slice", ArraySlice, 1715 "array_slice", ArraySlice,
1715 "array_unshift", ArrayUnshift, 1716 "array_unshift", ArrayUnshift,
1716 ]); 1717 ]);
1717 1718
1718 }); 1719 });
OLDNEW
« no previous file with comments | « no previous file | src/harmony-typedarray.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698