hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java
changeset 34185 ee71c590a456
parent 34172 19299c8b7c81
child 36599 8dd1694c0480
equal deleted inserted replaced
33813:4f376e851453 34185:ee71c590a456
    18  *
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    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
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  */
    22  */
       
    23 package compiler.whitebox;
    23 
    24 
    24 import sun.hotspot.WhiteBox;
    25 import sun.hotspot.WhiteBox;
    25 import sun.hotspot.code.NMethod;
    26 import sun.hotspot.code.NMethod;
    26 
       
    27 import java.lang.reflect.Constructor;
       
    28 import java.lang.reflect.Executable;
    27 import java.lang.reflect.Executable;
    29 import java.lang.reflect.Method;
       
    30 import java.util.Objects;
    28 import java.util.Objects;
    31 import java.util.concurrent.Callable;
    29 import java.util.concurrent.Callable;
    32 import java.util.function.Function;
    30 import java.util.function.Function;
    33 
    31 
    34 /**
    32 /**
    36  *
    34  *
    37  * @author igor.ignatyev@oracle.com
    35  * @author igor.ignatyev@oracle.com
    38  */
    36  */
    39 public abstract class CompilerWhiteBoxTest {
    37 public abstract class CompilerWhiteBoxTest {
    40     /** {@code CompLevel::CompLevel_none} -- Interpreter */
    38     /** {@code CompLevel::CompLevel_none} -- Interpreter */
    41     protected static final int COMP_LEVEL_NONE = 0;
    39     public static final int COMP_LEVEL_NONE = 0;
    42     /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
    40     /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
    43     protected static final int COMP_LEVEL_ANY = -1;
    41     public static final int COMP_LEVEL_ANY = -1;
    44     /** {@code CompLevel::CompLevel_simple} -- C1 */
    42     /** {@code CompLevel::CompLevel_simple} -- C1 */
    45     protected static final int COMP_LEVEL_SIMPLE = 1;
    43     public static final int COMP_LEVEL_SIMPLE = 1;
    46     /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */
    44     /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */
    47     protected static final int COMP_LEVEL_LIMITED_PROFILE = 2;
    45     public static final int COMP_LEVEL_LIMITED_PROFILE = 2;
    48     /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */
    46     /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */
    49     protected static final int COMP_LEVEL_FULL_PROFILE = 3;
    47     public static final int COMP_LEVEL_FULL_PROFILE = 3;
    50     /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
    48     /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
    51     protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
    49     public static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
    52     /** Maximal value for CompLevel */
    50     /** Maximal value for CompLevel */
    53     protected static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION;
    51     public static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION;
    54 
    52 
    55     /** Instance of WhiteBox */
    53     /** Instance of WhiteBox */
    56     protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
    54     protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
    57     /** Value of {@code -XX:CompileThreshold} */
    55     /** Value of {@code -XX:CompileThreshold} */
    58     protected static final int COMPILE_THRESHOLD
    56     protected static final int COMPILE_THRESHOLD
    68             = Integer.parseInt(getVMOption("TieredStopAtLevel", "0"));
    66             = Integer.parseInt(getVMOption("TieredStopAtLevel", "0"));
    69     /** Flag for verbose output, true if {@code -Dverbose} specified */
    67     /** Flag for verbose output, true if {@code -Dverbose} specified */
    70     protected static final boolean IS_VERBOSE
    68     protected static final boolean IS_VERBOSE
    71             = System.getProperty("verbose") != null;
    69             = System.getProperty("verbose") != null;
    72     /** invocation count to trigger compilation */
    70     /** invocation count to trigger compilation */
    73     protected static final int THRESHOLD;
    71     public static final int THRESHOLD;
    74     /** invocation count to trigger OSR compilation */
    72     /** invocation count to trigger OSR compilation */
    75     protected static final long BACKEDGE_THRESHOLD;
    73     protected static final long BACKEDGE_THRESHOLD;
    76     /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
    74     /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
    77     protected static final String MODE = System.getProperty("java.vm.info");
    75     protected static final String MODE = System.getProperty("java.vm.info");
    78 
    76 
   310     /**
   308     /**
   311      * Waits for completion of background compilation of the given executable.
   309      * Waits for completion of background compilation of the given executable.
   312      *
   310      *
   313      * @param executable Executable
   311      * @param executable Executable
   314      */
   312      */
   315     protected static final void waitBackgroundCompilation(Executable executable) {
   313     public static final void waitBackgroundCompilation(Executable executable) {
   316         if (!BACKGROUND_COMPILATION) {
   314         if (!BACKGROUND_COMPILATION) {
   317             return;
   315             return;
   318         }
   316         }
   319         final Object obj = new Object();
   317         final Object obj = new Object();
   320         for (int i = 0; i < 10
   318         for (int i = 0; i < 10
   439      * Skip the test for the specified value of Tiered Compilation
   437      * Skip the test for the specified value of Tiered Compilation
   440      * @param value of TieredCompilation the test should not run with
   438      * @param value of TieredCompilation the test should not run with
   441      * @return {@code true} if the test should be skipped,
   439      * @return {@code true} if the test should be skipped,
   442      *         {@code false} otherwise
   440      *         {@code false} otherwise
   443      */
   441      */
   444     protected static boolean skipOnTieredCompilation(boolean value) {
   442     public static boolean skipOnTieredCompilation(boolean value) {
   445         if (value == CompilerWhiteBoxTest.TIERED_COMPILATION) {
   443         if (value == CompilerWhiteBoxTest.TIERED_COMPILATION) {
   446             System.err.println("Test isn't applicable w/ "
   444             System.err.println("Test isn't applicable w/ "
   447                     + (value ? "enabled" : "disabled")
   445                     + (value ? "enabled" : "disabled")
   448                     + "TieredCompilation. Skip test.");
   446                     + "TieredCompilation. Skip test.");
   449             return true;
   447             return true;
   450         }
   448         }
   451         return false;
   449         return false;
   452     }
   450     }
   453 }
   451 }
   454 
   452 
   455 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
       
   456     /** constructor test case */
       
   457     CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
       
   458     /** method test case */
       
   459     METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
       
   460     /** static method test case */
       
   461     STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
       
   462     /** OSR constructor test case */
       
   463     OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
       
   464             Helper.OSR_CONSTRUCTOR_CALLABLE, true),
       
   465     /** OSR method test case */
       
   466     OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
       
   467     /** OSR static method test case */
       
   468     OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
       
   469 
       
   470     private final Executable executable;
       
   471     private final Callable<Integer> callable;
       
   472     private final boolean isOsr;
       
   473 
       
   474     private SimpleTestCase(Executable executable, Callable<Integer> callable,
       
   475             boolean isOsr) {
       
   476         this.executable = executable;
       
   477         this.callable = callable;
       
   478         this.isOsr = isOsr;
       
   479     }
       
   480 
       
   481     @Override
       
   482     public Executable getExecutable() {
       
   483         return executable;
       
   484     }
       
   485 
       
   486     @Override
       
   487     public Callable<Integer> getCallable() {
       
   488         return callable;
       
   489     }
       
   490 
       
   491     @Override
       
   492     public boolean isOsr() {
       
   493         return isOsr;
       
   494     }
       
   495 
       
   496     private static class Helper {
       
   497 
       
   498         private static final Callable<Integer> CONSTRUCTOR_CALLABLE
       
   499                 = new Callable<Integer>() {
       
   500             @Override
       
   501             public Integer call() throws Exception {
       
   502                 return new Helper(1337).hashCode();
       
   503             }
       
   504         };
       
   505 
       
   506         private static final Callable<Integer> METHOD_CALLABLE
       
   507                 = new Callable<Integer>() {
       
   508             private final Helper helper = new Helper();
       
   509 
       
   510             @Override
       
   511             public Integer call() throws Exception {
       
   512                 return helper.method();
       
   513             }
       
   514         };
       
   515 
       
   516         private static final Callable<Integer> STATIC_CALLABLE
       
   517                 = new Callable<Integer>() {
       
   518             @Override
       
   519             public Integer call() throws Exception {
       
   520                 return staticMethod();
       
   521             }
       
   522         };
       
   523 
       
   524         private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE
       
   525                 = new Callable<Integer>() {
       
   526             @Override
       
   527             public Integer call() throws Exception {
       
   528                 return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
       
   529             }
       
   530         };
       
   531 
       
   532         private static final Callable<Integer> OSR_METHOD_CALLABLE
       
   533                 = new Callable<Integer>() {
       
   534             private final Helper helper = new Helper();
       
   535 
       
   536             @Override
       
   537             public Integer call() throws Exception {
       
   538                 return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
       
   539             }
       
   540         };
       
   541 
       
   542         private static final Callable<Integer> OSR_STATIC_CALLABLE
       
   543                 = new Callable<Integer>() {
       
   544             @Override
       
   545             public Integer call() throws Exception {
       
   546                 return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
       
   547             }
       
   548         };
       
   549 
       
   550         private static final Constructor CONSTRUCTOR;
       
   551         private static final Constructor OSR_CONSTRUCTOR;
       
   552         private static final Method METHOD;
       
   553         private static final Method STATIC;
       
   554         private static final Method OSR_METHOD;
       
   555         private static final Method OSR_STATIC;
       
   556 
       
   557         static {
       
   558             try {
       
   559                 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class);
       
   560             } catch (NoSuchMethodException | SecurityException e) {
       
   561                 throw new RuntimeException(
       
   562                         "exception on getting method Helper.<init>(int)", e);
       
   563             }
       
   564             try {
       
   565                 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
       
   566                         Object.class, long.class);
       
   567             } catch (NoSuchMethodException | SecurityException e) {
       
   568                 throw new RuntimeException(
       
   569                         "exception on getting method Helper.<init>(Object, long)", e);
       
   570             }
       
   571             METHOD = getMethod("method");
       
   572             STATIC = getMethod("staticMethod");
       
   573             OSR_METHOD = getMethod("osrMethod", long.class);
       
   574             OSR_STATIC = getMethod("osrStaticMethod", long.class);
       
   575         }
       
   576 
       
   577         private static Method getMethod(String name, Class<?>... parameterTypes) {
       
   578             try {
       
   579                 return Helper.class.getDeclaredMethod(name, parameterTypes);
       
   580             } catch (NoSuchMethodException | SecurityException e) {
       
   581                 throw new RuntimeException(
       
   582                         "exception on getting method Helper." + name, e);
       
   583             }
       
   584         }
       
   585 
       
   586         private static int staticMethod() {
       
   587             return 1138;
       
   588         }
       
   589 
       
   590         private int method() {
       
   591             return 42;
       
   592         }
       
   593 
       
   594         /**
       
   595          * Deoptimizes all non-osr versions of the given executable after
       
   596          * compilation finished.
       
   597          *
       
   598          * @param e Executable
       
   599          * @throws Exception
       
   600          */
       
   601         private static void waitAndDeoptimize(Executable e) {
       
   602             CompilerWhiteBoxTest.waitBackgroundCompilation(e);
       
   603             if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
       
   604                 throw new RuntimeException(e + " must not be in queue");
       
   605             }
       
   606             // Deoptimize non-osr versions of executable
       
   607             WhiteBox.getWhiteBox().deoptimizeMethod(e, false);
       
   608         }
       
   609 
       
   610         /**
       
   611          * Executes the method multiple times to make sure we have
       
   612          * enough profiling information before triggering an OSR
       
   613          * compilation. Otherwise the C2 compiler may add uncommon traps.
       
   614          *
       
   615          * @param m Method to be executed
       
   616          * @return Number of times the method was executed
       
   617          * @throws Exception
       
   618          */
       
   619         private static int warmup(Method m) throws Exception {
       
   620             waitAndDeoptimize(m);
       
   621             Helper helper = new Helper();
       
   622             int result = 0;
       
   623             for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
       
   624                 result += (int)m.invoke(helper, 1);
       
   625             }
       
   626             // Wait to make sure OSR compilation is not blocked by
       
   627             // non-OSR compilation in the compile queue
       
   628             CompilerWhiteBoxTest.waitBackgroundCompilation(m);
       
   629             return result;
       
   630         }
       
   631 
       
   632         /**
       
   633          * Executes the constructor multiple times to make sure we
       
   634          * have enough profiling information before triggering an OSR
       
   635          * compilation. Otherwise the C2 compiler may add uncommon traps.
       
   636          *
       
   637          * @param c Constructor to be executed
       
   638          * @return Number of times the constructor was executed
       
   639          * @throws Exception
       
   640          */
       
   641         private static int warmup(Constructor c) throws Exception {
       
   642             waitAndDeoptimize(c);
       
   643             int result = 0;
       
   644             for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
       
   645                 result += c.newInstance(null, 1).hashCode();
       
   646             }
       
   647             // Wait to make sure OSR compilation is not blocked by
       
   648             // non-OSR compilation in the compile queue
       
   649             CompilerWhiteBoxTest.waitBackgroundCompilation(c);
       
   650             return result;
       
   651         }
       
   652 
       
   653         private static int osrStaticMethod(long limit) throws Exception {
       
   654             int result = 0;
       
   655             if (limit != 1) {
       
   656                 result = warmup(OSR_STATIC);
       
   657             }
       
   658             // Trigger osr compilation
       
   659             for (long i = 0; i < limit; ++i) {
       
   660                 result += staticMethod();
       
   661             }
       
   662             return result;
       
   663         }
       
   664 
       
   665         private int osrMethod(long limit) throws Exception {
       
   666             int result = 0;
       
   667             if (limit != 1) {
       
   668                 result = warmup(OSR_METHOD);
       
   669             }
       
   670             // Trigger osr compilation
       
   671             for (long i = 0; i < limit; ++i) {
       
   672                 result += method();
       
   673             }
       
   674             return result;
       
   675         }
       
   676 
       
   677         private final int x;
       
   678 
       
   679         // for method and OSR method test case
       
   680         public Helper() {
       
   681             x = 0;
       
   682         }
       
   683 
       
   684         // for OSR constructor test case
       
   685         private Helper(Object o, long limit) throws Exception {
       
   686             int result = 0;
       
   687             if (limit != 1) {
       
   688                 result = warmup(OSR_CONSTRUCTOR);
       
   689             }
       
   690             // Trigger osr compilation
       
   691             for (long i = 0; i < limit; ++i) {
       
   692                 result += method();
       
   693             }
       
   694             x = result;
       
   695         }
       
   696 
       
   697         // for constructor test case
       
   698         private Helper(int x) {
       
   699             this.x = x;
       
   700         }
       
   701 
       
   702         @Override
       
   703         public int hashCode() {
       
   704             return x;
       
   705         }
       
   706     }
       
   707 }