8060724: ant test262parallel in Nashorn spends a significant amount of time after almost all the tests are run
authorhannesw
Mon, 20 Oct 2014 14:09:17 +0200
changeset 27207 1f26a24d639a
parent 27206 d4a707c9db5a
child 27208 e8a33eadb339
8060724: ant test262parallel in Nashorn spends a significant amount of time after almost all the tests are run Reviewed-by: lagergren, attila, sundar
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java
nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Mon Oct 20 12:06:36 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Mon Oct 20 14:09:17 2014 +0200
@@ -150,6 +150,13 @@
         private final Context      context;
         private final ScriptLoader loader;
         private final CodeSource   codeSource;
+        private int usageCount = 0;
+        private int bytesDefined = 0;
+
+        // We reuse this installer for 10 compilations or 200000 defined bytes. Usually the first condition
+        // will occur much earlier, the second is a safety measure for very large scripts/functions.
+        private final static int MAX_USAGES = 10;
+        private final static int MAX_BYTES_DEFINED = 200_000;
 
         private ContextCodeInstaller(final Context context, final ScriptLoader loader, final CodeSource codeSource) {
             this.context    = context;
@@ -168,6 +175,8 @@
 
         @Override
         public Class<?> install(final String className, final byte[] bytecode) {
+            usageCount++;
+            bytesDefined += bytecode.length;
             final String   binaryName = Compiler.binaryName(className);
             return loader.installClass(binaryName, bytecode, codeSource);
         }
@@ -225,6 +234,10 @@
 
         @Override
         public CodeInstaller<ScriptEnvironment> withNewLoader() {
+            // Reuse this installer if we're within our limits.
+            if (usageCount < MAX_USAGES && bytesDefined < MAX_BYTES_DEFINED) {
+                return this;
+            }
             return new ContextCodeInstaller(context, context.createNewLoader(), codeSource);
         }
 
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java	Mon Oct 20 12:06:36 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java	Mon Oct 20 14:09:17 2014 +0200
@@ -78,7 +78,8 @@
     // ParallelTestRunner-specific
     private static final String    TEST_JS_THREADS     = "test.js.threads";
     private static final String    TEST_JS_REPORT_FILE = "test.js.report.file";
-    private static final int       THREADS             = Integer.getInteger(TEST_JS_THREADS, Runtime.getRuntime().availableProcessors());
+    // test262 does a lot of eval's and the JVM hates multithreaded class definition, so lower thread count is usually faster.
+    private static final int       THREADS = Integer.getInteger(TEST_JS_THREADS, Runtime.getRuntime().availableProcessors() > 4 ? 4 : 2);
 
     private final List<ScriptRunnable> tests    = new ArrayList<>();
     private final Set<String>      orphans  = new TreeSet<>();