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 }