test/java/lang/invoke/LFCaching/LambdaFormTestCase.java

Print this page

        

@@ -29,10 +29,11 @@
 import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.List;
 import java.util.function.Function;
 import jdk.testlibrary.Utils;
+import jdk.testlibrary.TimeLimitedRunner;
 
 /**
  * Lambda forms caching test case class. Contains all necessary test routines to
  * test lambda forms caching in method handles returned by methods of
  * MethodHandles class.

@@ -43,11 +44,11 @@
 
     private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle";
     private final static String INTERNAL_FORM_METHOD_NAME = "internalForm";
     private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO
             = 45 / (128.0 * 1024 * 1024);
-    private static final long TIMEOUT = Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT);
+    private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9);
 
     /**
      * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is
      * used to get a lambda form from a method handle.
      */

@@ -73,10 +74,56 @@
         }
     }
 
     private final TestMethods testMethod;
     private long gcCountAtStart;
+
+    private static class TestRunInfo {
+
+        final long totalIterations;
+        long doneIterations;
+        long testCounter;
+        long failCounter;
+        boolean passed;
+
+        TestRunInfo(long testCaseNum, long testLimit) {
+            long iterations = Math.max(1, testLimit / testCaseNum);
+            System.out.printf("Number of iterations according to -DtestLimit is %d (%d cases)%n",
+                    iterations, iterations * testCaseNum);
+            HotSpotDiagnosticMXBean hsDiagBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
+            long codeCacheSize = Long.parseLong(
+                    hsDiagBean.getVMOption("ReservedCodeCacheSize").getValue());
+            System.out.printf("Code cache size is %d bytes%n", codeCacheSize);
+            long iterationsByCodeCacheSize = (long) (codeCacheSize
+                    * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO);
+            long nonProfiledCodeCacheSize = Long.parseLong(
+                    hsDiagBean.getVMOption("NonProfiledCodeHeapSize").getValue());
+            System.out.printf("Non-profiled code cache size is %d bytes%n", nonProfiledCodeCacheSize);
+            long iterationsByNonProfiledCodeCacheSize = (long) (nonProfiledCodeCacheSize
+                    * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO);
+            System.out.printf("Number of iterations limited by code cache size is %d (%d cases)%n",
+                    iterationsByCodeCacheSize, iterationsByCodeCacheSize * testCaseNum);
+            System.out.printf("Number of iterations limited by non-profiled code cache size is %d (%d cases)%n",
+                    iterationsByNonProfiledCodeCacheSize, iterationsByNonProfiledCodeCacheSize * testCaseNum);
+            iterations = Math.min(iterationsByCodeCacheSize,
+                    Math.min(iterations, iterationsByNonProfiledCodeCacheSize));
+            if (iterations == 0) {
+                System.out.println("Warning: code cache size is too small to provide at"
+                        + " least one iteration! Test will try to do one iteration.");
+                iterations = 1;
+            }
+            System.out.printf("Number of iterations is set to %d (%d cases)%n",
+                    iterations, iterations * testCaseNum);
+            System.out.flush();
+            totalIterations = iterations;
+            doneIterations = 0L;
+            testCounter = 0L;
+            failCounter = 0L;
+            passed = true;
+        }
+    }
+
     /**
      * Test case constructor. Generates test cases with random method types for
      * given methods form {@code j.l.i.MethodHandles} class.
      *
      * @param testMethod A method from {@code j.l.i.MethodHandles} class which

@@ -106,73 +153,46 @@
      * @param ctor constructor of LambdaFormCachingTest or its child classes
      * object.
      * @param testMethods list of test methods
      */
     public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
-        boolean passed = true;
-        int testCounter = 0;
-        int failCounter = 0;
-        long testCaseNum = testMethods.size();
-        long iterations = Math.max(1, Helper.TEST_LIMIT / testCaseNum);
-        System.out.printf("Number of iterations according to -DtestLimit is %d (%d cases)%n",
-                iterations, iterations * testCaseNum);
-        HotSpotDiagnosticMXBean hsDiagBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
-        long codeCacheSize = Long.parseLong(
-                hsDiagBean.getVMOption("ReservedCodeCacheSize").getValue());
-        System.out.printf("Code cache size is %d bytes%n", codeCacheSize);
-        long iterationsByCodeCacheSize = (long) (codeCacheSize
-                * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO);
-        long nonProfiledCodeCacheSize = Long.parseLong(
-                hsDiagBean.getVMOption("NonProfiledCodeHeapSize").getValue());
-        System.out.printf("Non-profiled code cache size is %d bytes%n", nonProfiledCodeCacheSize);
-        long iterationsByNonProfiledCodeCacheSize = (long) (nonProfiledCodeCacheSize
-                * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO);
-        System.out.printf("Number of iterations limited by code cache size is %d (%d cases)%n",
-                iterationsByCodeCacheSize, iterationsByCodeCacheSize * testCaseNum);
-        System.out.printf("Number of iterations limited by non-profiled code cache size is %d (%d cases)%n",
-                iterationsByNonProfiledCodeCacheSize, iterationsByNonProfiledCodeCacheSize * testCaseNum);
-        iterations = Math.min(iterationsByCodeCacheSize,
-                Math.min(iterations, iterationsByNonProfiledCodeCacheSize));
-        if (iterations == 0) {
-            System.out.println("Warning: code cache size is too small to provide at"
-                    + " least one iteration! Test will try to do one iteration.");
-            iterations = 1;
+        LambdaFormTestCase.TestRunInfo runInfo =
+                new LambdaFormTestCase.TestRunInfo(testMethods.size(), Helper.TEST_LIMIT);
+        TimeLimitedRunner runner = new TimeLimitedRunner(TIMEOUT, 4.0d,
+                () -> {
+                    if (runInfo.doneIterations >= runInfo.totalIterations) {
+                        return false;
         }
-        System.out.printf("Number of iterations is set to %d (%d cases)%n",
-                iterations, iterations * testCaseNum);
-        System.out.flush();
-        long startTime = System.currentTimeMillis();
-        for (long i = 0; i < iterations; i++) {
-            System.err.println(String.format("Iteration %d:", i));
+                    System.err.println(String.format("Iteration %d:", runInfo.doneIterations));
             for (TestMethods testMethod : testMethods) {
                 LambdaFormTestCase testCase = ctor.apply(testMethod);
                 try {
                     System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n",
                             testCase.getTestMethod().name);
                     testCase.doTest();
                     System.err.println("PASSED");
                 } catch (Throwable t) {
                     t.printStackTrace();
                     System.err.println("FAILED");
-                    passed = false;
-                    failCounter++;
-                }
-                testCounter++;
+                            runInfo.passed = false;
+                            runInfo.failCounter++;
             }
-            long passedTime = System.currentTimeMillis() - startTime;
-            long avgIterTime = passedTime / (i + 1);
-            long remainTime = TIMEOUT - passedTime;
-            if (avgIterTime > 2 * remainTime) {
-                System.err.printf("Stopping iterations because of lack of time.%n"
-                        + "Increase timeout factor for more iterations.%n");
-                break;
+                        runInfo.testCounter++;
             }
+                    runInfo.doneIterations++;
+                    return true;
+                });
+        try {
+            runner.call();
+        } catch (Exception ex) {
+            System.err.println("FAILED");
+            throw new Error("Unexpected error!", ex);
         }
-        if (!passed) {
+        if (!runInfo.passed) {
             throw new Error(String.format("%d of %d test cases FAILED! %n"
                     + "Rerun the test with the same \"-Dseed=\" option as in the log file!",
-                    failCounter, testCounter));
+                    runInfo.failCounter, runInfo.testCounter));
         } else {
-            System.err.println(String.format("All %d test cases PASSED!", testCounter));
+            System.err.println(String.format("All %d test cases PASSED!", runInfo.testCounter));
         }
     }
 }