hotspot/test/compiler/whitebox/SimpleTestCase.java
changeset 34185 ee71c590a456
parent 34155 8d9e0cbf93a2
child 38025 5ed9ce1e4a2f
equal deleted inserted replaced
33813:4f376e851453 34185:ee71c590a456
       
     1 /*
       
     2  * Copyright (c) 2015, 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 package compiler.whitebox;
       
    25 
       
    26 import java.lang.reflect.Constructor;
       
    27 import java.lang.reflect.Executable;
       
    28 import java.lang.reflect.Method;
       
    29 import java.util.concurrent.Callable;
       
    30 import sun.hotspot.WhiteBox;
       
    31 
       
    32 public enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
       
    33     /** constructor test case */
       
    34     CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
       
    35     /** method test case */
       
    36     METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
       
    37     /** static method test case */
       
    38     STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
       
    39     /** OSR constructor test case */
       
    40     OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
       
    41             Helper.OSR_CONSTRUCTOR_CALLABLE, true),
       
    42     /** OSR method test case */
       
    43     OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
       
    44     /** OSR static method test case */
       
    45     OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
       
    46 
       
    47     private final Executable executable;
       
    48     private final Callable<Integer> callable;
       
    49     private final boolean isOsr;
       
    50 
       
    51     private SimpleTestCase(Executable executable, Callable<Integer> callable,
       
    52             boolean isOsr) {
       
    53         this.executable = executable;
       
    54         this.callable = callable;
       
    55         this.isOsr = isOsr;
       
    56     }
       
    57 
       
    58     @Override
       
    59     public Executable getExecutable() {
       
    60         return executable;
       
    61     }
       
    62 
       
    63     @Override
       
    64     public Callable<Integer> getCallable() {
       
    65         return callable;
       
    66     }
       
    67 
       
    68     @Override
       
    69     public boolean isOsr() {
       
    70         return isOsr;
       
    71     }
       
    72 
       
    73     private static class Helper {
       
    74 
       
    75         private static final Callable<Integer> CONSTRUCTOR_CALLABLE
       
    76                 = new Callable<Integer>() {
       
    77             @Override
       
    78             public Integer call() throws Exception {
       
    79                 return new Helper(1337).hashCode();
       
    80             }
       
    81         };
       
    82 
       
    83         private static final Callable<Integer> METHOD_CALLABLE
       
    84                 = new Callable<Integer>() {
       
    85             private final Helper helper = new Helper();
       
    86 
       
    87             @Override
       
    88             public Integer call() throws Exception {
       
    89                 return helper.method();
       
    90             }
       
    91         };
       
    92 
       
    93         private static final Callable<Integer> STATIC_CALLABLE
       
    94                 = new Callable<Integer>() {
       
    95             @Override
       
    96             public Integer call() throws Exception {
       
    97                 return staticMethod();
       
    98             }
       
    99         };
       
   100 
       
   101         private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE
       
   102                 = new Callable<Integer>() {
       
   103             @Override
       
   104             public Integer call() throws Exception {
       
   105                 return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
       
   106             }
       
   107         };
       
   108 
       
   109         private static final Callable<Integer> OSR_METHOD_CALLABLE
       
   110                 = new Callable<Integer>() {
       
   111             private final Helper helper = new Helper();
       
   112 
       
   113             @Override
       
   114             public Integer call() throws Exception {
       
   115                 return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
       
   116             }
       
   117         };
       
   118 
       
   119         private static final Callable<Integer> OSR_STATIC_CALLABLE
       
   120                 = new Callable<Integer>() {
       
   121             @Override
       
   122             public Integer call() throws Exception {
       
   123                 return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
       
   124             }
       
   125         };
       
   126 
       
   127         private static final Constructor CONSTRUCTOR;
       
   128         private static final Constructor OSR_CONSTRUCTOR;
       
   129         private static final Method METHOD;
       
   130         private static final Method STATIC;
       
   131         private static final Method OSR_METHOD;
       
   132         private static final Method OSR_STATIC;
       
   133 
       
   134         static {
       
   135             try {
       
   136                 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class);
       
   137             } catch (NoSuchMethodException | SecurityException e) {
       
   138                 throw new RuntimeException(
       
   139                         "exception on getting method Helper.<init>(int)", e);
       
   140             }
       
   141             try {
       
   142                 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
       
   143                         Object.class, long.class);
       
   144             } catch (NoSuchMethodException | SecurityException e) {
       
   145                 throw new RuntimeException(
       
   146                         "exception on getting method Helper.<init>(Object, long)", e);
       
   147             }
       
   148             METHOD = getMethod("method");
       
   149             STATIC = getMethod("staticMethod");
       
   150             OSR_METHOD = getMethod("osrMethod", long.class);
       
   151             OSR_STATIC = getMethod("osrStaticMethod", long.class);
       
   152         }
       
   153 
       
   154         private static Method getMethod(String name, Class<?>... parameterTypes) {
       
   155             try {
       
   156                 return Helper.class.getDeclaredMethod(name, parameterTypes);
       
   157             } catch (NoSuchMethodException | SecurityException e) {
       
   158                 throw new RuntimeException(
       
   159                         "exception on getting method Helper." + name, e);
       
   160             }
       
   161         }
       
   162 
       
   163         private static int staticMethod() {
       
   164             return 1138;
       
   165         }
       
   166 
       
   167         private int method() {
       
   168             return 42;
       
   169         }
       
   170 
       
   171         /**
       
   172          * Deoptimizes all non-osr versions of the given executable after
       
   173          * compilation finished.
       
   174          *
       
   175          * @param e Executable
       
   176          * @throws Exception
       
   177          */
       
   178         private static void waitAndDeoptimize(Executable e) {
       
   179             CompilerWhiteBoxTest.waitBackgroundCompilation(e);
       
   180             if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
       
   181                 throw new RuntimeException(e + " must not be in queue");
       
   182             }
       
   183             // Deoptimize non-osr versions of executable
       
   184             WhiteBox.getWhiteBox().deoptimizeMethod(e, false);
       
   185         }
       
   186 
       
   187         /**
       
   188          * Executes the method multiple times to make sure we have
       
   189          * enough profiling information before triggering an OSR
       
   190          * compilation. Otherwise the C2 compiler may add uncommon traps.
       
   191          *
       
   192          * @param m Method to be executed
       
   193          * @return Number of times the method was executed
       
   194          * @throws Exception
       
   195          */
       
   196         private static int warmup(Method m) throws Exception {
       
   197             waitAndDeoptimize(m);
       
   198             Helper helper = new Helper();
       
   199             int result = 0;
       
   200             for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
       
   201                 result += (int)m.invoke(helper, 1);
       
   202             }
       
   203             // Wait to make sure OSR compilation is not blocked by
       
   204             // non-OSR compilation in the compile queue
       
   205             CompilerWhiteBoxTest.waitBackgroundCompilation(m);
       
   206             return result;
       
   207         }
       
   208 
       
   209         /**
       
   210          * Executes the constructor multiple times to make sure we
       
   211          * have enough profiling information before triggering an OSR
       
   212          * compilation. Otherwise the C2 compiler may add uncommon traps.
       
   213          *
       
   214          * @param c Constructor to be executed
       
   215          * @return Number of times the constructor was executed
       
   216          * @throws Exception
       
   217          */
       
   218         private static int warmup(Constructor c) throws Exception {
       
   219             waitAndDeoptimize(c);
       
   220             int result = 0;
       
   221             for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
       
   222                 result += c.newInstance(null, 1).hashCode();
       
   223             }
       
   224             // Wait to make sure OSR compilation is not blocked by
       
   225             // non-OSR compilation in the compile queue
       
   226             CompilerWhiteBoxTest.waitBackgroundCompilation(c);
       
   227             return result;
       
   228         }
       
   229 
       
   230         private static int osrStaticMethod(long limit) throws Exception {
       
   231             int result = 0;
       
   232             if (limit != 1) {
       
   233                 result = warmup(OSR_STATIC);
       
   234             }
       
   235             // Trigger osr compilation
       
   236             for (long i = 0; i < limit; ++i) {
       
   237                 result += staticMethod();
       
   238             }
       
   239             return result;
       
   240         }
       
   241 
       
   242         private int osrMethod(long limit) throws Exception {
       
   243             int result = 0;
       
   244             if (limit != 1) {
       
   245                 result = warmup(OSR_METHOD);
       
   246             }
       
   247             // Trigger osr compilation
       
   248             for (long i = 0; i < limit; ++i) {
       
   249                 result += method();
       
   250             }
       
   251             return result;
       
   252         }
       
   253 
       
   254         private final int x;
       
   255 
       
   256         // for method and OSR method test case
       
   257         public Helper() {
       
   258             x = 0;
       
   259         }
       
   260 
       
   261         // for OSR constructor test case
       
   262         private Helper(Object o, long limit) throws Exception {
       
   263             int result = 0;
       
   264             if (limit != 1) {
       
   265                 result = warmup(OSR_CONSTRUCTOR);
       
   266             }
       
   267             // Trigger osr compilation
       
   268             for (long i = 0; i < limit; ++i) {
       
   269                 result += method();
       
   270             }
       
   271             x = result;
       
   272         }
       
   273 
       
   274         // for constructor test case
       
   275         private Helper(int x) {
       
   276             this.x = x;
       
   277         }
       
   278 
       
   279         @Override
       
   280         public int hashCode() {
       
   281             return x;
       
   282         }
       
   283     }
       
   284 }