Index: src/array.js |
diff --git a/src/array.js b/src/array.js |
index 585d1da8427507f0ef0ea3cb12470d3c9bc21488..7fd2a06d87b439ba8fdd9d30e339476866a89948 100644 |
--- a/src/array.js |
+++ b/src/array.js |
@@ -90,7 +90,8 @@ 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)) { |
+ if (!is_array || length < 1000 || %IsObserved(array) || |
+ %HasComplexElements(array)) { |
return false; |
} |
if (!%_IsSmi(length)) { |
@@ -203,7 +204,7 @@ function ConvertToLocaleString(e) { |
// This function implements the optimized splice implementation that can use |
// special array operations to handle sparse arrays in a sensible fashion. |
-function SmartSlice(array, start_i, del_count, len, deleted_elements) { |
+function SparseSlice(array, start_i, del_count, len, deleted_elements) { |
// Move deleted elements to a new array (the return value from splice). |
var indices = %GetArrayKeys(array, start_i + del_count); |
if (IS_NUMBER(indices)) { |
@@ -233,7 +234,7 @@ function SmartSlice(array, start_i, del_count, len, deleted_elements) { |
// This function implements the optimized splice implementation that can use |
// special array operations to handle sparse arrays in a sensible fashion. |
-function SmartMove(array, start_i, del_count, len, num_additional_args) { |
+function SparseMove(array, start_i, del_count, len, num_additional_args) { |
// Bail out if no moving is necessary. |
if (num_additional_args === del_count) return; |
// Move data to new array. |
@@ -608,8 +609,8 @@ function ArrayShift() { |
var first = array[0]; |
- if (IS_ARRAY(array)) { |
- SmartMove(array, 0, 1, len, 0); |
+ if (UseSparseVariant(array, len, IS_ARRAY(array), len)) { |
+ SparseMove(array, 0, 1, len, 0); |
} else { |
SimpleMove(array, 0, 1, len, 0); |
} |
@@ -648,10 +649,10 @@ function ArrayUnshift(arg1) { // length == 1 |
var array = TO_OBJECT_INLINE(this); |
var len = TO_UINT32(array.length); |
var num_arguments = %_ArgumentsLength(); |
- var is_sealed = ObjectIsSealed(array); |
- if (IS_ARRAY(array) && !is_sealed && len > 0) { |
- SmartMove(array, 0, 0, len, num_arguments); |
+ if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) && |
+ !ObjectIsSealed(array)) { |
+ SparseMove(array, 0, 0, len, num_arguments); |
} else { |
SimpleMove(array, 0, 0, len, num_arguments); |
} |
@@ -697,7 +698,7 @@ function ArraySlice(start, end) { |
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); |
+ SparseSlice(array, start_i, end_i - start_i, len, result); |
} else { |
SimpleSlice(array, start_i, end_i - start_i, len, result); |
} |
@@ -813,8 +814,8 @@ function ArraySplice(start, delete_count) { |
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); |
+ SparseSlice(array, start_i, del_count, len, deleted_elements); |
+ SparseMove(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); |