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

Side by Side Diff: src/array.js

Issue 656423004: Narrow cases where Sparse/Smart versions of Array methods are used (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added more tests Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/objects.h » ('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 "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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 } 83 }
84 } 84 }
85 return %StringBuilderConcat(elements, elements_length, ''); 85 return %StringBuilderConcat(elements, elements_length, '');
86 } 86 }
87 87
88 88
89 function UseSparseVariant(array, length, is_array, touched) { 89 function UseSparseVariant(array, length, is_array, touched) {
90 // Only use the sparse variant on arrays that are likely to be sparse and the 90 // Only use the sparse variant on arrays that are likely to be sparse and the
91 // number of elements touched in the operation is relatively small compared to 91 // number of elements touched in the operation is relatively small compared to
92 // the overall size of the array. 92 // the overall size of the array.
93 if (!is_array || length < 1000 || %IsObserved(array)) { 93 if (!is_array || length < 1000 || %IsObserved(array) ||
94 %HasComplexElements(array)) {
94 return false; 95 return false;
95 } 96 }
96 if (!%_IsSmi(length)) { 97 if (!%_IsSmi(length)) {
97 return true; 98 return true;
98 } 99 }
99 var elements_threshold = length >> 2; // No more than 75% holes 100 var elements_threshold = length >> 2; // No more than 75% holes
100 var estimated_elements = %EstimateNumberOfElements(array); 101 var estimated_elements = %EstimateNumberOfElements(array);
101 return (estimated_elements < elements_threshold) && 102 return (estimated_elements < elements_threshold) &&
102 (touched > estimated_elements * 4); 103 (touched > estimated_elements * 4);
103 } 104 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 // must throw a TypeError if ToObject(e).toLocaleString isn't 197 // must throw a TypeError if ToObject(e).toLocaleString isn't
197 // callable. 198 // callable.
198 var e_obj = ToObject(e); 199 var e_obj = ToObject(e);
199 return %ToString(e_obj.toLocaleString()); 200 return %ToString(e_obj.toLocaleString());
200 } 201 }
201 } 202 }
202 203
203 204
204 // This function implements the optimized splice implementation that can use 205 // This function implements the optimized splice implementation that can use
205 // special array operations to handle sparse arrays in a sensible fashion. 206 // special array operations to handle sparse arrays in a sensible fashion.
206 function SmartSlice(array, start_i, del_count, len, deleted_elements) { 207 function SparseSlice(array, start_i, del_count, len, deleted_elements) {
207 // Move deleted elements to a new array (the return value from splice). 208 // Move deleted elements to a new array (the return value from splice).
208 var indices = %GetArrayKeys(array, start_i + del_count); 209 var indices = %GetArrayKeys(array, start_i + del_count);
209 if (IS_NUMBER(indices)) { 210 if (IS_NUMBER(indices)) {
210 var limit = indices; 211 var limit = indices;
211 for (var i = start_i; i < limit; ++i) { 212 for (var i = start_i; i < limit; ++i) {
212 var current = array[i]; 213 var current = array[i];
213 if (!IS_UNDEFINED(current) || i in array) { 214 if (!IS_UNDEFINED(current) || i in array) {
214 deleted_elements[i - start_i] = current; 215 deleted_elements[i - start_i] = current;
215 } 216 }
216 } 217 }
217 } else { 218 } else {
218 var length = indices.length; 219 var length = indices.length;
219 for (var k = 0; k < length; ++k) { 220 for (var k = 0; k < length; ++k) {
220 var key = indices[k]; 221 var key = indices[k];
221 if (!IS_UNDEFINED(key)) { 222 if (!IS_UNDEFINED(key)) {
222 if (key >= start_i) { 223 if (key >= start_i) {
223 var current = array[key]; 224 var current = array[key];
224 if (!IS_UNDEFINED(current) || key in array) { 225 if (!IS_UNDEFINED(current) || key in array) {
225 deleted_elements[key - start_i] = current; 226 deleted_elements[key - start_i] = current;
226 } 227 }
227 } 228 }
228 } 229 }
229 } 230 }
230 } 231 }
231 } 232 }
232 233
233 234
234 // This function implements the optimized splice implementation that can use 235 // This function implements the optimized splice implementation that can use
235 // special array operations to handle sparse arrays in a sensible fashion. 236 // special array operations to handle sparse arrays in a sensible fashion.
236 function SmartMove(array, start_i, del_count, len, num_additional_args) { 237 function SparseMove(array, start_i, del_count, len, num_additional_args) {
237 // Bail out if no moving is necessary. 238 // Bail out if no moving is necessary.
238 if (num_additional_args === del_count) return; 239 if (num_additional_args === del_count) return;
239 // Move data to new array. 240 // Move data to new array.
240 var new_array = new InternalArray(len - del_count + num_additional_args); 241 var new_array = new InternalArray(len - del_count + num_additional_args);
241 var indices = %GetArrayKeys(array, len); 242 var indices = %GetArrayKeys(array, len);
242 if (IS_NUMBER(indices)) { 243 if (IS_NUMBER(indices)) {
243 var limit = indices; 244 var limit = indices;
244 for (var i = 0; i < start_i && i < limit; ++i) { 245 for (var i = 0; i < start_i && i < limit; ++i) {
245 var current = array[i]; 246 var current = array[i];
246 if (!IS_UNDEFINED(current) || i in array) { 247 if (!IS_UNDEFINED(current) || i in array) {
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 if (ObjectIsSealed(array)) { 602 if (ObjectIsSealed(array)) {
602 throw MakeTypeError("array_functions_change_sealed", 603 throw MakeTypeError("array_functions_change_sealed",
603 ["Array.prototype.shift"]); 604 ["Array.prototype.shift"]);
604 } 605 }
605 606
606 if (%IsObserved(array)) 607 if (%IsObserved(array))
607 return ObservedArrayShift.call(array, len); 608 return ObservedArrayShift.call(array, len);
608 609
609 var first = array[0]; 610 var first = array[0];
610 611
611 if (IS_ARRAY(array)) { 612 if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
612 SmartMove(array, 0, 1, len, 0); 613 SparseMove(array, 0, 1, len, 0);
613 } else { 614 } else {
614 SimpleMove(array, 0, 1, len, 0); 615 SimpleMove(array, 0, 1, len, 0);
615 } 616 }
616 617
617 array.length = len - 1; 618 array.length = len - 1;
618 619
619 return first; 620 return first;
620 } 621 }
621 622
622 function ObservedArrayUnshift() { 623 function ObservedArrayUnshift() {
(...skipping 18 matching lines...) Expand all
641 642
642 function ArrayUnshift(arg1) { // length == 1 643 function ArrayUnshift(arg1) { // length == 1
643 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift"); 644 CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
644 645
645 if (%IsObserved(this)) 646 if (%IsObserved(this))
646 return ObservedArrayUnshift.apply(this, arguments); 647 return ObservedArrayUnshift.apply(this, arguments);
647 648
648 var array = TO_OBJECT_INLINE(this); 649 var array = TO_OBJECT_INLINE(this);
649 var len = TO_UINT32(array.length); 650 var len = TO_UINT32(array.length);
650 var num_arguments = %_ArgumentsLength(); 651 var num_arguments = %_ArgumentsLength();
651 var is_sealed = ObjectIsSealed(array);
652 652
653 if (IS_ARRAY(array) && !is_sealed && len > 0) { 653 if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) &&
654 SmartMove(array, 0, 0, len, num_arguments); 654 !ObjectIsSealed(array)) {
655 SparseMove(array, 0, 0, len, num_arguments);
655 } else { 656 } else {
656 SimpleMove(array, 0, 0, len, num_arguments); 657 SimpleMove(array, 0, 0, len, num_arguments);
657 } 658 }
658 659
659 for (var i = 0; i < num_arguments; i++) { 660 for (var i = 0; i < num_arguments; i++) {
660 array[i] = %_Arguments(i); 661 array[i] = %_Arguments(i);
661 } 662 }
662 663
663 var new_length = len + num_arguments; 664 var new_length = len + num_arguments;
664 array.length = new_length; 665 array.length = new_length;
(...skipping 25 matching lines...) Expand all
690 if (end_i > len) end_i = len; 691 if (end_i > len) end_i = len;
691 } 692 }
692 693
693 var result = []; 694 var result = [];
694 695
695 if (end_i < start_i) return result; 696 if (end_i < start_i) return result;
696 697
697 if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) { 698 if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
698 %NormalizeElements(array); 699 %NormalizeElements(array);
699 %NormalizeElements(result); 700 %NormalizeElements(result);
700 SmartSlice(array, start_i, end_i - start_i, len, result); 701 SparseSlice(array, start_i, end_i - start_i, len, result);
701 } else { 702 } else {
702 SimpleSlice(array, start_i, end_i - start_i, len, result); 703 SimpleSlice(array, start_i, end_i - start_i, len, result);
703 } 704 }
704 705
705 result.length = end_i - start_i; 706 result.length = end_i - start_i;
706 707
707 return result; 708 return result;
708 } 709 }
709 710
710 711
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 807
807 var changed_elements = del_count; 808 var changed_elements = del_count;
808 if (num_elements_to_add != del_count) { 809 if (num_elements_to_add != del_count) {
809 // If the slice needs to do a actually move elements after the insertion 810 // If the slice needs to do a actually move elements after the insertion
810 // point, then include those in the estimate of changed elements. 811 // point, then include those in the estimate of changed elements.
811 changed_elements += len - start_i - del_count; 812 changed_elements += len - start_i - del_count;
812 } 813 }
813 if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) { 814 if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
814 %NormalizeElements(array); 815 %NormalizeElements(array);
815 %NormalizeElements(deleted_elements); 816 %NormalizeElements(deleted_elements);
816 SmartSlice(array, start_i, del_count, len, deleted_elements); 817 SparseSlice(array, start_i, del_count, len, deleted_elements);
817 SmartMove(array, start_i, del_count, len, num_elements_to_add); 818 SparseMove(array, start_i, del_count, len, num_elements_to_add);
818 } else { 819 } else {
819 SimpleSlice(array, start_i, del_count, len, deleted_elements); 820 SimpleSlice(array, start_i, del_count, len, deleted_elements);
820 SimpleMove(array, start_i, del_count, len, num_elements_to_add); 821 SimpleMove(array, start_i, del_count, len, num_elements_to_add);
821 } 822 }
822 823
823 // Insert the arguments into the resulting array in 824 // Insert the arguments into the resulting array in
824 // place of the deleted elements. 825 // place of the deleted elements.
825 var i = start_i; 826 var i = start_i;
826 var arguments_index = 2; 827 var arguments_index = 2;
827 var arguments_length = %_ArgumentsLength(); 828 var arguments_length = %_ArgumentsLength();
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 )); 1569 ));
1569 1570
1570 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array( 1571 SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
1571 "join", getFunction("join", ArrayJoin), 1572 "join", getFunction("join", ArrayJoin),
1572 "pop", getFunction("pop", ArrayPop), 1573 "pop", getFunction("pop", ArrayPop),
1573 "push", getFunction("push", ArrayPush) 1574 "push", getFunction("push", ArrayPush)
1574 )); 1575 ));
1575 } 1576 }
1576 1577
1577 SetUpArray(); 1578 SetUpArray();
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698