8222550: runtime/MemberName/MemberNameLeak.java times out
Reviewed-by: coleenp, dholmes
--- a/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java Thu Apr 18 09:27:28 2019 +0200
+++ b/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java Wed Apr 17 07:41:12 2019 +0200
@@ -33,10 +33,15 @@
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. MemberNameLeak
*/
+import java.io.*;
+import java.nio.file.*;
import java.lang.invoke.*;
import java.lang.reflect.*;
+import java.text.*;
+import java.util.*;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.Utils;
import sun.hotspot.WhiteBox;
import sun.hotspot.code.Compiler;
import sun.hotspot.gc.GC;
@@ -47,6 +52,7 @@
// The size of the ResolvedMethodTable is 1024. 2000 entries
// is enough to trigger a grow/cleaning of the table after a GC.
private static int methodCount = 2000;
+ public static ArrayList<MethodHandle> keepAlive;
static class Leak {
public void callMe() {
@@ -56,6 +62,8 @@
Leak leak = new Leak();
WhiteBox wb = WhiteBox.getWhiteBox();
+ keepAlive = new ArrayList<>(methodCount);
+
ClassWithManyMethodsClassLoader classLoader = new ClassWithManyMethodsClassLoader();
Class<?> clazz = classLoader.create(className, methodPrefix, methodCount);
@@ -74,14 +82,20 @@
MethodHandle mh1 = lookup.findSpecial(clazz, methodName, mt, clazz);
mh1.invoke(o);
+
+ keepAlive.add(mh1);
}
long after = wb.resolvedMethodItemsCount();
+ System.out.println("wb.resolvedMethodItemsCount() after setup: " + after);
+
if (after == before) {
throw new RuntimeException("Too few resolved methods");
}
+ keepAlive = null;
+
// Wait until ServiceThread cleans ResolvedMethod table
int cnt = 0;
while (true) {
@@ -99,11 +113,20 @@
}
}
+ private static Path createGcLogPath(String prefix) throws IOException {
+ Path gcLog = Utils.createTempFile(prefix, "log");
+ Files.delete(gcLog);
+ return gcLog;
+ }
+
+ private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
public static void test(GC gc, boolean doConcurrent) throws Throwable {
- System.err.println("test(" + gc + ", " + doConcurrent + ")");
+ Path gcLogPath = createGcLogPath("gc." + gc + "." + doConcurrent);
+ System.err.println("test(" + gc + ", " + doConcurrent + ")" + " " + dateFormat.format(new Date()));
// Run this Leak class with logging
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
- "-Xlog:membername+table=trace,gc+verify=debug",
+ "-Xlog:membername+table=trace,gc+verify=debug,gc:" + gcLogPath + ":time,utctime,uptime,pid,level,tags",
"-XX:+UnlockExperimentalVMOptions",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
@@ -115,13 +138,23 @@
"-XX:+ClassUnloadingWithConcurrentMark",
"-XX:+Use" + gc + "GC",
Leak.class.getName());
+
+ // Check process
OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.outputTo(System.out);
+ output.errorTo(System.err);
+ output.shouldHaveExitValue(0);
+
+ // Check gc log file
+ OutputAnalyzer gcLogOutput = new OutputAnalyzer(gcLogPath);
+
// Hardcoded names for classes generated by GeneratedClassLoader
String descriptor = className + "." + methodPrefix + "0()V";
- output.shouldContain("ResolvedMethod entry added for " + descriptor);
- output.shouldContain("ResolvedMethod entry found for " + descriptor);
- output.shouldContain("ResolvedMethod entry removed");
- output.shouldHaveExitValue(0);
+ gcLogOutput.shouldContain("ResolvedMethod entry added for " + descriptor);
+ gcLogOutput.shouldContain("ResolvedMethod entry found for " + descriptor);
+ gcLogOutput.shouldContain("ResolvedMethod entry removed");
+
+ System.err.println("test(" + gc + ", " + doConcurrent + ")" + " done " + dateFormat.format(new Date()));
}
private static boolean supportsSTW(GC gc) {