67 protected static final int TIERED_STOP_AT_LEVEL |
67 protected static final int TIERED_STOP_AT_LEVEL |
68 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); |
68 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); |
69 /** Flag for verbose output, true if {@code -Dverbose} specified */ |
69 /** Flag for verbose output, true if {@code -Dverbose} specified */ |
70 protected static final boolean IS_VERBOSE |
70 protected static final boolean IS_VERBOSE |
71 = System.getProperty("verbose") != null; |
71 = System.getProperty("verbose") != null; |
72 /** count of invocation to triger compilation */ |
72 /** invocation count to trigger compilation */ |
73 protected static final int THRESHOLD; |
73 protected static final int THRESHOLD; |
74 /** count of invocation to triger OSR compilation */ |
74 /** invocation count to trigger OSR compilation */ |
75 protected static final long BACKEDGE_THRESHOLD; |
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; |
76 /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ |
78 /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ |
77 protected static final String MODE = System.getProperty("java.vm.info"); |
79 protected static final String MODE = System.getProperty("java.vm.info"); |
78 |
80 |
79 static { |
81 static { |
80 if (TIERED_COMPILATION) { |
82 if (TIERED_COMPILATION) { |
214 * @throws RuntimeException if {@linkplain #method} is in compiler queue or |
216 * @throws RuntimeException if {@linkplain #method} is in compiler queue or |
215 * is compiled, or if {@linkplain #method} has zero |
217 * is compiled, or if {@linkplain #method} has zero |
216 * compilation level. |
218 * compilation level. |
217 */ |
219 */ |
218 protected final void checkNotCompiled() { |
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() { |
219 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { |
231 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { |
220 throw new RuntimeException(method + " must not be in queue"); |
232 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 } |
233 } |
228 if (WHITE_BOX.isMethodCompiled(method, true)) { |
234 if (WHITE_BOX.isMethodCompiled(method, true)) { |
229 throw new RuntimeException(method + " must be not osr_compiled"); |
235 throw new RuntimeException(method + " must be not osr_compiled"); |
230 } |
236 } |
231 if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { |
237 if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { |
293 |
299 |
294 /** |
300 /** |
295 * Waits for completion of background compilation of {@linkplain #method}. |
301 * Waits for completion of background compilation of {@linkplain #method}. |
296 */ |
302 */ |
297 protected final void waitBackgroundCompilation() { |
303 protected final void waitBackgroundCompilation() { |
|
304 waitBackgroundCompilation(method); |
|
305 } |
|
306 |
|
307 /** |
|
308 * Waits for completion of background compilation of the given executable. |
|
309 * |
|
310 * @param executable Executable |
|
311 */ |
|
312 protected static final void waitBackgroundCompilation(Executable executable) { |
298 if (!BACKGROUND_COMPILATION) { |
313 if (!BACKGROUND_COMPILATION) { |
299 return; |
314 return; |
300 } |
315 } |
301 final Object obj = new Object(); |
316 final Object obj = new Object(); |
302 for (int i = 0; i < 10 |
317 for (int i = 0; i < 10 |
303 && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) { |
318 && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) { |
304 synchronized (obj) { |
319 synchronized (obj) { |
305 try { |
320 try { |
306 obj.wait(1000); |
321 obj.wait(1000); |
307 } catch (InterruptedException e) { |
322 } catch (InterruptedException e) { |
308 Thread.currentThread().interrupt(); |
323 Thread.currentThread().interrupt(); |
412 |
427 |
413 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { |
428 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { |
414 /** constructor test case */ |
429 /** constructor test case */ |
415 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), |
430 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), |
416 /** method test case */ |
431 /** method test case */ |
417 METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), |
432 METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), |
418 /** static method test case */ |
433 /** static method test case */ |
419 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), |
434 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), |
420 /** OSR constructor test case */ |
435 /** OSR constructor test case */ |
421 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, |
436 OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, |
422 Helper.OSR_CONSTRUCTOR_CALLABLE, true), |
437 Helper.OSR_CONSTRUCTOR_CALLABLE, true), |
423 /** OSR method test case */ |
438 /** OSR method test case */ |
424 OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), |
439 OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), |
425 /** OSR static method test case */ |
440 /** OSR static method test case */ |
426 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); |
441 OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); |
427 |
442 |
428 private final Executable executable; |
443 private final Executable executable; |
429 private final Callable<Integer> callable; |
444 private final Callable<Integer> callable; |
481 |
496 |
482 private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE |
497 private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE |
483 = new Callable<Integer>() { |
498 = new Callable<Integer>() { |
484 @Override |
499 @Override |
485 public Integer call() throws Exception { |
500 public Integer call() throws Exception { |
486 return new Helper(null).hashCode(); |
501 int result = warmup(OSR_CONSTRUCTOR); |
|
502 return result + new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode(); |
487 } |
503 } |
488 }; |
504 }; |
489 |
505 |
490 private static final Callable<Integer> OSR_METHOD_CALLABLE |
506 private static final Callable<Integer> OSR_METHOD_CALLABLE |
491 = new Callable<Integer>() { |
507 = new Callable<Integer>() { |
492 private final Helper helper = new Helper(); |
508 private final Helper helper = new Helper(); |
493 |
509 |
494 @Override |
510 @Override |
495 public Integer call() throws Exception { |
511 public Integer call() throws Exception { |
496 return helper.osrMethod(); |
512 int result = warmup(OSR_METHOD); |
|
513 return result + helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); |
497 } |
514 } |
498 }; |
515 }; |
499 |
516 |
500 private static final Callable<Integer> OSR_STATIC_CALLABLE |
517 private static final Callable<Integer> OSR_STATIC_CALLABLE |
501 = new Callable<Integer>() { |
518 = new Callable<Integer>() { |
502 @Override |
519 @Override |
503 public Integer call() throws Exception { |
520 public Integer call() throws Exception { |
504 return osrStaticMethod(); |
521 int result = warmup(OSR_STATIC); |
|
522 return result + osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD); |
505 } |
523 } |
506 }; |
524 }; |
|
525 |
|
526 /** |
|
527 * Deoptimizes all non-osr versions of the given executable after |
|
528 * compilation finished. |
|
529 * |
|
530 * @param e Executable |
|
531 * @throws Exception |
|
532 */ |
|
533 private static void waitAndDeoptimize(Executable e) throws Exception { |
|
534 CompilerWhiteBoxTest.waitBackgroundCompilation(e); |
|
535 if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) { |
|
536 throw new RuntimeException(e + " must not be in queue"); |
|
537 } |
|
538 // Deoptimize non-osr versions of executable |
|
539 WhiteBox.getWhiteBox().deoptimizeMethod(e, false); |
|
540 } |
|
541 |
|
542 /** |
|
543 * Executes the method multiple times to make sure we have |
|
544 * enough profiling information before triggering an OSR |
|
545 * compilation. Otherwise the C2 compiler may add uncommon traps. |
|
546 * |
|
547 * @param m Method to be executed |
|
548 * @return Number of times the method was executed |
|
549 * @throws Exception |
|
550 */ |
|
551 private static int warmup(Method m) throws Exception { |
|
552 Helper helper = new Helper(); |
|
553 int result = 0; |
|
554 for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) { |
|
555 result += (int)m.invoke(helper, 1); |
|
556 } |
|
557 // Deoptimize non-osr versions |
|
558 waitAndDeoptimize(m); |
|
559 return result; |
|
560 } |
|
561 |
|
562 /** |
|
563 * Executes the constructor multiple times to make sure we |
|
564 * have enough profiling information before triggering an OSR |
|
565 * compilation. Otherwise the C2 compiler may add uncommon traps. |
|
566 * |
|
567 * @param c Constructor to be executed |
|
568 * @return Number of times the constructor was executed |
|
569 * @throws Exception |
|
570 */ |
|
571 private static int warmup(Constructor c) throws Exception { |
|
572 int result = 0; |
|
573 for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) { |
|
574 result += c.newInstance(null, 1).hashCode(); |
|
575 } |
|
576 // Deoptimize non-osr versions |
|
577 waitAndDeoptimize(c); |
|
578 return result; |
|
579 } |
507 |
580 |
508 private static final Constructor CONSTRUCTOR; |
581 private static final Constructor CONSTRUCTOR; |
509 private static final Constructor OSR_CONSTRUCTOR; |
582 private static final Constructor OSR_CONSTRUCTOR; |
510 private static final Method METHOD; |
583 private static final Method METHOD; |
511 private static final Method STATIC; |
584 private static final Method STATIC; |
519 throw new RuntimeException( |
592 throw new RuntimeException( |
520 "exception on getting method Helper.<init>(int)", e); |
593 "exception on getting method Helper.<init>(int)", e); |
521 } |
594 } |
522 try { |
595 try { |
523 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( |
596 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( |
524 Object.class); |
597 Object.class, long.class); |
525 } catch (NoSuchMethodException | SecurityException e) { |
598 } catch (NoSuchMethodException | SecurityException e) { |
526 throw new RuntimeException( |
599 throw new RuntimeException( |
527 "exception on getting method Helper.<init>(Object)", e); |
600 "exception on getting method Helper.<init>(Object, long)", e); |
528 } |
601 } |
529 METHOD = getMethod("method"); |
602 METHOD = getMethod("method"); |
530 STATIC = getMethod("staticMethod"); |
603 STATIC = getMethod("staticMethod"); |
531 OSR_METHOD = getMethod("osrMethod"); |
604 OSR_METHOD = getMethod("osrMethod", long.class); |
532 OSR_STATIC = getMethod("osrStaticMethod"); |
605 OSR_STATIC = getMethod("osrStaticMethod", long.class); |
533 } |
606 } |
534 |
607 |
535 private static Method getMethod(String name) { |
608 private static Method getMethod(String name, Class<?>... parameterTypes) { |
536 try { |
609 try { |
537 return Helper.class.getDeclaredMethod(name); |
610 return Helper.class.getDeclaredMethod(name, parameterTypes); |
538 } catch (NoSuchMethodException | SecurityException e) { |
611 } catch (NoSuchMethodException | SecurityException e) { |
539 throw new RuntimeException( |
612 throw new RuntimeException( |
540 "exception on getting method Helper." + name, e); |
613 "exception on getting method Helper." + name, e); |
541 } |
614 } |
542 |
|
543 } |
615 } |
544 |
616 |
545 private static int staticMethod() { |
617 private static int staticMethod() { |
546 return 1138; |
618 return 1138; |
547 } |
619 } |
548 |
620 |
549 private int method() { |
621 private int method() { |
550 return 42; |
622 return 42; |
551 } |
623 } |
552 |
624 |
553 private static int osrStaticMethod() { |
625 private static int osrStaticMethod(long limit) { |
554 int result = 0; |
626 int result = 0; |
555 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { |
627 for (long i = 0; i < limit; ++i) { |
556 result += staticMethod(); |
628 result += staticMethod(); |
557 } |
629 } |
558 return result; |
630 return result; |
559 } |
631 } |
560 |
632 |
561 private int osrMethod() { |
633 private int osrMethod(long limit) { |
562 int result = 0; |
634 int result = 0; |
563 for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { |
635 for (long i = 0; i < limit; ++i) { |
564 result += method(); |
636 result += method(); |
565 } |
637 } |
566 return result; |
638 return result; |
567 } |
639 } |
568 |
640 |