Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java
41153 views
1
/*
2
* Copyright (c) 2014, 2021, 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
* @test NullCheckDroppingsTest
26
* @bug 8054492
27
* @summary Casting can result in redundant null checks in generated code
28
* @requires vm.hasJFR
29
* @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
30
* @library /test/lib
31
* @modules java.base/jdk.internal.misc
32
* java.management
33
*
34
* @build sun.hotspot.WhiteBox
35
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
36
* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
37
* -Xmixed -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:CompileThreshold=1000
38
* -XX:CompileCommand=exclude,compiler.intrinsics.klass.CastNullCheckDroppingsTest::runTest
39
* compiler.intrinsics.klass.CastNullCheckDroppingsTest
40
*/
41
42
package compiler.intrinsics.klass;
43
44
import jdk.jfr.Recording;
45
import jdk.jfr.consumer.RecordedEvent;
46
import jdk.test.lib.Platform;
47
import jdk.test.lib.jfr.EventNames;
48
import jdk.test.lib.jfr.Events;
49
import sun.hotspot.WhiteBox;
50
import sun.hotspot.code.NMethod;
51
52
import java.io.IOException;
53
import java.lang.invoke.MethodHandle;
54
import java.lang.invoke.MethodHandles;
55
import java.lang.invoke.MethodType;
56
import java.lang.reflect.Method;
57
import java.util.List;
58
import java.util.function.BiFunction;
59
60
public class CastNullCheckDroppingsTest {
61
62
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
63
64
static final BiFunction<Class, Object, Object> fCast = (c, o) -> c.cast(o);
65
66
static final MethodHandle SET_SSINK;
67
static final MethodHandle MH_CAST;
68
69
static {
70
try {
71
SET_SSINK = MethodHandles.lookup().findSetter(CastNullCheckDroppingsTest.class, "ssink", String.class);
72
MH_CAST = MethodHandles.lookup().findVirtual(Class.class,
73
"cast",
74
MethodType.methodType(Object.class, Object.class));
75
}
76
catch (Exception e) {
77
throw new Error(e);
78
}
79
}
80
81
static volatile String svalue = "A";
82
static volatile Object onull = null;
83
static volatile Integer iobj = new Integer(0);
84
static volatile int[] arr = new int[2];
85
static volatile Class objClass = String.class;
86
static volatile Class nullClass = null;
87
88
String ssink;
89
Integer isink;
90
int[] asink;
91
92
public static void main(String[] args) throws Exception {
93
if (!Platform.isServer() || Platform.isEmulatedClient()) {
94
throw new Error("TESTBUG: Not server mode");
95
}
96
// Make sure background compilation is disabled
97
if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) {
98
throw new Error("TESTBUG: Background compilation enabled");
99
}
100
// Make sure Tiered compilation is disabled
101
if (WHITE_BOX.getBooleanVMFlag("TieredCompilation")) {
102
throw new Error("TESTBUG: Tiered compilation enabled");
103
}
104
105
Method methodClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testClassCast", String.class);
106
Method methodMHCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testMHCast", String.class);
107
Method methodMHSetter = CastNullCheckDroppingsTest.class.getDeclaredMethod("testMHSetter", String.class);
108
Method methodFunction = CastNullCheckDroppingsTest.class.getDeclaredMethod("testFunction", String.class);
109
110
CastNullCheckDroppingsTest t = new CastNullCheckDroppingsTest();
111
t.runTest(methodClassCast, false, svalue);
112
t.runTest(methodMHCast, false, svalue);
113
t.runTest(methodMHSetter, false, svalue);
114
t.runTest(methodFunction, false, svalue);
115
116
// Edge cases
117
Method methodClassCastNull = CastNullCheckDroppingsTest.class.getDeclaredMethod("testClassCastNull", String.class);
118
Method methodNullClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testNullClassCast", String.class);
119
Method methodClassCastObj = CastNullCheckDroppingsTest.class.getDeclaredMethod("testClassCastObj", Object.class);
120
Method methodObjClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testObjClassCast", String.class);
121
Method methodClassCastInt = CastNullCheckDroppingsTest.class.getDeclaredMethod("testClassCastInt", Object.class);
122
Method methodIntClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testIntClassCast", Object.class);
123
Method methodClassCastint = CastNullCheckDroppingsTest.class.getDeclaredMethod("testClassCastint", Object.class);
124
Method methodintClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testintClassCast", Object.class);
125
Method methodClassCastPrim = CastNullCheckDroppingsTest.class.getDeclaredMethod("testClassCastPrim", Object.class);
126
Method methodPrimClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testPrimClassCast", Object.class);
127
Method methodVarClassCast = CastNullCheckDroppingsTest.class.getDeclaredMethod("testVarClassCast", Class.class);
128
129
t.runTest(methodClassCastNull, false, svalue);
130
t.runTest(methodNullClassCast, false, svalue);
131
t.runTest(methodClassCastObj, false, svalue);
132
t.runTest(methodObjClassCast, true, svalue);
133
t.runTest(methodClassCastInt, false, svalue);
134
t.runTest(methodIntClassCast, true, svalue);
135
t.runTest(methodClassCastint, false, svalue);
136
t.runTest(methodintClassCast, false, svalue);
137
t.runTest(methodClassCastPrim, false, svalue);
138
t.runTest(methodPrimClassCast, true, svalue);
139
t.runTest(methodVarClassCast, true, objClass);
140
}
141
142
void testClassCast(String s) {
143
try {
144
ssink = String.class.cast(s);
145
} catch (Throwable t) {
146
throw new Error(t);
147
}
148
}
149
150
void testClassCastNull(String s) {
151
try {
152
ssink = String.class.cast(null);
153
} catch (Throwable t) {
154
throw new Error(t);
155
}
156
}
157
158
void testNullClassCast(String s) {
159
try {
160
ssink = (String)nullClass.cast(s);
161
throw new AssertionError("NullPointerException is not thrown");
162
} catch (NullPointerException t) {
163
// Ignore NullPointerException
164
} catch (Throwable t) {
165
throw new Error(t);
166
}
167
}
168
169
void testClassCastObj(Object s) {
170
try {
171
ssink = String.class.cast(s);
172
} catch (Throwable t) {
173
throw new Error(t);
174
}
175
}
176
177
void testObjClassCast(String s) {
178
try {
179
ssink = (String)objClass.cast(s);
180
} catch (Throwable t) {
181
throw new Error(t);
182
}
183
}
184
185
void testVarClassCast(Class cl) {
186
try {
187
ssink = (String)cl.cast(svalue);
188
if (cl == null) {
189
throw new AssertionError("NullPointerException is not thrown");
190
}
191
} catch (NullPointerException t) {
192
// Ignore NullPointerException
193
} catch (Throwable t) {
194
throw new Error(t);
195
}
196
}
197
198
void testClassCastInt(Object s) {
199
try {
200
ssink = String.class.cast(iobj);
201
throw new AssertionError("ClassCastException is not thrown");
202
} catch (ClassCastException t) {
203
// Ignore ClassCastException: Cannot cast java.lang.Integer to java.lang.String
204
} catch (Throwable t) {
205
throw new Error(t);
206
}
207
}
208
209
void testIntClassCast(Object s) {
210
try {
211
isink = Integer.class.cast(s);
212
if (s != null) {
213
throw new AssertionError("ClassCastException is not thrown");
214
}
215
} catch (ClassCastException t) {
216
// Ignore ClassCastException: Cannot cast java.lang.String to java.lang.Integer
217
} catch (Throwable t) {
218
throw new Error(t);
219
}
220
}
221
222
void testClassCastint(Object s) {
223
try {
224
ssink = String.class.cast(45);
225
throw new AssertionError("ClassCastException is not thrown");
226
} catch (ClassCastException t) {
227
// Ignore ClassCastException: Cannot cast java.lang.Integer to java.lang.String
228
} catch (Throwable t) {
229
throw new Error(t);
230
}
231
}
232
233
void testintClassCast(Object s) {
234
try {
235
isink = int.class.cast(s);
236
if (s != null) {
237
throw new AssertionError("ClassCastException is not thrown");
238
}
239
} catch (ClassCastException t) {
240
// Ignore ClassCastException: Cannot cast java.lang.String to java.lang.Integer
241
} catch (Throwable t) {
242
throw new Error(t);
243
}
244
}
245
246
void testClassCastPrim(Object s) {
247
try {
248
ssink = String.class.cast(arr);
249
throw new AssertionError("ClassCastException is not thrown");
250
} catch (ClassCastException t) {
251
// Ignore ClassCastException: Cannot cast [I to java.lang.String
252
} catch (Throwable t) {
253
throw new Error(t);
254
}
255
}
256
257
void testPrimClassCast(Object s) {
258
try {
259
asink = int[].class.cast(s);
260
if (s != null) {
261
throw new AssertionError("ClassCastException is not thrown");
262
}
263
} catch (ClassCastException t) {
264
// Ignore ClassCastException: Cannot cast java.lang.String to [I
265
} catch (Throwable t) {
266
throw new Error(t);
267
}
268
}
269
270
void testMHCast(String s) {
271
try {
272
ssink = (String) (Object) MH_CAST.invokeExact(String.class, (Object) s);
273
} catch (Throwable t) {
274
throw new Error(t);
275
}
276
}
277
278
void testMHSetter(String s) {
279
try {
280
SET_SSINK.invokeExact(this, s);
281
} catch (Throwable t) {
282
throw new Error(t);
283
}
284
}
285
286
void testFunction(String s) {
287
try {
288
ssink = (String) fCast.apply(String.class, s);
289
} catch (Throwable t) {
290
throw new Error(t);
291
}
292
}
293
294
void runTest(Method method, boolean deopt, Object value) {
295
if (method == null) {
296
throw new AssertionError("method was not found");
297
}
298
// Ensure method is compiled
299
WHITE_BOX.testSetDontInlineMethod(method, true);
300
Recording recording = new Recording();
301
recording.enable(EventNames.Deoptimization);
302
recording.start();
303
304
for (int i = 0; i < 3000; i++) {
305
try {
306
method.invoke(this, value);
307
} catch (Exception e) {
308
throw new Error("Unexpected exception: ", e);
309
}
310
}
311
NMethod nm = getNMethod(method);
312
313
// Passing null should cause a de-optimization
314
// if method is compiled with a null-check.
315
try {
316
method.invoke(this, onull);
317
} catch (Exception e) {
318
throw new Error("Unexpected exception: ", e);
319
}
320
recording.stop();
321
List<RecordedEvent> events;
322
try {
323
events = Events.fromRecording(recording);
324
} catch (IOException e) {
325
throw new Error("failed to read jfr events", e);
326
}
327
328
checkDeoptimization(events, nm.compile_id, deopt);
329
330
if (!deopt) {
331
checkNoRecompilation(method, nm);
332
}
333
}
334
335
static NMethod getNMethod(Method test) {
336
// Because background compilation is disabled, method should now be compiled
337
if (!WHITE_BOX.isMethodCompiled(test)) {
338
throw new AssertionError(test + " not compiled");
339
}
340
341
NMethod nm = NMethod.get(test, false); // not OSR nmethod
342
if (nm == null) {
343
throw new AssertionError(test + " missing nmethod?");
344
}
345
if (nm.comp_level != 4) {
346
throw new AssertionError(test + " compiled by not C2: " + nm);
347
}
348
return nm;
349
}
350
351
static void checkDeoptimization(List<RecordedEvent> events, int compilerId, boolean mustExist) {
352
boolean exist = events.stream()
353
.filter(e -> e.getEventType().getName().equals(EventNames.Deoptimization))
354
.anyMatch(e -> compilerId == Events.assertField(e, "compileId").<Integer>getValue());
355
356
if (exist != mustExist) {
357
System.err.println("events:");
358
System.err.println(events);
359
throw new AssertionError("compilation must " + (mustExist ? "" : " not ") + " got deoptimized");
360
}
361
362
if (mustExist && events.stream()
363
.filter(e -> e.getEventType().getName().equals(EventNames.Deoptimization))
364
.filter(e -> compilerId == Events.assertField(e, "compileId").<Integer>getValue())
365
.noneMatch(e -> "null_check".equals(Events.assertField(e, "reason").getValue()))) {
366
System.err.println("events:");
367
System.err.println(events);
368
throw new AssertionError("no deoptimizations due to null_check found");
369
}
370
371
}
372
373
static void checkNoRecompilation(Method method, NMethod nmOrig) {
374
NMethod nm = NMethod.get(method, false); // not OSR nmethod
375
if (nm == null) {
376
throw new AssertionError(method + " missing nmethod?");
377
}
378
if (nm.comp_level != 4) {
379
throw new AssertionError(method + " compiled by not C2: " + nm);
380
}
381
if (nm.compile_id != nmOrig.compile_id) {
382
throw new AssertionError(method + " was recompiled: old nmethod=" + nmOrig + ", new nmethod=" + nm);
383
}
384
}
385
}
386
387