зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1000100 - Baseline postbarrier tidyup r=jandem
This commit is contained in:
Родитель
a580d15ad3
Коммит
1ca46994a4
|
@ -408,7 +408,8 @@ BaselineCompiler::emitEpilogue()
|
|||
#ifdef JSGC_GENERATIONAL
|
||||
// On input:
|
||||
// R2.scratchReg() contains object being written to.
|
||||
// Otherwise, baseline stack will be synced, so all other registers are usable as scratch.
|
||||
// Called with the baseline stack synced, except for R0 which is preserved.
|
||||
// All other registers are usable as scratch.
|
||||
// This calls:
|
||||
// void PostWriteBarrier(JSRuntime *rt, JSObject *obj);
|
||||
bool
|
||||
|
@ -418,6 +419,7 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot()
|
|||
|
||||
Register objReg = R2.scratchReg();
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(R0);
|
||||
regs.take(objReg);
|
||||
regs.take(BaselineFrameReg);
|
||||
Register scratch = regs.takeAny();
|
||||
|
@ -428,6 +430,7 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot()
|
|||
#elif defined(JS_CODEGEN_MIPS)
|
||||
masm.push(ra);
|
||||
#endif
|
||||
masm.pushValue(R0);
|
||||
|
||||
masm.setupUnalignedABICall(2, scratch);
|
||||
masm.movePtr(ImmPtr(cx->runtime()), scratch);
|
||||
|
@ -435,6 +438,7 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot()
|
|||
masm.passABIArg(objReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, PostWriteBarrier));
|
||||
|
||||
masm.popValue(R0);
|
||||
masm.ret();
|
||||
return true;
|
||||
}
|
||||
|
@ -2096,16 +2100,15 @@ BaselineCompiler::emit_JSOP_SETALIASEDVAR()
|
|||
frame.push(R0);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// Fully sync the stack if post-barrier is needed.
|
||||
// Only R0 is live at this point.
|
||||
// Scope coordinate object is already in R2.scratchReg().
|
||||
frame.syncStack(0);
|
||||
Register temp = R1.scratchReg();
|
||||
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &skipBarrier);
|
||||
masm.branchPtrInNurseryRange(objReg, temp, &skipBarrier);
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, objReg, temp, &skipBarrier);
|
||||
masm.branchValueIsNurseryObject(Assembler::NotEqual, R0, temp, &skipBarrier);
|
||||
|
||||
masm.call(&postBarrierSlot_);
|
||||
masm.call(&postBarrierSlot_); // Won't clobber R0
|
||||
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
|
@ -2461,11 +2464,12 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get)
|
|||
frame.push(R0);
|
||||
} else {
|
||||
masm.patchableCallPreBarrier(argAddr, MIRType_Value);
|
||||
storeValue(frame.peek(-1), argAddr, R0);
|
||||
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
|
||||
masm.storeValue(R0, argAddr);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// Fully sync the stack if post-barrier is needed.
|
||||
frame.syncStack(0);
|
||||
MOZ_ASSERT(frame.numUnsyncedSlots() == 0);
|
||||
|
||||
Register temp = R1.scratchReg();
|
||||
|
||||
// Reload the arguments object
|
||||
|
@ -2473,7 +2477,9 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get)
|
|||
masm.loadPtr(Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfArgsObj()), reg);
|
||||
|
||||
Label skipBarrier;
|
||||
masm.branchPtrInNurseryRange(reg, temp, &skipBarrier);
|
||||
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, reg, temp, &skipBarrier);
|
||||
masm.branchValueIsNurseryObject(Assembler::NotEqual, R0, temp, &skipBarrier);
|
||||
|
||||
masm.call(&postBarrierSlot_);
|
||||
|
||||
|
|
|
@ -734,16 +734,9 @@ inline bool
|
|||
ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val,
|
||||
Register scratch, GeneralRegisterSet saveRegs)
|
||||
{
|
||||
Nursery &nursery = cx->runtime()->gc.nursery;
|
||||
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, val, &skipBarrier);
|
||||
|
||||
masm.branchPtrInNurseryRange(obj, scratch, &skipBarrier);
|
||||
|
||||
Register valReg = masm.extractObject(val, scratch);
|
||||
masm.branchPtr(Assembler::Below, valReg, ImmWord(nursery.start()), &skipBarrier);
|
||||
masm.branchPtr(Assembler::AboveOrEqual, valReg, ImmWord(nursery.heapEnd()), &skipBarrier);
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, obj, scratch, &skipBarrier);
|
||||
masm.branchValueIsNurseryObject(Assembler::NotEqual, val, scratch, &skipBarrier);
|
||||
|
||||
// void PostWriteBarrier(JSRuntime *rt, JSObject *obj);
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
|
|
|
@ -1875,10 +1875,11 @@ CodeGenerator::visitPostWriteBarrierO(LPostWriteBarrierO *lir)
|
|||
JS_ASSERT(!nursery.isInside(&lir->object()->toConstant()->toObject()));
|
||||
#endif
|
||||
} else {
|
||||
masm.branchPtrInNurseryRange(ToRegister(lir->object()), temp, ool->rejoin());
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, ToRegister(lir->object()), temp,
|
||||
ool->rejoin());
|
||||
}
|
||||
|
||||
masm.branchPtrInNurseryRange(ToRegister(lir->value()), temp, ool->entry());
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, ToRegister(lir->value()), temp, ool->entry());
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
#endif
|
||||
|
@ -1901,11 +1902,12 @@ CodeGenerator::visitPostWriteBarrierV(LPostWriteBarrierV *lir)
|
|||
JS_ASSERT(!nursery.isInside(&lir->object()->toConstant()->toObject()));
|
||||
#endif
|
||||
} else {
|
||||
masm.branchPtrInNurseryRange(ToRegister(lir->object()), temp, ool->rejoin());
|
||||
masm.branchPtrInNurseryRange(Assembler::Equal, ToRegister(lir->object()), temp,
|
||||
ool->rejoin());
|
||||
}
|
||||
|
||||
ValueOperand value = ToValue(lir, LPostWriteBarrierV::Input);
|
||||
masm.branchValueIsNurseryObject(value, temp, ool->entry());
|
||||
masm.branchValueIsNurseryObject(Assembler::Equal, value, temp, ool->entry());
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
#endif
|
||||
|
|
|
@ -4350,8 +4350,10 @@ MacroAssemblerARMCompat::jumpWithPatch(RepatchLabel *label, Condition cond)
|
|||
#ifdef JSGC_GENERATIONAL
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
|
||||
MacroAssemblerARMCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label *label)
|
||||
{
|
||||
JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
JS_ASSERT(ptr != temp);
|
||||
JS_ASSERT(ptr != secondScratchReg_);
|
||||
|
||||
|
@ -4360,16 +4362,20 @@ MacroAssemblerARMCompat::branchPtrInNurseryRange(Register ptr, Register temp, La
|
|||
|
||||
ma_mov(Imm32(startChunk), secondScratchReg_);
|
||||
as_rsb(secondScratchReg_, secondScratchReg_, lsr(ptr, Nursery::ChunkShift));
|
||||
branch32(Assembler::Below, secondScratchReg_, Imm32(Nursery::NumNurseryChunks), label);
|
||||
branch32(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
secondScratchReg_, Imm32(Nursery::NumNurseryChunks), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label)
|
||||
MacroAssemblerARMCompat::branchValueIsNurseryObject(Condition cond, ValueOperand value,
|
||||
Register temp, Label *label)
|
||||
{
|
||||
JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, &done);
|
||||
branchPtrInNurseryRange(value.payloadReg(), temp, label);
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
|
|
@ -1599,8 +1599,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
void branchPtrInNurseryRange(Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label);
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label *label);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -370,27 +370,33 @@ MacroAssemblerX64::handleFailureWithHandlerTail()
|
|||
#ifdef JSGC_GENERATIONAL
|
||||
|
||||
void
|
||||
MacroAssemblerX64::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
|
||||
MacroAssemblerX64::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label *label)
|
||||
{
|
||||
JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
JS_ASSERT(ptr != temp);
|
||||
JS_ASSERT(ptr != ScratchReg);
|
||||
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), ScratchReg);
|
||||
addPtr(ptr, ScratchReg);
|
||||
branchPtr(Assembler::Below, ScratchReg, Imm32(Nursery::NurserySize), label);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
ScratchReg, Imm32(Nursery::NurserySize), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label)
|
||||
MacroAssemblerX64::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label *label)
|
||||
{
|
||||
JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
// 'Value' representing the start of the nursery tagged as a JSObject
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
Value start = ObjectValue(*reinterpret_cast<JSObject *>(nursery.start()));
|
||||
|
||||
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), ScratchReg);
|
||||
addPtr(value.valueReg(), ScratchReg);
|
||||
branchPtr(Assembler::Below, ScratchReg, Imm32(Nursery::NurserySize), label);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
ScratchReg, Imm32(Nursery::NurserySize), label);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1334,8 +1334,8 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
void branchPtrInNurseryRange(Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label);
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label *label);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -390,24 +390,30 @@ MacroAssemblerX86::branchTestValue(Condition cond, const ValueOperand &value, co
|
|||
#ifdef JSGC_GENERATIONAL
|
||||
|
||||
void
|
||||
MacroAssemblerX86::branchPtrInNurseryRange(Register ptr, Register temp, Label *label)
|
||||
MacroAssemblerX86::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label *label)
|
||||
{
|
||||
JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
JS_ASSERT(ptr != temp);
|
||||
JS_ASSERT(temp != InvalidReg); // A temp register is required for x86.
|
||||
|
||||
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
|
||||
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
|
||||
addPtr(ptr, temp);
|
||||
branchPtr(Assembler::Below, temp, Imm32(Nursery::NurserySize), label);
|
||||
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
|
||||
temp, Imm32(Nursery::NurserySize), label);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label)
|
||||
MacroAssemblerX86::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
|
||||
Label *label)
|
||||
{
|
||||
JS_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
||||
|
||||
Label done;
|
||||
|
||||
branchTestObject(Assembler::NotEqual, value, &done);
|
||||
branchPtrInNurseryRange(value.payloadReg(), temp, label);
|
||||
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
|
||||
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
|
|
@ -1124,8 +1124,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
|||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
void branchPtrInNurseryRange(Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(ValueOperand value, Register temp, Label *label);
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label *label);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче