1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * JDK-8035712: Restore some of the RuntimeCallSite specializations 26 * 27 * @test 28 * @run 29 */ 30 31if ((typeof Assert) == "undefined") { 32 Assert = { 33 assertTrue: function(x) { if(!x) { throw "expected true" } }, 34 assertFalse: function(x) { if(x) { throw "expected false" } }, 35 }; 36} 37 38function nop() {} 39 40function EQ(x, y) { 41 // Exercise normal evaluation 42 Assert.assertTrue (x == y); 43 Assert.assertTrue (y == x); 44 Assert.assertFalse(x != y); 45 Assert.assertFalse(y != x); 46 // Exercise the branch optimizer 47 if (x == y) { nop(); } else { Assert.fail(); } 48 if (y == x) { nop(); } else { Assert.fail(); } 49 if (x != y) { Assert.fail(); } else { nop(); } 50 if (y != x) { Assert.fail(); } else { nop(); } 51} 52 53function NE(x, y) { 54 // Exercise normal evaluation 55 Assert.assertTrue (x != y); 56 Assert.assertTrue (y != x); 57 Assert.assertFalse(x == y); 58 Assert.assertFalse(y == x); 59 // Exercise the branch optimizer 60 if (x != y) { nop(); } else { Assert.fail(); } 61 if (y != x) { nop(); } else { Assert.fail(); } 62 if (x == y) { Assert.fail(); } else { nop(); } 63 if (y == x) { Assert.fail(); } else { nop(); } 64} 65 66function STRICT_EQ(x, y) { 67 // Exercise normal evaluation 68 Assert.assertTrue (x === y); 69 Assert.assertTrue (y === x); 70 Assert.assertFalse(x !== y); 71 Assert.assertFalse(y !== x); 72 // Exercise the branch optimizer 73 if (x === y) { nop(); } else { Assert.fail(); } 74 if (y === x) { nop(); } else { Assert.fail(); } 75 if (x !== y) { Assert.fail(); } else { nop(); } 76 if (y !== x) { Assert.fail(); } else { nop(); } 77} 78 79function STRICT_NE(x, y) { 80 // Exercise normal evaluation 81 Assert.assertTrue (x !== y); 82 Assert.assertTrue (y !== x); 83 Assert.assertFalse(x === y); 84 Assert.assertFalse(y === x); 85 // Exercise the branch optimizer 86 if (x !== y) { nop(); } else { Assert.fail(); } 87 if (y !== x) { nop(); } else { Assert.fail(); } 88 if (x === y) { Assert.fail(); } else { nop(); } 89 if (y === x) { Assert.fail(); } else { nop(); } 90} 91 92function cmpToAnyNumber(cmp, value) { 93 cmp(1, value); 94 cmp(4294967296, value); 95 cmp(1.2, value); 96 cmp(Infinity, value); 97 cmp(-Infinity, value); 98 cmp(1/Infinity, value); 99 cmp(0, value); 100 cmp(-0, value); 101 cmp(true, value); 102 cmp(false, value); 103} 104 105function notEqualToAnyNumber(value) { 106 cmpToAnyNumber(NE, value); 107 cmpToAnyNumber(STRICT_NE, value); 108} 109 110notEqualToAnyNumber(null); 111notEqualToAnyNumber(void 0); 112notEqualToAnyNumber("abc"); 113notEqualToAnyNumber({}); 114notEqualToAnyNumber(["xyz"]); 115 116function objectWithPrimitiveFunctionNotEqualToAnyNumber(fnName) { 117 var obj = { 118 count: 0 119 }; 120 obj[fnName] = function() { this.count++; return "foo"; }; 121 notEqualToAnyNumber(obj); 122 // Every NE will invoke it 8 times; cmpToAnyNumber has 10 comparisons 123 // STRICT_NE doesn't invoke toString. 124 Assert.assertTrue(80 === obj.count); 125} 126objectWithPrimitiveFunctionNotEqualToAnyNumber("valueOf"); 127objectWithPrimitiveFunctionNotEqualToAnyNumber("toString"); 128 129function objectEqualButNotStrictlyEqual(val, obj) { 130 EQ(val, obj); 131 STRICT_NE(val, obj); 132} 133 134function numberEqualButNotStrictlyEqualToObject(num, obj) { 135 objectEqualButNotStrictlyEqual(num, obj); 136 objectEqualButNotStrictlyEqual(num, [obj]); 137 objectEqualButNotStrictlyEqual(num, [[obj]]); 138} 139 140function numberEqualButNotStrictlyEqualToZeroObjects(num) { 141 numberEqualButNotStrictlyEqualToObject(num, [0]); 142 numberEqualButNotStrictlyEqualToObject(num, ""); 143 numberEqualButNotStrictlyEqualToObject(num, []); 144 numberEqualButNotStrictlyEqualToObject(num, "0"); 145} 146 147numberEqualButNotStrictlyEqualToZeroObjects(0); 148numberEqualButNotStrictlyEqualToZeroObjects(1/Infinity); 149numberEqualButNotStrictlyEqualToZeroObjects(false); 150 151function numberEqualButNotStrictlyEqualToObjectEquivalent(num) { 152 var str = String(num); 153 objectEqualButNotStrictlyEqual(num, str); 154 objectEqualButNotStrictlyEqual(num, { valueOf: function() { return str }}); 155 objectEqualButNotStrictlyEqual(num, { toString: function() { return str }}); 156 objectEqualButNotStrictlyEqual(num, { valueOf: function() { return num }}); 157 objectEqualButNotStrictlyEqual(num, { toString: function() { return num }}); 158} 159 160numberEqualButNotStrictlyEqualToObjectEquivalent(1); 161numberEqualButNotStrictlyEqualToObjectEquivalent(4294967296); 162numberEqualButNotStrictlyEqualToObjectEquivalent(1.2); 163numberEqualButNotStrictlyEqualToObjectEquivalent(Infinity); 164numberEqualButNotStrictlyEqualToObjectEquivalent(-Infinity); 165numberEqualButNotStrictlyEqualToObjectEquivalent(1/Infinity); 166numberEqualButNotStrictlyEqualToObjectEquivalent(0); 167numberEqualButNotStrictlyEqualToObjectEquivalent(-0); 168 169STRICT_EQ(1, new java.lang.Integer(1)); 170STRICT_EQ(1, new java.lang.Double(1)); 171STRICT_EQ(1.2, new java.lang.Double(1.2)); 172 173function LE(x, y) { 174 // Exercise normal evaluation 175 Assert.assertTrue(x <= y); 176 Assert.assertTrue(y >= x); 177 Assert.assertFalse(x > y); 178 Assert.assertFalse(x < y); 179 // Exercise the branch optimizer 180 if (x <= y) { nop(); } else { Assert.fail(); } 181 if (y >= x) { nop(); } else { Assert.fail(); } 182 if (x > y) { Assert.fail(); } else { nop(); } 183 if (y < x) { Assert.fail(); } else { nop(); } 184} 185 186function mutuallyLessThanOrEqual(x, y) { 187 LE(x, y); 188 LE(y, x); 189} 190 191mutuallyLessThanOrEqual(0, null); 192mutuallyLessThanOrEqual(false, null); 193mutuallyLessThanOrEqual(1/Infinity, null); 194 195function mutuallyLessThanEqualToObjectWithValue(num, val) { 196 mutuallyLessThanOrEqual(num, { valueOf: function() { return val } }); 197 mutuallyLessThanOrEqual(num, { toString: function() { return val } }); 198} 199 200mutuallyLessThanEqualToObjectWithValue(false, 0); 201mutuallyLessThanEqualToObjectWithValue(false, ""); 202 203mutuallyLessThanEqualToObjectWithValue(true, 1); 204mutuallyLessThanEqualToObjectWithValue(true, "1"); 205 206function lessThanEqualToObjectEquivalent(num) { 207 var str = String(num); 208 mutuallyLessThanOrEqual(num, str); 209 mutuallyLessThanEqualToObjectWithValue(num, num); 210 mutuallyLessThanEqualToObjectWithValue(num, str); 211} 212 213lessThanEqualToObjectEquivalent(1); 214lessThanEqualToObjectEquivalent(4294967296); 215lessThanEqualToObjectEquivalent(1.2); 216lessThanEqualToObjectEquivalent(Infinity); 217lessThanEqualToObjectEquivalent(-Infinity); 218lessThanEqualToObjectEquivalent(1/Infinity); 219lessThanEqualToObjectEquivalent(0); 220lessThanEqualToObjectEquivalent(-0); 221 222function INCOMPARABLE(x, y) { 223 // Exercise normal evaluation 224 Assert.assertFalse(x < y); 225 Assert.assertFalse(x > y); 226 Assert.assertFalse(x <= y); 227 Assert.assertFalse(x >= y); 228 Assert.assertFalse(y < x); 229 Assert.assertFalse(y > x); 230 Assert.assertFalse(y <= x); 231 Assert.assertFalse(y >= x); 232 // Exercise the branch optimizer 233 if (x < y) { Assert.fail(); } else { nop(); } 234 if (x > y) { Assert.fail(); } else { nop(); } 235 if (x <= y) { Assert.fail(); } else { nop(); } 236 if (x >= y) { Assert.fail(); } else { nop(); } 237 if (y < x) { Assert.fail(); } else { nop(); } 238 if (y > x) { Assert.fail(); } else { nop(); } 239 if (y <= x) { Assert.fail(); } else { nop(); } 240 if (y >= x) { Assert.fail(); } else { nop(); } 241} 242 243function isIncomparable(value) { 244 cmpToAnyNumber(INCOMPARABLE, value); 245} 246 247isIncomparable(void 0); 248isIncomparable({ valueOf: function() { return NaN }}); 249isIncomparable({ toString: function() { return NaN }}); 250 251// Force ScriptRuntime.LT(Object, Object) etc. comparisons 252function cmpObj(fn, x, y) { 253 fn({valueOf: function() { return x }}, {valueOf: function() { return y }}); 254} 255 256function LT(x, y) { 257 Assert.assertTrue(x < y); 258 Assert.assertTrue(y > x); 259 Assert.assertFalse(x >= y); 260 Assert.assertFalse(y <= x); 261} 262 263cmpObj(LT, 1, 2); 264cmpObj(LT, 1, "2"); 265cmpObj(LT, "1", 2); 266cmpObj(LT, "a", "b"); 267cmpObj(LT, -Infinity, 0); 268cmpObj(LT, 0, Infinity); 269cmpObj(LT, -Infinity, Infinity); 270cmpObj(INCOMPARABLE, 1, NaN); 271cmpObj(INCOMPARABLE, NaN, NaN); 272cmpObj(INCOMPARABLE, "boo", NaN); 273cmpObj(INCOMPARABLE, 1, "boo"); // boo number value will be NaN 274 275// Test that a comparison call site can deoptimize from (int, int) to (object, object) 276(function(){ 277 var x = [1, 2, "a"]; 278 var y = [2, "3", "b"]; 279 for(var i = 0; i < 3; ++i) { 280 Assert.assertTrue(x[i] < y[i]); 281 } 282})(); 283