test/compiler/types/TypeSpeculation.java

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
equal deleted inserted replaced
-1:000000000000 0:f90c822e73f8
1 /*
2 * Copyright (c) 2013, 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
26 * @bug 8024070
27 * @summary Test that type speculation doesn't cause incorrect execution
28 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation TypeSpeculation
29 *
30 */
31
32 public class TypeSpeculation {
33
34 interface I {
35 }
36
37 static class A {
38 int m() {
39 return 1;
40 }
41 }
42
43 static class B extends A implements I {
44 int m() {
45 return 2;
46 }
47 }
48
49 static class C extends B {
50 int m() {
51 return 3;
52 }
53 }
54
55 static int test1_invokevirtual(A a) {
56 return a.m();
57 }
58
59 static int test1_1(A a) {
60 return test1_invokevirtual(a);
61 }
62
63 static boolean test1() {
64 A a = new A();
65 B b = new B();
66 C c = new C();
67
68 // pollute profile at test1_invokevirtual to make sure the
69 // compiler cannot rely on it
70 for (int i = 0; i < 5000; i++) {
71 test1_invokevirtual(a);
72 test1_invokevirtual(b);
73 test1_invokevirtual(c);
74 }
75
76 // profiling + speculation should make test1_invokevirtual
77 // inline A.m() with a guard
78 for (int i = 0; i < 20000; i++) {
79 int res = test1_1(b);
80 if (res != b.m()) {
81 System.out.println("test1 failed with class B");
82 return false;
83 }
84 }
85 // check that the guard works as expected by passing a
86 // different type
87 int res = test1_1(a);
88 if (res != a.m()) {
89 System.out.println("test1 failed with class A");
90 return false;
91 }
92 return true;
93 }
94
95 static int test2_invokevirtual(A a) {
96 return a.m();
97 }
98
99 static int test2_1(A a, boolean t) {
100 A aa;
101 if (t) {
102 aa = (B)a;
103 } else {
104 aa = a;
105 }
106 // if a of type B is passed to test2_1, the static type of aa
107 // here is no better than A but the profiled type is B so this
108 // should inline
109 return test2_invokevirtual(aa);
110 }
111
112 static boolean test2() {
113 A a = new A();
114 B b = new B();
115 C c = new C();
116
117 // pollute profile at test2_invokevirtual to make sure the
118 // compiler cannot rely on it
119 for (int i = 0; i < 5000; i++) {
120 test2_invokevirtual(a);
121 test2_invokevirtual(b);
122 test2_invokevirtual(c);
123 }
124
125 // profiling + speculation should make test2_invokevirtual
126 // inline A.m() with a guard
127 for (int i = 0; i < 20000; i++) {
128 int res = test2_1(b, (i % 2) == 0);
129 if (res != b.m()) {
130 System.out.println("test2 failed with class B");
131 return false;
132 }
133 }
134 // check that the guard works as expected by passing a
135 // different type
136 int res = test2_1(a, false);
137 if (res != a.m()) {
138 System.out.println("test2 failed with class A");
139 return false;
140 }
141 return true;
142 }
143
144 static int test3_invokevirtual(A a) {
145 return a.m();
146 }
147
148 static void test3_2(A a) {
149 }
150
151 static int test3_1(A a, int i) {
152 if (i == 0) {
153 return 0;
154 }
155 // If we come here and a is of type B but parameter profiling
156 // is polluted, both branches of the if below should have
157 // profiling that tell us and inlining of the virtual call
158 // should happen
159 if (i == 1) {
160 test3_2(a);
161 } else {
162 test3_2(a);
163 }
164 return test3_invokevirtual(a);
165 }
166
167 static boolean test3() {
168 A a = new A();
169 B b = new B();
170 C c = new C();
171
172 // pollute profile at test3_invokevirtual and test3_1 to make
173 // sure the compiler cannot rely on it
174 for (int i = 0; i < 3000; i++) {
175 test3_invokevirtual(a);
176 test3_invokevirtual(b);
177 test3_invokevirtual(c);
178 test3_1(a, 0);
179 test3_1(b, 0);
180 }
181
182 // profiling + speculation should make test3_invokevirtual
183 // inline A.m() with a guard
184 for (int i = 0; i < 20000; i++) {
185 int res = test3_1(b, (i % 2) + 1);
186 if (res != b.m()) {
187 System.out.println("test3 failed with class B");
188 return false;
189 }
190 }
191 // check that the guard works as expected by passing a
192 // different type
193 int res = test3_1(a, 1);
194 if (res != a.m()) {
195 System.out.println("test3 failed with class A");
196 return false;
197 }
198 return true;
199 }
200
201 // Mix 2 incompatible profiled types
202 static int test4_invokevirtual(A a) {
203 return a.m();
204 }
205
206 static void test4_2(A a) {
207 }
208
209 static int test4_1(A a, boolean b) {
210 if (b) {
211 test4_2(a);
212 } else {
213 test4_2(a);
214 }
215 // shouldn't inline
216 return test4_invokevirtual(a);
217 }
218
219 static boolean test4() {
220 A a = new A();
221 B b = new B();
222 C c = new C();
223
224 // pollute profile at test3_invokevirtual and test3_1 to make
225 // sure the compiler cannot rely on it
226 for (int i = 0; i < 3000; i++) {
227 test4_invokevirtual(a);
228 test4_invokevirtual(b);
229 test4_invokevirtual(c);
230 }
231
232 for (int i = 0; i < 20000; i++) {
233 if ((i % 2) == 0) {
234 int res = test4_1(a, true);
235 if (res != a.m()) {
236 System.out.println("test4 failed with class A");
237 return false;
238 }
239 } else {
240 int res = test4_1(b, false);
241 if (res != b.m()) {
242 System.out.println("test4 failed with class B");
243 return false;
244 }
245 }
246 }
247 return true;
248 }
249
250 // Mix one profiled type with an incompatible type
251 static int test5_invokevirtual(A a) {
252 return a.m();
253 }
254
255 static void test5_2(A a) {
256 }
257
258 static int test5_1(A a, boolean b) {
259 if (b) {
260 test5_2(a);
261 } else {
262 A aa = (B)a;
263 }
264 // shouldn't inline
265 return test5_invokevirtual(a);
266 }
267
268 static boolean test5() {
269 A a = new A();
270 B b = new B();
271 C c = new C();
272
273 // pollute profile at test3_invokevirtual and test3_1 to make
274 // sure the compiler cannot rely on it
275 for (int i = 0; i < 3000; i++) {
276 test5_invokevirtual(a);
277 test5_invokevirtual(b);
278 test5_invokevirtual(c);
279 }
280
281 for (int i = 0; i < 20000; i++) {
282 if ((i % 2) == 0) {
283 int res = test5_1(a, true);
284 if (res != a.m()) {
285 System.out.println("test5 failed with class A");
286 return false;
287 }
288 } else {
289 int res = test5_1(b, false);
290 if (res != b.m()) {
291 System.out.println("test5 failed with class B");
292 return false;
293 }
294 }
295 }
296 return true;
297 }
298
299 // Mix incompatible profiled types
300 static void test6_2(Object o) {
301 }
302
303 static Object test6_1(Object o, boolean b) {
304 if (b) {
305 test6_2(o);
306 } else {
307 test6_2(o);
308 }
309 return o;
310 }
311
312 static boolean test6() {
313 A a = new A();
314 A[] aa = new A[10];
315
316 for (int i = 0; i < 20000; i++) {
317 if ((i % 2) == 0) {
318 test6_1(a, true);
319 } else {
320 test6_1(aa, false);
321 }
322 }
323 return true;
324 }
325
326 // Mix a profiled type with an incompatible type
327 static void test7_2(Object o) {
328 }
329
330 static Object test7_1(Object o, boolean b) {
331 if (b) {
332 test7_2(o);
333 } else {
334 Object oo = (A[])o;
335 }
336 return o;
337 }
338
339 static boolean test7() {
340 A a = new A();
341 A[] aa = new A[10];
342
343 for (int i = 0; i < 20000; i++) {
344 if ((i % 2) == 0) {
345 test7_1(a, true);
346 } else {
347 test7_1(aa, false);
348 }
349 }
350 return true;
351 }
352
353 // Mix a profiled type with an interface
354 static void test8_2(Object o) {
355 }
356
357 static I test8_1(Object o) {
358 test8_2(o);
359 return (I)o;
360 }
361
362 static boolean test8() {
363 A a = new A();
364 B b = new B();
365 C c = new C();
366
367 for (int i = 0; i < 20000; i++) {
368 test8_1(b);
369 }
370 return true;
371 }
372
373 // Mix a profiled type with a constant
374 static void test9_2(Object o) {
375 }
376
377 static Object test9_1(Object o, boolean b) {
378 Object oo;
379 if (b) {
380 test9_2(o);
381 oo = o;
382 } else {
383 oo = "some string";
384 }
385 return oo;
386 }
387
388 static boolean test9() {
389 A a = new A();
390
391 for (int i = 0; i < 20000; i++) {
392 if ((i % 2) == 0) {
393 test9_1(a, true);
394 } else {
395 test9_1(a, false);
396 }
397 }
398 return true;
399 }
400
401 // java/lang/Object:AnyNull:exact *,iid=top
402 // meets
403 // stable:bottom[int:max..0]:NotNull *
404 static void test10_4(Object o) {
405 }
406
407 static void test10_3(Object o, boolean b) {
408 if (b) {
409 test10_4(o);
410 }
411 }
412
413 static void test10_2(Object o, boolean b1, boolean b2) {
414 if (b1) {
415 test10_3(o, b2);
416 }
417 }
418
419 static void test10_1(B[] b, boolean b1, boolean b2) {
420 test10_2(b, b1, b2);
421 }
422
423 static boolean test10() {
424 Object o = new Object();
425 A[] a = new A[10];
426 B[] b = new B[10];
427 B[] c = new C[10];
428 for (int i = 0; i < 20000; i++) {
429 test10_1(b, false, false);
430 test10_1(c, false, false);
431 test10_2(a, true, false);
432 test10_3(o, true);
433 }
434 return true;
435 }
436
437 // stable:TypeSpeculation$B:TopPTR *,iid=top[int:max..0]:TopPTR *,iid=top
438 // meets
439 // java/lang/Object:AnyNull:exact *,iid=top
440 static void test11_3(Object o) {
441 }
442
443 static void test11_2(Object o, boolean b) {
444 if (b) {
445 test11_3(o);
446 }
447 }
448
449 static void test11_1(B[] b, boolean bb) {
450 test11_2(b, bb);
451 }
452
453 static boolean test11() {
454 Object o = new Object();
455 B[] b = new B[10];
456 B[] c = new C[10];
457 for (int i = 0; i < 20000; i++) {
458 test11_1(b, false);
459 test11_1(c, false);
460 test11_2(o, true);
461 }
462 return true;
463 }
464
465 // TypeSpeculation$I *
466 // meets
467 // java/lang/Object:AnyNull *,iid=top
468 static void test12_3(Object o) {
469 }
470
471 static void test12_2(Object o, boolean b) {
472 if (b) {
473 test12_3(o);
474 }
475 }
476
477 static void test12_1(I i, boolean b) {
478 test12_2(i, b);
479 }
480
481 static boolean test12() {
482 Object o = new Object();
483 B b = new B();
484 C c = new C();
485 for (int i = 0; i < 20000; i++) {
486 test12_1(b, false);
487 test12_1(c, false);
488 test12_2(o, true);
489 }
490 return true;
491 }
492
493 // stable:bottom[int:max..0]:NotNull *
494 // meets
495 // stable:TypeSpeculation$A:TopPTR *,iid=top[int:max..0]:AnyNull:exact *,iid=top
496 static Object test13_3(Object o, boolean b) {
497 Object oo;
498 if (b) {
499 oo = o;
500 } else {
501 oo = new A[10];
502 }
503 return oo;
504 }
505
506 static void test13_2(Object o, boolean b1, boolean b2) {
507 if (b1) {
508 test13_3(o, b2);
509 }
510 }
511
512 static void test13_1(B[] b, boolean b1, boolean b2) {
513 test13_2(b, b1, b2);
514 }
515
516 static boolean test13() {
517 A[] a = new A[10];
518 B[] b = new B[10];
519 B[] c = new C[10];
520 for (int i = 0; i < 20000; i++) {
521 test13_1(b, false, false);
522 test13_1(c, false, false);
523 test13_2(a, true, (i%2) == 0);
524 }
525 return true;
526 }
527
528 static public void main(String[] args) {
529 boolean success = true;
530
531 success = test1() && success;
532
533 success = test2() && success;
534
535 success = test3() && success;
536
537 success = test4() && success;
538
539 success = test5() && success;
540
541 success = test6() && success;
542
543 success = test7() && success;
544
545 success = test8() && success;
546
547 success = test9() && success;
548
549 success = test10() && success;
550
551 success = test11() && success;
552
553 success = test12() && success;
554
555 success = test13() && success;
556
557 if (success) {
558 System.out.println("TEST PASSED");
559 } else {
560 throw new RuntimeException("TEST FAILED: erroneous bound check elimination");
561 }
562 }
563 }

mercurial