Bug 792398 - Recover arguments from bailouts. r=luke

This commit is contained in:
Nicolas B. Pierron 2012-10-04 23:13:37 -07:00
parent e47ccd76c3
commit 39538cd3ea
4 changed files with 57 additions and 1 deletions

View File

@ -595,6 +595,41 @@ ion::ThunkToInterpreter(Value *vp)
if (JSOp(*pc) == JSOP_LOOPENTRY)
cx->regs().pc = GetNextPc(pc);
// When JSScript::argumentsOptimizationFailed, we cannot access Ion frames
// in order to create an arguments object for them. However, there is an
// invariant that script->needsArgsObj() implies fp->hasArgsObj() (after the
// prologue), so we must create one now for each inlined frame which needs
// one.
{
br->entryfp()->clearRunningInIon();
ScriptFrameIter iter(cx);
StackFrame *fp = NULL;
Rooted<JSScript*> script(cx, NULL);
do {
JS_ASSERT(!iter.isIon());
fp = iter.fp();
script = iter.script();
if (script->needsArgsObj()) {
// Currently IonMonkey does not compile if the script needs an
// arguments object, so the frame should not have any argument
// object yet.
JS_ASSERT(!fp->hasArgsObj());
ArgumentsObject *argsobj = ArgumentsObject::createExpected(cx, fp);
if (!argsobj)
return Interpret_Error;
InternalBindingsHandle bindings(script, &script->bindings);
const unsigned var = Bindings::argumentsVarIndex(cx, bindings);
// The arguments is a local binding and needsArgsObj does not
// check if it is clobbered. Ensure that the local binding
// restored during bailout before storing the arguments object
// to the slot.
if (fp->unaliasedLocal(var).isMagic(JS_OPTIMIZED_ARGUMENTS))
fp->unaliasedLocal(var) = ObjectValue(*argsobj);
}
++iter;
} while (fp != br->entryfp());
}
if (activation->entryfp() == br->entryfp()) {
// If the bailout entry fp is the same as the activation entryfp, then
// there are no scripted frames below us. In this case, just shortcut

View File

@ -0,0 +1,19 @@
function g() { assertEq(false, true) }
var max = 400; ct = 0;
function f(b) {
if (b) {
f(b - 1);
} else {
g = {
apply:function(x,y) {
assertEq(x, null);
assertEq(y[0], ct);
++ct;
}
};
}
g.apply(null, arguments);
}
f(max - 1);
assertEq(ct, max);

View File

@ -2573,7 +2573,7 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
*/
for (AllFramesIter i(cx->stack.space()); !i.done(); ++i) {
StackFrame *fp = i.fp();
if (fp->isFunctionFrame() && fp->script() == script) {
if (fp->isFunctionFrame() && !fp->runningInIon() && fp->script() == script) {
ArgumentsObject *argsobj = ArgumentsObject::createExpected(cx, fp);
if (!argsobj) {
/*

View File

@ -36,6 +36,8 @@ SetMissingFormalArgsToUndefined(HeapValue *dstBase, unsigned numActuals, unsigne
static void
CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
{
JS_ASSERT(!fp->beginsIonActivation());
HeapValue *dstBase = dst;
unsigned numActuals = fp->numActualArgs();
unsigned numFormals = fp->callee().nargs;