[INFER] Add rejoins for call sites that can trigger GC, bug 671943.

This commit is contained in:
Brian Hackett 2011-07-16 07:15:34 -07:00
parent 14ffb09713
commit 2291066d7c
5 changed files with 34 additions and 4 deletions

View File

@ -0,0 +1,12 @@
gczeal(2);
o1 = Iterator;
var o2 = (function() { return arguments; })();
function f(o) {
for(var j=0; j<20; j++) {
Object.seal(o2);
(function() { return eval(o); })() == o1;
(function() { return {x: arguments}.x; })();
if (false) {};
}
}
f({});

View File

@ -0,0 +1,9 @@
schedulegc(11);
function foo(n) {
if (n == 10)
foo.apply = function(a, b) { return b[0]; }
return n;
}
function bar() { return foo.apply(null, arguments); }
for (var i = 0; i < 20; i++)
assertEq(bar(i), i);

View File

@ -739,7 +739,7 @@ mjit::Compiler::generatePrologue()
/* Create the call object. */
if (script->fun->isHeavyweight()) {
prepareStubCall(Uses(0));
INLINE_STUBCALL(stubs::CreateFunCallObject, REJOIN_NONE);
INLINE_STUBCALL(stubs::CreateFunCallObject, REJOIN_CREATE_CALL_OBJECT);
}
j.linkTo(masm.label(), &masm);
@ -2634,7 +2634,7 @@ mjit::Compiler::generateMethod()
JSObject *regex = script->getRegExp(fullAtomIndex(PC));
prepareStubCall(Uses(0));
masm.move(ImmPtr(regex), Registers::ArgReg1);
INLINE_STUBCALL(stubs::RegExp, REJOIN_NONE);
INLINE_STUBCALL(stubs::RegExp, REJOIN_PUSH_OBJECT);
frame.takeReg(Registers::ReturnReg);
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
}
@ -3310,7 +3310,7 @@ mjit::Compiler::checkCallApplySpeculation(uint32 callImmArgc, uint32 speculatedA
int32 frameDepthAdjust;
if (applyTricks == LazyArgsObj) {
OOL_STUBCALL(stubs::Arguments, REJOIN_NONE);
OOL_STUBCALL(stubs::Arguments, REJOIN_RESUME);
frameDepthAdjust = +1;
} else {
frameDepthAdjust = 0;

View File

@ -1435,13 +1435,19 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
*/
if (!CheckStackQuota(f))
return js_InternalThrow(f);
SetValueRangeToUndefined(fp->slots(), script->nfixed);
if (fp->fun()->isHeavyweight()) {
if (!js::CreateFunCallObject(cx, fp))
return js_InternalThrow(f);
}
/* FALLTHROUGH */
}
case REJOIN_CREATE_CALL_OBJECT: {
fp->scopeChain();
SetValueRangeToUndefined(fp->slots(), script->nfixed);
/* Construct the 'this' object for the frame if necessary. */
if (!ScriptPrologueOrGeneratorResume(cx, fp, types::UseNewTypeAtEntry(cx, fp)))

View File

@ -289,6 +289,9 @@ enum RejoinState {
*/
REJOIN_CHECK_ARGUMENTS,
/* A GC while making a call object occurred, discarding the script's jitcode. */
REJOIN_CREATE_CALL_OBJECT,
/*
* State after calling a stub which returns a JIT code pointer for a call
* or NULL for an already-completed call.