mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 20:17:37 +00:00
Bug 988950 - Add a macro assembler instruction to check if a pointer is in the nursery r=jandem
This commit is contained in:
parent
0d8a56a9e2
commit
7192a5c411
@ -416,7 +416,6 @@ BaselineCompiler::emitEpilogue()
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// On input:
|
||||
// R2.scratchReg() contains object being written to.
|
||||
// R1.scratchReg() contains slot index being written to.
|
||||
// Otherwise, baseline stack will be synced, so all other registers are usable as scratch.
|
||||
// This calls:
|
||||
// void PostWriteBarrier(JSRuntime *rt, JSObject *obj);
|
||||
@ -2101,15 +2100,13 @@ BaselineCompiler::emit_JSOP_SETALIASEDVAR()
|
||||
// Fully sync the stack if post-barrier is needed.
|
||||
// Scope coordinate object is already in R2.scratchReg().
|
||||
frame.syncStack(0);
|
||||
Register temp = R1.scratchReg();
|
||||
|
||||
Nursery &nursery = cx->runtime()->gcNursery;
|
||||
Label skipBarrier;
|
||||
Label isTenured;
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &skipBarrier);
|
||||
masm.branchPtr(Assembler::Below, objReg, ImmWord(nursery.start()), &isTenured);
|
||||
masm.branchPtr(Assembler::Below, objReg, ImmWord(nursery.heapEnd()), &skipBarrier);
|
||||
masm.branchPtrInNurseryRange(objReg, temp, &skipBarrier);
|
||||
|
||||
masm.bind(&isTenured);
|
||||
masm.call(&postBarrierSlot_);
|
||||
|
||||
masm.bind(&skipBarrier);
|
||||
@ -2419,6 +2416,7 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get)
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// Fully sync the stack if post-barrier is needed.
|
||||
frame.syncStack(0);
|
||||
Register temp = R1.scratchReg();
|
||||
|
||||
// Reload the arguments object
|
||||
Register reg = R2.scratchReg();
|
||||
@ -2426,11 +2424,8 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get)
|
||||
|
||||
Nursery &nursery = cx->runtime()->gcNursery;
|
||||
Label skipBarrier;
|
||||
Label isTenured;
|
||||
masm.branchPtr(Assembler::Below, reg, ImmWord(nursery.start()), &isTenured);
|
||||
masm.branchPtr(Assembler::Below, reg, ImmWord(nursery.heapEnd()), &skipBarrier);
|
||||
masm.branchPtrInNurseryRange(reg, temp, &skipBarrier);
|
||||
|
||||
masm.bind(&isTenured);
|
||||
masm.call(&postBarrierSlot_);
|
||||
|
||||
masm.bind(&skipBarrier);
|
||||
|
@ -738,10 +738,7 @@ ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, Val
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, val, &skipBarrier);
|
||||
|
||||
Label isTenured;
|
||||
masm.branchPtr(Assembler::Below, obj, ImmWord(nursery.start()), &isTenured);
|
||||
masm.branchPtr(Assembler::Below, obj, ImmWord(nursery.heapEnd()), &skipBarrier);
|
||||
masm.bind(&isTenured);
|
||||
masm.branchPtrInNurseryRange(obj, scratch, &skipBarrier);
|
||||
|
||||
Register valReg = masm.extractObject(val, scratch);
|
||||
masm.branchPtr(Assembler::Below, valReg, ImmWord(nursery.start()), &skipBarrier);
|
||||
|
@ -1831,22 +1831,16 @@ CodeGenerator::visitPostWriteBarrierO(LPostWriteBarrierO *lir)
|
||||
if (!addOutOfLineCode(ool))
|
||||
return false;
|
||||
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
Register temp = ToRegister(lir->temp());
|
||||
|
||||
if (lir->object()->isConstant()) {
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
JS_ASSERT(!nursery.isInside(&lir->object()->toConstant()->toObject()));
|
||||
} else {
|
||||
Register objreg = ToRegister(lir->object());
|
||||
masm.movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
masm.addPtr(objreg, temp);
|
||||
masm.branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), ool->rejoin());
|
||||
masm.branchPtrInNurseryRange(ToRegister(lir->object()), temp, ool->rejoin());
|
||||
}
|
||||
|
||||
Register valuereg = ToRegister(lir->value());
|
||||
masm.movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
masm.addPtr(valuereg, temp);
|
||||
masm.branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), ool->entry());
|
||||
masm.branchPtrInNurseryRange(ToRegister(lir->value()), temp, ool->entry());
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
#endif
|
||||
@ -1861,27 +1855,17 @@ CodeGenerator::visitPostWriteBarrierV(LPostWriteBarrierV *lir)
|
||||
if (!addOutOfLineCode(ool))
|
||||
return false;
|
||||
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
Register temp = ToRegister(lir->temp());
|
||||
|
||||
if (lir->object()->isConstant()) {
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
JS_ASSERT(!nursery.isInside(&lir->object()->toConstant()->toObject()));
|
||||
} else {
|
||||
Register temp = ToRegister(lir->temp());
|
||||
Register objreg = ToRegister(lir->object());
|
||||
masm.movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
masm.addPtr(objreg, temp);
|
||||
masm.branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), ool->rejoin());
|
||||
masm.branchPtrInNurseryRange(ToRegister(lir->object()), temp, ool->rejoin());
|
||||
}
|
||||
|
||||
ValueOperand value = ToValue(lir, LPostWriteBarrierV::Input);
|
||||
masm.branchTestObject(Assembler::NotEqual, value, ool->rejoin());
|
||||
|
||||
// This section is a little different because we mustn't trash the temp
|
||||
// register before we use its contents.
|
||||
Register temp = ToRegister(lir->temp());
|
||||
masm.unboxObject(value, temp);
|
||||
masm.addPtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
masm.branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), ool->entry());
|
||||
masm.branchValueIsNurseryObject(value, temp, ool->entry());
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
#endif
|
||||
|
@ -1786,3 +1786,40 @@ MacroAssembler::spsUnmarkJit(SPSProfiler *p, Register temp)
|
||||
|
||||
bind(&spsNotEnabled);
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
|
||||
void
|
||||
MacroAssembler::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
|
||||
{
|
||||
JS_ASSERT(ptr != temp);
|
||||
JS_ASSERT(temp != 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);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1352,6 +1352,11 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
convertTypedOrValueToInt(src, temp, output, fail, IntConversion_ClampToUint8);
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
void branchPtrInNurseryRange(Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label);
|
||||
#endif
|
||||
|
||||
public:
|
||||
class AfterICSaveLive {
|
||||
friend class MacroAssembler;
|
||||
|
Loading…
Reference in New Issue
Block a user