[INFER] Evict as necessary when restoring parent registers before branching, bug 646001.

This commit is contained in:
Brian Hackett 2011-03-29 16:36:06 -07:00
parent d7434b87f6
commit 14684c4e4b
2 changed files with 29 additions and 2 deletions

View File

@ -0,0 +1,12 @@
function jit(on)
{
if (on && !options().match(/tracejit/)) { }
}
try { test(); } catch (e) {}
function test(
)
{
for (var j=0;j<5;++j) { switch(1.1) { case 2: case NaN: } }
jit(false);
reportCompare('xxxxxxx'.test(new j('(x+)(x*)')));
}

View File

@ -833,7 +833,7 @@ FrameState::relocateReg(AnyRegisterID reg, RegisterAllocation *alloc, Uses uses)
* watch for variables which are carried across the branch but are in a
* the register for a different carried entry, we just spill these for now.
*/
JS_ASSERT(alloc->assigned(reg) && !a->freeRegs.hasReg(reg));
JS_ASSERT(!a->freeRegs.hasReg(reg));
for (unsigned i = 0; i < uses.nuses; i++) {
FrameEntry *fe = peek(-1 - i);
@ -977,9 +977,24 @@ FrameState::syncForBranch(jsbytecode *target, Uses uses)
a->freeRegs.takeReg(reg);
regstate(reg).associate(fe, RematInfo::DATA);
/*
* If this register is also a parent register at the branch target,
* we are restoring a parent register we previously evicted.
*/
if (alloc->getParentRegs().hasReg(reg))
a->parentRegs.putReg(reg);
}
restoreParentRegistersInMask(masm, alloc->getParentRegs().freeMask & ~a->parentRegs.freeMask, true);
/* Restore any parent registers needed at the branch, evicting those still in use. */
Registers parents(alloc->getParentRegs().freeMask & ~a->parentRegs.freeMask);
while (!parents.empty()) {
AnyRegisterID reg = parents.takeAnyReg();
if (!a->freeRegs.hasReg(reg))
relocateReg(reg, alloc, uses);
a->parentRegs.putReg(reg);
restoreParentRegister(masm, reg);
}
return true;
}