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

Unified Diff: src/array.js

Issue 416403002: Keep new arrays allocated with 'new Array(N)' in fast mode (revisited) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/elements.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/array.js
diff --git a/src/array.js b/src/array.js
index 15cbbf21a6003a3336be6dd6e5f755154c510a28..60a6834198bc421b8c41c076696006680c8b82b6 100644
--- a/src/array.js
+++ b/src/array.js
@@ -86,11 +86,20 @@ function SparseJoin(array, len, convert) {
}
-function UseSparseVariant(object, length, is_array) {
- return is_array &&
- length > 1000 &&
- (!%_IsSmi(length) ||
- %EstimateNumberOfElements(object) < (length >> 2));
+function UseSparseVariant(array, length, is_array, touched) {
+ // Only use the sparse variant on arrays that are likely to be sparse and the
+ // number of elements touched in the operation is relatively small compared to
+ // the overall size of the array.
+ if (!is_array || length < 1000 || %IsObserved(array)) {
+ return false;
+ }
+ if (!%_IsSmi(length)) {
+ return true;
+ }
+ var elements_threshold = length >> 2; // No more than 75% holes
+ var estimated_elements = %EstimateNumberOfElements(array);
+ return (estimated_elements < elements_threshold) &&
+ (touched > estimated_elements * 4);
}
@@ -107,7 +116,8 @@ function Join(array, length, separator, convert) {
// Attempt to convert the elements.
try {
- if (UseSparseVariant(array, length, is_array)) {
+ if (UseSparseVariant(array, length, is_array, length)) {
+ %NormalizeElements(array);
if (separator.length == 0) {
return SparseJoin(array, length, convert);
} else {
@@ -518,13 +528,15 @@ function ArrayReverse() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
var array = TO_OBJECT_INLINE(this);
- var j = TO_UINT32(array.length) - 1;
+ var len = TO_UINT32(array.length);
- if (UseSparseVariant(array, j, IS_ARRAY(array))) {
- SparseReverse(array, j+1);
+ if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
+ %NormalizeElements(array);
+ SparseReverse(array, len);
return array;
}
+ var j = len - 1;
for (var i = 0; i < j; i++, j--) {
var current_i = array[i];
if (!IS_UNDEFINED(current_i) || i in array) {
@@ -670,10 +682,9 @@ function ArraySlice(start, end) {
if (end_i < start_i) return result;
- if (IS_ARRAY(array) &&
- !%IsObserved(array) &&
- (end_i > 1000) &&
- (%EstimateNumberOfElements(array) < end_i)) {
+ if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
+ %NormalizeElements(array);
+ %NormalizeElements(result);
SmartSlice(array, start_i, end_i - start_i, len, result);
} else {
SimpleSlice(array, start_i, end_i - start_i, len, result);
@@ -781,24 +792,20 @@ function ArraySplice(start, delete_count) {
["Array.prototype.splice"]);
}
- var use_simple_splice = true;
- if (IS_ARRAY(array) &&
- num_elements_to_add !== del_count) {
- // If we are only deleting/moving a few things near the end of the
- // array then the simple version is going to be faster, because it
- // doesn't touch most of the array.
- var estimated_non_hole_elements = %EstimateNumberOfElements(array);
- if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) {
- use_simple_splice = false;
- }
+ var changed_elements = del_count;
+ if (num_elements_to_add != del_count) {
+ // If the slice needs to do a actually move elements after the insertion
+ // point, then include those in the estimate of changed elements.
+ changed_elements += len - start_i - del_count;
}
-
- if (use_simple_splice) {
- SimpleSlice(array, start_i, del_count, len, deleted_elements);
- SimpleMove(array, start_i, del_count, len, num_elements_to_add);
- } else {
+ if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
+ %NormalizeElements(array);
+ %NormalizeElements(deleted_elements);
SmartSlice(array, start_i, del_count, len, deleted_elements);
SmartMove(array, start_i, del_count, len, num_elements_to_add);
+ } else {
+ SimpleSlice(array, start_i, del_count, len, deleted_elements);
+ SimpleMove(array, start_i, del_count, len, num_elements_to_add);
}
// Insert the arguments into the resulting array in
@@ -1283,7 +1290,8 @@ function ArrayIndexOf(element, index) {
}
var min = index;
var max = length;
- if (UseSparseVariant(this, length, IS_ARRAY(this))) {
+ if (UseSparseVariant(this, length, IS_ARRAY(this), max - min)) {
+ %NormalizeElements(this);
var indices = %GetArrayKeys(this, length);
if (IS_NUMBER(indices)) {
// It's an interval.
@@ -1338,7 +1346,8 @@ function ArrayLastIndexOf(element, index) {
}
var min = 0;
var max = index;
- if (UseSparseVariant(this, length, IS_ARRAY(this))) {
+ if (UseSparseVariant(this, length, IS_ARRAY(this), index)) {
+ %NormalizeElements(this);
var indices = %GetArrayKeys(this, index + 1);
if (IS_NUMBER(indices)) {
// It's an interval.
« no previous file with comments | « no previous file | src/elements.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698