Skip to content

Commit

Permalink
Consolidate multiple optimization levels down to one
Browse files Browse the repository at this point in the history
Replace the "optimization level" parameter in context with a single boolean called "interpretedMode". The old optimization level API is still there, but deprecated, and it works the same way, in that an "optimization" level of zero or higher triggers compiled mode, and less than zero triggers interpreted mode. And just as optimization level zero was previously the default, compiled mode is still the default.
  • Loading branch information
gbrail authored Dec 17, 2024
1 parent ebfedb3 commit 8f8c3dc
Show file tree
Hide file tree
Showing 42 changed files with 270 additions and 2,712 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public static class AbstractClassState {
public void init()
throws IllegalAccessException, InvocationTargetException, InstantiationException {
cx = Context.enter();
cx.setOptimizationLevel(9);
cx.setLanguageVersion(Context.VERSION_ES6);

scope = cx.initStandardObjects();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public static class MathState {
@Setup(Level.Trial)
public void setup() throws IOException {
cx = Context.enter();
cx.setOptimizationLevel(9);
cx.setLanguageVersion(Context.VERSION_ES6);
scope = cx.initStandardObjects();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public static class FieldTestState {
@SuppressWarnings("unused")
public void create() throws IOException {
cx = Context.enter();
cx.setOptimizationLevel(9);
cx.setLanguageVersion(Context.VERSION_ES6);

scope = new Global(cx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public static class PropertyState {
@Setup(Level.Trial)
public void setup() throws IOException {
cx = Context.enter();
cx.setOptimizationLevel(9);
cx.setLanguageVersion(Context.VERSION_ES6);
scope = cx.initStandardObjects();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ abstract static class AbstractState {
public void setUp() {
cx = Context.enter();
cx.setLanguageVersion(Context.VERSION_ES6);
cx.setOptimizationLevel(9);
scope = cx.initStandardObjects();

try (FileReader rdr = new FileReader(fileName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ void evaluateSource(Context cx, Scriptable scope, String fileName) {
void initialize() {
cx = Context.enter();
cx.setLanguageVersion(Context.VERSION_ES6);
cx.setOptimizationLevel(9);
scope = cx.initStandardObjects();
evaluateSource(cx, scope, "testsrc/benchmarks/framework.js");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,21 @@
public class RhinoScriptEngine extends AbstractScriptEngine implements Compilable, Invocable {

/**
* Reserved key for the Rhino optimization level. Default is "9," for optimized and compiled
* code. Set this to "-1" to run Rhino in interpreted mode -- this is much much slower but the
* only option on platforms like Android that don't support class files.
* Reserved key for the Rhino optimization level. This is supported for backward compatibility
* -- any value less than zero results in using interpreted mode.
*
* @deprecated Replaced in 1.8.0; use {@link #INTERPRETED_MODE} instead.
*/
@Deprecated
public static final String OPTIMIZATION_LEVEL = "org.mozilla.javascript.optimization_level";

/**
* Reserved key for interpreted mode, which is much slower than the default compiled mode but
* necessary on Android where Rhino can't generate class files.
*/
public static final String INTERPRETED_MODE = "org.mozilla.javascript.interpreted_mode";

static final int DEFAULT_LANGUAGE_VERSION = Context.VERSION_ES6;
private static final int DEFAULT_OPT = 9;
private static final boolean DEFAULT_DEBUG = true;
private static final String DEFAULT_FILENAME = "eval";

Expand Down Expand Up @@ -268,15 +275,21 @@ public ScriptEngineFactory getFactory() {
return factory;
}

@SuppressWarnings("deprecation")
private void configureContext(Context cx) throws ScriptException {
Object lv = get(ScriptEngine.LANGUAGE_VERSION);
if (lv != null) {
cx.setLanguageVersion(parseInteger(lv));
}
Object ol = get(OPTIMIZATION_LEVEL);
if (ol != null) {
// Handle backwardly-compatible "optimization level".
cx.setOptimizationLevel(parseInteger(ol));
}
Object interpreted = get(INTERPRETED_MODE);
if (interpreted != null) {
cx.setInterpretedMode(parseBoolean(interpreted));
}
}

private static int parseInteger(Object v) throws ScriptException {
Expand All @@ -286,11 +299,21 @@ private static int parseInteger(Object v) throws ScriptException {
} catch (NumberFormatException nfe) {
throw new ScriptException("Invalid number " + v);
}
} else if (v instanceof Integer) {
return ((Integer) v).intValue();
} else {
throw new ScriptException("Value must be a string or number");
}
if (v instanceof Integer) {
return (Integer) v;
}
throw new ScriptException("Value must be a string or number");
}

private static boolean parseBoolean(Object v) throws ScriptException {
if (v instanceof String) {
return Boolean.parseBoolean((String) v);
}
if (v instanceof Boolean) {
return (Boolean) v;
}
throw new ScriptException("Value must be a string or boolean");
}

private String getFilename() {
Expand Down Expand Up @@ -327,7 +350,6 @@ protected boolean hasFeature(Context cx, int featureIndex) {
@Override
protected void onContextCreated(Context cx) {
cx.setLanguageVersion(Context.VERSION_ES6);
cx.setOptimizationLevel(DEFAULT_OPT);
cx.setGeneratingDebug(DEFAULT_DEBUG);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void hello() throws ScriptException {

@Test
public void helloInterpreted() throws ScriptException {
engine.put(RhinoScriptEngine.OPTIMIZATION_LEVEL, -1);
engine.put(RhinoScriptEngine.INTERPRETED_MODE, true);
Object result = engine.eval("'Hello, World!';");
assertEquals(result, "Hello, World!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,10 +738,10 @@ private static String do_eval(Context cx, StackFrame frame, String expr) {
String resultString;
Debugger saved_debugger = cx.getDebugger();
Object saved_data = cx.getDebuggerContextData();
int saved_level = cx.getOptimizationLevel();
boolean wasInterpreted = cx.isInterpretedMode();

cx.setDebugger(null, null);
cx.setOptimizationLevel(-1);
cx.setInterpretedMode(false);
cx.setGeneratingDebug(false);
try {
Callable script = (Callable) cx.compileString(expr, "", 0, null);
Expand All @@ -755,7 +755,7 @@ private static String do_eval(Context cx, StackFrame frame, String expr) {
resultString = exc.getMessage();
} finally {
cx.setGeneratingDebug(true);
cx.setOptimizationLevel(saved_level);
cx.setInterpretedMode(wasInterpreted);
cx.setDebugger(saved_debugger, saved_data);
}
if (resultString == null) {
Expand Down Expand Up @@ -874,7 +874,7 @@ public void contextCreated(Context cx) {
Debugger debugger = new DimIProxy(dim, IPROXY_DEBUG);
cx.setDebugger(debugger, contextData);
cx.setGeneratingDebug(true);
cx.setOptimizationLevel(-1);
cx.setInterpretedMode(true);
}

/** Called when a Context is destroyed. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ public String[] processOptions(String args[]) {
continue;
}
if ((arg.equals("-opt") || arg.equals("-O")) && ++i < args.length) {
int optLevel = Integer.parseInt(args[i]);
compilerEnv.setOptimizationLevel(optLevel);
// As of 1.8.0, optimization levels no longer have an effect, but
// parse this for backward compatibility with existing scripts.
// Technically the optimization level was replaced with "interpreted
// mode, but this tool only makes sense in compiled mode.
continue;
}
} catch (NumberFormatException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ public static String[] processOptions(String args[]) {
continue;
}
if (arg.equals("-opt") || arg.equals("-O")) {
// As of 1.8.0, this bit remains for backward compatibility,
// although it is no longer documented in the "help" message.
if (++i == args.length) {
usageError = arg;
break goodUsage;
Expand All @@ -296,14 +298,13 @@ public static String[] processOptions(String args[]) {
usageError = args[i];
break goodUsage;
}
if (opt == -2) {
// Compatibility with Cocoon Rhino fork
opt = -1;
} else if (!Context.isValidOptimizationLevel(opt)) {
usageError = args[i];
break goodUsage;
if (opt < 0) {
shellContextFactory.setInterpretedMode(true);
}
shellContextFactory.setOptimizationLevel(opt);
continue;
}
if (arg.equals("-int") || arg.equals("-interpreted")) {
shellContextFactory.setInterpretedMode(true);
continue;
}
if (arg.equals("-encoding")) {
Expand Down Expand Up @@ -551,7 +552,7 @@ static void processFileSecure(Context cx, Scriptable scope, String path, Object
Object source = readFileOrUrl(path, !isClass);

byte[] digest = getDigest(source);
String key = path + "_" + cx.getOptimizationLevel();
String key = path + "_" + (cx.isInterpretedMode() ? "interpreted" : "compiled");
ScriptReference ref = scriptCache.get(key, digest);
Script script = ref != null ? ref.get() : null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ShellContextFactory extends ContextFactory {
private boolean strictMode;
private boolean warningAsError;
private int languageVersion = Context.VERSION_ES6;
private int optimizationLevel;
private boolean interpretedMode;
private boolean generatingDebug;
private boolean allowReservedKeywords = true;
private ErrorReporter errorReporter;
Expand Down Expand Up @@ -43,7 +43,7 @@ protected boolean hasFeature(Context cx, int featureIndex) {
@Override
protected void onContextCreated(Context cx) {
cx.setLanguageVersion(languageVersion);
cx.setOptimizationLevel(optimizationLevel);
cx.setInterpretedMode(interpretedMode);
if (errorReporter != null) {
cx.setErrorReporter(errorReporter);
}
Expand All @@ -67,10 +67,9 @@ public void setLanguageVersion(int version) {
this.languageVersion = version;
}

public void setOptimizationLevel(int optimizationLevel) {
Context.checkOptimizationLevel(optimizationLevel);
public void setInterpretedMode(boolean interpreted) {
checkNotSealed();
this.optimizationLevel = optimizationLevel;
this.interpretedMode = interpreted;
}

public void setErrorReporter(ErrorReporter errorReporter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ msg.shell.usage =\
\ -w Enable warnings.\n\
\ -version 100|110|120|130|140|150|160|170|180|200\n\
\ Set a specific language version.\n\
\ -opt [-1|0-9] Set optimization level.\n\
\ -int \n\
\ -interpreted Run in interpreted mode.\n\
\ -f script-filename Execute script file, or "-" for interactive.\n\
\ -e script-source Evaluate inline script.\n\
\ -modules [uri] Add a single path or URL element to the CommonJS\n\
Expand Down Expand Up @@ -114,8 +115,6 @@ Usage: java {0} [OPTION]... SOURCE...\n\
Valid options are: \n\
\ -version VERSION Use the specified language version.\n\
\ VERSION should be one of 100|110|120|130|140|150|160|170.\n\
\ -opt LEVEL Use optimization with the specified level.\n\
\ LEVEL should be one of 0..9.\n\
\ -debug, -g Include debug information.\n\
\ -nosource Do not include source to function objects.\n\
\ It makes f.toString() useless and violates ECMAScript\n\
Expand Down
27 changes: 22 additions & 5 deletions rhino/src/main/java/org/mozilla/javascript/CompilerEnvirons.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public CompilerEnvirons() {
reservedKeywordAsIdentifier = true;
allowMemberExprAsFunctionName = false;
xmlAvailable = true;
optimizationLevel = 0;
interpretedMode = false;
generatingSource = true;
strictMode = false;
warningAsError = false;
Expand All @@ -35,7 +35,7 @@ public void initFromContext(Context cx) {
warningAsError = cx.hasFeature(Context.FEATURE_WARNING_AS_ERROR);
xmlAvailable = cx.hasFeature(Context.FEATURE_E4X);

optimizationLevel = cx.getOptimizationLevel();
interpretedMode = cx.isInterpretedMode();

generatingSource = cx.isGeneratingSource();
activationNames = cx.activationNames;
Expand Down Expand Up @@ -98,13 +98,30 @@ public void setXmlAvailable(boolean flag) {
xmlAvailable = flag;
}

/**
* @deprecated As of 1.8.0, use {@link #isInterpretedMode()} instead.
*/
@Deprecated
public final int getOptimizationLevel() {
return optimizationLevel;
return interpretedMode ? -1 : 9;
}

public final boolean isInterpretedMode() {
return interpretedMode;
}

/**
* @deprecated As of 1.8.0, use {@link #setInterpretedMode(boolean)} instead.
*/
@Deprecated
@SuppressWarnings("deprecation")
public void setOptimizationLevel(int level) {
Context.checkOptimizationLevel(level);
this.optimizationLevel = level;
interpretedMode = (level < 0);
}

public void setInterpretedMode(boolean interpretedMode) {
this.interpretedMode = interpretedMode;
}

public final boolean isGeneratingSource() {
Expand Down Expand Up @@ -255,7 +272,7 @@ public static CompilerEnvirons ideEnvirons() {
private boolean reservedKeywordAsIdentifier;
private boolean allowMemberExprAsFunctionName;
private boolean xmlAvailable;
private int optimizationLevel;
private boolean interpretedMode;
private boolean generatingSource;
private boolean strictMode;
private boolean warningAsError;
Expand Down
Loading

0 comments on commit 8f8c3dc

Please sign in to comment.