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