Bug 908903 - Add testing function to toggle jit compiler options. r=jandem

This commit is contained in:
Nicolas Pierron 2013-08-27 13:45:14 -07:00
parent a45b40f0b8
commit 5779bb4c77
5 changed files with 131 additions and 13 deletions

View File

@ -800,11 +800,11 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
::JS_SetParallelParsingEnabled(context->mContext, parallelParsing);
::JS_SetParallelIonCompilationEnabled(context->mContext, parallelIonCompilation);
::JS_SetGlobalCompilerOption(context->mContext, JSCOMPILER_BASELINE_USECOUNT_TRIGGER,
(useBaselineJITEager ? 0 : -1));
::JS_SetGlobalJitCompilerOption(context->mContext, JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER,
(useBaselineJITEager ? 0 : -1));
::JS_SetGlobalCompilerOption(context->mContext, JSCOMPILER_ION_USECOUNT_TRIGGER,
(useIonEager ? 0 : -1));
::JS_SetGlobalJitCompilerOption(context->mContext, JSJITCOMPILER_ION_USECOUNT_TRIGGER,
(useIonEager ? 0 : -1));
// Save the new defaults for the next page load (InitContext).
context->mDefaultJSOptions = newDefaultJSOptions;

View File

@ -1005,6 +1005,53 @@ js::testingFunc_bailout(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
static bool
SetJitCompilerOption(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject callee(cx, &args.callee());
if (args.length() != 2) {
ReportUsageError(cx, callee, "Wrong number of arguments.");
return false;
}
if (!args[0].isString()) {
ReportUsageError(cx, callee, "First argument must be a String.");
return false;
}
if (!args[1].isInt32()) {
ReportUsageError(cx, callee, "Second argument must be an Int32.");
return false;
}
JSFlatString *strArg = JS_FlattenString(cx, args[0].toString());
#define JIT_COMPILER_MATCH(key, string) \
else if (JS_FlatStringEqualsAscii(strArg, string)) \
opt = JSJITCOMPILER_ ## key;
JSJitCompilerOption opt = JSJITCOMPILER_NOT_AN_OPTION;
if (false) {}
JIT_COMPILER_OPTIONS(JIT_COMPILER_MATCH);
#undef JIT_COMPILER_MATCH
if (opt == JSJITCOMPILER_NOT_AN_OPTION) {
ReportUsageError(cx, callee, "First argument does not name a valid option (see jsapi.h).");
return false;
}
int32_t number = args[1].toInt32();
if (number < 0)
number = -1;
JS_SetGlobalJitCompilerOption(cx, opt, uint32_t(number));
args.rval().setBoolean(true);
return true;
}
static const JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'compartment')",
@ -1192,6 +1239,10 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
"bailout()",
" Force a bailout out of ionmonkey (if running in ionmonkey)."),
JS_FN_HELP("setJitCompilerOption", SetJitCompilerOption, 2, 0,
"setCompilerOption(<option>, <number>)",
" Set a compiler option indexed in JSCompileOption enum to a number.\n"),
JS_FS_HELP_END
};

View File

@ -0,0 +1,54 @@
function f(x) {
return x + 1;
}
setJitCompilerOption("ion.usecount.trigger", 2);
setJitCompilerOption("baseline.usecount.trigger", 0);
assertEq(f(1), 2); // usecount == 1 => eagerly compile with baseline.
assertEq(f(0.5), 1.5); // usecount == 2 => normaly compile with ion.
// invalidate for unexpect output.
function normal() {
setJitCompilerOption("ion.usecount.trigger", 8);
setJitCompilerOption("baseline.usecount.trigger", 5);
}
function eager() {
setJitCompilerOption("ion.usecount.trigger", 0);
}
function h(x) {
return x + 1;
}
function g(x) {
normal();
return h(x) + 1;
}
normal();
for (var i = 0; i < 10; i++) {
eager();
assertEq(g(i), i + 2);
}
// Check for wrong arguments.
try {
setJitCompilerOption("not.an.option", 51);
assertEq(false, true);
} catch (x) { }
try {
var ion = { usecount: { trigger: null } };
setJitCompilerOption(ion.usecount.trigger, 42);
assertEq(false, true);
} catch (x) { }
try {
setJitCompilerOption("ion.usecount.trigger", "32");
assertEq(false, true);
} catch (x) { }

View File

@ -6442,22 +6442,26 @@ JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled)
}
JS_PUBLIC_API(void)
JS_SetGlobalCompilerOption(JSContext *cx, JSCompilerOption opt, uint32_t value)
JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value)
{
#ifdef JS_ION
jit::IonOptions defaultValues;
switch (opt) {
case JSCOMPILER_BASELINE_USECOUNT_TRIGGER:
case JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER:
if (value == uint32_t(-1))
value = defaultValues.baselineUsesBeforeCompile;
jit::js_IonOptions.baselineUsesBeforeCompile = value;
break;
case JSCOMPILER_ION_USECOUNT_TRIGGER:
case JSJITCOMPILER_ION_USECOUNT_TRIGGER:
if (value == uint32_t(-1))
value = defaultValues.usesBeforeCompile;
jit::js_IonOptions.usesBeforeCompile = value;
jit::js_IonOptions.eagerCompilation = (value == 0);
if (value == 0)
jit::js_IonOptions.setEagerCompilation();
break;
default:
break;
}
#endif

View File

@ -4619,13 +4619,22 @@ JS_SetParallelParsingEnabled(JSContext *cx, bool enabled);
extern JS_PUBLIC_API(void)
JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled);
typedef enum JSCompilerOption {
JSCOMPILER_BASELINE_USECOUNT_TRIGGER,
JSCOMPILER_ION_USECOUNT_TRIGGER
} JSCompilerOption;
#define JIT_COMPILER_OPTIONS(Register) \
Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger") \
Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger")
typedef enum JSJitCompilerOption {
#define JIT_COMPILER_DECLARE(key, str) \
JSJITCOMPILER_ ## key,
JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
#undef JIT_COMPILER_DECLARE
JSJITCOMPILER_NOT_AN_OPTION
} JSJitCompilerOption;
extern JS_PUBLIC_API(void)
JS_SetGlobalCompilerOption(JSContext *cx, JSCompilerOption opt, uint32_t value);
JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value);
/*
* Convert a uint32_t index into a jsid.