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

Side by Side Diff: src/array.js

Issue 349073002: Remove SmartMove from array.js (Closed) Base URL: git://github.com/v8/v8.git@bleeding_edge
Patch Set: ws Created 6 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
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 "use strict"; 5 "use strict";
6 6
7 // This file relies on the fact that the following declarations have been made 7 // This file relies on the fact that the following declarations have been made
8 // in runtime.js: 8 // in runtime.js:
9 // var $Array = global.Array; 9 // var $Array = global.Array;
10 10
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 if (!IS_UNDEFINED(current) || key in array) { 214 if (!IS_UNDEFINED(current) || key in array) {
215 deleted_elements[key - start_i] = current; 215 deleted_elements[key - start_i] = current;
216 } 216 }
217 } 217 }
218 } 218 }
219 } 219 }
220 } 220 }
221 } 221 }
222 222
223 223
224 // This function implements the optimized splice implementation that can use
225 // special array operations to handle sparse arrays in a sensible fashion.
226 function SmartMove(array, start_i, del_count, len, num_additional_args) {
227 // Move data to new array.
228 var new_array = new InternalArray(len - del_count + num_additional_args);
229 var indices = %GetArrayKeys(array, len);
230 if (IS_NUMBER(indices)) {
231 var limit = indices;
232 for (var i = 0; i < start_i && i < limit; ++i) {
233 var current = array[i];
234 if (!IS_UNDEFINED(current) || i in array) {
235 new_array[i] = current;
236 }
237 }
238 for (var i = start_i + del_count; i < limit; ++i) {
239 var current = array[i];
240 if (!IS_UNDEFINED(current) || i in array) {
241 new_array[i - del_count + num_additional_args] = current;
242 }
243 }
244 } else {
245 var length = indices.length;
246 for (var k = 0; k < length; ++k) {
247 var key = indices[k];
248 if (!IS_UNDEFINED(key)) {
249 if (key < start_i) {
250 var current = array[key];
251 if (!IS_UNDEFINED(current) || key in array) {
252 new_array[key] = current;
253 }
254 } else if (key >= start_i + del_count) {
255 var current = array[key];
256 if (!IS_UNDEFINED(current) || key in array) {
257 new_array[key - del_count + num_additional_args] = current;
258 }
259 }
260 }
261 }
262 }
263 // Move contents of new_array into this array
264 %MoveArrayContents(new_array, array);
265 }
266
267
268 // This is part of the old simple-minded splice. We are using it either 224 // This is part of the old simple-minded splice. We are using it either
269 // because the receiver is not an array (so we have no choice) or because we 225 // because the receiver is not an array (so we have no choice) or because we
270 // know we are not deleting or moving a lot of elements. 226 // know we are not deleting or moving a lot of elements.
271 function SimpleSlice(array, start_i, del_count, len, deleted_elements) { 227 function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
272 for (var i = 0; i < del_count; i++) { 228 for (var i = 0; i < del_count; i++) {
273 var index = start_i + i; 229 var index = start_i + i;
274 // The spec could also be interpreted such that %HasOwnProperty 230 // The spec could also be interpreted such that %HasOwnProperty
275 // would be the appropriate test. We follow KJS in consulting the 231 // would be the appropriate test. We follow KJS in consulting the
276 // prototype. 232 // prototype.
277 var current = array[index]; 233 var current = array[index];
278 if (!IS_UNDEFINED(current) || index in array) { 234 if (!IS_UNDEFINED(current) || index in array) {
279 deleted_elements[i] = current; 235 deleted_elements[i] = current;
280 } 236 }
281 } 237 }
282 } 238 }
283 239
284 240
285 function SimpleMove(array, start_i, del_count, len, num_additional_args) { 241 function SimpleMove(array, start_i, del_count, len, num_additional_args,
286 if (num_additional_args !== del_count) { 242 force) {
243 if (num_additional_args !== del_count || force) {
rafaelw 2014/06/22 23:59:18 Note that |force| is required here because the spe
287 // Move the existing elements after the elements to be deleted 244 // Move the existing elements after the elements to be deleted
288 // to the right position in the resulting array. 245 // to the right position in the resulting array.
289 if (num_additional_args > del_count) { 246 if (num_additional_args > del_count) {
290 for (var i = len - del_count; i > start_i; i--) { 247 for (var i = len - del_count; i > start_i; i--) {
291 var from_index = i + del_count - 1; 248 var from_index = i + del_count - 1;
292 var to_index = i + num_additional_args - 1; 249 var to_index = i + num_additional_args - 1;
293 // The spec could also be interpreted such that 250 // The spec could also be interpreted such that
294 // %HasOwnProperty would be the appropriate test. We follow 251 // %HasOwnProperty would be the appropriate test. We follow
295 // KJS in consulting the prototype. 252 // KJS in consulting the prototype.
296 var current = array[from_index]; 253 var current = array[from_index];
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 if (ObjectIsSealed(array)) { 536 if (ObjectIsSealed(array)) {
580 throw MakeTypeError("array_functions_change_sealed", 537 throw MakeTypeError("array_functions_change_sealed",
581 ["Array.prototype.shift"]); 538 ["Array.prototype.shift"]);
582 } 539 }
583 540
584 if (%IsObserved(array)) 541 if (%IsObserved(array))
585 return ObservedArrayShift.call(array, len); 542 return ObservedArrayShift.call(array, len);
586 543
587 var first = array[0]; 544 var first = array[0];
588 545
589 if (IS_ARRAY(array)) { 546 SimpleMove(array, 0, 1, len, 0);
590 SmartMove(array, 0, 1, len, 0);
591 } else {
592 SimpleMove(array, 0, 1, len, 0);
593 }
594 547
595 array.length = len - 1; 548 array.length = len - 1;
596 549
597 return first; 550 return first;
598 } 551 }
599 552
600 function ObservedArrayUnshift() { 553 function ObservedArrayUnshift() {
601 var len = TO_UINT32(this.length); 554 var len = TO_UINT32(this.length);
602 var num_arguments = %_ArgumentsLength(); 555 var num_arguments = %_ArgumentsLength();
603 556
(...skipping 15 matching lines...) Expand all
619 572
620 function ArrayUnshift(arg1) { // length == 1 573 function ArrayUnshift(arg1) { // length == 1
621 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); 574 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
622 575
623 if (%IsObserved(this)) 576 if (%IsObserved(this))
624 return ObservedArrayUnshift.apply(this, arguments); 577 return ObservedArrayUnshift.apply(this, arguments);
625 578
626 var array = TO_OBJECT_INLINE(this); 579 var array = TO_OBJECT_INLINE(this);
627 var len = TO_UINT32(array.length); 580 var len = TO_UINT32(array.length);
628 var num_arguments = %_ArgumentsLength(); 581 var num_arguments = %_ArgumentsLength();
629 var is_sealed = ObjectIsSealed(array); 582 SimpleMove(array, 0, 0, len, num_arguments, true);
630
631 if (IS_ARRAY(array) && !is_sealed && len > 0) {
632 SmartMove(array, 0, 0, len, num_arguments);
633 } else {
634 SimpleMove(array, 0, 0, len, num_arguments);
635 }
636
637 for (var i = 0; i < num_arguments; i++) { 583 for (var i = 0; i < num_arguments; i++) {
638 array[i] = %_Arguments(i); 584 array[i] = %_Arguments(i);
639 } 585 }
640 586
641 var new_length = len + num_arguments; 587 var new_length = len + num_arguments;
642 array.length = new_length; 588 array.length = new_length;
643 return new_length; 589 return new_length;
644 } 590 }
645 591
646 592
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; 722 var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
777 723
778 if (del_count != num_elements_to_add && ObjectIsSealed(array)) { 724 if (del_count != num_elements_to_add && ObjectIsSealed(array)) {
779 throw MakeTypeError("array_functions_change_sealed", 725 throw MakeTypeError("array_functions_change_sealed",
780 ["Array.prototype.splice"]); 726 ["Array.prototype.splice"]);
781 } else if (del_count > 0 && ObjectIsFrozen(array)) { 727 } else if (del_count > 0 && ObjectIsFrozen(array)) {
782 throw MakeTypeError("array_functions_on_frozen", 728 throw MakeTypeError("array_functions_on_frozen",
783 ["Array.prototype.splice"]); 729 ["Array.prototype.splice"]);
784 } 730 }
785 731
786 var use_simple_splice = true; 732 SimpleSlice(array, start_i, del_count, len, deleted_elements);
Toon Verwaest 2014/06/23 08:42:36 I guess now you can remove the "Simple" prefixes
787 if (IS_ARRAY(array) && 733 SimpleMove(array, start_i, del_count, len, num_elements_to_add);
788 num_elements_to_add !== del_count) {
789 // If we are only deleting/moving a few things near the end of the
790 // array then the simple version is going to be faster, because it
791 // doesn't touch most of the array.
792 var estimated_non_hole_elements = %EstimateNumberOfElements(array);
793 if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) {
794 use_simple_splice = false;
795 }
796 }
797
798 if (use_simple_splice) {
799 SimpleSlice(array, start_i, del_count, len, deleted_elements);
800 SimpleMove(array, start_i, del_count, len, num_elements_to_add);
801 } else {
802 SmartSlice(array, start_i, del_count, len, deleted_elements);
803 SmartMove(array, start_i, del_count, len, num_elements_to_add);
804 }
805 734
806 // Insert the arguments into the resulting array in 735 // Insert the arguments into the resulting array in
807 // place of the deleted elements. 736 // place of the deleted elements.
808 var i = start_i; 737 var i = start_i;
809 var arguments_index = 2; 738 var arguments_index = 2;
810 var arguments_length = %_ArgumentsLength(); 739 var arguments_length = %_ArgumentsLength();
811 while (arguments_index < arguments_length) { 740 while (arguments_index < arguments_length) {
812 array[i++] = %_Arguments(arguments_index++); 741 array[i++] = %_Arguments(arguments_index++);
813 } 742 }
814 array.length = len - del_count + num_elements_to_add; 743 array.length = len - del_count + num_elements_to_add;
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 )); 1454 ));
1526 1455
1527 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( 1456 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
1528 "join", getFunction("join", ArrayJoin), 1457 "join", getFunction("join", ArrayJoin),
1529 "pop", getFunction("pop", ArrayPop), 1458 "pop", getFunction("pop", ArrayPop),
1530 "push", getFunction("push", ArrayPush) 1459 "push", getFunction("push", ArrayPush)
1531 )); 1460 ));
1532 } 1461 }
1533 1462
1534 SetUpArray(); 1463 SetUpArray();
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/array-functions-prototype-misc.js » ('j') | test/mjsunit/array-functions-prototype-misc.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698