[ARM,MIPS] Skip slow tests
[WebKit-https.git] / JSTests / stress / arith-log10-on-various-types.js
1 //@ skip if not $jitTests
2 //@ defaultNoEagerRun
3 "use strict";
4
5 let log10OfHalf = Math.log10(0.5);
6
7 let validInputTestCases = [
8     // input as string, expected result as string.
9     ["undefined", "NaN"],
10     ["null", "-Infinity"],
11     ["1", "0"],
12     ["0", "-Infinity"],
13     ["-0.", "-Infinity"],
14     ["0.5", "" + log10OfHalf],
15     ["Math.PI", "" + Math.log10(Math.PI)],
16     ["Infinity", "Infinity"],
17     ["-Infinity", "NaN"],
18     ["NaN", "NaN"],
19     ["\"WebKit\"", "NaN"],
20     ["\"0.5\"", "" + log10OfHalf],
21     ["{ valueOf: () => { return 0.5; } }", "" + log10OfHalf],
22 ];
23
24 let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
25
26 function isIdentical(result, expected)
27 {
28     if (expected === expected) {
29         if (result !== expected)
30             return false;
31         if (!expected)
32             return (1 / expected) === (1 / result);
33
34         return true;
35     }
36     return result !== result;
37 }
38
39
40 // Test Math.log10() without arguments.
41 function opaqueLog10NoArgument() {
42     return Math.log10();
43 }
44 noInline(opaqueLog10NoArgument);
45 noOSRExitFuzzing(opaqueLog10NoArgument);
46
47 function testNoArgument() {
48     for (let i = 0; i < 1e4; ++i) {
49         let output = opaqueLog10NoArgument();
50         if (output === output) {
51             throw "Failed opaqueLog10NoArgument";
52         }
53     }
54     if (numberOfDFGCompiles(opaqueLog10NoArgument) > 1)
55         throw "The call without arguments should never exit.";
56 }
57 testNoArgument();
58
59
60 // Test Math.log10() with a very polymorphic input. All test cases are seen at each iteration.
61 function opaqueAllTypesLog10(argument) {
62     return Math.log10(argument);
63 }
64 noInline(opaqueAllTypesLog10);
65 noOSRExitFuzzing(opaqueAllTypesLog10);
66
67 function testAllTypesCall() {
68     for (let i = 0; i < 1e3; ++i) {
69         for (let testCaseInput of validInputTypedTestCases) {
70             let output = opaqueAllTypesLog10(testCaseInput[0]);
71             if (!isIdentical(output, testCaseInput[1]))
72                 throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
73         }
74     }
75     if (numberOfDFGCompiles(opaqueAllTypesLog10) > 2)
76         throw "We should have detected log10() was polymorphic and generated a generic version.";
77 }
78 testAllTypesCall();
79
80
81 // Test Math.log10() on a completely typed input. Every call see only one type.
82 function testSingleTypeCall() {
83     for (let testCaseInput of validInputTestCases) {
84         eval(`
85             function opaqueLog10(argument) {
86                 return Math.log10(argument);
87             }
88             noInline(opaqueLog10);
89             noOSRExitFuzzing(opaqueLog10);
90
91             for (let i = 0; i < 1e4; ++i) {
92                 if (!isIdentical(opaqueLog10(${testCaseInput[0]}), ${testCaseInput[1]})) {
93                     throw "Failed testSingleTypeCall()";
94                 }
95             }
96             if (numberOfDFGCompiles(opaqueLog10) > 1)
97                 throw "We should have compiled a single log10 for the expected type.";
98         `);
99     }
100 }
101 testSingleTypeCall();
102
103
104 // Test Math.log10() on constants
105 function testConstant() {
106     for (let testCaseInput of validInputTestCases) {
107         eval(`
108             function opaqueLog10OnConstant() {
109                 return Math.log10(${testCaseInput[0]});
110             }
111             noInline(opaqueLog10OnConstant);
112             noOSRExitFuzzing(opaqueLog10OnConstant);
113
114             for (let i = 0; i < 1e4; ++i) {
115                 if (!isIdentical(opaqueLog10OnConstant(), ${testCaseInput[1]})) {
116                     throw "Failed testConstant()";
117                 }
118             }
119             if (numberOfDFGCompiles(opaqueLog10OnConstant) > 1)
120                 throw "We should have compiled a single log10 for the expected type.";
121         `);
122     }
123 }
124 testConstant();
125
126
127 // Verify we call valueOf() exactly once per call.
128 function opaqueLog10ForSideEffects(argument) {
129     return Math.log10(argument);
130 }
131 noInline(opaqueLog10ForSideEffects);
132 noOSRExitFuzzing(opaqueLog10ForSideEffects);
133
134 function testSideEffect() {
135     let testObject = {
136         counter: 0,
137         valueOf: function() { ++this.counter; return 0.2; }
138     };
139     let log10Result = Math.log10(0.2);
140     for (let i = 0; i < 1e4; ++i) {
141         if (opaqueLog10ForSideEffects(testObject) !== log10Result)
142             throw "Incorrect result in testSideEffect()";
143     }
144     if (testObject.counter !== 1e4)
145         throw "Failed testSideEffect()";
146     if (numberOfDFGCompiles(opaqueLog10ForSideEffects) > 1)
147         throw "opaqueLog10ForSideEffects() is predictable, it should only be compiled once.";
148 }
149 testSideEffect();
150
151
152 // Verify log10() is not subject to CSE if the argument has side effects.
153 function opaqueLog10ForCSE(argument) {
154     return Math.log10(argument) + Math.log10(argument) + Math.log10(argument);
155 }
156 noInline(opaqueLog10ForCSE);
157 noOSRExitFuzzing(opaqueLog10ForCSE);
158
159 function testCSE() {
160     let testObject = {
161         counter: 0,
162         valueOf: function() { ++this.counter; return 0.2; }
163     };
164     let log10Result = Math.log10(0.2);
165     let threelog10Result = log10Result + log10Result + log10Result;
166     for (let i = 0; i < 1e4; ++i) {
167         if (opaqueLog10ForCSE(testObject) !== threelog10Result)
168             throw "Incorrect result in testCSE()";
169     }
170     if (testObject.counter !== 3e4)
171         throw "Failed testCSE()";
172     if (numberOfDFGCompiles(opaqueLog10ForCSE) > 1)
173         throw "opaqueLog10ForCSE() is predictable, it should only be compiled once.";
174 }
175 testCSE();
176
177
178 // Verify log10() is not subject to DCE if the argument has side effects.
179 function opaqueLog10ForDCE(argument) {
180     Math.log10(argument);
181 }
182 noInline(opaqueLog10ForDCE);
183 noOSRExitFuzzing(opaqueLog10ForDCE);
184
185 function testDCE() {
186     let testObject = {
187         counter: 0,
188         valueOf: function() { ++this.counter; return 0.2; }
189     };
190     for (let i = 0; i < 1e4; ++i) {
191         opaqueLog10ForDCE(testObject);
192     }
193     if (testObject.counter !== 1e4)
194         throw "Failed testDCE()";
195     if (numberOfDFGCompiles(opaqueLog10ForDCE) > 1)
196         throw "opaqueLog10ForDCE() is predictable, it should only be compiled once.";
197 }
198 testDCE();
199
200
201 // Test exceptions in the argument.
202 function testException() {
203     let counter = 0;
204     function opaqueLog10WithException(argument) {
205         let result = Math.log10(argument);
206         ++counter;
207         return result;
208     }
209     noInline(opaqueLog10WithException);
210
211     let testObject = { valueOf: () => {  return 0.1; } };
212     let log10Result = Math.log10(0.1);
213
214     // Warm up without exception.
215     for (let i = 0; i < 1e3; ++i) {
216         if (opaqueLog10WithException(testObject) !== log10Result)
217             throw "Incorrect result in opaqueLog10WithException()";
218     }
219
220     let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
221
222     for (let i = 0; i < 1e2; ++i) {
223         try {
224             if (opaqueLog10WithException(testThrowObject) !== 8)
225                 throw "This code should not be reached!!";
226         } catch (e) {
227             if (e !== testObject) {
228                 throw "Wrong object thrown from opaqueLog10WithException."
229             }
230         }
231     }
232
233     if (counter !== 1e3) {
234         throw "Invalid count in testException()";
235     }
236 }
237 testException();