Reviewers: adamk,
Message:
I couldn't figure out how to trigger sparse reverse. If anyone has advice,
that'd be appreciated.
Description:
Array.prototype.reverse should call [[HasProperty]] on elements before
[[Get]]
This is a change from ES5 to ES6: When reversing an array, first it is
checked
whether the element exists, before the element is looked up. The order in
ES6
is
[[HasElement]] lower
[[Get]] lower (if present)
[[HasElement]] upper
[[Get]] upper (if present)
In ES5, on the other hand, the order was
[[Get]] lower
[[Get]] upper
[[HasElement]] lower
[[HasElement]] upper
Unfortunately, this patch probably makes reverse a bit slower because the
previous code was able to skip the [[HasElement]] check when the element was
not undefined. (This optimization is invalid with the addition of Proxies,
but those aren't turned on yet.) I have not benchmarked it yet, so I don't
know how big the effect is. It will be a bit of work to recover the
optimization, since any old array could have a getter which modifies the
array and our JavaScript code doesn't tend to look deeply into object maps.
BUG=v8:4223
R=adamk
LOG=Y
Please review this at https://codereview.chromium.org/1238593003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+24, -12 lines):
M src/array.js
A test/mjsunit/es6/array-reverse-order.js
Index: src/array.js
diff --git a/src/array.js b/src/array.js
index
7baabf83610c3c333eb13b9a5463c652ccaa3839..deec030b5a298aef8a54b2df0b78734abc230817
100644
--- a/src/array.js
+++ b/src/array.js
@@ -567,10 +567,10 @@ function SparseReverse(array, len) {
high = len - i - 1;
}
- var current_i = array[low];
- if (!IS_UNDEFINED(current_i) || low in array) {
- var current_j = array[high];
- if (!IS_UNDEFINED(current_j) || high in array) {
+ if (low in array) {
+ var current_i = array[low];
+ if (high in array) {
+ var current_j = array[high];
array[low] = current_j;
array[high] = current_i;
} else {
@@ -578,8 +578,8 @@ function SparseReverse(array, len) {
delete array[low];
}
} else {
- var current_j = array[high];
- if (!IS_UNDEFINED(current_j) || high in array) {
+ if (high in array) {
+ var current_j = array[high];
array[low] = current_j;
delete array[high];
}
@@ -591,10 +591,10 @@ function SparseReverse(array, len) {
function InnerArrayReverse(array, len) {
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) {
- var current_j = array[j];
- if (!IS_UNDEFINED(current_j) || j in array) {
+ if (i in array) {
+ var current_i = array[i];
+ if (j in array) {
+ var current_j = array[j];
array[i] = current_j;
array[j] = current_i;
} else {
@@ -602,8 +602,8 @@ function InnerArrayReverse(array, len) {
delete array[i];
}
} else {
- var current_j = array[j];
- if (!IS_UNDEFINED(current_j) || j in array) {
+ if (j in array) {
+ var current_j = array[j];
array[i] = current_j;
delete array[j];
}
Index: test/mjsunit/es6/array-reverse-order.js
diff --git a/test/mjsunit/es6/array-reverse-order.js
b/test/mjsunit/es6/array-reverse-order.js
new file mode 100644
index
0000000000000000000000000000000000000000..591c36fe908991d49da5b88260010d831fafa1a5
--- /dev/null
+++ b/test/mjsunit/es6/array-reverse-order.js
@@ -0,0 +1,12 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ES6 specifically says that elements should be checked with
[[HasElement]] before
+// [[Get]]. This is observable in case a getter deletes elements. ES5 put
the
+// [[HasElement]] after the [[Get]].
+// TODO(littledan): Add a test which triggers the sparse codepath. Below,
the
+// non-sparse codepath is tested.
+
+assertTrue(1 in Array.prototype.reverse.call(
+ {length:2, get 0(){delete this[0];}, 1: "b"}))
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.