mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-04 21:20:17 +00:00
8009982: Lazy execution bugfix. Added lazy sunspider unit test. Added mandreel to compile-octane test. Fixed warnings
Reviewed-by: sundar, jlaskey
This commit is contained in:
parent
d671cda73c
commit
2aeaf10fff
@ -176,7 +176,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
|
||||
|
||||
// -- Internals only below this point
|
||||
|
||||
private void checkConfigPermission() {
|
||||
private static void checkConfigPermission() {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission("nashorn.setConfig"));
|
||||
|
||||
@ -3230,8 +3230,7 @@ final class CodeGenerator extends NodeOperatorVisitor {
|
||||
}
|
||||
|
||||
private void newFunctionObject(final FunctionNode functionNode) {
|
||||
final boolean isLazy = functionNode.isLazy();
|
||||
final Class<?>[] cparams = new Class<?>[] { RecompilableScriptFunctionData.class, ScriptObject.class };
|
||||
final boolean isLazy = functionNode.isLazy();
|
||||
|
||||
new ObjectCreator(this, new ArrayList<String>(), new ArrayList<Symbol>(), false, false) {
|
||||
@Override
|
||||
@ -3246,7 +3245,7 @@ final class CodeGenerator extends NodeOperatorVisitor {
|
||||
} else {
|
||||
m.loadNull();
|
||||
}
|
||||
m.invoke(constructorNoLookup(className, cparams));
|
||||
m.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class));
|
||||
}
|
||||
}.makeObject(method);
|
||||
}
|
||||
|
||||
@ -217,8 +217,6 @@ public final class Compiler {
|
||||
append(safeSourceName(functionNode.getSource()));
|
||||
|
||||
this.scriptName = sb.toString();
|
||||
|
||||
LOG.info("Initializing compiler for '" + functionNode.getName() + "' scriptName = " + scriptName + ", root function: '" + functionNode.getName() + "' lazy=" + functionNode.isLazy());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,7 +359,10 @@ public final class Compiler {
|
||||
final Map<String, Class<?>> installedClasses = new HashMap<>();
|
||||
|
||||
final String rootClassName = firstCompileUnitName();
|
||||
final Class<?> rootClass = install(rootClassName, bytecode.get(rootClassName));
|
||||
final byte[] rootByteCode = bytecode.get(rootClassName);
|
||||
final Class<?> rootClass = install(rootClassName, rootByteCode);
|
||||
|
||||
int length = rootByteCode.length;
|
||||
|
||||
installedClasses.put(rootClassName, rootClass);
|
||||
|
||||
@ -370,7 +371,10 @@ public final class Compiler {
|
||||
if (className.equals(rootClassName)) {
|
||||
continue;
|
||||
}
|
||||
installedClasses.put(className, install(className, entry.getValue()));
|
||||
final byte[] code = entry.getValue();
|
||||
length += code.length;
|
||||
|
||||
installedClasses.put(className, install(className, code));
|
||||
}
|
||||
|
||||
for (final CompileUnit unit : compileUnits) {
|
||||
@ -388,12 +392,32 @@ public final class Compiler {
|
||||
}
|
||||
});
|
||||
|
||||
LOG.info("Installed root class: " + rootClass + " and " + bytecode.size() + " compile unit classes");
|
||||
final StringBuilder sb;
|
||||
if (LOG.isEnabled()) {
|
||||
sb = new StringBuilder();
|
||||
sb.append("Installed class '").
|
||||
append(rootClass.getSimpleName()).
|
||||
append('\'').
|
||||
append(" bytes=").
|
||||
append(length).
|
||||
append('.');
|
||||
if (bytecode.size() > 1) {
|
||||
sb.append(' ').append(bytecode.size()).append(" compile units.");
|
||||
}
|
||||
} else {
|
||||
sb = null;
|
||||
}
|
||||
|
||||
if (Timing.isEnabled()) {
|
||||
final long duration = System.currentTimeMillis() - t0;
|
||||
Timing.accumulateTime("[Code Installation]", duration);
|
||||
LOG.info("Installation time: " + duration + " ms");
|
||||
if (sb != null) {
|
||||
sb.append(" Install time: ").append(duration).append(" ms");
|
||||
}
|
||||
}
|
||||
|
||||
if (sb != null) {
|
||||
LOG.info(sb.toString());
|
||||
}
|
||||
|
||||
return rootClass;
|
||||
|
||||
@ -218,8 +218,9 @@ public class FunctionNode extends Block {
|
||||
private static final int HAS_ALL_VARS_IN_SCOPE = HAS_DEEP_WITH_OR_EVAL | IS_SPLIT | HAS_LAZY_CHILDREN;
|
||||
/** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */
|
||||
private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL;
|
||||
/** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep with or eval. */
|
||||
private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_WITH_OR_EVAL;
|
||||
/** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep with or eval.
|
||||
* We also pessimistically need a parent scope if we have lazy children that have not yet been compiled */
|
||||
private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_WITH_OR_EVAL | HAS_LAZY_CHILDREN;
|
||||
|
||||
/** What is the return type of this function? */
|
||||
private Type returnType = Type.UNKNOWN;
|
||||
@ -724,13 +725,10 @@ public class FunctionNode extends Block {
|
||||
* their parent scope, functions that reference themselves, and non-strict functions that need an Arguments object
|
||||
* (since it exposes {@code arguments.callee} property) will need to have a callee parameter.
|
||||
*
|
||||
* We also conservatively need a callee if we have lazy children, i.e. nested function nodes that have not yet
|
||||
* been evaluated. _They_ may need the callee and we don't know it
|
||||
*
|
||||
* @return true if the function's generated Java method needs a {@code callee} parameter.
|
||||
*/
|
||||
public boolean needsCallee() {
|
||||
return hasLazyChildren() || needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode());
|
||||
return needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1076,7 +1074,7 @@ public class FunctionNode extends Block {
|
||||
} else {
|
||||
this.flags |= USES_ANCESTOR_SCOPE;
|
||||
final FunctionNode parentFn = findParentFunction();
|
||||
if(parentFn != null) {
|
||||
if (parentFn != null) {
|
||||
parentFn.setUsesScopeSymbol(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1528,8 +1528,9 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
|
||||
addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
|
||||
}
|
||||
|
||||
private void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
|
||||
private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
for (Field f : scriptEnv.getClass().getFields()) {
|
||||
try {
|
||||
|
||||
@ -126,7 +126,7 @@ public class Parser extends AbstractParser {
|
||||
/** Namespace for function names where not explicitly given */
|
||||
private final Namespace namespace;
|
||||
|
||||
private static DebugLogger LOG = new DebugLogger("parser");
|
||||
private static final DebugLogger LOG = new DebugLogger("parser");
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
||||
@ -744,6 +744,7 @@ public final class Context {
|
||||
global = (GlobalObject)Context.getGlobalTrusted();
|
||||
script = global.findCachedClass(source);
|
||||
if (script != null) {
|
||||
Compiler.LOG.fine("Code cache hit for " + source + " avoiding recompile.");
|
||||
return script;
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,8 +60,7 @@ final class ScriptLoader extends NashornLoader {
|
||||
synchronized Class<?> installClass(final String name, final byte[] data, final CodeSource cs) {
|
||||
if (cs == null) {
|
||||
return defineClass(name, data, 0, data.length, new ProtectionDomain(null, getPermissions(null)));
|
||||
} else {
|
||||
return defineClass(name, data, 0, data.length, cs);
|
||||
}
|
||||
return defineClass(name, data, 0, data.length, cs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,6 +412,7 @@ public final class JavaAdapterFactory {
|
||||
public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType) throws Exception {
|
||||
final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType });
|
||||
return AccessController.doPrivileged(new PrivilegedExceptionAction<MethodHandle>() {
|
||||
@Override
|
||||
public MethodHandle run() throws Exception {
|
||||
return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get(
|
||||
"dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
|
||||
|
||||
@ -95,14 +95,14 @@ public class DefaultRegExp extends RegExp {
|
||||
return null; // never matches or similar, e.g. a[]
|
||||
}
|
||||
|
||||
RegExpMatcher matcher = this.matcher;
|
||||
RegExpMatcher currentMatcher = this.matcher;
|
||||
|
||||
if (matcher == null || matcher.getInput() != str) {
|
||||
matcher = new DefaultMatcher(str);
|
||||
this.matcher = matcher;
|
||||
if (currentMatcher == null || matcher.getInput() != str) {
|
||||
currentMatcher = new DefaultMatcher(str);
|
||||
this.matcher = currentMatcher;
|
||||
}
|
||||
|
||||
return matcher;
|
||||
return currentMatcher;
|
||||
}
|
||||
|
||||
class DefaultMatcher implements RegExpMatcher {
|
||||
|
||||
@ -97,14 +97,14 @@ public class JoniRegExp extends RegExp {
|
||||
return null;
|
||||
}
|
||||
|
||||
RegExpMatcher matcher = this.matcher;
|
||||
RegExpMatcher currentMatcher = this.matcher;
|
||||
|
||||
if (matcher == null || input != matcher.getInput()) {
|
||||
matcher = new JoniMatcher(input);
|
||||
this.matcher = matcher;
|
||||
if (currentMatcher == null || input != currentMatcher.getInput()) {
|
||||
currentMatcher = new JoniMatcher(input);
|
||||
this.matcher = currentMatcher;
|
||||
}
|
||||
|
||||
return matcher;
|
||||
return currentMatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -156,7 +156,7 @@ public abstract class RegExp {
|
||||
*
|
||||
* @param key the message key
|
||||
* @param str string argument
|
||||
* @throws jdk.nashorn.internal.runtime.ParserException
|
||||
* @throws jdk.nashorn.internal.runtime.ParserException unconditionally
|
||||
*/
|
||||
protected static void throwParserException(final String key, final String str) throws ParserException {
|
||||
throw new ParserException(ECMAErrors.getMessage("parser.error.regex." + key, str));
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package jdk.nashorn.internal.runtime.regexp;
|
||||
|
||||
import jdk.nashorn.internal.parser.Lexer;
|
||||
import jdk.nashorn.internal.runtime.ParserException;
|
||||
import jdk.nashorn.internal.runtime.options.Options;
|
||||
|
||||
@ -35,7 +34,6 @@ import jdk.nashorn.internal.runtime.options.Options;
|
||||
*/
|
||||
public class RegExpFactory {
|
||||
|
||||
|
||||
private final static RegExpFactory instance;
|
||||
|
||||
private final static String JDK = "jdk";
|
||||
@ -60,7 +58,8 @@ public class RegExpFactory {
|
||||
* Creates a Regular expression from the given {@code pattern} and {@code flags} strings.
|
||||
*
|
||||
* @param pattern RegExp pattern string
|
||||
* @param flags RegExp flags string
|
||||
* @param flags RegExp flags string
|
||||
* @return new RegExp
|
||||
* @throws ParserException if flags is invalid or pattern string has syntax error.
|
||||
*/
|
||||
protected RegExp compile(final String pattern, final String flags) throws ParserException {
|
||||
@ -71,8 +70,8 @@ public class RegExpFactory {
|
||||
* Compile a regexp with the given {@code source} and {@code flags}.
|
||||
*
|
||||
* @param pattern RegExp pattern string
|
||||
* @param flags flag string
|
||||
*
|
||||
* @param flags flag string
|
||||
* @return new RegExp
|
||||
* @throws ParserException if invalid source or flags
|
||||
*/
|
||||
public static RegExp create(final String pattern, final String flags) {
|
||||
|
||||
@ -80,11 +80,11 @@ public final class RegExpResult {
|
||||
|
||||
/**
|
||||
* Get the group with the given index or the empty string if group index is not valid.
|
||||
* @param index the group index
|
||||
* @param groupIndex the group index
|
||||
* @return the group or ""
|
||||
*/
|
||||
public Object getGroup(int index) {
|
||||
return index >= 0 && index < groups.length ? groups[index] : "";
|
||||
public Object getGroup(final int groupIndex) {
|
||||
return groupIndex >= 0 && groupIndex < groups.length ? groups[groupIndex] : "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -182,8 +182,6 @@ final class RegExpScanner extends Scanner {
|
||||
* @return Committed token
|
||||
*/
|
||||
private boolean commit(final int n) {
|
||||
final int startIn = position;
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
sb.append(ch0);
|
||||
|
||||
@ -16,6 +16,9 @@ Compiled OK: earley-boyer.js
|
||||
Compiling... gbemu.js
|
||||
Compiled OK: gbemu.js
|
||||
|
||||
Compiling... mandreel.js
|
||||
Compiled OK: mandreel.js
|
||||
|
||||
Compiling... navier-stokes.js
|
||||
Compiled OK: navier-stokes.js
|
||||
|
||||
|
||||
@ -31,7 +31,8 @@ var tests = [
|
||||
"crypto.js",
|
||||
"deltablue.js",
|
||||
"earley-boyer.js",
|
||||
"gbemu.js",
|
||||
"gbemu.js",
|
||||
"mandreel.js",
|
||||
"navier-stokes.js",
|
||||
"pdfjs.js",
|
||||
"raytrace.js",
|
||||
@ -49,6 +50,12 @@ var ignoreTeardown = [
|
||||
{ name: "gbemu.js" },
|
||||
];
|
||||
|
||||
|
||||
//TODO mandreel can be compiled as a test, but not run multiple times unless modified to not have global state
|
||||
var compileOnly = {
|
||||
"mandreel.js" : true
|
||||
};
|
||||
|
||||
var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
|
||||
|
||||
// TODO: why is this path hard coded when it's defined in project properties?
|
||||
@ -63,6 +70,10 @@ function endsWith(str, suffix) {
|
||||
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||
}
|
||||
|
||||
function should_compile_only(name) {
|
||||
return (typeof compile_only !== 'undefined') || compileOnly[name] === true;
|
||||
}
|
||||
|
||||
function run_one_benchmark(arg, iters) {
|
||||
|
||||
var file_name;
|
||||
@ -77,14 +88,18 @@ function run_one_benchmark(arg, iters) {
|
||||
}
|
||||
file_name = file[file.length - 1];
|
||||
|
||||
if (typeof compile_only !== 'undefined') {
|
||||
var compile_and_return = should_compile_only(file_name);
|
||||
if (compile_and_return) {
|
||||
if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
|
||||
return;
|
||||
}
|
||||
print("Compiling... " + file_name);
|
||||
}
|
||||
|
||||
load(path + 'base.js');
|
||||
load(arg);
|
||||
|
||||
if (typeof compile_only !== 'undefined') {
|
||||
if (compile_and_return) {
|
||||
print("Compiled OK: " + file_name);
|
||||
print("");
|
||||
return;
|
||||
@ -164,7 +179,7 @@ function run_one_benchmark(arg, iters) {
|
||||
|
||||
function run_suite(tests, iters) {
|
||||
for (var idx = 0; idx < tests.length; idx++) {
|
||||
run_one_benchmark(tests[idx], iters, false);
|
||||
run_one_benchmark(tests[idx], iters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
nashorn/test/script/basic/runsunspider-eager.js
Normal file
33
nashorn/test/script/basic/runsunspider-eager.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* runsunspider : runs the sunspider tests and checks for compliance
|
||||
*
|
||||
* @test
|
||||
* @option -timezone=PST
|
||||
* @runif external.sunspider
|
||||
*/
|
||||
|
||||
load(__DIR__ + "runsunspider.js");
|
||||
|
||||
34
nashorn/test/script/basic/runsunspider-lazy.js
Normal file
34
nashorn/test/script/basic/runsunspider-lazy.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* runsunspider : runs the sunspider tests and checks for compliance
|
||||
*
|
||||
* @test
|
||||
* @option -timezone=PST
|
||||
* @option --lazy-compilation
|
||||
* @runif external.sunspider
|
||||
*/
|
||||
|
||||
load(__DIR__ + "runsunspider.js");
|
||||
|
||||
@ -24,39 +24,11 @@
|
||||
/**
|
||||
* runsunspider : runs the sunspider tests and checks for compliance
|
||||
*
|
||||
* @test
|
||||
* @option -timezone=PST
|
||||
* @runif external.sunspider
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is not a test, but a test "framework" for running sunspider tests.
|
||||
*
|
||||
*/
|
||||
|
||||
function assertEq(a, b) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user