8043632: Parallelize class installation and various script fixes

Reviewed-by: sundar, attila
This commit is contained in:
Marcus Lagergren 2014-05-21 16:12:40 +02:00
parent cc1275a3bf
commit b4b7b4e53d
11 changed files with 157 additions and 211 deletions

51
nashorn/bin/run_octane.sh Normal file
View File

@ -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

View File

@ -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 @@ $FLAGS \
-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 @@ jdk.nashorn.tools.Shell ${@}
# 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

View File

@ -737,26 +737,6 @@ an implementation based on Joni, the regular expression engine used by
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 @@ etc. It will also show the internal representation of respective field
(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

View File

@ -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>

View File

@ -55,6 +55,7 @@ import java.util.List;
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 @@ enum CompilationPhase {
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 @@ enum CompilationPhase {
@Override
public String toString() {
return "'Class Installation'";
}
}
};
/** pre conditions required for function node to which this transform is to be applied */

View File

@ -95,7 +95,8 @@ public final class ScriptEnvironment {
/** 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 {

View File

@ -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");

View File

@ -1,4 +0,0 @@
289
11094405
4294967293
-4722

View File

@ -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");

View File

@ -1,4 +0,0 @@
289
11094405
4294967293
-4722

View File

@ -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());