Bug 1128490 - Mark formal arguments in Ion frames which use lazy arguments, r=jandem.

This commit is contained in:
Brian Hackett 2015-02-10 14:41:59 -07:00
parent 817924eff7
commit 72999501ac
3 changed files with 37 additions and 8 deletions

View File

@ -0,0 +1,10 @@
for (var i = 0; i < 1000; ++i) {
function isNotEmpty(obj) {
for (var i = 0 ; i < arguments.length; i++) {
minorgc();
var o = arguments[i];
}
};
isNotEmpty([1]);
}

View File

@ -171,11 +171,16 @@ BacktrackingAllocator::canAddToGroup(VirtualRegisterGroup *group, BacktrackingVi
return true;
}
static bool
IsArgumentSlotDefinition(LDefinition *def)
{
return def->policy() == LDefinition::FIXED && def->output()->isArgument();
}
static bool
IsThisSlotDefinition(LDefinition *def)
{
return def->policy() == LDefinition::FIXED &&
def->output()->isArgument() &&
return IsArgumentSlotDefinition(def) &&
def->output()->toArgument()->index() < THIS_FRAME_ARGSLOT + sizeof(Value);
}
@ -199,6 +204,16 @@ BacktrackingAllocator::tryGroupRegisters(uint32_t vreg0, uint32_t vreg1)
return true;
}
// Registers which might spill to the frame's argument slots can only be
// grouped with other such registers if the frame might access those
// arguments through a lazy arguments object.
if ((IsArgumentSlotDefinition(reg0->def()) || IsArgumentSlotDefinition(reg1->def())) &&
graph.mir().entryBlock()->info().script()->argumentsAliasesFormals())
{
if (*reg0->def()->output() != *reg1->def()->output())
return true;
}
VirtualRegisterGroup *group0 = reg0->group(), *group1 = reg1->group();
if (!group0 && group1)

View File

@ -971,17 +971,21 @@ ReadAllocation(const JitFrameIterator &frame, const LAllocation *a)
#endif
static void
MarkThisAndExtraActualArguments(JSTracer *trc, const JitFrameIterator &frame)
MarkThisAndArguments(JSTracer *trc, const JitFrameIterator &frame)
{
// Mark |this| and any extra actual arguments for an Ion frame. Marking of
// formal arguments is taken care of by the frame's safepoint/snapshot.
// formal arguments is taken care of by the frame's safepoint/snapshot,
// except when the script's lazy arguments object aliases those formals,
// in which case we mark them as well.
JitFrameLayout *layout = frame.jsFrame();
size_t nargs = frame.numActualArgs();
size_t nformals = 0;
if (CalleeTokenIsFunction(layout->calleeToken()))
nformals = CalleeTokenToFunction(layout->calleeToken())->nargs();
if (CalleeTokenIsFunction(layout->calleeToken())) {
JSFunction *fun = CalleeTokenToFunction(layout->calleeToken());
nformals = fun->nonLazyScript()->argumentsAliasesFormals() ? 0 : fun->nargs();
}
Value *argv = layout->argv();
@ -1023,7 +1027,7 @@ MarkIonJSFrame(JSTracer *trc, const JitFrameIterator &frame)
ionScript = frame.ionScriptFromCalleeToken();
}
MarkThisAndExtraActualArguments(trc, frame);
MarkThisAndArguments(trc, frame);
const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp());
@ -1082,7 +1086,7 @@ MarkBailoutFrame(JSTracer *trc, const JitFrameIterator &frame)
// We have to mark the list of actual arguments, as only formal arguments
// are represented in the Snapshot.
MarkThisAndExtraActualArguments(trc, frame);
MarkThisAndArguments(trc, frame);
// Under a bailout, do not have a Safepoint to only iterate over GC-things.
// Thus we use a SnapshotIterator to trace all the locations which would be