attila@1252: /* sundar@1482: * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. attila@1252: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. sundar@1482: * attila@1252: * This code is free software; you can redistribute it and/or modify it attila@1252: * under the terms of the GNU General Public License version 2 only, as attila@1252: * published by the Free Software Foundation. sundar@1482: * attila@1252: * This code is distributed in the hope that it will be useful, but WITHOUT attila@1252: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or attila@1252: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License attila@1252: * version 2 for more details (a copy is included in the LICENSE file that attila@1252: * accompanied this code). sundar@1482: * attila@1252: * You should have received a copy of the GNU General Public License version attila@1252: * 2 along with this work; if not, write to the Free Software Foundation, attila@1252: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. sundar@1482: * attila@1252: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA attila@1252: * or visit www.oracle.com if you need additional information or have any attila@1252: * questions. attila@1252: */ attila@1252: attila@1252: /** attila@1252: * JDK-8035712: Restore some of the RuntimeCallSite specializations attila@1252: * attila@1252: * @test attila@1252: * @run attila@1252: */ attila@1252: attila@1252: if ((typeof Assert) == "undefined") { attila@1252: Assert = { attila@1252: assertTrue: function(x) { if(!x) { throw "expected true" } }, attila@1252: assertFalse: function(x) { if(x) { throw "expected false" } }, attila@1252: }; attila@1252: } attila@1252: attila@1252: function nop() {} attila@1252: attila@1252: function EQ(x, y) { attila@1252: // Exercise normal evaluation attila@1252: Assert.assertTrue (x == y); attila@1252: Assert.assertTrue (y == x); attila@1252: Assert.assertFalse(x != y); attila@1252: Assert.assertFalse(y != x); attila@1252: // Exercise the branch optimizer attila@1252: if (x == y) { nop(); } else { Assert.fail(); } attila@1252: if (y == x) { nop(); } else { Assert.fail(); } attila@1252: if (x != y) { Assert.fail(); } else { nop(); } attila@1252: if (y != x) { Assert.fail(); } else { nop(); } attila@1252: } attila@1252: attila@1252: function NE(x, y) { attila@1252: // Exercise normal evaluation attila@1252: Assert.assertTrue (x != y); attila@1252: Assert.assertTrue (y != x); attila@1252: Assert.assertFalse(x == y); attila@1252: Assert.assertFalse(y == x); attila@1252: // Exercise the branch optimizer attila@1252: if (x != y) { nop(); } else { Assert.fail(); } attila@1252: if (y != x) { nop(); } else { Assert.fail(); } attila@1252: if (x == y) { Assert.fail(); } else { nop(); } attila@1252: if (y == x) { Assert.fail(); } else { nop(); } attila@1252: } attila@1252: attila@1252: function STRICT_EQ(x, y) { attila@1252: // Exercise normal evaluation attila@1252: Assert.assertTrue (x === y); attila@1252: Assert.assertTrue (y === x); attila@1252: Assert.assertFalse(x !== y); attila@1252: Assert.assertFalse(y !== x); attila@1252: // Exercise the branch optimizer attila@1252: if (x === y) { nop(); } else { Assert.fail(); } attila@1252: if (y === x) { nop(); } else { Assert.fail(); } attila@1252: if (x !== y) { Assert.fail(); } else { nop(); } attila@1252: if (y !== x) { Assert.fail(); } else { nop(); } attila@1252: } attila@1252: attila@1252: function STRICT_NE(x, y) { attila@1252: // Exercise normal evaluation attila@1252: Assert.assertTrue (x !== y); attila@1252: Assert.assertTrue (y !== x); attila@1252: Assert.assertFalse(x === y); attila@1252: Assert.assertFalse(y === x); attila@1252: // Exercise the branch optimizer attila@1252: if (x !== y) { nop(); } else { Assert.fail(); } attila@1252: if (y !== x) { nop(); } else { Assert.fail(); } attila@1252: if (x === y) { Assert.fail(); } else { nop(); } attila@1252: if (y === x) { Assert.fail(); } else { nop(); } attila@1252: } attila@1252: attila@1252: function cmpToAnyNumber(cmp, value) { attila@1252: cmp(1, value); attila@1252: cmp(4294967296, value); attila@1252: cmp(1.2, value); attila@1252: cmp(Infinity, value); attila@1252: cmp(-Infinity, value); attila@1252: cmp(1/Infinity, value); attila@1252: cmp(0, value); attila@1252: cmp(-0, value); attila@1252: cmp(true, value); attila@1252: cmp(false, value); attila@1252: } attila@1252: attila@1252: function notEqualToAnyNumber(value) { attila@1252: cmpToAnyNumber(NE, value); attila@1252: cmpToAnyNumber(STRICT_NE, value); attila@1252: } attila@1252: attila@1252: notEqualToAnyNumber(null); attila@1252: notEqualToAnyNumber(void 0); attila@1252: notEqualToAnyNumber("abc"); attila@1252: notEqualToAnyNumber({}); attila@1252: notEqualToAnyNumber(["xyz"]); attila@1252: attila@1252: function objectWithPrimitiveFunctionNotEqualToAnyNumber(fnName) { attila@1252: var obj = { attila@1252: count: 0 attila@1252: }; attila@1252: obj[fnName] = function() { this.count++; return "foo"; }; attila@1252: notEqualToAnyNumber(obj); attila@1252: // Every NE will invoke it 8 times; cmpToAnyNumber has 10 comparisons attila@1252: // STRICT_NE doesn't invoke toString. attila@1252: Assert.assertTrue(80 === obj.count); attila@1252: } attila@1252: objectWithPrimitiveFunctionNotEqualToAnyNumber("valueOf"); attila@1252: objectWithPrimitiveFunctionNotEqualToAnyNumber("toString"); attila@1252: attila@1252: function objectEqualButNotStrictlyEqual(val, obj) { attila@1252: EQ(val, obj); attila@1252: STRICT_NE(val, obj); attila@1252: } attila@1252: attila@1252: function numberEqualButNotStrictlyEqualToObject(num, obj) { attila@1252: objectEqualButNotStrictlyEqual(num, obj); attila@1252: objectEqualButNotStrictlyEqual(num, [obj]); attila@1252: objectEqualButNotStrictlyEqual(num, [[obj]]); attila@1252: } attila@1252: attila@1252: function numberEqualButNotStrictlyEqualToZeroObjects(num) { attila@1252: numberEqualButNotStrictlyEqualToObject(num, [0]); attila@1252: numberEqualButNotStrictlyEqualToObject(num, ""); attila@1252: numberEqualButNotStrictlyEqualToObject(num, []); attila@1252: numberEqualButNotStrictlyEqualToObject(num, "0"); attila@1252: } attila@1252: attila@1252: numberEqualButNotStrictlyEqualToZeroObjects(0); attila@1252: numberEqualButNotStrictlyEqualToZeroObjects(1/Infinity); attila@1252: numberEqualButNotStrictlyEqualToZeroObjects(false); attila@1252: attila@1252: function numberEqualButNotStrictlyEqualToObjectEquivalent(num) { attila@1252: var str = String(num); attila@1252: objectEqualButNotStrictlyEqual(num, str); attila@1252: objectEqualButNotStrictlyEqual(num, { valueOf: function() { return str }}); attila@1252: objectEqualButNotStrictlyEqual(num, { toString: function() { return str }}); attila@1252: objectEqualButNotStrictlyEqual(num, { valueOf: function() { return num }}); attila@1252: objectEqualButNotStrictlyEqual(num, { toString: function() { return num }}); attila@1252: } attila@1252: attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(1); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(4294967296); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(1.2); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(Infinity); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(-Infinity); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(1/Infinity); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(0); attila@1252: numberEqualButNotStrictlyEqualToObjectEquivalent(-0); attila@1252: attila@1252: STRICT_EQ(1, new java.lang.Integer(1)); attila@1252: STRICT_EQ(1, new java.lang.Double(1)); attila@1252: STRICT_EQ(1.2, new java.lang.Double(1.2)); attila@1252: attila@1252: function LE(x, y) { attila@1252: // Exercise normal evaluation attila@1252: Assert.assertTrue(x <= y); attila@1252: Assert.assertTrue(y >= x); attila@1252: Assert.assertFalse(x > y); attila@1252: Assert.assertFalse(x < y); attila@1252: // Exercise the branch optimizer attila@1252: if (x <= y) { nop(); } else { Assert.fail(); } attila@1252: if (y >= x) { nop(); } else { Assert.fail(); } attila@1252: if (x > y) { Assert.fail(); } else { nop(); } attila@1252: if (y < x) { Assert.fail(); } else { nop(); } attila@1252: } attila@1252: attila@1252: function mutuallyLessThanOrEqual(x, y) { attila@1252: LE(x, y); attila@1252: LE(y, x); attila@1252: } attila@1252: attila@1252: mutuallyLessThanOrEqual(0, null); attila@1252: mutuallyLessThanOrEqual(false, null); attila@1252: mutuallyLessThanOrEqual(1/Infinity, null); attila@1252: attila@1252: function mutuallyLessThanEqualToObjectWithValue(num, val) { attila@1252: mutuallyLessThanOrEqual(num, { valueOf: function() { return val } }); attila@1252: mutuallyLessThanOrEqual(num, { toString: function() { return val } }); attila@1252: } attila@1252: attila@1252: mutuallyLessThanEqualToObjectWithValue(false, 0); attila@1252: mutuallyLessThanEqualToObjectWithValue(false, ""); attila@1252: attila@1252: mutuallyLessThanEqualToObjectWithValue(true, 1); attila@1252: mutuallyLessThanEqualToObjectWithValue(true, "1"); attila@1252: attila@1252: function lessThanEqualToObjectEquivalent(num) { attila@1252: var str = String(num); attila@1252: mutuallyLessThanOrEqual(num, str); attila@1252: mutuallyLessThanEqualToObjectWithValue(num, num); attila@1252: mutuallyLessThanEqualToObjectWithValue(num, str); attila@1252: } attila@1252: attila@1252: lessThanEqualToObjectEquivalent(1); attila@1252: lessThanEqualToObjectEquivalent(4294967296); attila@1252: lessThanEqualToObjectEquivalent(1.2); attila@1252: lessThanEqualToObjectEquivalent(Infinity); attila@1252: lessThanEqualToObjectEquivalent(-Infinity); attila@1252: lessThanEqualToObjectEquivalent(1/Infinity); attila@1252: lessThanEqualToObjectEquivalent(0); attila@1252: lessThanEqualToObjectEquivalent(-0); attila@1252: attila@1252: function INCOMPARABLE(x, y) { attila@1252: // Exercise normal evaluation attila@1252: Assert.assertFalse(x < y); attila@1252: Assert.assertFalse(x > y); attila@1252: Assert.assertFalse(x <= y); attila@1252: Assert.assertFalse(x >= y); attila@1252: Assert.assertFalse(y < x); attila@1252: Assert.assertFalse(y > x); attila@1252: Assert.assertFalse(y <= x); attila@1252: Assert.assertFalse(y >= x); attila@1252: // Exercise the branch optimizer attila@1252: if (x < y) { Assert.fail(); } else { nop(); } attila@1252: if (x > y) { Assert.fail(); } else { nop(); } attila@1252: if (x <= y) { Assert.fail(); } else { nop(); } attila@1252: if (x >= y) { Assert.fail(); } else { nop(); } attila@1252: if (y < x) { Assert.fail(); } else { nop(); } attila@1252: if (y > x) { Assert.fail(); } else { nop(); } attila@1252: if (y <= x) { Assert.fail(); } else { nop(); } attila@1252: if (y >= x) { Assert.fail(); } else { nop(); } attila@1252: } attila@1252: attila@1252: function isIncomparable(value) { attila@1252: cmpToAnyNumber(INCOMPARABLE, value); attila@1252: } attila@1252: attila@1252: isIncomparable(void 0); attila@1252: isIncomparable({ valueOf: function() { return NaN }}); attila@1252: isIncomparable({ toString: function() { return NaN }}); attila@1252: attila@1252: // Force ScriptRuntime.LT(Object, Object) etc. comparisons attila@1252: function cmpObj(fn, x, y) { attila@1252: fn({valueOf: function() { return x }}, {valueOf: function() { return y }}); attila@1252: } attila@1252: attila@1252: function LT(x, y) { attila@1252: Assert.assertTrue(x < y); attila@1252: Assert.assertTrue(y > x); attila@1252: Assert.assertFalse(x >= y); attila@1252: Assert.assertFalse(y <= x); attila@1252: } attila@1252: attila@1252: cmpObj(LT, 1, 2); attila@1252: cmpObj(LT, 1, "2"); attila@1252: cmpObj(LT, "1", 2); attila@1252: cmpObj(LT, "a", "b"); attila@1252: cmpObj(LT, -Infinity, 0); attila@1252: cmpObj(LT, 0, Infinity); attila@1252: cmpObj(LT, -Infinity, Infinity); attila@1252: cmpObj(INCOMPARABLE, 1, NaN); attila@1252: cmpObj(INCOMPARABLE, NaN, NaN); attila@1252: cmpObj(INCOMPARABLE, "boo", NaN); attila@1252: cmpObj(INCOMPARABLE, 1, "boo"); // boo number value will be NaN attila@1252: attila@1252: // Test that a comparison call site can deoptimize from (int, int) to (object, object) attila@1252: (function(){ attila@1252: var x = [1, 2, "a"]; attila@1252: var y = [2, "3", "b"]; attila@1252: for(var i = 0; i < 3; ++i) { attila@1252: Assert.assertTrue(x[i] < y[i]); attila@1252: } attila@1252: })();