52 /** Maximal value for CompLevel */ 53 protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; 54 55 /** Instance of WhiteBox */ 56 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 57 /** Value of {@code -XX:CompileThreshold} */ 58 protected static final int COMPILE_THRESHOLD 59 = Integer.parseInt(getVMOption("CompileThreshold", "10000")); 60 /** Value of {@code -XX:BackgroundCompilation} */ 61 protected static final boolean BACKGROUND_COMPILATION 62 = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); 63 /** Value of {@code -XX:TieredCompilation} */ 64 protected static final boolean TIERED_COMPILATION 65 = Boolean.valueOf(getVMOption("TieredCompilation", "false")); 66 /** Value of {@code -XX:TieredStopAtLevel} */ 67 protected static final int TIERED_STOP_AT_LEVEL 68 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); 69 /** Flag for verbose output, true if {@code -Dverbose} specified */ 70 protected static final boolean IS_VERBOSE 71 = System.getProperty("verbose") != null; 72 /** count of invocation to triger compilation */ 73 protected static final int THRESHOLD; 74 /** count of invocation to triger OSR compilation */ 75 protected static final long BACKEDGE_THRESHOLD; 76 /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ 77 protected static final String MODE = System.getProperty("java.vm.info"); 78 79 static { 80 if (TIERED_COMPILATION) { 81 BACKEDGE_THRESHOLD = THRESHOLD = 150000; 82 } else { 83 THRESHOLD = COMPILE_THRESHOLD; 84 BACKEDGE_THRESHOLD = COMPILE_THRESHOLD * Long.parseLong(getVMOption( 85 "OnStackReplacePercentage")); 86 } 87 } 88 89 /** 90 * Returns value of VM option. 91 * 92 * @param name option's name 93 * @return value of option or {@code null}, if option doesn't exist 94 * @throws NullPointerException if name is null 95 */ 199 protected final void checkNotCompiled(int compLevel) { 200 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 201 throw new RuntimeException(method + " must not be in queue"); 202 } 203 if (WHITE_BOX.getMethodCompilationLevel(method, false) >= compLevel) { 204 throw new RuntimeException(method + " comp_level must be >= maxCompLevel"); 205 } 206 if (WHITE_BOX.getMethodCompilationLevel(method, true) >= compLevel) { 207 throw new RuntimeException(method + " osr_comp_level must be >= maxCompLevel"); 208 } 209 } 210 211 /** 212 * Checks, that {@linkplain #method} is not compiled. 213 * 214 * @throws RuntimeException if {@linkplain #method} is in compiler queue or 215 * is compiled, or if {@linkplain #method} has zero 216 * compilation level. 217 */ 218 protected final void checkNotCompiled() { 219 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 220 throw new RuntimeException(method + " must not be in queue"); 221 } 222 if (WHITE_BOX.isMethodCompiled(method, false)) { 223 throw new RuntimeException(method + " must be not compiled"); 224 } 225 if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) { 226 throw new RuntimeException(method + " comp_level must be == 0"); 227 } 228 if (WHITE_BOX.isMethodCompiled(method, true)) { 229 throw new RuntimeException(method + " must be not osr_compiled"); 230 } 231 if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { 232 throw new RuntimeException(method + " osr_comp_level must be == 0"); 233 } 234 } 235 236 /** 237 * Checks, that {@linkplain #method} is compiled. 238 * 239 * @throws RuntimeException if {@linkplain #method} isn't in compiler queue 240 * and isn't compiled, or if {@linkplain #method} 241 * has nonzero compilation level 242 */ 243 protected final void checkCompiled() { 244 final long start = System.currentTimeMillis(); 245 waitBackgroundCompilation(); 246 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 247 System.err.printf("Warning: %s is still in queue after %dms%n", 397 398 /** 399 * @return {@code true} if the current test case is OSR and the mode is 400 * Xcomp, otherwise {@code false} 401 */ 402 protected boolean skipXcompOSR() { 403 boolean result = testCase.isOsr() 404 && CompilerWhiteBoxTest.MODE.startsWith("compiled "); 405 if (result && IS_VERBOSE) { 406 System.err.printf("Warning: %s is not applicable in %s%n", 407 testCase.name(), CompilerWhiteBoxTest.MODE); 408 } 409 return result; 410 } 411 } 412 413 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { 414 /** constructor test case */ 415 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), 416 /** method test case */ 417 METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), 418 /** static method test case */ 419 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), 420 /** OSR constructor test case */ 421 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, 422 Helper.OSR_CONSTRUCTOR_CALLABLE, true), 423 /** OSR method test case */ 424 OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), 425 /** OSR static method test case */ 426 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); 427 428 private final Executable executable; 429 private final Callable<Integer> callable; 430 private final boolean isOsr; 431 432 private SimpleTestCase(Executable executable, Callable<Integer> callable, 433 boolean isOsr) { 434 this.executable = executable; 435 this.callable = callable; 436 this.isOsr = isOsr; 437 } 438 439 @Override 440 public Executable getExecutable() { 441 return executable; 442 } 443 444 @Override 466 private final Helper helper = new Helper(); 467 468 @Override 469 public Integer call() throws Exception { 470 return helper.method(); 471 } 472 }; 473 474 private static final Callable<Integer> STATIC_CALLABLE 475 = new Callable<Integer>() { 476 @Override 477 public Integer call() throws Exception { 478 return staticMethod(); 479 } 480 }; 481 482 private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE 483 = new Callable<Integer>() { 484 @Override 485 public Integer call() throws Exception { 486 return new Helper(null).hashCode(); 487 } 488 }; 489 490 private static final Callable<Integer> OSR_METHOD_CALLABLE 491 = new Callable<Integer>() { 492 private final Helper helper = new Helper(); 493 494 @Override 495 public Integer call() throws Exception { 496 return helper.osrMethod(); 497 } 498 }; 499 500 private static final Callable<Integer> OSR_STATIC_CALLABLE 501 = new Callable<Integer>() { 502 @Override 503 public Integer call() throws Exception { 504 return osrStaticMethod(); 505 } 506 }; 507 508 private static final Constructor CONSTRUCTOR; 509 private static final Constructor OSR_CONSTRUCTOR; 510 private static final Method METHOD; 511 private static final Method STATIC; 512 private static final Method OSR_METHOD; 513 private static final Method OSR_STATIC; 514 515 static { 516 try { 517 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class); 518 } catch (NoSuchMethodException | SecurityException e) { 519 throw new RuntimeException( 520 "exception on getting method Helper.<init>(int)", e); 521 } 522 try { 523 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( 524 Object.class); 525 } catch (NoSuchMethodException | SecurityException e) { 526 throw new RuntimeException( 527 "exception on getting method Helper.<init>(Object)", e); 528 } 529 METHOD = getMethod("method"); 530 STATIC = getMethod("staticMethod"); 531 OSR_METHOD = getMethod("osrMethod"); 532 OSR_STATIC = getMethod("osrStaticMethod"); 533 } 534 535 private static Method getMethod(String name) { 536 try { 537 return Helper.class.getDeclaredMethod(name); 538 } catch (NoSuchMethodException | SecurityException e) { 539 throw new RuntimeException( 540 "exception on getting method Helper." + name, e); 541 } 542 543 } 544 545 private static int staticMethod() { 546 return 1138; 547 } 548 549 private int method() { 550 return 42; 551 } 552 553 private static int osrStaticMethod() { 554 int result = 0; 555 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { 556 result += staticMethod(); 557 } 558 return result; 559 } 560 561 private int osrMethod() { 562 int result = 0; 563 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { 564 result += method(); 565 } 566 return result; 567 } 568 569 private final int x; 570 571 // for method and OSR method test case 572 public Helper() { 573 x = 0; 574 } 575 576 // for OSR constructor test case 577 private Helper(Object o) { 578 int result = 0; 579 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { 580 result += method(); 581 } 582 x = result; 583 } 584 585 // for constructor test case 586 private Helper(int x) { 587 this.x = x; 588 } 589 590 @Override 591 public int hashCode() { 592 return x; 593 } 594 } 595 } | 52 /** Maximal value for CompLevel */ 53 protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; 54 55 /** Instance of WhiteBox */ 56 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 57 /** Value of {@code -XX:CompileThreshold} */ 58 protected static final int COMPILE_THRESHOLD 59 = Integer.parseInt(getVMOption("CompileThreshold", "10000")); 60 /** Value of {@code -XX:BackgroundCompilation} */ 61 protected static final boolean BACKGROUND_COMPILATION 62 = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); 63 /** Value of {@code -XX:TieredCompilation} */ 64 protected static final boolean TIERED_COMPILATION 65 = Boolean.valueOf(getVMOption("TieredCompilation", "false")); 66 /** Value of {@code -XX:TieredStopAtLevel} */ 67 protected static final int TIERED_STOP_AT_LEVEL 68 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); 69 /** Flag for verbose output, true if {@code -Dverbose} specified */ 70 protected static final boolean IS_VERBOSE 71 = System.getProperty("verbose") != null; 72 /** invocation count to trigger compilation */ 73 protected static final int THRESHOLD; 74 /** invocation count to trigger OSR compilation */ 75 protected static final long BACKEDGE_THRESHOLD; 76 /** invocation count to warm up method before triggering OSR compilation */ 77 protected static final long OSR_WARMUP = 2000; 78 /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ 79 protected static final String MODE = System.getProperty("java.vm.info"); 80 81 static { 82 if (TIERED_COMPILATION) { 83 BACKEDGE_THRESHOLD = THRESHOLD = 150000; 84 } else { 85 THRESHOLD = COMPILE_THRESHOLD; 86 BACKEDGE_THRESHOLD = COMPILE_THRESHOLD * Long.parseLong(getVMOption( 87 "OnStackReplacePercentage")); 88 } 89 } 90 91 /** 92 * Returns value of VM option. 93 * 94 * @param name option's name 95 * @return value of option or {@code null}, if option doesn't exist 96 * @throws NullPointerException if name is null 97 */ 201 protected final void checkNotCompiled(int compLevel) { 202 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 203 throw new RuntimeException(method + " must not be in queue"); 204 } 205 if (WHITE_BOX.getMethodCompilationLevel(method, false) >= compLevel) { 206 throw new RuntimeException(method + " comp_level must be >= maxCompLevel"); 207 } 208 if (WHITE_BOX.getMethodCompilationLevel(method, true) >= compLevel) { 209 throw new RuntimeException(method + " osr_comp_level must be >= maxCompLevel"); 210 } 211 } 212 213 /** 214 * Checks, that {@linkplain #method} is not compiled. 215 * 216 * @throws RuntimeException if {@linkplain #method} is in compiler queue or 217 * is compiled, or if {@linkplain #method} has zero 218 * compilation level. 219 */ 220 protected final void checkNotCompiled() { 221 if (WHITE_BOX.isMethodCompiled(method, false)) { 222 throw new RuntimeException(method + " must be not compiled"); 223 } 224 if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) { 225 throw new RuntimeException(method + " comp_level must be == 0"); 226 } 227 checkNotOsrCompiled(); 228 } 229 230 protected final void checkNotOsrCompiled() { 231 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 232 throw new RuntimeException(method + " must not be in queue"); 233 } 234 if (WHITE_BOX.isMethodCompiled(method, true)) { 235 throw new RuntimeException(method + " must be not osr_compiled"); 236 } 237 if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { 238 throw new RuntimeException(method + " osr_comp_level must be == 0"); 239 } 240 } 241 242 /** 243 * Checks, that {@linkplain #method} is compiled. 244 * 245 * @throws RuntimeException if {@linkplain #method} isn't in compiler queue 246 * and isn't compiled, or if {@linkplain #method} 247 * has nonzero compilation level 248 */ 249 protected final void checkCompiled() { 250 final long start = System.currentTimeMillis(); 251 waitBackgroundCompilation(); 252 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 253 System.err.printf("Warning: %s is still in queue after %dms%n", 403 404 /** 405 * @return {@code true} if the current test case is OSR and the mode is 406 * Xcomp, otherwise {@code false} 407 */ 408 protected boolean skipXcompOSR() { 409 boolean result = testCase.isOsr() 410 && CompilerWhiteBoxTest.MODE.startsWith("compiled "); 411 if (result && IS_VERBOSE) { 412 System.err.printf("Warning: %s is not applicable in %s%n", 413 testCase.name(), CompilerWhiteBoxTest.MODE); 414 } 415 return result; 416 } 417 } 418 419 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { 420 /** constructor test case */ 421 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), 422 /** method test case */ 423 METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), 424 /** static method test case */ 425 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), 426 /** OSR constructor test case */ 427 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, 428 Helper.OSR_CONSTRUCTOR_CALLABLE, true), 429 /** OSR method test case */ 430 OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), 431 /** OSR static method test case */ 432 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); 433 434 private final Executable executable; 435 private final Callable<Integer> callable; 436 private final boolean isOsr; 437 438 private SimpleTestCase(Executable executable, Callable<Integer> callable, 439 boolean isOsr) { 440 this.executable = executable; 441 this.callable = callable; 442 this.isOsr = isOsr; 443 } 444 445 @Override 446 public Executable getExecutable() { 447 return executable; 448 } 449 450 @Override 472 private final Helper helper = new Helper(); 473 474 @Override 475 public Integer call() throws Exception { 476 return helper.method(); 477 } 478 }; 479 480 private static final Callable<Integer> STATIC_CALLABLE 481 = new Callable<Integer>() { 482 @Override 483 public Integer call() throws Exception { 484 return staticMethod(); 485 } 486 }; 487 488 private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE 489 = new Callable<Integer>() { 490 @Override 491 public Integer call() throws Exception { 492 int result = warmup(OSR_CONSTRUCTOR); 493 return result + new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode(); 494 } 495 }; 496 497 private static final Callable<Integer> OSR_METHOD_CALLABLE 498 = new Callable<Integer>() { 499 private final Helper helper = new Helper(); 500 501 @Override 502 public Integer call() throws Exception { 503 int result = warmup(OSR_METHOD); 504 return result + helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); 505 } 506 }; 507 508 private static final Callable<Integer> OSR_STATIC_CALLABLE 509 = new Callable<Integer>() { 510 @Override 511 public Integer call() throws Exception { 512 int result = warmup(OSR_STATIC); 513 return result + osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); 514 } 515 }; 516 517 /** 518 * Deoptimizes the given executable after compilation finished. 519 * 520 * @param e Executable 521 * @throws Exception 522 */ 523 private static void deoptimize(Executable e) throws Exception { 524 if (CompilerWhiteBoxTest.BACKGROUND_COMPILATION) { 525 // Wait for background compilation 526 for (int i = 0; i < 10 && WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e); ++i) { 527 Thread.sleep(1000); 528 } 529 } 530 if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) { 531 throw new RuntimeException(e + " must not be in queue"); 532 } 533 WhiteBox.getWhiteBox().deoptimizeMethod(e, false); 534 } 535 536 /** 537 * Executes the method multiple times to make sure we have 538 * enough profiling information before triggering an OSR 539 * compilation. Otherwise the C2 compiler may add uncommon traps. 540 * 541 * @param m Method to be executed 542 * @return Number of times the method was executed 543 * @throws Exception 544 */ 545 private static int warmup(Method m) throws Exception { 546 Helper helper = new Helper(); 547 int result = 0; 548 for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) { 549 result += (int)m.invoke(helper, 1); 550 } 551 // Make sure method is not (yet) compiled 552 deoptimize(m); 553 return result; 554 } 555 556 /** 557 * Executes the constructor multiple times to make sure we 558 * have enough profiling information before triggering an OSR 559 * compilation. Otherwise the C2 compiler may add uncommon traps. 560 * 561 * @param c Constructor to be executed 562 * @return Number of times the constructor was executed 563 * @throws Exception 564 */ 565 private static int warmup(Constructor c) throws Exception { 566 int result = 0; 567 for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) { 568 result += c.newInstance(null, 1).hashCode(); 569 } 570 // Make sure method is not (yet) compiled 571 deoptimize(c); 572 return result; 573 } 574 575 private static final Constructor CONSTRUCTOR; 576 private static final Constructor OSR_CONSTRUCTOR; 577 private static final Method METHOD; 578 private static final Method STATIC; 579 private static final Method OSR_METHOD; 580 private static final Method OSR_STATIC; 581 582 static { 583 try { 584 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class); 585 } catch (NoSuchMethodException | SecurityException e) { 586 throw new RuntimeException( 587 "exception on getting method Helper.<init>(int)", e); 588 } 589 try { 590 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( 591 Object.class, long.class); 592 } catch (NoSuchMethodException | SecurityException e) { 593 throw new RuntimeException( 594 "exception on getting method Helper.<init>(Object, long)", e); 595 } 596 METHOD = getMethod("method"); 597 STATIC = getMethod("staticMethod"); 598 OSR_METHOD = getMethod("osrMethod", long.class); 599 OSR_STATIC = getMethod("osrStaticMethod", long.class); 600 } 601 602 private static Method getMethod(String name, Class<?>... parameterTypes) { 603 try { 604 return Helper.class.getDeclaredMethod(name, parameterTypes); 605 } catch (NoSuchMethodException | SecurityException e) { 606 throw new RuntimeException( 607 "exception on getting method Helper." + name, e); 608 } 609 } 610 611 private static int staticMethod() { 612 return 1138; 613 } 614 615 private int method() { 616 return 42; 617 } 618 619 private static int osrStaticMethod(long limit) { 620 int result = 0; 621 for (long i = 0; i < limit; ++i) { 622 result += staticMethod(); 623 } 624 return result; 625 } 626 627 private int osrMethod(long limit) { 628 int result = 0; 629 for (long i = 0; i < limit; ++i) { 630 result += method(); 631 } 632 return result; 633 } 634 635 private final int x; 636 637 // for method and OSR method test case 638 public Helper() { 639 x = 0; 640 } 641 642 // for OSR constructor test case 643 private Helper(Object o, long limit) { 644 int result = 0; 645 for (long i = 0; i < limit; ++i) { 646 result += method(); 647 } 648 x = result; 649 } 650 651 // for constructor test case 652 private Helper(int x) { 653 this.x = x; 654 } 655 656 @Override 657 public int hashCode() { 658 return x; 659 } 660 } 661 } |