21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 import com.oracle.testlibrary.jsr292.Helper; |
24 import com.oracle.testlibrary.jsr292.Helper; |
25 import com.sun.management.HotSpotDiagnosticMXBean; |
25 import com.sun.management.HotSpotDiagnosticMXBean; |
26 |
26 import java.lang.invoke.MethodHandle; |
27 import java.lang.management.GarbageCollectorMXBean; |
27 import java.lang.management.GarbageCollectorMXBean; |
28 import java.lang.management.ManagementFactory; |
28 import java.lang.management.ManagementFactory; |
|
29 import java.lang.ref.Reference; |
|
30 import java.lang.reflect.Field; |
29 import java.lang.reflect.Method; |
31 import java.lang.reflect.Method; |
30 import java.util.Collection; |
32 import java.util.Collection; |
31 import java.util.List; |
33 import java.util.List; |
32 import java.util.function.Function; |
34 import java.util.function.Function; |
33 import jdk.testlibrary.Utils; |
35 import jdk.testlibrary.Utils; |
40 * |
42 * |
41 * @author kshefov |
43 * @author kshefov |
42 */ |
44 */ |
43 public abstract class LambdaFormTestCase { |
45 public abstract class LambdaFormTestCase { |
44 |
46 |
45 private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle"; |
|
46 private final static String INTERNAL_FORM_METHOD_NAME = "internalForm"; |
|
47 private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO |
47 private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO |
48 = 45 / (128.0 * 1024 * 1024); |
48 = 45 / (128.0 * 1024 * 1024); |
49 private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9); |
49 private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9); |
50 |
50 |
51 /** |
51 /** |
52 * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is |
52 * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is |
53 * used to get a lambda form from a method handle. |
53 * used to get a lambda form from a method handle. |
54 */ |
54 */ |
55 protected final static Method INTERNAL_FORM; |
55 protected final static Method INTERNAL_FORM; |
|
56 protected final static Field DEBUG_NAME; |
|
57 protected final static Field REF_FIELD; |
56 private static final List<GarbageCollectorMXBean> gcInfo; |
58 private static final List<GarbageCollectorMXBean> gcInfo; |
57 |
59 |
58 private static long gcCount() { |
60 private static long gcCount() { |
59 return gcInfo.stream().mapToLong(GarbageCollectorMXBean::getCollectionCount).sum(); |
61 return gcInfo.stream().mapToLong(GarbageCollectorMXBean::getCollectionCount).sum(); |
60 } |
62 } |
61 |
63 |
62 static { |
64 static { |
63 try { |
65 try { |
64 Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME); |
66 INTERNAL_FORM = MethodHandle.class.getDeclaredMethod("internalForm"); |
65 INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME); |
|
66 INTERNAL_FORM.setAccessible(true); |
67 INTERNAL_FORM.setAccessible(true); |
|
68 |
|
69 DEBUG_NAME = Class.forName("java.lang.invoke.LambdaForm").getDeclaredField("debugName"); |
|
70 DEBUG_NAME.setAccessible(true); |
|
71 |
|
72 REF_FIELD = Reference.class.getDeclaredField("referent"); |
|
73 REF_FIELD.setAccessible(true); |
67 } catch (Exception ex) { |
74 } catch (Exception ex) { |
68 throw new Error("Unexpected exception: ", ex); |
75 throw new Error("Unexpected exception: ", ex); |
69 } |
76 } |
70 |
77 |
71 gcInfo = ManagementFactory.getGarbageCollectorMXBeans(); |
78 gcInfo = ManagementFactory.getGarbageCollectorMXBeans(); |
136 try { |
143 try { |
137 System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n", |
144 System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n", |
138 testCase.getTestMethod().name); |
145 testCase.getTestMethod().name); |
139 testCase.doTest(); |
146 testCase.doTest(); |
140 System.err.println("PASSED"); |
147 System.err.println("PASSED"); |
|
148 } catch (OutOfMemoryError e) { |
|
149 // Don't swallow OOME so a heap dump can be created. |
|
150 System.err.println("FAILED"); |
|
151 throw e; |
141 } catch (Throwable t) { |
152 } catch (Throwable t) { |
142 t.printStackTrace(); |
153 t.printStackTrace(); |
143 System.err.printf("FAILED. Caused by %s%n", t.getMessage()); |
154 System.err.printf("FAILED. Caused by %s%n", t.getMessage()); |
144 passed = false; |
155 passed = false; |
145 failCounter++; |
156 failCounter++; |