8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option
authorkshefov
Wed, 17 Jun 2015 20:19:51 +0300
changeset 31179 a823fb6fdf2e
parent 31178 6ad68e35506d
child 31181 27ccb72932ee
8062904: TEST_BUG: Tests java/lang/invoke/LFCaching fail when run with -Xcomp option Reviewed-by: vlivanov
jdk/test/java/lang/invoke/LFCaching/LFCachingTestCase.java
jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java
jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java
jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java
jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java
--- a/jdk/test/java/lang/invoke/LFCaching/LFCachingTestCase.java	Wed Jun 17 20:17:25 2015 +0300
+++ b/jdk/test/java/lang/invoke/LFCaching/LFCachingTestCase.java	Wed Jun 17 20:19:51 2015 +0300
@@ -77,7 +77,7 @@
             }
         } catch (IllegalAccessException | IllegalArgumentException |
                 SecurityException | InvocationTargetException ex) {
-            throw new Error("Unexpected exception: ", ex);
+            throw new Error("Unexpected exception", ex);
         }
     }
 }
--- a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java	Wed Jun 17 20:17:25 2015 +0300
+++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java	Wed Jun 17 20:19:51 2015 +0300
@@ -24,6 +24,7 @@
 /*
  * @test LFGarbageCollectedTest
  * @bug 8046703
+ * @key randomness
  * @ignore 8078602
  * @summary Test verifies that lambda forms are garbage collected
  * @author kshefov
@@ -73,7 +74,7 @@
             try {
                 adapter = testCase.getTestCaseMH(data, TestMethods.Kind.ONE);
             } catch (NoSuchMethodException ex) {
-                throw new Error("Unexpected exception: ", ex);
+                throw new Error("Unexpected exception", ex);
             }
             mtype = adapter.type();
             Object lambdaForm = INTERNAL_FORM.invoke(adapter);
@@ -94,7 +95,7 @@
             collectLambdaForm();
         } catch (IllegalAccessException | IllegalArgumentException |
                 InvocationTargetException ex) {
-            throw new Error("Unexpected exception: ", ex);
+            throw new Error("Unexpected exception", ex);
         }
     }
 
--- a/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Wed Jun 17 20:17:25 2015 +0300
+++ b/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Wed Jun 17 20:19:51 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 /*
  * @test LFMultiThreadCachingTest
  * @bug 8046703
+ * @key randomness
  * @summary Test verifies that lambda forms are cached when run with multiple threads
  * @author kshefov
  * @library /lib/testlibrary/jsr292 /lib/testlibrary
@@ -35,18 +36,23 @@
  */
 
 import java.lang.invoke.MethodHandle;
+import java.util.Collections;
 import java.util.EnumSet;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.CyclicBarrier;
+import com.oracle.testlibrary.jsr292.CodeCacheOverflowProcessor;
 
 /**
  * Multiple threaded lambda forms caching test class.
  */
 public final class LFMultiThreadCachingTest extends LFCachingTestCase {
+
     private static final TestMethods.Kind[] KINDS;
+
     static {
         EnumSet<TestMethods.Kind> set = EnumSet.complementOf(EnumSet.of(TestMethods.Kind.EXCEPT));
         KINDS = set.toArray(new TestMethods.Kind[set.size()]);
@@ -72,21 +78,55 @@
         ConcurrentLinkedQueue<MethodHandle> adapters = new ConcurrentLinkedQueue<>();
         CyclicBarrier begin = new CyclicBarrier(CORES);
         CountDownLatch end = new CountDownLatch(CORES);
+        final Map<Thread, Throwable> threadUncaughtExceptions
+                = Collections.synchronizedMap(new HashMap<Thread, Throwable>(CORES));
+        Thread.UncaughtExceptionHandler exHandler = (t, e) -> {
+            threadUncaughtExceptions.put(t, e);
+        };
         for (int i = 0; i < CORES; ++i) {
             TestMethods.Kind kind = KINDS[i % KINDS.length];
-            new Thread(() -> {
+            Thread t = new Thread(() -> {
                 try {
                     begin.await();
                     adapters.add(getTestMethod().getTestCaseMH(data, kind));
-                } catch (InterruptedException | BrokenBarrierException | IllegalAccessException | NoSuchMethodException ex) {
-                    throw new Error("Unexpected exception: ", ex);
+                } catch (InterruptedException | BrokenBarrierException
+                        | IllegalAccessException | NoSuchMethodException ex) {
+                    throw new Error("Unexpected exception", ex);
                 } finally {
                     end.countDown();
                 }
-            }).start();
+            });
+            t.setUncaughtExceptionHandler(exHandler);
+            t.start();
         }
         try {
             end.await();
+            boolean vmeThrown = false;
+            boolean nonVmeThrown = false;
+            Throwable vme = null;
+            for (Map.Entry<Thread,
+                    Throwable> entry : threadUncaughtExceptions.entrySet()) {
+                Thread t =  entry.getKey();
+                Throwable e = entry.getValue();
+                System.err.printf("%nA thread with name \"%s\" of %d threads"
+                        + " has thrown exception:%n", t.getName(), CORES);
+                e.printStackTrace();
+                if (CodeCacheOverflowProcessor.isThrowableCausedByVME(e)) {
+                    vmeThrown = true;
+                    vme = e;
+                } else {
+                    nonVmeThrown = true;
+                }
+                if (nonVmeThrown) {
+                    throw new Error("One ore more threads have"
+                            + " thrown unexpected exceptions. See log.");
+                }
+                if (vmeThrown) {
+                    throw new Error("One ore more threads have"
+                            + " thrown VirtualMachineError caused by"
+                            + " code cache overflow. See log.", vme);
+                }
+            }
         } catch (InterruptedException ex) {
             throw new Error("Unexpected exception: ", ex);
         }
--- a/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java	Wed Jun 17 20:17:25 2015 +0300
+++ b/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java	Wed Jun 17 20:19:51 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 /*
  * @test LFSingleThreadCachingTest
  * @bug 8046703
+ * @key randomness
  * @summary Test verifies that lambda forms are cached when run with single thread
  * @author kshefov
  * @library /lib/testlibrary/jsr292 /lib/testlibrary
@@ -62,7 +63,7 @@
             adapter1 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
             adapter2 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.TWO);
         } catch (NoSuchMethodException | IllegalAccessException ex) {
-            throw new Error("Unexpected exception: ", ex);
+            throw new Error("Unexpected exception", ex);
         }
         checkLFCaching(adapter1, adapter2);
     }
--- a/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java	Wed Jun 17 20:17:25 2015 +0300
+++ b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java	Wed Jun 17 20:19:51 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
  */
 
 import com.oracle.testlibrary.jsr292.Helper;
-import com.sun.management.HotSpotDiagnosticMXBean;
+import com.oracle.testlibrary.jsr292.CodeCacheOverflowProcessor;
 import java.lang.invoke.MethodHandle;
 import java.lang.management.GarbageCollectorMXBean;
 import java.lang.management.ManagementFactory;
@@ -44,8 +44,6 @@
  */
 public abstract class LambdaFormTestCase {
 
-    private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO
-            = 45 / (128.0 * 1024 * 1024);
     private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9);
 
     /**
@@ -72,7 +70,7 @@
             REF_FIELD = Reference.class.getDeclaredField("referent");
             REF_FIELD.setAccessible(true);
         } catch (Exception ex) {
-            throw new Error("Unexpected exception: ", ex);
+            throw new Error("Unexpected exception", ex);
         }
 
         gcInfo = ManagementFactory.getGarbageCollectorMXBeans();
@@ -101,28 +99,6 @@
             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;
-            }
             System.out.printf("Number of iterations is set to %d (%d cases)%n",
                     iterations, iterations * testCaseNum);
             System.out.flush();
@@ -141,22 +117,27 @@
             for (TestMethods testMethod : testMethods) {
                 LambdaFormTestCase testCase = ctor.apply(testMethod);
                 try {
-                    System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n",
+                    System.err.printf("Tested LF caching feature"
+                            + " with MethodHandles.%s method.%n",
                             testCase.getTestMethod().name);
-                    testCase.doTest();
+                    Throwable t = CodeCacheOverflowProcessor
+                            .runMHTest(testCase::doTest);
+                    if (t != null) {
+                        return false;
+                    }
                     System.err.println("PASSED");
-                } catch (OutOfMemoryError e) {
+                } catch (OutOfMemoryError oome) {
                     // Don't swallow OOME so a heap dump can be created.
                     System.err.println("FAILED");
-                    throw e;
+                    throw oome;
                 } catch (Throwable t) {
                     t.printStackTrace();
                     System.err.printf("FAILED. Caused by %s%n", t.getMessage());
                     passed = false;
                     failCounter++;
                 }
-                    testCounter++;
-                }
+                testCounter++;
+            }
             doneIterations++;
             return true;
         }
@@ -205,8 +186,8 @@
      * @param testMethods list of test methods
      */
     public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
-        LambdaFormTestCase.TestRun run =
-                new LambdaFormTestCase.TestRun(ctor, testMethods);
+        LambdaFormTestCase.TestRun run
+                = new LambdaFormTestCase.TestRun(ctor, testMethods);
         TimeLimitedRunner runner = new TimeLimitedRunner(TIMEOUT, 4.0d, run::doIteration);
         try {
             runner.call();