JDK-8035712.js revision 1197:20c3aef2b4cb
1356290Sjkim/*
2298998Sjkim * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
3298998Sjkim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4298998Sjkim *
5298998Sjkim * This code is free software; you can redistribute it and/or modify it
6298998Sjkim * under the terms of the GNU General Public License version 2 only, as
7298998Sjkim * published by the Free Software Foundation.
8298998Sjkim *
9298998Sjkim * This code is distributed in the hope that it will be useful, but WITHOUT
10298998Sjkim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11298998Sjkim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12298998Sjkim * version 2 for more details (a copy is included in the LICENSE file that
13298998Sjkim * accompanied this code).
14298998Sjkim *
15298998Sjkim * You should have received a copy of the GNU General Public License version
16298998Sjkim * 2 along with this work; if not, write to the Free Software Foundation,
17298998Sjkim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18298998Sjkim *
19298998Sjkim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20298998Sjkim * or visit www.oracle.com if you need additional information or have any
21298998Sjkim * questions.
22298998Sjkim */
23298998Sjkim
24298998Sjkim/**
25298998Sjkim * JDK-8035712: Restore some of the RuntimeCallSite specializations
26298998Sjkim *
27298998Sjkim * @test
28298998Sjkim * @run
29298998Sjkim */
30298998Sjkim
31298998Sjkimif ((typeof Assert) == "undefined") {
32298998Sjkim    Assert = {
33298998Sjkim        assertTrue: function(x) { if(!x) { throw "expected true" } },
34298998Sjkim        assertFalse: function(x) { if(x) { throw "expected false" } },
35298998Sjkim    };
36298998Sjkim}
37298998Sjkim
38298998Sjkimfunction nop() {}
39298998Sjkim
40298998Sjkimfunction EQ(x, y) {
41298998Sjkim    // Exercise normal evaluation
42298998Sjkim    Assert.assertTrue (x == y);
43298998Sjkim    Assert.assertTrue (y == x);
44298998Sjkim    Assert.assertFalse(x != y);
45298998Sjkim    Assert.assertFalse(y != x);
46298998Sjkim    // Exercise the branch optimizer
47298998Sjkim    if (x == y) { nop(); } else { Assert.fail(); }
48298998Sjkim    if (y == x) { nop(); } else { Assert.fail(); }
49312826Sjkim    if (x != y) { Assert.fail(); } else { nop(); }
50298998Sjkim    if (y != x) { Assert.fail(); } else { nop(); }
51298998Sjkim}
52298998Sjkim
53298998Sjkimfunction NE(x, y) {
54298998Sjkim    // Exercise normal evaluation
55298998Sjkim    Assert.assertTrue (x != y);
56298998Sjkim    Assert.assertTrue (y != x);
57344604Sjkim    Assert.assertFalse(x == y);
58344604Sjkim    Assert.assertFalse(y == x);
59344604Sjkim    // Exercise the branch optimizer
60344604Sjkim    if (x != y) { nop(); } else { Assert.fail(); }
61344604Sjkim    if (y != x) { nop(); } else { Assert.fail(); }
62344604Sjkim    if (x == y) { Assert.fail(); } else { nop(); }
63298998Sjkim    if (y == x) { Assert.fail(); } else { nop(); }
64344604Sjkim}
65344604Sjkim
66344604Sjkimfunction STRICT_EQ(x, y) {
67344604Sjkim    // Exercise normal evaluation
68298998Sjkim    Assert.assertTrue (x === y);
69298998Sjkim    Assert.assertTrue (y === x);
70344604Sjkim    Assert.assertFalse(x !== y);
71298998Sjkim    Assert.assertFalse(y !== x);
72298998Sjkim    // Exercise the branch optimizer
73298998Sjkim    if (x === y) { nop(); } else { Assert.fail(); }
74298998Sjkim    if (y === x) { nop(); } else { Assert.fail(); }
75298998Sjkim    if (x !== y) { Assert.fail(); } else { nop(); }
76298998Sjkim    if (y !== x) { Assert.fail(); } else { nop(); }
77298998Sjkim}
78298998Sjkim
79298998Sjkimfunction STRICT_NE(x, y) {
80298998Sjkim    // Exercise normal evaluation
81298998Sjkim    Assert.assertTrue (x !== y);
82298998Sjkim    Assert.assertTrue (y !== x);
83298998Sjkim    Assert.assertFalse(x === y);
84298998Sjkim    Assert.assertFalse(y === x);
85298998Sjkim    // Exercise the branch optimizer
86298998Sjkim    if (x !== y) { nop(); } else { Assert.fail(); }
87298998Sjkim    if (y !== x) { nop(); } else { Assert.fail(); }
88298998Sjkim    if (x === y) { Assert.fail(); } else { nop(); }
89298998Sjkim    if (y === x) { Assert.fail(); } else { nop(); }
90298998Sjkim}
91298998Sjkim
92298998Sjkimfunction cmpToAnyNumber(cmp, value) {
93298998Sjkim    cmp(1, value);
94298998Sjkim    cmp(4294967296, value);
95298998Sjkim    cmp(1.2, value);
96298998Sjkim    cmp(Infinity, value);
97298998Sjkim    cmp(-Infinity, value);
98298998Sjkim    cmp(1/Infinity, value);
99298998Sjkim    cmp(0, value);
100298998Sjkim    cmp(-0, value);
101298998Sjkim    cmp(true, value);
102298998Sjkim    cmp(false, value);
103298998Sjkim}
104298998Sjkim
105298998Sjkimfunction notEqualToAnyNumber(value) {
106298998Sjkim    cmpToAnyNumber(NE, value);
107298998Sjkim    cmpToAnyNumber(STRICT_NE, value);
108298998Sjkim}
109298998Sjkim
110298998SjkimnotEqualToAnyNumber(null);
111298998SjkimnotEqualToAnyNumber(void 0);
112298998SjkimnotEqualToAnyNumber("abc");
113298998SjkimnotEqualToAnyNumber({});
114298998SjkimnotEqualToAnyNumber(["xyz"]);
115298998Sjkim
116298998Sjkimfunction objectWithPrimitiveFunctionNotEqualToAnyNumber(fnName) {
117298998Sjkim    var obj = {
118298998Sjkim        count: 0
119298998Sjkim    };
120298998Sjkim    obj[fnName] = function() { this.count++; return "foo"; };
121298998Sjkim    notEqualToAnyNumber(obj);
122298998Sjkim    // Every NE will invoke it 8 times; cmpToAnyNumber has 10 comparisons
123298998Sjkim    // STRICT_NE doesn't invoke toString.
124298998Sjkim    Assert.assertTrue(80 === obj.count);
125298998Sjkim}
126298998SjkimobjectWithPrimitiveFunctionNotEqualToAnyNumber("valueOf");
127298998SjkimobjectWithPrimitiveFunctionNotEqualToAnyNumber("toString");
128298998Sjkim
129298998Sjkimfunction objectEqualButNotStrictlyEqual(val, obj) {
130298998Sjkim    EQ(val, obj);
131298998Sjkim    STRICT_NE(val, obj);
132298998Sjkim}
133298998Sjkim
134298998Sjkimfunction numberEqualButNotStrictlyEqualToObject(num, obj) {
135298998Sjkim    objectEqualButNotStrictlyEqual(num, obj);
136356290Sjkim    objectEqualButNotStrictlyEqual(num, [obj]);
137298998Sjkim    objectEqualButNotStrictlyEqual(num, [[obj]]);
138298998Sjkim}
139298998Sjkim
140298998Sjkimfunction numberEqualButNotStrictlyEqualToZeroObjects(num) {
141298998Sjkim    numberEqualButNotStrictlyEqualToObject(num, [0]);
142298998Sjkim    numberEqualButNotStrictlyEqualToObject(num, "");
143298998Sjkim    numberEqualButNotStrictlyEqualToObject(num, []);
144298998Sjkim    numberEqualButNotStrictlyEqualToObject(num, "0");
145298998Sjkim}
146298998Sjkim
147298998SjkimnumberEqualButNotStrictlyEqualToZeroObjects(0);
148298998SjkimnumberEqualButNotStrictlyEqualToZeroObjects(1/Infinity);
149298998SjkimnumberEqualButNotStrictlyEqualToZeroObjects(false);
150298998Sjkim
151298998Sjkimfunction numberEqualButNotStrictlyEqualToObjectEquivalent(num) {
152298998Sjkim    var str = String(num);
153298998Sjkim    objectEqualButNotStrictlyEqual(num, str);
154298998Sjkim    objectEqualButNotStrictlyEqual(num, { valueOf:  function() { return str }});
155298998Sjkim    objectEqualButNotStrictlyEqual(num, { toString: function() { return str }});
156298998Sjkim    objectEqualButNotStrictlyEqual(num, { valueOf:  function() { return num }});
157298998Sjkim    objectEqualButNotStrictlyEqual(num, { toString: function() { return num }});
158298998Sjkim}
159298998Sjkim
160298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(1);
161298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(4294967296);
162298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(1.2);
163298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(Infinity);
164298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(-Infinity);
165298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(1/Infinity);
166298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(0);
167298998SjkimnumberEqualButNotStrictlyEqualToObjectEquivalent(-0);
168298998Sjkim
169298998SjkimSTRICT_EQ(1, new java.lang.Integer(1));
170298998SjkimSTRICT_EQ(1, new java.lang.Double(1));
171298998SjkimSTRICT_EQ(1.2, new java.lang.Double(1.2));
172298998Sjkim
173298998Sjkimfunction LE(x, y) {
174298998Sjkim    // Exercise normal evaluation
175298998Sjkim    Assert.assertTrue(x <= y);
176298998Sjkim    Assert.assertTrue(y >= x);
177298998Sjkim    Assert.assertFalse(x > y);
178298998Sjkim    Assert.assertFalse(x < y);
179298998Sjkim    // Exercise the branch optimizer
180298998Sjkim    if (x <= y) { nop(); } else { Assert.fail(); }
181344604Sjkim    if (y >= x) { nop(); } else { Assert.fail(); }
182298998Sjkim    if (x > y) { Assert.fail(); } else { nop(); }
183344604Sjkim    if (y < x) { Assert.fail(); } else { nop(); }
184298998Sjkim}
185298998Sjkim
186298998Sjkimfunction mutuallyLessThanOrEqual(x, y) {
187298998Sjkim    LE(x, y);
188298998Sjkim    LE(y, x);
189344604Sjkim}
190298998Sjkim
191298998SjkimmutuallyLessThanOrEqual(0, null);
192298998SjkimmutuallyLessThanOrEqual(false, null);
193298998SjkimmutuallyLessThanOrEqual(1/Infinity, null);
194344604Sjkim
195298998Sjkimfunction mutuallyLessThanEqualToObjectWithValue(num, val) {
196344604Sjkim    mutuallyLessThanOrEqual(num, { valueOf: function() { return val } });
197298998Sjkim    mutuallyLessThanOrEqual(num, { toString: function() { return val } });
198344604Sjkim}
199298998Sjkim
200298998SjkimmutuallyLessThanEqualToObjectWithValue(false, 0);
201298998SjkimmutuallyLessThanEqualToObjectWithValue(false, "");
202298998Sjkim
203298998SjkimmutuallyLessThanEqualToObjectWithValue(true, 1);
204298998SjkimmutuallyLessThanEqualToObjectWithValue(true, "1");
205344604Sjkim
206298998Sjkimfunction lessThanEqualToObjectEquivalent(num) {
207298998Sjkim    var str = String(num);
208298998Sjkim    mutuallyLessThanOrEqual(num, str);
209298998Sjkim    mutuallyLessThanEqualToObjectWithValue(num, num);
210298998Sjkim    mutuallyLessThanEqualToObjectWithValue(num, str);
211298998Sjkim}
212298998Sjkim
213298998SjkimlessThanEqualToObjectEquivalent(1);
214344604SjkimlessThanEqualToObjectEquivalent(4294967296);
215298998SjkimlessThanEqualToObjectEquivalent(1.2);
216344604SjkimlessThanEqualToObjectEquivalent(Infinity);
217298998SjkimlessThanEqualToObjectEquivalent(-Infinity);
218298998SjkimlessThanEqualToObjectEquivalent(1/Infinity);
219298998SjkimlessThanEqualToObjectEquivalent(0);
220298998SjkimlessThanEqualToObjectEquivalent(-0);
221298998Sjkim
222298998Sjkimfunction INCOMPARABLE(x, y) {
223344604Sjkim    // Exercise normal evaluation
224298998Sjkim    Assert.assertFalse(x < y);
225298998Sjkim    Assert.assertFalse(x > y);
226298998Sjkim    Assert.assertFalse(x <= y);
227298998Sjkim    Assert.assertFalse(x >= y);
228298998Sjkim    Assert.assertFalse(y < x);
229298998Sjkim    Assert.assertFalse(y > x);
230298998Sjkim    Assert.assertFalse(y <= x);
231298998Sjkim    Assert.assertFalse(y >= x);
232298998Sjkim    // Exercise the branch optimizer
233298998Sjkim    if (x < y) { Assert.fail(); } else { nop(); }
234344604Sjkim    if (x > y) { Assert.fail(); } else { nop(); }
235298998Sjkim    if (x <= y) { Assert.fail(); } else { nop(); }
236298998Sjkim    if (x >= y) { Assert.fail(); } else { nop(); }
237298998Sjkim    if (y < x) { Assert.fail(); } else { nop(); }
238298998Sjkim    if (y > x) { Assert.fail(); } else { nop(); }
239344604Sjkim    if (y <= x) { Assert.fail(); } else { nop(); }
240298998Sjkim    if (y >= x) { Assert.fail(); } else { nop(); }
241298998Sjkim}
242298998Sjkim
243298998Sjkimfunction isIncomparable(value) {
244298998Sjkim    cmpToAnyNumber(INCOMPARABLE, value);
245298998Sjkim}
246298998Sjkim
247298998SjkimisIncomparable(void 0);
248298998SjkimisIncomparable({ valueOf: function() { return NaN }});
249344604SjkimisIncomparable({ toString: function() { return NaN }});
250298998Sjkim
251298998Sjkim// Force ScriptRuntime.LT(Object, Object) etc. comparisons
252344604Sjkimfunction cmpObj(fn, x, y) {
253298998Sjkim    fn({valueOf: function() { return x }}, {valueOf: function() { return y }});
254298998Sjkim}
255344604Sjkim
256298998Sjkimfunction LT(x, y) {
257344604Sjkim    Assert.assertTrue(x < y);
258298998Sjkim    Assert.assertTrue(y > x);
259298998Sjkim    Assert.assertFalse(x >= y);
260344604Sjkim    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