Bug 988950 - Use scratch register instead of temp where possible r=jandem

This commit is contained in:
Jon Coppeard 2014-04-23 13:48:35 +01:00
parent f576917080
commit c4cd68db81
8 changed files with 31 additions and 37 deletions

View File

@ -1831,7 +1831,7 @@ CodeGenerator::visitPostWriteBarrierO(LPostWriteBarrierO *lir)
if (!addOutOfLineCode(ool))
return false;
Register temp = ToRegister(lir->temp());
Register temp = ToTempRegisterOrInvalid(lir->temp());
if (lir->object()->isConstant()) {
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
@ -1855,7 +1855,7 @@ CodeGenerator::visitPostWriteBarrierV(LPostWriteBarrierV *lir)
if (!addOutOfLineCode(ool))
return false;
Register temp = ToRegister(lir->temp());
Register temp = ToTempRegisterOrInvalid(lir->temp());
if (lir->object()->isConstant()) {
const Nursery &nursery = GetIonContext()->runtime->gcNursery();

View File

@ -2331,15 +2331,17 @@ LIRGenerator::visitPostWriteBarrier(MPostWriteBarrier *ins)
#ifdef JSGC_GENERATIONAL
switch (ins->value()->type()) {
case MIRType_Object: {
LDefinition tmp = needTempForObjectInNurseryRange() ? temp() : LDefinition::BogusTemp();
LPostWriteBarrierO *lir =
new(alloc()) LPostWriteBarrierO(useRegisterOrConstant(ins->object()),
useRegister(ins->value()),
temp());
useRegister(ins->value()), tmp);
return add(lir, ins) && assignSafepoint(lir, ins);
}
case MIRType_Value: {
bool needTemp = needTempForObjectInNurseryRange() || needTempForValueIsNurseryObject();
LDefinition tmp = needTemp ? temp() : LDefinition::BogusTemp();
LPostWriteBarrierV *lir =
new(alloc()) LPostWriteBarrierV(useRegisterOrConstant(ins->object()), temp());
new(alloc()) LPostWriteBarrierV(useRegisterOrConstant(ins->object()), tmp);
if (!useBox(lir, LPostWriteBarrierV::Input, ins->value()))
return false;
return add(lir, ins) && assignSafepoint(lir, ins);

View File

@ -35,6 +35,9 @@ class LIRGeneratorARM : public LIRGeneratorShared
return LDefinition::BogusTemp();
}
bool needTempForObjectInNurseryRange() { return false; }
bool needTempForValueIsNurseryObject() { return false; }
// x64 has a scratch register, so no need for another temp for dispatch
// ICs.
LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) {

View File

@ -4340,12 +4340,12 @@ void
MacroAssemblerARMCompat::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
{
JS_ASSERT(ptr != temp);
JS_ASSERT(temp != InvalidReg);
JS_ASSERT(ptr != ScratchRegister);
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
addPtr(ptr, temp);
branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), label);
movePtr(ImmWord(-ptrdiff_t(nursery.start())), ScratchRegister);
addPtr(ptr, ScratchRegister);
branchPtr(Assembler::Below, ScratchRegister, Imm32(Nursery::NurserySize), label);
}
void
@ -4354,17 +4354,7 @@ MacroAssemblerARMCompat::branchValueIsNurseryObject(ValueOperand value, Register
Label done;
branchTestObject(Assembler::NotEqual, value, &done);
Register obj = extractObject(value, temp);
// valobj and temp may be the same register, in which case we mustn't trash it
// before we use its contents.
if (obj == temp) {
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
addPtr(ImmWord(-ptrdiff_t(nursery.start())), obj);
branchPtr(Assembler::Below, obj, Imm32(Nursery::NurserySize), label);
} else {
branchPtrInNurseryRange(obj, temp, label);
}
branchPtrInNurseryRange(value.payloadReg(), temp, label);
bind(&done);
}

View File

@ -35,6 +35,9 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared
LDefinition tempToUnbox();
bool needTempForObjectInNurseryRange() { return false; }
bool needTempForValueIsNurseryObject() { return true; }
// x64 has a scratch register, so no need for another temp for dispatch
// ICs.
LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) {

View File

@ -389,23 +389,26 @@ void
MacroAssemblerX64::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
{
JS_ASSERT(ptr != temp);
JS_ASSERT(temp != InvalidReg);
JS_ASSERT(ptr != ScratchReg);
// temp may be InvalidReg.
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
addPtr(ptr, temp);
branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), label);
movePtr(ImmWord(-ptrdiff_t(nursery.start())), ScratchReg);
addPtr(ptr, ScratchReg);
branchPtr(Assembler::Below, ScratchReg, Imm32(Nursery::NurserySize), label);
}
void
MacroAssemblerX64::branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label)
{
JS_ASSERT(temp != InvalidReg);
Label done;
branchTestObject(Assembler::NotEqual, value, &done);
Register obj = extractObject(value, temp);
// valobj and temp may be the same register, in which case we mustn't trash it
// obj and temp may be the same register, in which case we mustn't trash it
// before we use its contents.
if (obj == temp) {
const Nursery &nursery = GetIonContext()->runtime->gcNursery();

View File

@ -38,6 +38,9 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared
return LDefinition::BogusTemp();
}
bool needTempForObjectInNurseryRange() { return true; }
bool needTempForValueIsNurseryObject() { return true; }
LDefinition tempForDispatchCache(MIRType outputType = MIRType_None);
void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex);

View File

@ -434,7 +434,7 @@ void
MacroAssemblerX86::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
{
JS_ASSERT(ptr != temp);
JS_ASSERT(temp != InvalidReg);
JS_ASSERT(temp != InvalidReg); // A temp register is required for x86.
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
@ -448,17 +448,7 @@ MacroAssemblerX86::branchValueIsNurseryObject(ValueOperand value, Register temp,
Label done;
branchTestObject(Assembler::NotEqual, value, &done);
Register obj = extractObject(value, temp);
// valobj and temp may be the same register, in which case we mustn't trash it
// before we use its contents.
if (obj == temp) {
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
addPtr(ImmWord(-ptrdiff_t(nursery.start())), obj);
branchPtr(Assembler::Below, obj, Imm32(Nursery::NurserySize), label);
} else {
branchPtrInNurseryRange(obj, temp, label);
}
branchPtrInNurseryRange(value.payloadReg(), temp, label);
bind(&done);
}