changeset 6860:c88a4554854c

8046268: compiler/whitebox/ tests fail : must be osr_compiled Summary: Added code to 'warm up' the methods before triggering OSR compilation by executing them a limited number of times. Like this, the profile information marks the loop exit as taken and we don't add an uncommon trap. Reviewed-by: kvn, dlong, iignatyev
author thartmann
date Mon, 13 Oct 2014 12:30:37 +0200
parents 063338b89a56
children 564d97997064
files test/compiler/whitebox/CompilerWhiteBoxTest.java test/compiler/whitebox/MakeMethodNotCompilableTest.java
diffstat 2 files changed, 97 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Oct 31 11:13:41 2014 -0700
+++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Mon Oct 13 12:30:37 2014 +0200
@@ -72,10 +72,12 @@
     /** Flag for verbose output, true if {@code -Dverbose} specified */
     protected static final boolean IS_VERBOSE
             = System.getProperty("verbose") != null;
-    /** count of invocation to triger compilation */
+    /** invocation count to trigger compilation */
     protected static final int THRESHOLD;
-    /** count of invocation to triger OSR compilation */
+    /** invocation count to trigger OSR compilation */
     protected static final long BACKEDGE_THRESHOLD;
+    /** invocation count to warm up method before triggering OSR compilation */
+    protected static final long OSR_WARMUP = 2000;
     /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
     protected static final String MODE = System.getProperty("java.vm.info");
 
@@ -227,15 +229,19 @@
      *                          compilation level.
      */
     protected final void checkNotCompiled() {
-        if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
-            throw new RuntimeException(method + " must not be in queue");
-        }
         if (WHITE_BOX.isMethodCompiled(method, false)) {
             throw new RuntimeException(method + " must be not compiled");
         }
         if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) {
             throw new RuntimeException(method + " comp_level must be == 0");
         }
+        checkNotOsrCompiled();
+    }
+
+    protected final void checkNotOsrCompiled() {
+        if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
+            throw new RuntimeException(method + " must not be in queue");
+        }
         if (WHITE_BOX.isMethodCompiled(method, true)) {
             throw new RuntimeException(method + " must be not osr_compiled");
         }
@@ -306,12 +312,21 @@
      * Waits for completion of background compilation of {@linkplain #method}.
      */
     protected final void waitBackgroundCompilation() {
+        waitBackgroundCompilation(method);
+    }
+
+    /**
+     * Waits for completion of background compilation of the given executable.
+     *
+     * @param executable Executable
+     */
+    protected static final void waitBackgroundCompilation(Executable executable) {
         if (!BACKGROUND_COMPILATION) {
             return;
         }
         final Object obj = new Object();
         for (int i = 0; i < 10
-                && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) {
+                && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) {
             synchronized (obj) {
                 try {
                     obj.wait(1000);
@@ -425,14 +440,14 @@
     /** constructor test case */
     CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
     /** method test case */
-    METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
+    METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
     /** static method test case */
     STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
     /** OSR constructor test case */
     OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
             Helper.OSR_CONSTRUCTOR_CALLABLE, true),
     /** OSR method test case */
-    OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
+    OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
     /** OSR static method test case */
     OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
 
@@ -494,7 +509,8 @@
                 = new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return new Helper(null).hashCode();
+                int result = warmup(OSR_CONSTRUCTOR);
+                return result + new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
             }
         };
 
@@ -504,7 +520,8 @@
 
             @Override
             public Integer call() throws Exception {
-                return helper.osrMethod();
+                int result = warmup(OSR_METHOD);
+                return result + helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
             }
         };
 
@@ -512,10 +529,66 @@
                 = new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return osrStaticMethod();
+                int result = warmup(OSR_STATIC);
+                return result + osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
             }
         };
 
+        /**
+         * Deoptimizes all non-osr versions of the given executable after
+         * compilation finished.
+         *
+         * @param e Executable
+         * @throws Exception
+         */
+        private static void waitAndDeoptimize(Executable e) throws Exception {
+            CompilerWhiteBoxTest.waitBackgroundCompilation(e);
+            if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
+                throw new RuntimeException(e + " must not be in queue");
+            }
+            // Deoptimize non-osr versions of executable
+            WhiteBox.getWhiteBox().deoptimizeMethod(e, false);
+        }
+
+        /**
+         * Executes the method multiple times to make sure we have
+         * enough profiling information before triggering an OSR
+         * compilation. Otherwise the C2 compiler may add uncommon traps.
+         *
+         * @param m Method to be executed
+         * @return Number of times the method was executed
+         * @throws Exception
+         */
+        private static int warmup(Method m) throws Exception {
+            Helper helper = new Helper();
+            int result = 0;
+            for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) {
+                result += (int)m.invoke(helper, 1);
+            }
+            // Deoptimize non-osr versions
+            waitAndDeoptimize(m);
+            return result;
+        }
+
+        /**
+         * Executes the constructor multiple times to make sure we
+         * have enough profiling information before triggering an OSR
+         * compilation. Otherwise the C2 compiler may add uncommon traps.
+         *
+         * @param c Constructor to be executed
+         * @return Number of times the constructor was executed
+         * @throws Exception
+         */
+        private static int warmup(Constructor c) throws Exception {
+            int result = 0;
+            for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) {
+                result += c.newInstance(null, 1).hashCode();
+            }
+            // Deoptimize non-osr versions
+            waitAndDeoptimize(c);
+            return result;
+        }
+
         private static final Constructor CONSTRUCTOR;
         private static final Constructor OSR_CONSTRUCTOR;
         private static final Method METHOD;
@@ -532,25 +605,24 @@
             }
             try {
                 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
-                        Object.class);
+                        Object.class, long.class);
             } catch (NoSuchMethodException | SecurityException e) {
                 throw new RuntimeException(
-                        "exception on getting method Helper.<init>(Object)", e);
+                        "exception on getting method Helper.<init>(Object, long)", e);
             }
             METHOD = getMethod("method");
             STATIC = getMethod("staticMethod");
-            OSR_METHOD = getMethod("osrMethod");
-            OSR_STATIC = getMethod("osrStaticMethod");
+            OSR_METHOD = getMethod("osrMethod", long.class);
+            OSR_STATIC = getMethod("osrStaticMethod", long.class);
         }
 
-        private static Method getMethod(String name) {
+        private static Method getMethod(String name, Class<?>... parameterTypes) {
             try {
-                return Helper.class.getDeclaredMethod(name);
+                return Helper.class.getDeclaredMethod(name, parameterTypes);
             } catch (NoSuchMethodException | SecurityException e) {
                 throw new RuntimeException(
                         "exception on getting method Helper." + name, e);
             }
-
         }
 
         private static int staticMethod() {
@@ -561,17 +633,17 @@
             return 42;
         }
 
-        private static int osrStaticMethod() {
+        private static int osrStaticMethod(long limit) {
             int result = 0;
-            for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
+            for (long i = 0; i < limit; ++i) {
                 result += staticMethod();
             }
             return result;
         }
 
-        private int osrMethod() {
+        private int osrMethod(long limit) {
             int result = 0;
-            for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
+            for (long i = 0; i < limit; ++i) {
                 result += method();
             }
             return result;
@@ -585,9 +657,9 @@
         }
 
         // for OSR constructor test case
-        private Helper(Object o) {
+        private Helper(Object o, long limit) {
             int result = 0;
-            for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
+            for (long i = 0; i < limit; ++i) {
                 result += method();
             }
             x = result;
--- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Oct 31 11:13:41 2014 -0700
+++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Mon Oct 13 12:30:37 2014 +0200
@@ -138,7 +138,7 @@
         }
 
         compile();
-        checkNotCompiled();
+        checkNotOsrCompiled();
         if (isCompilable()) {
             throw new RuntimeException(method + " must be not compilable");
         }