summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit/compiler')
-rw-r--r--deps/v8/test/mjsunit/compiler/abstract-equal-symbol.js135
-rw-r--r--deps/v8/test/mjsunit/compiler/array-buffer-is-view.js64
-rw-r--r--deps/v8/test/mjsunit/compiler/array-is-array.js105
-rw-r--r--deps/v8/test/mjsunit/compiler/context-sensitivity.js550
-rw-r--r--deps/v8/test/mjsunit/compiler/dataview-constant.js173
-rw-r--r--deps/v8/test/mjsunit/compiler/dataview-neutered.js376
-rw-r--r--deps/v8/test/mjsunit/compiler/dataview-nonconstant.js173
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js53
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis-array.js32
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis-rest-parameters.js31
-rw-r--r--deps/v8/test/mjsunit/compiler/instanceof2.js233
-rw-r--r--deps/v8/test/mjsunit/compiler/instanceof3.js233
-rw-r--r--deps/v8/test/mjsunit/compiler/int64.js91
-rw-r--r--deps/v8/test/mjsunit/compiler/math-imul.js76
-rw-r--r--deps/v8/test/mjsunit/compiler/math-max.js38
-rw-r--r--deps/v8/test/mjsunit/compiler/math-min.js38
-rw-r--r--deps/v8/test/mjsunit/compiler/number-abs.js76
-rw-r--r--deps/v8/test/mjsunit/compiler/number-add.js62
-rw-r--r--deps/v8/test/mjsunit/compiler/number-ceil.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/number-comparison-truncations.js152
-rw-r--r--deps/v8/test/mjsunit/compiler/number-divide.js207
-rw-r--r--deps/v8/test/mjsunit/compiler/number-floor.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/number-issafeinteger.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/number-max.js23
-rw-r--r--deps/v8/test/mjsunit/compiler/number-min.js23
-rw-r--r--deps/v8/test/mjsunit/compiler/number-modulus.js256
-rw-r--r--deps/v8/test/mjsunit/compiler/number-round.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/number-subtract.js34
-rw-r--r--deps/v8/test/mjsunit/compiler/number-toboolean.js45
-rw-r--r--deps/v8/test/mjsunit/compiler/number-trunc.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/redundancy-elimination.js194
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-7121.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-884052.js16
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-890057.js16
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-890620.js25
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-895799.js26
-rw-r--r--deps/v8/test/mjsunit/compiler/strict-equal-symbol.js50
-rw-r--r--deps/v8/test/mjsunit/compiler/string-add-try-catch.js57
-rw-r--r--deps/v8/test/mjsunit/compiler/string-from-code-point.js32
-rw-r--r--deps/v8/test/mjsunit/compiler/typed-array-constructor.js2
40 files changed, 3800 insertions, 9 deletions
diff --git a/deps/v8/test/mjsunit/compiler/abstract-equal-symbol.js b/deps/v8/test/mjsunit/compiler/abstract-equal-symbol.js
new file mode 100644
index 0000000000..c1057e1d1b
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/abstract-equal-symbol.js
@@ -0,0 +1,135 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt --noalways-opt
+
+// Known symbols abstract equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo() { return a == b; }
+
+ assertFalse(foo());
+ assertFalse(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo());
+})();
+
+// Known symbols abstract in-equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo() { return a != b; }
+
+ assertTrue(foo());
+ assertTrue(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo());
+})();
+
+// Known symbol on one side abstract equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo(a) { return a == b; }
+
+ // Warmup
+ assertTrue(foo(b));
+ assertFalse(foo(a));
+ assertTrue(foo(b));
+ assertFalse(foo(a));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo(b));
+ assertFalse(foo(a));
+ assertOptimized(foo);
+
+ // Make optimized code bail out
+ assertFalse(foo("a"));
+ assertUnoptimized(foo);
+
+ // Make sure TurboFan learns the new feedback
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo("a"));
+ assertOptimized(foo);
+})();
+
+// Known symbol on one side abstract in-equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo(a) { return a != b; }
+
+ // Warmup
+ assertFalse(foo(b));
+ assertTrue(foo(a));
+ assertFalse(foo(b));
+ assertTrue(foo(a));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(b));
+ assertTrue(foo(a));
+
+ // Make optimized code bail out
+ assertTrue(foo("a"));
+ assertUnoptimized(foo);
+
+ // Make sure TurboFan learns the new feedback
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo("a"));
+ assertOptimized(foo);
+})();
+
+// Feedback based symbol abstract equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo(a, b) { return a == b; }
+
+ // Warmup
+ assertTrue(foo(b, b));
+ assertFalse(foo(a, b));
+ assertTrue(foo(a, a));
+ assertFalse(foo(b, a));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo(a, a));
+ assertFalse(foo(b, a));
+
+ // Make optimized code bail out
+ assertFalse(foo("a", b));
+ assertUnoptimized(foo);
+
+ // Make sure TurboFan learns the new feedback
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo("a", b));
+ assertOptimized(foo);
+})();
+
+// Feedback based symbol abstract in-equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo(a, b) { return a != b; }
+
+ assertFalse(foo(b, b));
+ assertTrue(foo(a, b));
+ assertFalse(foo(a, a));
+ assertTrue(foo(b, a));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(a, a));
+ assertTrue(foo(b, a));
+
+ // Make optimized code bail out
+ assertTrue(foo("a", b));
+ assertUnoptimized(foo);
+
+ // Make sure TurboFan learns the new feedback
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo("a", b));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/array-buffer-is-view.js b/deps/v8/test/mjsunit/compiler/array-buffer-is-view.js
new file mode 100644
index 0000000000..b56763b5b2
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/array-buffer-is-view.js
@@ -0,0 +1,64 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that ObjectIsArrayBufferView lowering works correctly
+// in EffectControlLinearizer in the case that the input is
+// known to be a HeapObject by TurboFan. For this we use the
+// simple trick with an object literal whose field `x` will
+// only ever contain HeapObjects and so the representation
+// tracking is going to pick it up.
+(function() {
+ function foo(x) {
+ return ArrayBuffer.isView({x}.x);
+ }
+
+ assertFalse(foo(Symbol()));
+ assertFalse(foo("some string"));
+ assertFalse(foo(new Object()));
+ assertFalse(foo(new Array()));
+ assertFalse(foo(new ArrayBuffer(1)));
+ assertTrue(foo(new Int32Array(1)));
+ assertTrue(foo(new DataView(new ArrayBuffer(1))));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(Symbol()));
+ assertFalse(foo("some string"));
+ assertFalse(foo(new Object()));
+ assertFalse(foo(new Array()));
+ assertFalse(foo(new ArrayBuffer(1)));
+ assertTrue(foo(new Int32Array(1)));
+ assertTrue(foo(new DataView(new ArrayBuffer(1))));
+ assertOptimized(foo);
+})();
+
+// Test that ObjectIsArrayBufferView lowering works correctly
+// in EffectControlLinearizer in the case that the input is
+// some arbitrary tagged value.
+(function() {
+ function foo(x) {
+ return ArrayBuffer.isView(x);
+ }
+
+ assertFalse(foo(1));
+ assertFalse(foo(1.1));
+ assertFalse(foo(Symbol()));
+ assertFalse(foo("some string"));
+ assertFalse(foo(new Object()));
+ assertFalse(foo(new Array()));
+ assertFalse(foo(new ArrayBuffer(1)));
+ assertTrue(foo(new Int32Array(1)));
+ assertTrue(foo(new DataView(new ArrayBuffer(1))));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(1));
+ assertFalse(foo(1.1));
+ assertFalse(foo(Symbol()));
+ assertFalse(foo("some string"));
+ assertFalse(foo(new Object()));
+ assertFalse(foo(new Array()));
+ assertFalse(foo(new ArrayBuffer(1)));
+ assertTrue(foo(new Int32Array(1)));
+ assertTrue(foo(new DataView(new ArrayBuffer(1))));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/array-is-array.js b/deps/v8/test/mjsunit/compiler/array-is-array.js
new file mode 100644
index 0000000000..37c916ddac
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/array-is-array.js
@@ -0,0 +1,105 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test JSObjectIsArray in JSTypedLowering for the case that the
+// input value is known to be an Array literal.
+(function() {
+ function foo() {
+ return Array.isArray([]);
+ }
+
+ assertTrue(foo());
+ assertTrue(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo());
+})();
+
+// Test JSObjectIsArray in JSTypedLowering for the case that the
+// input value is known to be a Proxy for an Array literal.
+(function() {
+ function foo() {
+ return Array.isArray(new Proxy([], {}));
+ }
+
+ assertTrue(foo());
+ assertTrue(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo());
+})();
+
+// Test JSObjectIsArray in JSTypedLowering for the case that the
+// input value is known to be an Object literal.
+(function() {
+ function foo() {
+ return Array.isArray({});
+ }
+
+ assertFalse(foo());
+ assertFalse(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo());
+})();
+
+// Test JSObjectIsArray in JSTypedLowering for the case that the
+// input value is known to be a Proxy for an Object literal.
+(function() {
+ function foo() {
+ return Array.isArray(new Proxy({}, {}));
+ }
+
+ assertFalse(foo());
+ assertFalse(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo());
+})();
+
+// Test JSObjectIsArray in JSTypedLowering for the case that
+// TurboFan doesn't know anything about the input value.
+(function() {
+ function foo(x) {
+ return Array.isArray(x);
+ }
+
+ assertFalse(foo({}));
+ assertFalse(foo(new Proxy({}, {})));
+ assertTrue(foo([]));
+ assertTrue(foo(new Proxy([], {})));
+ assertThrows(() => {
+ const {proxy, revoke} = Proxy.revocable([], {});
+ revoke();
+ foo(proxy);
+ }, TypeError);
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo({}));
+ assertFalse(foo(new Proxy({}, {})));
+ assertTrue(foo([]));
+ assertTrue(foo(new Proxy([], {})));
+ assertThrows(() => {
+ const {proxy, revoke} = Proxy.revocable([], {});
+ revoke();
+ foo(proxy);
+ }, TypeError);
+})();
+
+// Test JSObjectIsArray in JSTypedLowering for the case that
+// we pass a revoked proxy and catch the exception locally.
+(function() {
+ function foo(x) {
+ const {proxy, revoke} = Proxy.revocable(x, {});
+ revoke();
+ try {
+ return Array.isArray(proxy);
+ } catch (e) {
+ return e;
+ }
+ }
+
+ assertInstanceof(foo([]), TypeError);
+ assertInstanceof(foo({}), TypeError);
+ %OptimizeFunctionOnNextCall(foo);
+ assertInstanceof(foo([]), TypeError);
+ assertInstanceof(foo({}), TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/context-sensitivity.js b/deps/v8/test/mjsunit/compiler/context-sensitivity.js
new file mode 100644
index 0000000000..1f0f1f274a
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/context-sensitivity.js
@@ -0,0 +1,550 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+const object1 = {[Symbol.toPrimitive]() { return 1; }};
+const thrower = {[Symbol.toPrimitive]() { throw new Error(); }};
+
+// Test that JSAdd is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y + x);
+ }
+
+ assertEquals(1, foo(0));
+ assertEquals(2, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(0));
+ assertEquals(2, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSSubtract is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y - x);
+ }
+
+ assertEquals(1, foo(0));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(0));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSMultiply is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y * x);
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSDivide is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y / x);
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSModulus is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y % x);
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSExponentiate is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y ** x);
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSBitwiseOr is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y | x);
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSBitwiseAnd is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y & x);
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSBitwiseXor is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y ^ x);
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSShiftLeft is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y << x);
+ }
+
+ assertEquals(2, foo(1));
+ assertEquals(2, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(1));
+ assertEquals(2, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSShiftRight is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y >> x);
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSShiftRightLogical is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y >>> x);
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSEqual is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y == x);
+ }
+
+ assertFalse(foo(0));
+ assertTrue(foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(0));
+ assertTrue(foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSLessThan is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y < x);
+ }
+
+ assertFalse(foo(0));
+ assertFalse(foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(0));
+ assertFalse(foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSGreaterThan is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => x > y);
+ }
+
+ assertFalse(foo(0));
+ assertFalse(foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(0));
+ assertFalse(foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSLessThanOrEqual is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => y <= x);
+ }
+
+ assertFalse(foo(0));
+ assertTrue(foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(0));
+ assertTrue(foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSGreaterThanOrEqual is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn(1);
+ }
+
+ function foo(x) {
+ return bar(y => x >= y);
+ }
+
+ assertFalse(foo(0));
+ assertTrue(foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(0));
+ assertTrue(foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSInstanceOf is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn({});
+ }
+
+ function foo(c) {
+ return bar(o => o instanceof c);
+ }
+
+ assertTrue(foo(Object));
+ assertFalse(foo(Array));
+ assertThrows(() => foo({[Symbol.hasInstance]() { throw new Error(); }}));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo(Object));
+ assertFalse(foo(Array));
+ assertThrows(() => foo({[Symbol.hasInstance]() { throw new Error(); }}));
+})();
+
+// Test that JSBitwiseNot is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(x) {
+ return bar(() => ~x);
+ }
+
+ assertEquals(0, foo(-1));
+ assertEquals(~1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(-1));
+ assertEquals(~1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSNegate is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(x) {
+ return bar(() => -x);
+ }
+
+ assertEquals(1, foo(-1));
+ assertEquals(-1, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(-1));
+ assertEquals(-1, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSIncrement is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(x) {
+ return bar(() => ++x);
+ }
+
+ assertEquals(1, foo(0));
+ assertEquals(2, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(0));
+ assertEquals(2, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSDecrement is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(x) {
+ return bar(() => --x);
+ }
+
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(object1));
+ assertThrows(() => foo(thrower));
+})();
+
+// Test that JSCreateArguments[UnmappedArguments] is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo() {
+ "use strict";
+ return bar(() => arguments)[0];
+ }
+
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 2));
+ assertEquals(undefined, foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 2));
+ assertEquals(undefined, foo());
+})();
+
+// Test that JSCreateArguments[RestParameters] is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(...args) {
+ return bar(() => args)[0];
+ }
+
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 2));
+ assertEquals(undefined, foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 2));
+ assertEquals(undefined, foo());
+})();
+
+// Test that JSLoadGlobal/JSStoreGlobal are not context-sensitive.
+(function(global) {
+ var actualValue = 'Some value';
+
+ Object.defineProperty(global, 'globalValue', {
+ configurable: true,
+ enumerable: true,
+ get: function() {
+ return actualValue;
+ },
+ set: function(v) {
+ actualValue = v;
+ }
+ });
+
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(v) {
+ return bar(() => {
+ const o = globalValue;
+ globalValue = v;
+ return o;
+ });
+ }
+
+ assertEquals('Some value', foo('Another value'));
+ assertEquals('Another value', actualValue);
+ assertEquals('Another value', foo('Some value'));
+ assertEquals('Some value', actualValue);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals('Some value', foo('Another value'));
+ assertEquals('Another value', actualValue);
+ assertEquals('Another value', foo('Some value'));
+ assertEquals('Some value', actualValue);
+})(this);
+
+// Test that for..in is not context-sensitive.
+(function() {
+ function bar(fn) {
+ return fn();
+ }
+
+ function foo(o) {
+ return bar(() => {
+ var s = "";
+ for (var k in o) { s += k; }
+ return s;
+ });
+ }
+
+ assertEquals('abc', foo({a: 1, b: 2, c: 3}));
+ assertEquals('ab', foo(Object.create({a: 1, b: 2})));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals('abc', foo({a: 1, b: 2, c: 3}));
+ assertEquals("ab", foo(Object.create({a:1, b:2})));
+})();
+
+// Test that most generator operations are not context-sensitive.
+(function() {
+ function bar(fn) {
+ let s = undefined;
+ for (const x of fn()) {
+ if (s === undefined) s = x;
+ else s += x;
+ }
+ return s;
+ }
+
+ function foo(x, y, z) {
+ return bar(function*() {
+ yield x;
+ yield y;
+ yield z;
+ });
+ }
+
+ assertEquals(6, foo(1, 2, 3));
+ assertEquals("abc", foo("a", "b", "c"));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(6, foo(1, 2, 3));
+ assertEquals("abc", foo("a", "b", "c"));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/dataview-constant.js b/deps/v8/test/mjsunit/compiler/dataview-constant.js
new file mode 100644
index 0000000000..f5f0b5e955
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/dataview-constant.js
@@ -0,0 +1,173 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test DataView.prototype.getInt8()/setInt8() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setInt8(0, 42);
+ dv.setInt8(1, 24);
+
+ function foo(i) {
+ const x = dv.getInt8(i);
+ dv.setInt8(i, x+1);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(1));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(1));
+})();
+
+// Test DataView.prototype.getUint8()/setUint8() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setUint8(0, 42);
+ dv.setUint8(1, 24);
+
+ function foo(i) {
+ const x = dv.getUint8(i);
+ dv.setUint8(i, x+1);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(1));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(1));
+})();
+
+// Test DataView.prototype.getInt16()/setInt16() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setInt16(0, 42, true);
+ dv.setInt16(2, 24, true);
+
+ function foo(i) {
+ const x = dv.getInt16(i, true);
+ dv.setInt16(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(2));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(2));
+})();
+
+// Test DataView.prototype.getUint16()/setUint16() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setUint16(0, 42, true);
+ dv.setUint16(2, 24, true);
+
+ function foo(i) {
+ const x = dv.getUint16(i, true);
+ dv.setUint16(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(2));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(2));
+})();
+
+// Test DataView.prototype.getInt32()/setInt32() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setInt32(0, 42, true);
+ dv.setInt32(4, 24, true);
+
+ function foo(i) {
+ const x = dv.getInt32(i, true);
+ dv.setInt32(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(4));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(4));
+})();
+
+// Test DataView.prototype.getUint32()/setUint32() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setUint32(0, 42, true);
+ dv.setUint32(4, 24, true);
+
+ function foo(i) {
+ const x = dv.getUint32(i, true);
+ dv.setUint32(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(4));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(4));
+})();
+
+// Test DataView.prototype.getFloat32()/setFloat32() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setFloat32(0, 42, true);
+ dv.setFloat32(4, 24, true);
+
+ function foo(i) {
+ const x = dv.getFloat32(i, true);
+ dv.setFloat32(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(4));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(4));
+})();
+
+// Test DataView.prototype.getFloat64()/setFloat64() for constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setFloat64(0, 42, true);
+ dv.setFloat64(8, 24, true);
+
+ function foo(i) {
+ const x = dv.getFloat64(i, true);
+ dv.setFloat64(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(0));
+ assertEquals(24, foo(8));
+ assertEquals(43, foo(0));
+ assertEquals(25, foo(8));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(0));
+ assertEquals(26, foo(8));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/dataview-neutered.js b/deps/v8/test/mjsunit/compiler/dataview-neutered.js
new file mode 100644
index 0000000000..54b35f73c8
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/dataview-neutered.js
@@ -0,0 +1,376 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt --noalways-opt
+
+// Invalidate the neutering protector.
+%ArrayBufferNeuter(new ArrayBuffer(1));
+
+// Check DataView.prototype.getInt8() optimization.
+(function() {
+ const ab = new ArrayBuffer(1);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getInt8(0);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getUint8() optimization.
+(function() {
+ const ab = new ArrayBuffer(1);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getUint8(0);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getInt16() optimization.
+(function() {
+ const ab = new ArrayBuffer(2);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getInt16(0, true);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getUint16() optimization.
+(function() {
+ const ab = new ArrayBuffer(2);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getUint16(0, true);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getInt32() optimization.
+(function() {
+ const ab = new ArrayBuffer(4);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getInt32(0, true);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getUint32() optimization.
+(function() {
+ const ab = new ArrayBuffer(4);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getUint32(0, true);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getFloat32() optimization.
+(function() {
+ const ab = new ArrayBuffer(4);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getFloat32(0, true);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.getFloat64() optimization.
+(function() {
+ const ab = new ArrayBuffer(8);
+ const dv = new DataView(ab);
+
+ function foo(dv) {
+ return dv.getFloat64(0, true);
+ }
+
+ assertEquals(0, foo(dv));
+ assertEquals(0, foo(dv));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(dv));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setInt8() optimization.
+(function() {
+ const ab = new ArrayBuffer(1);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setInt8(0, x);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getInt8(0));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getInt8(0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setUint8() optimization.
+(function() {
+ const ab = new ArrayBuffer(1);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setUint8(0, x);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getUint8(0));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getUint8(0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setInt16() optimization.
+(function() {
+ const ab = new ArrayBuffer(2);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setInt16(0, x, true);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getInt16(0, true));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getInt16(0, true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setUint16() optimization.
+(function() {
+ const ab = new ArrayBuffer(2);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setUint16(0, x, true);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getUint16(0, true));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getUint16(0, true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setInt32() optimization.
+(function() {
+ const ab = new ArrayBuffer(4);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setInt32(0, x, true);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getInt32(0, true));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getInt32(0, true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setUint32() optimization.
+(function() {
+ const ab = new ArrayBuffer(4);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setUint32(0, x, true);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getUint32(0, true));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getUint32(0, true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setFloat32() optimization.
+(function() {
+ const ab = new ArrayBuffer(4);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setFloat32(0, x, true);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getFloat32(0, true));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getFloat32(0, true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
+
+// Check DataView.prototype.setFloat64() optimization.
+(function() {
+ const ab = new ArrayBuffer(8);
+ const dv = new DataView(ab);
+
+ function foo(dv, x) {
+ return dv.setFloat64(0, x, true);
+ }
+
+ assertEquals(undefined, foo(dv, 1));
+ assertEquals(1, dv.getFloat64(0, true));
+ assertEquals(undefined, foo(dv, 2));
+ assertEquals(2, dv.getFloat64(0, true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(undefined, foo(dv, 3));
+ assertOptimized(foo);
+ %ArrayBufferNeuter(ab);
+ assertThrows(() => foo(dv, 4), TypeError);
+ assertUnoptimized(foo);
+ %OptimizeFunctionOnNextCall(foo);
+ assertThrows(() => foo(dv, 5), TypeError);
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/dataview-nonconstant.js b/deps/v8/test/mjsunit/compiler/dataview-nonconstant.js
new file mode 100644
index 0000000000..0420660c83
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/dataview-nonconstant.js
@@ -0,0 +1,173 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test DataView.prototype.getInt8()/setInt8() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setInt8(0, 42);
+ dv.setInt8(1, 24);
+
+ function foo(dv, i) {
+ const x = dv.getInt8(i);
+ dv.setInt8(i, x+1);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 1));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 1));
+})();
+
+// Test DataView.prototype.getUint8()/setUint8() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setUint8(0, 42);
+ dv.setUint8(1, 24);
+
+ function foo(dv, i) {
+ const x = dv.getUint8(i);
+ dv.setUint8(i, x+1);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 1));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 1));
+})();
+
+// Test DataView.prototype.getInt16()/setInt16() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setInt16(0, 42, true);
+ dv.setInt16(2, 24, true);
+
+ function foo(dv, i) {
+ const x = dv.getInt16(i, true);
+ dv.setInt16(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 2));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 2));
+})();
+
+// Test DataView.prototype.getUint16()/setUint16() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setUint16(0, 42, true);
+ dv.setUint16(2, 24, true);
+
+ function foo(dv, i) {
+ const x = dv.getUint16(i, true);
+ dv.setUint16(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 2));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 2));
+})();
+
+// Test DataView.prototype.getInt32()/setInt32() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setInt32(0, 42, true);
+ dv.setInt32(4, 24, true);
+
+ function foo(dv, i) {
+ const x = dv.getInt32(i, true);
+ dv.setInt32(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 4));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 4));
+})();
+
+// Test DataView.prototype.getUint32()/setUint32() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setUint32(0, 42, true);
+ dv.setUint32(4, 24, true);
+
+ function foo(dv, i) {
+ const x = dv.getUint32(i, true);
+ dv.setUint32(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 4));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 4));
+})();
+
+// Test DataView.prototype.getFloat32()/setFloat32() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setFloat32(0, 42, true);
+ dv.setFloat32(4, 24, true);
+
+ function foo(dv, i) {
+ const x = dv.getFloat32(i, true);
+ dv.setFloat32(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 4));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 4));
+})();
+
+// Test DataView.prototype.getFloat64()/setFloat64() for non-constant DataViews.
+(function() {
+ const dv = new DataView(new ArrayBuffer(1024));
+ dv.setFloat64(0, 42, true);
+ dv.setFloat64(8, 24, true);
+
+ function foo(dv, i) {
+ const x = dv.getFloat64(i, true);
+ dv.setFloat64(i, x+1, true);
+ return x;
+ }
+
+ assertEquals(42, foo(dv, 0));
+ assertEquals(24, foo(dv, 8));
+ assertEquals(43, foo(dv, 0));
+ assertEquals(25, foo(dv, 8));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(44, foo(dv, 0));
+ assertEquals(26, foo(dv, 8));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js b/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js
index f520167e19..65e736c706 100644
--- a/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis-arguments.js
@@ -185,3 +185,56 @@
%OptimizeFunctionOnNextCall(f);
f(); f();
})();
+
+// Test variable index access to strict arguments
+// with up to 2 elements.
+(function testArgumentsVariableIndexStrict() {
+ function g() {
+ "use strict";
+ var s = 0;
+ for (var i = 0; i < arguments.length; ++i) s += arguments[i];
+ return s;
+ }
+
+ function f(x, y) {
+ // (a) arguments[i] is dead code since arguments.length is 0.
+ const a = g();
+ // (b) arguments[i] always yields the first element.
+ const b = g(x);
+ // (c) arguments[i] can yield either x or y.
+ const c = g(x, y);
+ return a + b + c;
+ }
+
+ assertEquals(4, f(1, 2));
+ assertEquals(5, f(2, 1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(4, f(1, 2));
+ assertEquals(5, f(2, 1));
+})();
+
+// Test variable index access to sloppy arguments
+// with up to 2 elements.
+(function testArgumentsVariableIndexSloppy() {
+ function g() {
+ var s = 0;
+ for (var i = 0; i < arguments.length; ++i) s += arguments[i];
+ return s;
+ }
+
+ function f(x, y) {
+ // (a) arguments[i] is dead code since arguments.length is 0.
+ const a = g();
+ // (b) arguments[i] always yields the first element.
+ const b = g(x);
+ // (c) arguments[i] can yield either x or y.
+ const c = g(x, y);
+ return a + b + c;
+ }
+
+ assertEquals(4, f(1, 2));
+ assertEquals(5, f(2, 1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(4, f(1, 2));
+ assertEquals(5, f(2, 1));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-array.js b/deps/v8/test/mjsunit/compiler/escape-analysis-array.js
new file mode 100644
index 0000000000..2c44fa8c9b
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis-array.js
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test variable index access to array with 1 element.
+(function testOneElementArrayVariableIndex() {
+ function f(i) {
+ const a = new Array("first");
+ return a[i];
+ }
+
+ assertEquals("first", f(0));
+ assertEquals("first", f(0));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals("first", f(0));
+})();
+
+// Test variable index access to array with 2 elements.
+(function testTwoElementArrayVariableIndex() {
+ function f(i) {
+ const a = new Array("first", "second");
+ return a[i];
+ }
+
+ assertEquals("first", f(0));
+ assertEquals("second", f(1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals("first", f(0));
+ assertEquals("second", f(1));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-rest-parameters.js b/deps/v8/test/mjsunit/compiler/escape-analysis-rest-parameters.js
new file mode 100644
index 0000000000..2ac1253a18
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis-rest-parameters.js
@@ -0,0 +1,31 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test variable index access to rest parameters
+// with up to 2 elements.
+(function testRestParametersVariableIndex() {
+ function g(...args) {
+ let s = 0;
+ for (let i = 0; i < args.length; ++i) s += args[i];
+ return s;
+ }
+
+ function f(x, y) {
+ // (a) args[i] is dead code since args.length is 0.
+ const a = g();
+ // (b) args[i] always yields the first element.
+ const b = g(x);
+ // (c) args[i] can yield either x or y.
+ const c = g(x, y);
+ return a + b + c;
+ }
+
+ assertEquals(4, f(1, 2));
+ assertEquals(5, f(2, 1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(4, f(1, 2));
+ assertEquals(5, f(2, 1));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/instanceof2.js b/deps/v8/test/mjsunit/compiler/instanceof2.js
new file mode 100644
index 0000000000..ca006e3046
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/instanceof2.js
@@ -0,0 +1,233 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+
+// Without instance creation:
+
+(function() {
+ function Goo() {};
+ const goo = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ const goo = {};
+ Goo.prototype = Object.prototype;
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ const goo = {};
+ Goo.prototype = 42
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+(function() {
+ function Goo() {};
+ const goo = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ const goo = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+ Goo.prototype = 42;
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+
+// With instance creation:
+
+(function() {
+ function Goo() {};
+ const goo = new Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ const goo = new Goo();
+ Goo.prototype = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ const goo = new Goo();
+ Goo.prototype = 42;
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+(function() {
+ function Goo() {};
+ const goo = new Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+ Goo.prototype = {};
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ const goo = new Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+ Goo.prototype = 42
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+(function() {
+ function Goo() {};
+ Goo.prototype = 42;
+ const goo = new Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ Goo.prototype = {};
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ Goo.prototype = 42;
+ const goo = new Goo();
+ Goo.prototype = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ Goo.prototype = {};
+ const goo = new Goo();
+ Goo.prototype = 42;
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function Goo() {};
+ Goo.prototype = {};
+ const goo = new Goo();
+ Goo.prototype = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/instanceof3.js b/deps/v8/test/mjsunit/compiler/instanceof3.js
new file mode 100644
index 0000000000..e390c42092
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/instanceof3.js
@@ -0,0 +1,233 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+
+// Without instance creation:
+
+(function() {
+ function* Goo() {};
+ const goo = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = {};
+ Goo.prototype = Object.prototype;
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = {};
+ Goo.prototype = 42
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+ Goo.prototype = 42;
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+
+// With instance creation:
+
+(function() {
+ function* Goo() {};
+ const goo = Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = Goo();
+ Goo.prototype = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = Goo();
+ Goo.prototype = 42;
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+ Goo.prototype = {};
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ const goo = Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertTrue(IsGoo(goo));
+ assertTrue(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertTrue(IsGoo(goo));
+ Goo.prototype = 42
+ assertThrows(_ => IsGoo(goo), TypeError);
+})();
+
+(function() {
+ function* Goo() {};
+ Goo.prototype = 42;
+ const goo = Goo();
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ Goo.prototype = {};
+ assertFalse(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ Goo.prototype = 42;
+ const goo = Goo();
+ Goo.prototype = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertFalse(IsGoo(goo));
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ Goo.prototype = {};
+ const goo = Goo();
+ Goo.prototype = 42;
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertThrows(_ => IsGoo(goo), TypeError);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ %OptimizeFunctionOnNextCall(IsGoo);
+ assertThrows(_ => IsGoo(goo), TypeError);
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
+
+(function() {
+ function* Goo() {};
+ Goo.prototype = {};
+ const goo = Goo();
+ Goo.prototype = {};
+
+ function IsGoo(x) {
+ return x instanceof Goo;
+ }
+
+ assertFalse(IsGoo(goo));
+ assertFalse(IsGoo(goo));
+ %OptimizeFunctionOnNextCall(IsGoo);
+ Goo.prototype = Object.prototype;
+ assertTrue(IsGoo(goo));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/int64.js b/deps/v8/test/mjsunit/compiler/int64.js
new file mode 100644
index 0000000000..0a88a95895
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/int64.js
@@ -0,0 +1,91 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test NumberAdd with PositiveSafeInteger -> PositiveSafeInteger (as Tagged).
+(function() {
+ function foo(x) {
+ const i = x ? 0xFFFFFFFF : 0;
+ return i + 1;
+ }
+
+ assertEquals(0x000000001, foo(false));
+ assertEquals(0x000000001, foo(false));
+ assertEquals(0x100000000, foo(true));
+ assertEquals(0x100000000, foo(true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0x000000001, foo(false));
+ assertEquals(0x100000000, foo(true));
+})();
+
+// Test NumberAdd with SafeInteger -> SafeInteger (as Tagged).
+(function() {
+ function foo(x) {
+ const i = x ? 0xFFFFFFFF : -1;
+ return i + 1;
+ }
+
+ assertEquals(0x000000000, foo(false));
+ assertEquals(0x000000000, foo(false));
+ assertEquals(0x100000000, foo(true));
+ assertEquals(0x100000000, foo(true));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0x000000000, foo(false));
+ assertEquals(0x100000000, foo(true));
+})();
+
+// NumberAdd: Smi x Unsigned32 -> SafeInteger (as Float64).
+(function() {
+ const a = new Float64Array(1);
+
+ function foo(o) {
+ a[0] = o.x + 0xFFFFFFFF;
+ return a[0];
+ }
+
+ assertEquals(0x0FFFFFFFF, foo({x:0}));
+ assertEquals(0x100000000, foo({x:1}));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0x100000000, foo({x:1}));
+})();
+
+// NumberAdd: Smi x Unsigned32 -> SafeInteger (as TaggedSigned).
+(function() {
+ function foo(o) {
+ return {x: Math.floor((o.x + 11123456789) + -11123456788)}.x;
+ }
+
+ assertEquals(1, foo({x:0}));
+ assertEquals(2, foo({x:1}));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo({x:1}));
+})();
+
+// NumberSubtract: Unsigned32 x Unsigned32 -> SafeInteger (as Word32).
+(function() {
+ function foo(a, i) {
+ i = ((i >>> 0)) - 0xFFFFFFFF;
+ return a[i];
+ }
+
+ assertEquals(1, foo([1], 0xFFFFFFFF));
+ assertEquals(2, foo([2], 0xFFFFFFFF));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([3], 0xFFFFFFFF));
+})();
+
+// Test that the Deoptimizer can handle Word64 properly.
+(function() {
+ function foo(b) {
+ const i = ((b >>> 0)) - 0xFFFFFFFF;
+ %DeoptimizeFunction(foo);
+ return i;
+ }
+
+ assertEquals(0, foo(0xFFFFFFFF));
+ assertEquals(0, foo(0xFFFFFFFF));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0xFFFFFFFF));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/math-imul.js b/deps/v8/test/mjsunit/compiler/math-imul.js
new file mode 100644
index 0000000000..1de18a6a2d
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/math-imul.js
@@ -0,0 +1,76 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test Math.imul() with no inputs.
+(function() {
+ function foo() { return Math.imul(); }
+
+ assertEquals(0, foo());
+ assertEquals(0, foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo());
+})();
+
+// Test Math.imul() with only one input.
+(function() {
+ function foo(x) { return Math.imul(x); }
+
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(3));
+})();
+
+// Test Math.imul() with wrong types.
+(function() {
+ function foo(x, y) { return Math.imul(x, y); }
+
+ assertEquals(0, foo(null, 1));
+ assertEquals(0, foo(2, undefined));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(null, 1));
+ assertEquals(0, foo(2, undefined));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(null, 1));
+ assertEquals(0, foo(2, undefined));
+ assertOptimized(foo);
+})();
+
+// Test Math.imul() with signed integers (statically known).
+(function() {
+ function foo(x, y) { return Math.imul(x|0, y|0); }
+
+ assertEquals(1, foo(1, 1));
+ assertEquals(2, foo(2, 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1, 1));
+ assertEquals(2, foo(2, 1));
+ assertOptimized(foo);
+})();
+
+// Test Math.imul() with unsigned integers (statically known).
+(function() {
+ function foo(x, y) { return Math.imul(x>>>0, y>>>0); }
+
+ assertEquals(1, foo(1, 1));
+ assertEquals(2, foo(2, 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1, 1));
+ assertEquals(2, foo(2, 1));
+ assertOptimized(foo);
+})();
+
+// Test Math.imul() with floating-point numbers.
+(function() {
+ function foo(x, y) { return Math.imul(x, y); }
+
+ assertEquals(1, foo(1.1, 1.1));
+ assertEquals(2, foo(2.1, 1.1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1.1, 1.1));
+ assertEquals(2, foo(2.1, 1.1));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/math-max.js b/deps/v8/test/mjsunit/compiler/math-max.js
new file mode 100644
index 0000000000..350bdfba88
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/math-max.js
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test the case where TurboFan can statically rule out -0 from the
+// Math.max type.
+(function() {
+ function foo(x) {
+ // Arrange x such that TurboFan infers type [-inf, inf] \/ MinusZero.
+ x = +x;
+ x = Math.round(x);
+ return Object.is(-0, Math.max(1, x))
+ }
+
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+})();
+
+// Test the case where -0 is ruled out because it's strictly less than +0.
+(function() {
+ function foo(x) {
+ // Arrange x such that TurboFan infers type [-inf, inf] \/ MinusZero.
+ x = +x;
+ x = Math.round(x);
+ return Object.is(-0, Math.max(0, x))
+ }
+
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/math-min.js b/deps/v8/test/mjsunit/compiler/math-min.js
new file mode 100644
index 0000000000..882103984d
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/math-min.js
@@ -0,0 +1,38 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Test the case where TurboFan can statically rule out -0 from the
+// Math.min type.
+(function() {
+ function foo(x) {
+ // Arrange x such that TurboFan infers type [-inf, inf] \/ MinusZero.
+ x = +x;
+ x = Math.round(x);
+ return Object.is(-0, Math.min(-1, x))
+ }
+
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+})();
+
+// Test the case where +0 is ruled out because it's strictly greater than -0.
+(function() {
+ function foo(x) {
+ // Arrange x such that TurboFan infers type [-inf, inf] \/ MinusZero.
+ x = +x;
+ x = Math.round(x);
+ return Object.is(+0, Math.min(-0, x))
+ }
+
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(-0));
+ assertFalse(foo(-1));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-abs.js b/deps/v8/test/mjsunit/compiler/number-abs.js
new file mode 100644
index 0000000000..9eb8ab5bb5
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-abs.js
@@ -0,0 +1,76 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberAbs correctly deals with PositiveInteger \/ MinusZero
+// and turns the -0 into a 0.
+(function() {
+ function foo(x) {
+ x = Math.floor(x);
+ x = Math.max(x, -0);
+ return 1 / Math.abs(x);
+ }
+
+ assertEquals(Infinity, foo(-0));
+ assertEquals(Infinity, foo(-0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(Infinity, foo(-0));
+})();
+
+// Test that NumberAbs properly passes the kIdentifyZeros truncation
+// for Signed32 \/ MinusZero inputs.
+(function() {
+ function foo(x) {
+ return Math.abs(x * -2);
+ }
+
+ assertEquals(2, foo(-1));
+ assertEquals(4, foo(-2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(-1));
+ assertEquals(4, foo(-2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
+
+// Test that NumberAbs properly passes the kIdentifyZeros truncation
+// for Unsigned32 \/ MinusZero inputs.
+(function() {
+ function foo(x) {
+ x = x | 0;
+ return Math.abs(Math.max(x * -2, 0));
+ }
+
+ assertEquals(2, foo(-1));
+ assertEquals(4, foo(-2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(-1));
+ assertEquals(4, foo(-2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
+
+// Test that NumberAbs properly passes the kIdentifyZeros truncation
+// for OrderedNumber inputs.
+(function() {
+ function foo(x) {
+ x = x | 0;
+ return Math.abs(Math.min(x * -2, 2 ** 32));
+ }
+
+ assertEquals(2, foo(-1));
+ assertEquals(4, foo(-2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(-1));
+ assertEquals(4, foo(-2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-add.js b/deps/v8/test/mjsunit/compiler/number-add.js
new file mode 100644
index 0000000000..61e6495c52
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-add.js
@@ -0,0 +1,62 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// This tests that NumberAdd passes on the right truncations
+// even if it figures out during SimplifiedLowering that it
+// can indeed do a Word32 operation (based on the feedback
+// baked in for its inputs by other operators).
+(function() {
+ // We need a + with Number feedback to get to a NumberAdd
+ // during the typed lowering pass of TurboFan's frontend.
+ function foo(x, y) { return x + y; }
+ foo(0.1, 0.2);
+ foo(0.1, 0.2);
+
+ // Now we need to fool TurboFan to think that it has to
+ // perform the `foo(x,-1)` on Float64 values until the
+ // very last moment (after the RETYPE phase of the
+ // SimplifiedLowering) where it realizes that the inputs
+ // and outputs of the NumberAdd allow it perform the
+ // operation on Word32.
+ function bar(x) {
+ x = Math.trunc(foo(x - 1, 1));
+ return foo(x, -1);
+ }
+
+ assertEquals(0, bar(1));
+ assertEquals(1, bar(2));
+ %OptimizeFunctionOnNextCall(bar);
+ assertEquals(2, bar(3));
+})();
+
+// This tests that SpeculativeNumberAdd can still lower to
+// Int32Add in SimplifiedLowering, which requires some magic
+// to make sure that SpeculativeNumberAdd survives to that
+// point, especially the JSTypedLowering needs to be unable
+// to tell that the inputs to SpeculativeNumberAdd are non
+// String primitives.
+(function() {
+ // We need a function that has a + with feedback Number or
+ // NumberOrOddball, but for whose inputs the JSTypedLowering
+ // cannot reduce it to NumberAdd (with SpeculativeToNumber
+ // conversions). We achieve this utilizing an object literal
+ // indirection here.
+ function baz(x) {
+ return {x}.x + x;
+ }
+ baz(null);
+ baz(undefined);
+
+ // Now we just need to truncate the result.
+ function foo(x) {
+ return baz(1) | 0;
+ }
+
+ assertEquals(2, foo());
+ assertEquals(2, foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo());
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-ceil.js b/deps/v8/test/mjsunit/compiler/number-ceil.js
new file mode 100644
index 0000000000..ce87cd0fc0
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-ceil.js
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberCeil propagates kIdentifyZeros truncations.
+(function() {
+ function foo(x) {
+ return Math.abs(Math.ceil(x * -2));
+ }
+
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-comparison-truncations.js b/deps/v8/test/mjsunit/compiler/number-comparison-truncations.js
new file mode 100644
index 0000000000..33abf6b913
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-comparison-truncations.js
@@ -0,0 +1,152 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that SpeculativeNumberEqual[SignedSmall] properly passes the
+// kIdentifyZeros truncation.
+(function() {
+ function foo(x, y) {
+ if (x * y === 0) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ assertOptimized(foo);
+ // Even if x*y produces -0 now, it should stay optimized.
+ assertEquals(0, foo(-3, 0));
+ assertEquals(0, foo(0, -3));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberEqual[Number] properly passes the
+// kIdentifyZeros truncation.
+(function() {
+ // Produce a SpeculativeNumberEqual with Number feedback.
+ function bar(x, y) { return x === y; }
+ bar(0.1, 0.5);
+ bar(-0, 100);
+
+ function foo(x, y) {
+ if (bar(x * y, 0)) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ assertOptimized(foo);
+ // Even if x*y produces -0 now, it should stay optimized.
+ assertEquals(0, foo(-3, 0));
+ assertEquals(0, foo(0, -3));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberLessThan[SignedSmall] properly passes the
+// kIdentifyZeros truncation.
+(function() {
+ function foo(x, y) {
+ if (x * y < 0) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(1, -1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1, -1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ assertOptimized(foo);
+ // Even if x*y produces -0 now, it should stay optimized.
+ assertEquals(1, foo(-3, 0));
+ assertEquals(1, foo(0, -3));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberLessThan[Number] properly passes the
+// kIdentifyZeros truncation.
+(function() {
+ // Produce a SpeculativeNumberLessThan with Number feedback.
+ function bar(x, y) { return x < y; }
+ bar(0.1, 0.5);
+ bar(-0, 100);
+
+ function foo(x, y) {
+ if (bar(x * y, 0)) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(1, -1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1, -1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ assertOptimized(foo);
+ // Even if x*y produces -0 now, it should stay optimized.
+ assertEquals(1, foo(-3, 0));
+ assertEquals(1, foo(0, -3));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberLessThanOrEqual[SignedSmall] properly passes the
+// kIdentifyZeros truncation.
+(function() {
+ function foo(x, y) {
+ if (x * y <= 0) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ assertOptimized(foo);
+ // Even if x*y produces -0 now, it should stay optimized.
+ assertEquals(0, foo(-3, 0));
+ assertEquals(0, foo(0, -3));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberLessThanOrEqual[Number] properly passes the
+// kIdentifyZeros truncation.
+(function() {
+ // Produce a SpeculativeNumberLessThanOrEqual with Number feedback.
+ function bar(x, y) { return x <= y; }
+ bar(0.1, 0.5);
+ bar(-0, 100);
+
+ function foo(x, y) {
+ if (bar(x * y, 0)) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(0, 1));
+ assertEquals(1, foo(1, 1));
+ assertEquals(1, foo(1, 2));
+ assertOptimized(foo);
+ // Even if x*y produces -0 now, it should stay optimized.
+ assertEquals(0, foo(-3, 0));
+ assertEquals(0, foo(0, -3));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-divide.js b/deps/v8/test/mjsunit/compiler/number-divide.js
new file mode 100644
index 0000000000..c4cc8fa881
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-divide.js
@@ -0,0 +1,207 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt --noalways-opt
+
+// Test that NumberDivide with Number feedback works if only in the
+// end SimplifiedLowering figures out that the inputs to this operation
+// are actually Unsigned32.
+(function() {
+ // We need a separately polluted % with NumberOrOddball feedback.
+ function bar(x) { return x / 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now just use the gadget above in a way that only after RETYPE
+ // in SimplifiedLowering we find out that the `x` is actually in
+ // Unsigned32 range (based on taking the SignedSmall feedback on
+ // the + operator).
+ function foo(x) {
+ x = (x >>> 0) + 1;
+ return bar(x) | 0;
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(2, foo(3));
+ assertEquals(2, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(2, foo(3));
+ assertEquals(2, foo(4));
+ assertOptimized(foo);
+})();
+
+// Test that NumberDivide with Number feedback works if only in the
+// end SimplifiedLowering figures out that the inputs to this operation
+// are actually Signed32.
+(function() {
+ // We need a separately polluted % with NumberOrOddball feedback.
+ function bar(x) { return x / 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now just use the gadget above in a way that only after RETYPE
+ // in SimplifiedLowering we find out that the `x` is actually in
+ // Signed32 range (based on taking the SignedSmall feedback on
+ // the + operator).
+ function foo(x) {
+ x = (x | 0) + 1;
+ return bar(x) | 0;
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(2, foo(3));
+ assertEquals(2, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(2, foo(3));
+ assertEquals(2, foo(4));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberDivide turns into CheckedInt32Div, and
+// that the "known power of two divisor" optimization works correctly.
+(function() {
+ function foo(x) { return (x | 0) / 2; }
+
+ // Warmup with proper int32 divisions.
+ assertEquals(1, foo(2));
+ assertEquals(2, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo(6));
+ assertOptimized(foo);
+
+ // Make optimized code fail.
+ assertEquals(0.5, foo(1));
+ assertUnoptimized(foo);
+
+ // Try again with the new feedback, and now it should stay optimized.
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(4, foo(8));
+ assertOptimized(foo);
+ assertEquals(0.5, foo(1));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberDivide turns into CheckedInt32Div, and
+// that the optimized code properly bails out on "division by zero".
+(function() {
+ function foo(x, y) { return x / y; }
+
+ // Warmup with proper int32 divisions.
+ assertEquals(2, foo(4, 2));
+ assertEquals(2, foo(8, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(2, 2));
+ assertOptimized(foo);
+
+ // Make optimized code fail.
+ assertEquals(Infinity, foo(1, 0));
+ assertUnoptimized(foo);
+
+ // Try again with the new feedback, and now it should stay optimized.
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(2, 1));
+ assertOptimized(foo);
+ assertEquals(Infinity, foo(1, 0));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberDivide turns into CheckedInt32Div, and
+// that the optimized code properly bails out on minus zero.
+(function() {
+ function foo(x, y) { return x / y; }
+
+ // Warmup with proper int32 divisions.
+ assertEquals(2, foo(4, 2));
+ assertEquals(2, foo(8, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(2, 2));
+ assertOptimized(foo);
+
+ // Make optimized code fail.
+ assertEquals(-0, foo(0, -1));
+ assertUnoptimized(foo);
+
+ // Try again with the new feedback, and now it should stay optimized.
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(2, 1));
+ assertOptimized(foo);
+ assertEquals(-0, foo(0, -1));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberDivide turns into CheckedInt32Div, and
+// that the optimized code properly bails out if result is -kMinInt.
+(function() {
+ function foo(x, y) { return x / y; }
+
+ // Warmup with proper int32 divisions.
+ assertEquals(2, foo(4, 2));
+ assertEquals(2, foo(8, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(2, 2));
+ assertOptimized(foo);
+
+ // Make optimized code fail.
+ assertEquals(2147483648, foo(-2147483648, -1));
+ assertUnoptimized(foo);
+
+ // Try again with the new feedback, and now it should stay optimized.
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(2, 1));
+ assertOptimized(foo);
+ assertEquals(2147483648, foo(-2147483648, -1));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberDivide turns into CheckedUint32Div, and
+// that the "known power of two divisor" optimization works correctly.
+(function() {
+ function foo(s) { return s.length / 2; }
+
+ // Warmup with proper uint32 divisions.
+ assertEquals(1, foo("ab".repeat(1)));
+ assertEquals(2, foo("ab".repeat(2)));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo("ab".repeat(3)));
+ assertOptimized(foo);
+
+ // Make optimized code fail.
+ assertEquals(0.5, foo("a"));
+ assertUnoptimized(foo);
+
+ // Try again with the new feedback, and now it should stay optimized.
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(4, foo("ab".repeat(4)));
+ assertOptimized(foo);
+ assertEquals(0.5, foo("a"));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberDivide turns into CheckedUint32Div, and
+// that the optimized code properly bails out on "division by zero".
+(function() {
+ function foo(x, y) { return (x >>> 0) / (y >>> 0); }
+
+ // Warmup with proper uint32 divisions.
+ assertEquals(2, foo(4, 2));
+ assertEquals(2, foo(8, 4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(2, 2));
+ assertOptimized(foo);
+
+ // Make optimized code fail.
+ assertEquals(Infinity, foo(1, 0));
+ assertUnoptimized(foo);
+
+ // Try again with the new feedback, and now it should stay optimized.
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(2, 1));
+ assertOptimized(foo);
+ assertEquals(Infinity, foo(1, 0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-floor.js b/deps/v8/test/mjsunit/compiler/number-floor.js
new file mode 100644
index 0000000000..180b89e559
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-floor.js
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberFloor propagates kIdentifyZeros truncations.
+(function() {
+ function foo(x) {
+ return Math.abs(Math.floor(x * -2));
+ }
+
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-issafeinteger.js b/deps/v8/test/mjsunit/compiler/number-issafeinteger.js
index 192fb6c124..b705e95ed5 100644
--- a/deps/v8/test/mjsunit/compiler/number-issafeinteger.js
+++ b/deps/v8/test/mjsunit/compiler/number-issafeinteger.js
@@ -40,11 +40,19 @@ function test(f) {
assertFalse(f(2 * near_lower - 7));
}
-function f(x) {
- return Number.isSafeInteger(+x);
-}
+// Check that the NumberIsSafeInteger simplified operator in
+// TurboFan does the right thing.
+function NumberIsSafeInteger(x) { return Number.isSafeInteger(+x); }
+test(NumberIsSafeInteger);
+test(NumberIsSafeInteger);
+%OptimizeFunctionOnNextCall(NumberIsSafeInteger);
+test(NumberIsSafeInteger);
-test(f);
-test(f);
-%OptimizeFunctionOnNextCall(f);
-test(f);
+// Check that the ObjectIsSafeInteger simplified operator in
+// TurboFan does the right thing as well (i.e. when TurboFan
+// is not able to tell statically that the inputs are numbers).
+function ObjectIsSafeInteger(x) { return Number.isSafeInteger(x); }
+test(ObjectIsSafeInteger);
+test(ObjectIsSafeInteger);
+%OptimizeFunctionOnNextCall(ObjectIsSafeInteger);
+test(ObjectIsSafeInteger);
diff --git a/deps/v8/test/mjsunit/compiler/number-max.js b/deps/v8/test/mjsunit/compiler/number-max.js
new file mode 100644
index 0000000000..7e5a4a4ad1
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-max.js
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberMax properly passes the kIdentifyZeros truncation.
+(function() {
+ function foo(x) {
+ if (Math.max(x * -2, 1) == 1) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(2));
+ assertEquals(1, foo(-1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(2));
+ assertEquals(1, foo(-1));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-min.js b/deps/v8/test/mjsunit/compiler/number-min.js
new file mode 100644
index 0000000000..72bff78686
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-min.js
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberMin properly passes the kIdentifyZeros truncation.
+(function() {
+ function foo(x) {
+ if (Math.min(x * -2, -1) == -2) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(1, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-modulus.js b/deps/v8/test/mjsunit/compiler/number-modulus.js
new file mode 100644
index 0000000000..5f695d1ee5
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-modulus.js
@@ -0,0 +1,256 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt --noalways-opt
+
+// Test that NumberModulus with Number feedback works if only in the
+// end SimplifiedLowering figures out that the inputs to this operation
+// are actually Unsigned32.
+(function() {
+ // We need a separately polluted % with NumberOrOddball feedback.
+ function bar(x) { return x % 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now just use the gadget above in a way that only after RETYPE
+ // in SimplifiedLowering we find out that the `x` is actually in
+ // Unsigned32 range (based on taking the SignedSmall feedback on
+ // the + operator).
+ function foo(x) {
+ x = (x >>> 0) + 1;
+ return bar(x) | 0;
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ assertOptimized(foo);
+})();
+
+// Test that NumberModulus with Number feedback works if only in the
+// end SimplifiedLowering figures out that the inputs to this operation
+// are actually Signed32.
+(function() {
+ // We need a separately polluted % with NumberOrOddball feedback.
+ function bar(x) { return x % 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now just use the gadget above in a way that only after RETYPE
+ // in SimplifiedLowering we find out that the `x` is actually in
+ // Signed32 range (based on taking the SignedSmall feedback on
+ // the + operator).
+ function foo(x) {
+ x = (x | 0) + 1;
+ return bar(x) | 0;
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberModulus with Number feedback works if
+// only in the end SimplifiedLowering figures out that the inputs to
+// this operation are actually Unsigned32.
+(function() {
+ // We need to use an object literal here to make sure that the
+ // SpeculativeNumberModulus is not turned into a NumberModulus
+ // early during JSTypedLowering.
+ function bar(x) { return {x}.x % 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now just use the gadget above in a way that only after RETYPE
+ // in SimplifiedLowering we find out that the `x` is actually in
+ // Unsigned32 range (based on taking the SignedSmall feedback on
+ // the + operator).
+ function foo(x) {
+ x = (x >>> 0) + 1;
+ return bar(x) | 0;
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberModulus with Number feedback works if
+// only in the end SimplifiedLowering figures out that the inputs to
+// this operation are actually Signed32.
+(function() {
+ // We need to use an object literal here to make sure that the
+ // SpeculativeNumberModulus is not turned into a NumberModulus
+ // early during JSTypedLowering.
+ function bar(x) { return {x}.x % 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now just use the gadget above in a way that only after RETYPE
+ // in SimplifiedLowering we find out that the `x` is actually in
+ // Signed32 range (based on taking the SignedSmall feedback on
+ // the + operator).
+ function foo(x) {
+ x = (x | 0) + 1;
+ return bar(x) | 0;
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+ assertEquals(1, foo(2));
+ assertEquals(0, foo(3));
+ assertEquals(1, foo(4));
+ assertOptimized(foo);
+})();
+
+// Test that NumberModulus works in the case where TurboFan
+// can infer that the output is Signed32 \/ MinusZero, and
+// there's a truncation on the result that identifies zeros
+// (via the SpeculativeNumberEqual).
+(function() {
+ // We need a separately polluted % with NumberOrOddball feedback.
+ function bar(x) { return x % 2; }
+ bar(undefined); // The % feedback is now NumberOrOddball.
+
+ // Now we just use the gadget above on an `x` that is known
+ // to be in Signed32 range and compare it to 0, which passes
+ // a truncation that identifies zeros.
+ function foo(x) {
+ if (bar(x | 0) == 0) return 0;
+ return 1;
+ }
+
+ assertEquals(0, foo(2));
+ assertEquals(1, foo(1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(2));
+ assertEquals(1, foo(1));
+ assertOptimized(foo);
+
+ // Now `foo` should stay optimized even if `x % 2` would
+ // produce -0, aka when we pass a negative value for `x`.
+ assertEquals(0, foo(-2));
+ assertEquals(1, foo(-1));
+ assertOptimized(foo);
+})();
+
+// Test that CheckedInt32Mod handles the slow-path (when
+// the left hand side is negative) correctly.
+(function() {
+ // We need a SpeculativeNumberModulus with SignedSmall feedback.
+ function foo(x, y) {
+ return x % y;
+ }
+
+ assertEquals(0, foo(2, 1));
+ assertEquals(0, foo(2, 2));
+ assertEquals(-1, foo(-3, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(2, 1));
+ assertEquals(0, foo(2, 2));
+ assertEquals(-1, foo(-3, 2));
+ assertOptimized(foo);
+
+ // Now `foo` should deoptimize if the result is -0.
+ assertEquals(-0, foo(-2, 2));
+ assertUnoptimized(foo);
+})();
+
+// Test that NumberModulus passes kIdentifiesZero to the
+// left hand side input when the result doesn't care about
+// 0 vs -0, even when the inputs are outside Signed32.
+(function() {
+ function foo(x) {
+ return (x * -2) % (2 ** 32) === 0;
+ }
+
+ assertFalse(foo(2));
+ assertFalse(foo(1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo(2));
+ assertFalse(foo(1));
+
+ // Now `foo` should stay optimized even if `x * -2` would
+ // produce -0, aka when we pass a zero value for `x`.
+ assertTrue(foo(0));
+ assertOptimized(foo);
+})();
+
+// Test that NumberModulus passes kIdentifiesZero to the
+// right hand side input, even when the inputs are outside
+// the Signed32 range.
+(function() {
+ function foo(x) {
+ return (2 ** 32) % (x * -2);
+ }
+
+ assertEquals(0, foo(1));
+ assertEquals(0, foo(1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(1));
+
+ // Now `foo` should stay optimized even if `x * -2` would
+ // produce -0, aka when we pass a zero value for `x`.
+ assertEquals(NaN, foo(0));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberModulus passes kIdentifiesZero
+// to the right hand side input, even when feedback is consumed.
+(function() {
+ function foo(x, y) {
+ return (x % (y * -2)) | 0;
+ }
+
+ assertEquals(0, foo(2, 1));
+ assertEquals(-1, foo(-3, 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo(2, 1));
+ assertEquals(-1, foo(-3, 1));
+ assertOptimized(foo);
+
+ // Now `foo` should stay optimized even if `y * -2` would
+ // produce -0, aka when we pass a zero value for `y`.
+ assertEquals(0, foo(2, 0));
+ assertOptimized(foo);
+})();
+
+// Test that SpeculativeNumberModulus passes kIdentifiesZero
+// to the left hand side input, even when feedback is consumed.
+(function() {
+ function foo(x, y) {
+ return ((x * -2) % y) | 0;
+ }
+
+ assertEquals(-2, foo(1, 3));
+ assertEquals(-2, foo(1, 3));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(-2, foo(1, 3));
+ assertOptimized(foo);
+
+ // Now `foo` should stay optimized even if `x * -2` would
+ // produce -0, aka when we pass a zero value for `x`.
+ assertEquals(0, foo(0, 2));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-round.js b/deps/v8/test/mjsunit/compiler/number-round.js
new file mode 100644
index 0000000000..9aec7f7a12
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-round.js
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberRound propagates kIdentifyZeros truncations.
+(function() {
+ function foo(x) {
+ return Math.abs(Math.round(x * -2));
+ }
+
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-subtract.js b/deps/v8/test/mjsunit/compiler/number-subtract.js
new file mode 100644
index 0000000000..cb3e1c7e70
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-subtract.js
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// This tests that SpeculativeNumberSubtract can still lower to
+// Int32Sub in SimplifiedLowering, which requires some magic
+// to make sure that SpeculativeNumberSubtract survives to that
+// point, especially the JSTypedLowering needs to be unable
+// to tell that the inputs to SpeculativeNumberAdd are not
+// Number, Undefined, Null or Boolean.
+(function() {
+ // We need a function that has a - with feedback Number or
+ // NumberOrOddball, but for whose inputs the JSTypedLowering
+ // cannot reduce it to NumberSubtract (with SpeculativeToNumber
+ // conversions). We achieve this utilizing an object literal
+ // indirection here.
+ function baz(x) {
+ return {x}.x - x;
+ }
+ baz(null);
+ baz(undefined);
+
+ // Now we just need to truncate the result.
+ function foo(x) {
+ return baz(42) | 0;
+ }
+
+ assertEquals(0, foo());
+ assertEquals(0, foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(0, foo());
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-toboolean.js b/deps/v8/test/mjsunit/compiler/number-toboolean.js
new file mode 100644
index 0000000000..02b30b3ed6
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-toboolean.js
@@ -0,0 +1,45 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberToBoolean properly passes the kIdentifyZeros truncation
+// for Signed32 \/ MinusZero inputs.
+(function() {
+ function foo(x) {
+ if (x * -2) return 1;
+ return 0;
+ }
+
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(1));
+ assertEquals(1, foo(2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
+
+
+// Test that NumberToBoolean properly passes the kIdentifyZeros truncation
+// for Unsigned32 \/ MinusZero inputs.
+(function() {
+ function foo(x) {
+ x = x | 0;
+ if (Math.max(x * -2, 0)) return 1;
+ return 0;
+ }
+
+ assertEquals(1, foo(-1));
+ assertEquals(1, foo(-2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo(-1));
+ assertEquals(1, foo(-2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/number-trunc.js b/deps/v8/test/mjsunit/compiler/number-trunc.js
new file mode 100644
index 0000000000..aa7d02c20f
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/number-trunc.js
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test that NumberTrunc propagates kIdentifyZeros truncations.
+(function() {
+ function foo(x) {
+ return Math.abs(Math.trunc(x * -2));
+ }
+
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(2, foo(1));
+ assertEquals(4, foo(2));
+ assertOptimized(foo);
+ // Now `foo` should stay optimized even if `x * -2` would produce `-0`.
+ assertEquals(0, foo(0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/redundancy-elimination.js b/deps/v8/test/mjsunit/compiler/redundancy-elimination.js
new file mode 100644
index 0000000000..1e5185adb7
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/redundancy-elimination.js
@@ -0,0 +1,194 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeNumberAdd with
+// Number feedback.
+(function() {
+ function bar(i) {
+ return ++i;
+ }
+ bar(0.1);
+
+ function foo(a, i) {
+ const x = a[i];
+ const y = a[bar(i)];
+ return x + y;
+ }
+
+ assertEquals(3, foo([1, 2], 0));
+ assertEquals(3, foo([1, 2], 0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([1, 2], 0));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeNumberAdd with
+// NumberOrOddball feedback.
+(function() {
+ function bar(i) {
+ return ++i;
+ }
+ assertEquals(NaN, bar(undefined));
+
+ function foo(a, i) {
+ const x = a[i];
+ const y = a[bar(i)];
+ return x + y;
+ }
+
+ assertEquals(3, foo([1, 2], 0));
+ assertEquals(3, foo([1, 2], 0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([1, 2], 0));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeNumberSubtract with
+// Number feedback.
+(function() {
+ function bar(i) {
+ return --i;
+ }
+ assertEquals(-0.9, bar(0.1));
+
+ function foo(a, i) {
+ const x = a[i];
+ const y = a[bar(i)];
+ return x + y;
+ }
+
+ assertEquals(3, foo([1, 2], 1));
+ assertEquals(3, foo([1, 2], 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([1, 2], 1));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeNumberSubtract with
+// NumberOrOddball feedback.
+(function() {
+ function bar(i) {
+ return --i;
+ }
+ assertEquals(NaN, bar(undefined));
+
+ function foo(a, i) {
+ const x = a[i];
+ const y = a[bar(i)];
+ return x + y;
+ }
+
+ assertEquals(3, foo([1, 2], 1));
+ assertEquals(3, foo([1, 2], 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([1, 2], 1));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeToNumber.
+(function() {
+ function foo(a, i) {
+ const x = a[i];
+ const y = i++;
+ return x + y;
+ }
+
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo([1, 2], 0));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeSafeIntegerAdd.
+(function() {
+ function foo(a, i) {
+ const x = a[i];
+ const y = a[++i];
+ return x + y;
+ }
+
+ assertEquals(3, foo([1, 2], 0));
+ assertEquals(3, foo([1, 2], 0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([1, 2], 0));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberOperation()
+// TurboFan optimization for the case of SpeculativeSafeIntegerSubtract.
+(function() {
+ function foo(a, i) {
+ const x = a[i];
+ const y = a[--i];
+ return x + y;
+ }
+
+ assertEquals(3, foo([1, 2], 1));
+ assertEquals(3, foo([1, 2], 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3, foo([1, 2], 1));
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberComparison()
+// TurboFan optimization for the case of SpeculativeNumberEqual.
+(function() {
+ function foo(a, i) {
+ const x = a[i];
+ if (i === 0) return x;
+ return i;
+ }
+
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 1));
+ // Even passing -0 should not deoptimize and
+ // of course still pass the equality test above.
+ assertEquals(9, foo([9, 2], -0));
+ assertOptimized(foo);
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberComparison()
+// TurboFan optimization for the case of SpeculativeNumberLessThan.
+(function() {
+ function foo(a, i) {
+ const x = a[i];
+ if (i < 1) return x;
+ return i;
+ }
+
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 1));
+ // Even passing -0 should not deoptimize and
+ // of course still pass the equality test above.
+ assertEquals(9, foo([9, 2], -0));
+ assertOptimized(foo);
+})();
+
+// Test the RedundancyElimination::ReduceSpeculativeNumberComparison()
+// TurboFan optimization for the case of SpeculativeNumberLessThanOrEqual.
+(function() {
+ function foo(a, i) {
+ const x = a[i];
+ if (i <= 0) return x;
+ return i;
+ }
+
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 1));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1, foo([1, 2], 0));
+ assertEquals(1, foo([1, 2], 1));
+ // Even passing -0 should not deoptimize and
+ // of course still pass the equality test above.
+ assertEquals(9, foo([9, 2], -0));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/regress-7121.js b/deps/v8/test/mjsunit/compiler/regress-7121.js
index 98c1a1ac19..bdf3133bb8 100644
--- a/deps/v8/test/mjsunit/compiler/regress-7121.js
+++ b/deps/v8/test/mjsunit/compiler/regress-7121.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --harmony-bigint
+// Flags: --allow-natives-syntax
function foo() { %_ToLength(42n) }
assertThrows(foo, TypeError);
diff --git a/deps/v8/test/mjsunit/compiler/regress-884052.js b/deps/v8/test/mjsunit/compiler/regress-884052.js
new file mode 100644
index 0000000000..babfcc3cea
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-884052.js
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+function foo() {
+ var a = new Array(2);
+ for (var i = 1; i > -1; i = i - 2) {
+ if (i < a.length) a = new Array(i);
+ }
+}
+
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/compiler/regress-890057.js b/deps/v8/test/mjsunit/compiler/regress-890057.js
new file mode 100644
index 0000000000..655c4431e9
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-890057.js
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+function f() {}
+function g() {
+ f.prototype = undefined;
+ f();
+ new f();
+}
+
+// Do not use %OptimizeFunctionOnNextCall here, this particular bug needs
+// to trigger truly concurrent compilation.
+for (let i = 0; i < 10000; i++) g();
diff --git a/deps/v8/test/mjsunit/compiler/regress-890620.js b/deps/v8/test/mjsunit/compiler/regress-890620.js
new file mode 100644
index 0000000000..f5fc7f4f65
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-890620.js
@@ -0,0 +1,25 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+var a = 42;
+
+function g(n) {
+ while (n > 0) {
+ a = new Array(n);
+ n--;
+ }
+}
+
+g(1);
+
+function f() {
+ g();
+}
+
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
+assertEquals(1, a.length);
diff --git a/deps/v8/test/mjsunit/compiler/regress-895799.js b/deps/v8/test/mjsunit/compiler/regress-895799.js
new file mode 100644
index 0000000000..4305b7427b
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-895799.js
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+class C extends Object {
+ constructor() {
+ try { super(); } catch (e) { };
+ return 1;
+ }
+}
+
+class A extends C {
+ constructor() {
+ super();
+ throw new Error();
+ return { get: () => this };
+ }
+}
+
+var D = new Proxy(A, { get() { %DeoptimizeFunction(A); } });
+
+try { Reflect.construct(A, [], D); } catch(e) {}
+%OptimizeFunctionOnNextCall(A);
+try { Reflect.construct(A, [], D); } catch(e) {}
diff --git a/deps/v8/test/mjsunit/compiler/strict-equal-symbol.js b/deps/v8/test/mjsunit/compiler/strict-equal-symbol.js
new file mode 100644
index 0000000000..aee1ecfa60
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/strict-equal-symbol.js
@@ -0,0 +1,50 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax
+
+// Known symbols strict equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo() { return a === b; }
+
+ assertFalse(foo());
+ assertFalse(foo());
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(foo());
+})();
+
+// Known symbol on one side strict equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo(a) { return a === b; }
+
+ assertTrue(foo(b));
+ assertFalse(foo(a));
+ assertTrue(foo(b));
+ assertFalse(foo(a));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo(b));
+ assertFalse(foo(a));
+})();
+
+// Feedback based symbol strict equality.
+(function() {
+ const a = Symbol("a");
+ const b = Symbol("b");
+
+ function foo(a, b) { return a === b; }
+
+ assertTrue(foo(b, b));
+ assertFalse(foo(a, b));
+ assertTrue(foo(a, a));
+ assertFalse(foo(b, a));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(foo(a, a));
+ assertFalse(foo(b, a));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/string-add-try-catch.js b/deps/v8/test/mjsunit/compiler/string-add-try-catch.js
index d7a3d2583c..5ae5b00d18 100644
--- a/deps/v8/test/mjsunit/compiler/string-add-try-catch.js
+++ b/deps/v8/test/mjsunit/compiler/string-add-try-catch.js
@@ -4,6 +4,9 @@
// Flags: --allow-natives-syntax
+// Test that string concatenation overflow (going over string max length)
+// is handled gracefully, i.e. an error is thrown
+
var a = "a".repeat(%StringMaxLength());
(function() {
@@ -37,3 +40,57 @@ var a = "a".repeat(%StringMaxLength());
foo("a");
assertInstanceof(foo(a), RangeError);
})();
+
+(function() {
+ function foo(a, b) {
+ try {
+ return "0123456789012".concat(a);
+ } catch (e) {
+ return e;
+ }
+ }
+
+ foo("a");
+ foo("a");
+ %OptimizeFunctionOnNextCall(foo);
+ foo("a");
+ assertInstanceof(foo(a), RangeError);
+})();
+
+var obj = {
+ toString: function() {
+ throw new Error('toString has thrown');
+ }
+};
+
+(function() {
+ function foo(a, b) {
+ try {
+ return "0123456789012" + obj;
+ } catch (e) {
+ return e;
+ }
+ }
+
+ foo("a");
+ foo("a");
+ %OptimizeFunctionOnNextCall(foo);
+ foo("a");
+ assertInstanceof(foo(a), Error);
+})();
+
+(function() {
+ function foo(a, b) {
+ try {
+ return a + 123;
+ } catch (e) {
+ return e;
+ }
+ }
+
+ foo("a");
+ foo("a");
+ %OptimizeFunctionOnNextCall(foo);
+ foo("a");
+ assertInstanceof(foo(a), RangeError);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/string-from-code-point.js b/deps/v8/test/mjsunit/compiler/string-from-code-point.js
new file mode 100644
index 0000000000..165ea0c234
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/string-from-code-point.js
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+// Flags: --allow-natives-syntax --opt --noalways-opt
+
+// Test that String.fromCodePoint() properly identifies zeros.
+(function() {
+ function foo(x) {
+ return String.fromCodePoint(x);
+ }
+
+ assertEquals("\u0000", foo(0));
+ assertEquals("\u0000", foo(-0));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals("\u0000", foo(0));
+ assertEquals("\u0000", foo(-0));
+ assertOptimized(foo);
+
+ // Now passing anything outside the valid code point
+ // range should invalidate the optimized code.
+ assertThrows(_ => foo(-1));
+ assertUnoptimized(foo);
+
+ // And TurboFan should not inline the builtin anymore
+ // from now on (aka no deoptimization loop).
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals("\u0000", foo(0));
+ assertEquals("\u0000", foo(-0));
+ assertThrows(_ => foo(-1));
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/typed-array-constructor.js b/deps/v8/test/mjsunit/compiler/typed-array-constructor.js
index a785eadf37..07d6a7ca4e 100644
--- a/deps/v8/test/mjsunit/compiler/typed-array-constructor.js
+++ b/deps/v8/test/mjsunit/compiler/typed-array-constructor.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --harmony-bigint
+// Flags: --allow-natives-syntax
const limit = %MaxSmi() + 1;