test/compiler/types/TypeSpeculation.java

Tue, 07 Jan 2014 12:38:22 +0100

author
roland
date
Tue, 07 Jan 2014 12:38:22 +0100
changeset 6212
29463147336b
parent 5991
b2ee5dc63353
child 6384
8f28240318a2
permissions
-rw-r--r--

8028536: Test cases to cover type system fixes pushed with 8024070
Summary: extra test cases for type speculation
Reviewed-by: kvn

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

mercurial