OpenJDK / jigsaw / jake / nashorn
changeset 1575:d47674217066
8138882: Performance regression due to anonymous classloading
Reviewed-by: attila, sundar
author | hannesw |
---|---|
date | Mon, 05 Oct 2015 18:58:21 +0200 |
parents | 68a026de1201 |
children | e281c7a891f9 |
files | src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptEnvironment.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties test/script/nosecurity/JDK-8044798.js |
diffstat | 4 files changed, 46 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Fri Oct 02 15:50:49 2015 +0200 +++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Mon Oct 05 18:58:21 2015 +0200 @@ -140,7 +140,7 @@ private static final LongAdder NAMED_INSTALLED_SCRIPT_COUNT = new LongAdder(); private static final LongAdder ANONYMOUS_INSTALLED_SCRIPT_COUNT = new LongAdder(); - private static final boolean DISABLE_VM_ANONYMOUS_CLASSES = Options.getBooleanProperty("nashorn.disableVmAnonymousClasses"); + /** * Should scripts use only object slots for fields, or dual long/object slots? The default * behaviour is to couple this to optimistic types, using dual representation if optimistic types are enabled @@ -775,7 +775,7 @@ * @return reusable compiled script across many global scopes. */ public MultiGlobalCompiledScript compileScript(final Source source) { - final Class<?> clazz = compile(source, this.errors, this._strict); + final Class<?> clazz = compile(source, this.errors, this._strict, false); final MethodHandle createProgramFunctionHandle = getCreateProgramFunctionHandle(clazz); return new MultiGlobalCompiledScript() { @@ -829,7 +829,7 @@ Class<?> clazz = null; try { - clazz = compile(source, new ThrowErrorManager(), strictFlag); + clazz = compile(source, new ThrowErrorManager(), strictFlag, true); } catch (final ParserException e) { e.throwAsEcmaException(global); return null; @@ -1379,10 +1379,10 @@ } private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) { - return getProgramFunction(compile(source, errMan, this._strict), scope); + return getProgramFunction(compile(source, errMan, this._strict, false), scope); } - private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) { + private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict, final boolean isEval) { // start with no errors, no warnings. errMan.reset(); @@ -1434,7 +1434,7 @@ final URL url = source.getURL(); final CodeSource cs = new CodeSource(url, (CodeSigner[])null); final CodeInstaller installer; - if (DISABLE_VM_ANONYMOUS_CLASSES || env._persistent_cache || !env._lazy_compilation) { + if (!env.useAnonymousClasses(isEval) || env._persistent_cache || !env._lazy_compilation) { // Persistent code cache and eager compilation preclude use of VM anonymous classes final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader; installer = new NamedContextCodeInstaller(this, cs, loader);
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptEnvironment.java Fri Oct 02 15:50:49 2015 +0200 +++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptEnvironment.java Mon Oct 05 18:58:21 2015 +0200 @@ -213,6 +213,14 @@ /** Timing */ public final Timing _timing; + /** Whether to use anonymous classes. See {@link #useAnonymousClasses(boolean)}. */ + private final AnonymousClasses _anonymousClasses; + private enum AnonymousClasses { + AUTO, + OFF, + ON + } + /** * Constructor * @@ -279,6 +287,18 @@ _version = options.getBoolean("version"); _verify_code = options.getBoolean("verify.code"); + final String anonClasses = options.getString("anonymous.classes"); + if (anonClasses == null || anonClasses.equals("auto")) { + _anonymousClasses = AnonymousClasses.AUTO; + } else if (anonClasses.equals("true")) { + _anonymousClasses = AnonymousClasses.ON; + } else if (anonClasses.equals("false")) { + _anonymousClasses = AnonymousClasses.OFF; + } else { + throw new RuntimeException("Unsupported value for anonymous classes: " + anonClasses); + } + + final String language = options.getString("language"); if (language == null || language.equals("es5")) { _es6 = false; @@ -411,4 +431,13 @@ return _timing != null ? _timing.isEnabled() : false; } + /** + * Returns true if compilation should use anonymous classes. + * @param isEval true if compilation is an eval call. + * @return true if anonymous classes should be used + */ + public boolean useAnonymousClasses(final boolean isEval) { + return _anonymousClasses == AnonymousClasses.ON || (_anonymousClasses == AnonymousClasses.AUTO && isEval); + } + }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties Fri Oct 02 15:50:49 2015 +0200 +++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties Mon Oct 05 18:58:21 2015 +0200 @@ -380,6 +380,15 @@ enterexit [trace callsite enter/exit], objects [print object properties]." \ } +nashorn.option.anonymous.classes = { \ + name="--anonymous-classes", \ + is_undocumented=true, \ + params=[auto|true|false], \ + default=auto, \ + type=string, \ + desc="Use VM anonymous classes for compiled scripts." \ +} + nashorn.option.verify.code = { \ name="--verify-code", \ is_undocumented=true, \
--- a/test/script/nosecurity/JDK-8044798.js Fri Oct 02 15:50:49 2015 +0200 +++ b/test/script/nosecurity/JDK-8044798.js Mon Oct 05 18:58:21 2015 +0200 @@ -126,12 +126,12 @@ // private compile method of Context class var compileMethod = Context.class.getDeclaredMethod("compile", - sourceCls, errorMgrCls, booleanCls); + sourceCls, errorMgrCls, booleanCls, booleanCls); compileMethod.accessible = true; var scriptCls = compileMethod.invoke(Context.context, Source.sourceFor("test", "print('hello')"), - new Context.ThrowErrorManager(), false); + new Context.ThrowErrorManager(), false, false); var SCRIPT_CLASS_NAME_PREFIX = "jdk.nashorn.internal.scripts.Script$"; print("script class name pattern satisfied? " +