Bug 708303 - Use pinReg/unpinReg more in write barriers (r=dmandelin)

This commit is contained in:
Bill McCloskey 2012-01-27 17:01:25 -08:00
Родитель df45761f54
Коммит 7d6baa84d7
4 изменённых файлов: 27 добавлений и 9 удалений

Просмотреть файл

@ -1154,6 +1154,10 @@ class ScriptAnalysis
/* Decompose the slot above. */ /* Decompose the slot above. */
bool arg; bool arg;
uint32_t index; uint32_t index;
const Value **basePointer() const {
return arg ? &nesting->argArray : &nesting->varArray;
}
}; };
NameAccess resolveNameAccess(JSContext *cx, jsid id, bool addDependency = false); NameAccess resolveNameAccess(JSContext *cx, jsid id, bool addDependency = false);

Просмотреть файл

@ -5552,7 +5552,13 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
if (cx->compartment->needsBarrier()) { if (cx->compartment->needsBarrier()) {
stubcc.linkExit(masm.jump(), Uses(0)); stubcc.linkExit(masm.jump(), Uses(0));
stubcc.leave(); stubcc.leave();
stubcc.masm.addPtr(Imm32(address.offset), address.base, Registers::ArgReg1);
/* sync() may have overwritten nameReg, so we reload its data. */
JS_ASSERT(address.base == nameReg);
stubcc.masm.move(ImmPtr(access.basePointer()), nameReg);
stubcc.masm.loadPtr(Address(nameReg), nameReg);
stubcc.masm.addPtr(Imm32(address.offset), nameReg, Registers::ArgReg1);
OOL_STUBCALL(stubs::WriteBarrier, REJOIN_NONE); OOL_STUBCALL(stubs::WriteBarrier, REJOIN_NONE);
stubcc.rejoin(Changes(0)); stubcc.rejoin(Changes(0));
} }

Просмотреть файл

@ -1188,17 +1188,26 @@ mjit::Compiler::jsop_setelem_dense()
/* /*
* The sync call below can potentially clobber key.reg() and slotsReg. * The sync call below can potentially clobber key.reg() and slotsReg.
* So we save and restore them. Additionally, the WriteBarrier stub can * We pin key.reg() to avoid it being clobbered. If |hoisted| is true,
* clobber both registers. The rejoin call will restore key.reg() but * we can also pin slotsReg. If not, then slotsReg is owned by the
* not slotsReg. So we restore it again after the stub call. * compiler and we save in manually to VMFrame::scratch.
*
* Additionally, the WriteBarrier stub can clobber both registers. The
* rejoin call will restore key.reg() but not slotsReg. So we save
* slotsReg in the frame and restore it after the stub call.
*/ */
stubcc.masm.storePtr(slotsReg, FrameAddress(offsetof(VMFrame, scratch))); stubcc.masm.storePtr(slotsReg, FrameAddress(offsetof(VMFrame, scratch)));
if (hoisted)
frame.pinReg(slotsReg);
if (!key.isConstant()) if (!key.isConstant())
stubcc.masm.push(key.reg()); frame.pinReg(key.reg());
frame.sync(stubcc.masm, Uses(3)); frame.sync(stubcc.masm, Uses(3));
if (!key.isConstant()) if (!key.isConstant())
stubcc.masm.pop(key.reg()); frame.unpinReg(key.reg());
stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg); if (hoisted)
frame.unpinReg(slotsReg);
else
stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, scratch)), slotsReg);
if (key.isConstant()) if (key.isConstant())
stubcc.masm.lea(Address(slotsReg, key.index() * sizeof(Value)), Registers::ArgReg1); stubcc.masm.lea(Address(slotsReg, key.index() * sizeof(Value)), Registers::ArgReg1);

Просмотреть файл

@ -919,8 +919,7 @@ FrameState::loadNameAddress(const analyze::ScriptAnalysis::NameAccess &access, R
{ {
JS_ASSERT(access.script && access.nesting); JS_ASSERT(access.script && access.nesting);
const Value **pbase = access.arg ? &access.nesting->argArray : &access.nesting->varArray; masm.move(ImmPtr(access.basePointer()), reg);
masm.move(ImmPtr(pbase), reg);
masm.loadPtr(Address(reg), reg); masm.loadPtr(Address(reg), reg);
return Address(reg, access.index * sizeof(Value)); return Address(reg, access.index * sizeof(Value));