Bug 798819 - Ensure the EnterJIT thunk exists when using FastInvoke. r=dvander

This commit is contained in:
Jan de Mooij 2012-10-06 15:39:04 -07:00
parent b9d0962f13
commit 80eafc3e89
4 changed files with 39 additions and 6 deletions

View File

@ -186,11 +186,6 @@ IonCompartment::mark(JSTracer *trc, JSCompartment *compartment)
if (activation->compartment() != compartment)
continue;
// Activations may be tied to the Method JIT, in which case enterJIT
// is not present on the activation's call stack.
if (!activation->entryfp() || activation->entryfp()->callingIntoIon())
continue;
// Both OSR and normal function calls depend on the EnterJIT code
// existing for entrance and exit.
mustMarkEnterJIT = true;
@ -1292,6 +1287,28 @@ ion::CanEnter(JSContext *cx, HandleScript script, StackFrame *fp, bool newType)
return Method_Compiled;
}
MethodStatus
ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script)
{
JS_ASSERT(ion::IsEnabled(cx));
// Skip if the code is expected to result in a bailout.
if (!script->hasIonScript() || script->ion->bailoutExpected())
return Method_Skipped;
if (!cx->compartment->ensureIonCompartmentExists(cx))
return Method_Error;
// This can GC, so afterward, script->ion is not guaranteed to be valid.
if (!cx->compartment->ionCompartment()->enterJIT(cx))
return Method_Error;
if (!script->ion)
return Method_Skipped;
return Method_Compiled;
}
static IonExecStatus
EnterIon(JSContext *cx, StackFrame *fp, void *jitcode)
{

View File

@ -226,6 +226,7 @@ bool SetIonContext(IonContext *ctx);
MethodStatus CanEnterAtBranch(JSContext *cx, HandleScript script,
StackFrame *fp, jsbytecode *pc);
MethodStatus CanEnter(JSContext *cx, HandleScript script, StackFrame *fp, bool newType);
MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script);
enum IonExecStatus
{

View File

@ -0,0 +1,10 @@
if (!this.gcPreserveCode)
gcPreserveCode = function() {};
this.toString = (function() {
x.filter(function() {})
});
x = [0, 0, 0, 0, 0, 0, 0];
gcPreserveCode()
print(this)
gc();
this + ''

View File

@ -1031,7 +1031,10 @@ class FastInvokeGuard
if (useIon_ && fun_) {
JS_ASSERT(fun_->script() == script_);
if (script_->hasIonScript() && !script_->ion->bailoutExpected()) {
ion::MethodStatus status = ion::CanEnterUsingFastInvoke(cx, script_);
if (status == ion::Method_Error)
return false;
if (status == ion::Method_Compiled) {
ion::IonExecStatus result = ion::FastInvoke(cx, fun_, args_);
if (result == ion::IonExec_Error)
return false;
@ -1040,6 +1043,8 @@ class FastInvokeGuard
return true;
}
JS_ASSERT(status == ion::Method_Skipped);
if (script_->canIonCompile()) {
// This script is not yet hot. Since calling into Ion is much
// faster here, bump the use count a bit to account for this.