8043632: Parallelize class installation and various script fixes.
Reviewed-by: sundar, attila
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/bin/run_octane.sh Wed May 21 16:12:40 2014 +0200
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Copyright (c) 2010, 2014, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+LOG="./octane_$(date|sed "s/ /_/g"|sed "s/:/_/g").log"
+
+run_one() {
+ sh ../bin/runopt.sh -scripting ../test/script/basic/run-octane.js -- $1 --verbose --iterations 25 | tee -a $LOG
+}
+
+if [ -z $1 ]; then
+
+ run_one "box2d"
+ run_one "code-load"
+ run_one "crypto"
+ run_one "deltablue"
+ run_one "earley-boyer"
+ run_one "gbemu"
+ run_one "mandreel"
+ run_one "navier-stokes"
+ run_one "pdfjs"
+ run_one "raytrace"
+ run_one "regexp"
+ run_one "richards"
+ run_one "splay"
+ run_one "typescript"
+ run_one "zlib"
+
+else
+ run_one $1
+fi
--- a/nashorn/bin/runopt.sh Wed May 21 16:12:40 2014 +0200
+++ b/nashorn/bin/runopt.sh Wed May 21 16:12:40 2014 +0200
@@ -1,4 +1,26 @@
#!/bin/sh
+#
+# Copyright (c) 2010, 2014, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
###########################################################################################
# This is a helper script to evaluate nashorn with optimistic types
@@ -23,6 +45,7 @@
# set the "method-sampling-interval" Normal and Maximum sample time as low as you
# can go (10 ms on most platforms). The default is normally higher. The increased
# sampling overhead is usually negligible for Nashorn runs, but the data is better
+
JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
@@ -44,15 +67,21 @@
-esa \
-Xbootclasspath/p:$NASHORN_JAR \
-Xms2G -Xmx2G \
--XX:+UnlockCommercialFeatures \
--XX:+FlightRecorder \
--XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024 \
-XX:TypeProfileLevel=222 \
-cp $CLASSPATH:../build/test/classes/ \
jdk.nashorn.tools.Shell ${@}
# Below are flags that may come in handy, but aren't used for default runs
+# Testing out new code optimizations using the generic hotspot "new code" parameter
+#-XX:+UnlockDiagnosticVMOptions \
+#-XX:+UseNewCode \
+
+# Flight recorder
+#-XX:+UnlockCommercialFeatures \
+#-XX:+FlightRecorder \
+#-XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024 \
+
# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine,
# keeping this flag around for experimental reasons. Replace + with - to switch it off
@@ -76,10 +105,6 @@
# compiler threads is set to 1 for determinsm.
#-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \
+# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments)
+# -XX:IncreaseFirstTierCompileThresholdAt=XX
-#[20/05/14 14:05:54] Albert Noll: IncreaseFirstTierCompileThresholdAt=XX
-#[20/05/14 14:06:03] Albert Noll: where X is between 1..100
-#[20/05/14 14:06:33] Albert Noll: The smaller X is, the less methods are being compiled with C1
-#[20/05/14 14:07:37] Albert Noll: You can also do more aggressive sweeping with:
-# NmethodSweepActivity=XX
-#[20/05/14 14:07:47] Albert Noll: The default value is 10
--- a/nashorn/docs/DEVELOPER_README Wed May 21 16:12:40 2014 +0200
+++ b/nashorn/docs/DEVELOPER_README Wed May 21 16:12:40 2014 +0200
@@ -737,26 +737,6 @@
the JRuby project. The default value for this flag is "joni"
-SYSTEM PROPERTY: -Dnashorn.time
-
-This enables timers for various phases of script compilation. The timers
-will be dumped when the Nashorn process exits. We see a percentage value
-of how much time was spent not executing bytecode (i.e. compilation and
-internal tasks) at the end of the report.
-
-Here is an example:
-
-[JavaScript Parsing] 61 ms
-[Constant Folding] 11 ms
-[Control Flow Lowering] 26 ms
-[Type Attribution] 81 ms
-[Range Analysis] 0 ms
-[Code Splitting] 29 ms
-[Type Finalization] 19 ms
-[Bytecode Generation] 189 ms
-[Code Installation] 7 ms
-Total runtime: 508 ms (Non-runtime: 423 ms [83%])
-
===============
2. The loggers.
===============
@@ -887,6 +867,34 @@
(Object in the normal case, unless running with the dual field
representation)
+* time
+
+This enables timers for various phases of script compilation. The timers
+will be dumped when the Nashorn process exits. We see a percentage value
+of how much time was spent not executing bytecode (i.e. compilation and
+internal tasks) at the end of the report.
+
+A finer level than "info" will show individual compilation timings as they
+happen.
+
+Here is an example:
+
+[time] Accumulated complation phase Timings:
+[time]
+[time] 'JavaScript Parsing' 1076 ms
+[time] 'Constant Folding' 159 ms
+[time] 'Control Flow Lowering' 303 ms
+[time] 'Program Point Calculation' 282 ms
+[time] 'Builtin Replacement' 71 ms
+[time] 'Code Splitting' 670 ms
+[time] 'Symbol Assignment' 474 ms
+[time] 'Scope Depth Computation' 249 ms
+[time] 'Optimistic Type Assignment' 186 ms
+[time] 'Local Variable Type Calculation' 526 ms
+[time] 'Bytecode Generation' 5177 ms
+[time] 'Class Installation' 1854 ms
+[time]
+[time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%])
=======================
3. Undocumented options
--- a/nashorn/make/build-benchmark.xml Wed May 21 16:12:40 2014 +0200
+++ b/nashorn/make/build-benchmark.xml Wed May 21 16:12:40 2014 +0200
@@ -24,12 +24,12 @@
<project name="nashorn-benchmarks" default="all" basedir="..">
<target name="octane-init" depends="jar">
- <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes pdfjs raytrace regexp richards splay"/>
+ <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes mandreel pdfjs raytrace regexp richards splay typescript zlib"/>
</target>
- <!-- ignore benchmarks where rhino crashes -->
+ <!-- ignore benchmarks where rhino crashes - the test harness should do this now -->
<target name="octane-init-rhino" depends="jar">
- <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes raytrace regexp richards splay"/>
+ <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes mandreel pdfjs raytrace regexp richards splay typescript zlib"/>
</target>
<!-- box2d -->
@@ -151,7 +151,6 @@
</antcall>
</target>
-
<!-- mandreel -->
<target name="octane-mandreel" depends="jar">
<antcall target="run-octane">
@@ -333,14 +332,13 @@
<target name="octane-single-process" depends="octane-init">
<antcall target="run-octane"/>
</target>
-
- <!-- zlib excluded due to missing implementation of 'read' -->
+
<target name="octane-separate-process" depends=
"octane-box2d, octane-code-load, octane-crypto,
octane-deltablue, octane-earley-boyer, octane-gbemu,
octane-mandreel, octane-navier-stokes, octane-pdfjs,
octane-raytrace, octane-regexp, octane-richards,
- octane-splay, octane-typescript"/>
+ octane-splay, octane-typescript, octane-zlib"/>
<target name="--single-process" unless="${octane-test-sys-prop.separate.process}">
<antcall target="octane-single-process"/>
@@ -373,12 +371,13 @@
<propertyref prefix="nashorn."/>
</syspropertyset>
<arg value="${octane-test-sys-prop.test.js.framework}"/>
+ <arg value="-scripting"/>
<arg value="--"/>
<arg value="${octane-tests}"/>
<arg value="--runtime"/>
<arg value="Nashorn"/>
<arg value="--verbose"/>
- <arg value="--iterations 8"/>
+ <arg value="--iterations 10"/>
</java>
</target>
@@ -390,7 +389,7 @@
<arg value="--runtime"/>
<arg value="v8"/>
<arg value="--verbose"/>
- <arg value="--iterations 8"/>
+ <arg value="--iterations 10"/>
</exec>
</target>
@@ -407,7 +406,7 @@
<arg value="--runtime"/>
<arg value="Rhino"/>
<arg value="--verbose"/>
- <arg value="--iterations 8"/>
+ <arg value="--iterations 10"/>
</java>
</target>
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed May 21 16:12:40 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed May 21 16:12:40 2014 +0200
@@ -55,6 +55,7 @@
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.function.Consumer;
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
import jdk.nashorn.internal.ir.FunctionNode;
@@ -513,34 +514,41 @@
throw new CompilationException("Internal compiler error: root class not found!");
}
- // do these in a loop, to use only one privileged action - this significantly
- // reduces class installation overhead
- log.fine("Preparing source and constant fields...");
- try {
- final Object[] constants = compiler.getConstantData().toArray();
- // Need doPrivileged because these fields are private
- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ // do these in parallel, this significantly reduces class installation overhead
+ // however - it still means that every thread needs a separate doPrivileged
+ final Object[] constants = compiler.getConstantData().toArray();
+ installedClasses.entrySet().parallelStream().forEach(
+ new Consumer<Entry<String, Class<?>>>() {
@Override
- public Void run() throws Exception {
- for (final Entry<String, Class<?>> entry : installedClasses.entrySet()) {
- final Class<?> clazz = entry.getValue();
- log.fine("Initializing source for ", clazz);
- //use reflection to write source and constants table to installed classes
- final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
- sourceField.setAccessible(true);
- sourceField.set(null, compiler.getSource());
+ public void accept(final Entry<String, Class<?>> entry) {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() {
+ try {
+ final Class<?> clazz = entry.getValue();
+ log.fine("Initializing source for ", clazz);
+ //use reflection to write source and constants table to installed classes
+ final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
+ sourceField.setAccessible(true);
+ sourceField.set(null, compiler.getSource());
- log.fine("Initializing constants for ", clazz);
- final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
- constantsField.setAccessible(true);
- constantsField.set(null, constants);
+ log.fine("Initializing constants for ", clazz);
+ final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
+ constantsField.setAccessible(true);
+ constantsField.set(null, constants);
+ } catch (final IllegalAccessException | NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+ });
+ } catch (final PrivilegedActionException e) {
+ throw new RuntimeException(e);
}
- return null;
}
});
- } catch (final PrivilegedActionException e) {
- throw new RuntimeException(e);
- }
+ log.fine("Done");
log.fine("Done");
// index recompilable script function datas in the constant pool
@@ -587,7 +595,8 @@
@Override
public String toString() {
return "'Class Installation'";
- }
+ }
+
};
/** pre conditions required for function node to which this transform is to be applied */
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Wed May 21 16:12:40 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Wed May 21 16:12:40 2014 +0200
@@ -95,7 +95,8 @@
/** Argument passed to compile only if optimistic compilation should take place */
public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic";
- /** * Behavior when encountering a function declaration in a lexical context where only statements are acceptable
+ /**
+ * Behavior when encountering a function declaration in a lexical context where only statements are acceptable
* (function declarations are source elements, but not statements).
*/
public enum FunctionStatementBehavior {
--- a/nashorn/test/script/basic/ranges_disabled.js Wed May 21 16:12:40 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * range analysis test. check that computation return values are correct
- * both with and without range analysis
- *
- * @test
- * @run
- */
-
-load(__DIR__ + "ranges_payload.js");
--- a/nashorn/test/script/basic/ranges_disabled.js.EXPECTED Wed May 21 16:12:40 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-289
-11094405
-4294967293
--4722
--- a/nashorn/test/script/basic/ranges_enabled.js Wed May 21 16:12:40 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * range analysis test. check that computation return values are correct
- * both with and without range analysis
- *
- * @test
- * @option --range-analysis
- * @run
- */
-
-load(__DIR__ + "ranges_payload.js");
--- a/nashorn/test/script/basic/ranges_enabled.js.EXPECTED Wed May 21 16:12:40 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-289
-11094405
-4294967293
--4722
--- a/nashorn/test/script/basic/ranges_payload.js Wed May 21 16:12:40 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * range analysis test. check that computation return values are correct
- * both with and without range analysis
- *
- * @subtest
- */
-
-function f(c) {
- var v = c & 0xffff;
- var w = v & 0xfff;
- var x = v * w;
- return x;
-}
-
-function g() {
- var sum = 0;
- for (var x = 0; x < 4711; x++) {
- sum += x;
- }
- return sum;
-}
-
-function g2() {
- var sum = 0;
- //make sure we overflow
- var displacement = 0x7ffffffe;
- for (var x = displacement; x < (displacement + 2); x++) {
- sum += x;
- }
- return sum;
-}
-
-//mostly provide code coverage for all the range operations
-function h() {
- var sum = 0;
- sum += 4711;
- sum &= 0xffff;
- sum /= 2;
- sum *= 2;
- sum -= 4;
- sum |= 2;
- sum ^= 17;
- sum = sum % 10000;
- sum = -sum;
- return sum
-}
-
-print(f(17));
-print(g());
-print(g2());
-print(h());