Bug 1291292 - Use chunk location word for nursery test in JIT code r=jandem

This commit is contained in:
Jon Coppeard 2016-08-11 17:14:56 +01:00
Родитель 4d37e5f20d
Коммит 31b63af33d
14 изменённых файлов: 89 добавлений и 99 удалений

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

@ -1365,6 +1365,9 @@ TenuredCell::isAligned() const
}
#endif
static const int32_t ChunkLocationOffsetFromLastByte =
int32_t(gc::ChunkLocationOffset) - int32_t(gc::ChunkMask);
} /* namespace gc */
} /* namespace js */

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

@ -2529,7 +2529,7 @@ BaselineCompiler::emit_JSOP_SETALIASEDVAR()
Register temp = R1.scratchReg();
Label skipBarrier;
masm.branchPtrInNurseryRange(Assembler::Equal, objReg, temp, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::Equal, objReg, temp, &skipBarrier);
masm.branchValueIsNurseryObject(Assembler::NotEqual, R0, temp, &skipBarrier);
masm.call(&postBarrierSlot_); // Won't clobber R0
@ -2945,7 +2945,7 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get)
Label skipBarrier;
masm.branchPtrInNurseryRange(Assembler::Equal, reg, temp, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::Equal, reg, temp, &skipBarrier);
masm.branchValueIsNurseryObject(Assembler::NotEqual, R0, temp, &skipBarrier);
masm.call(&postBarrierSlot_);
@ -3977,8 +3977,8 @@ BaselineCompiler::emit_JSOP_INITIALYIELD()
Register temp = R1.scratchReg();
Label skipBarrier;
masm.branchPtrInNurseryRange(Assembler::Equal, genObj, temp, &skipBarrier);
masm.branchPtrInNurseryRange(Assembler::NotEqual, scopeObj, temp, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::Equal, genObj, temp, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::NotEqual, scopeObj, temp, &skipBarrier);
masm.push(genObj);
MOZ_ASSERT(genObj == R2.scratchReg());
masm.call(&postBarrierSlot_);
@ -4022,8 +4022,8 @@ BaselineCompiler::emit_JSOP_YIELD()
Register temp = R1.scratchReg();
Label skipBarrier;
masm.branchPtrInNurseryRange(Assembler::Equal, genObj, temp, &skipBarrier);
masm.branchPtrInNurseryRange(Assembler::NotEqual, scopeObj, temp, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::Equal, genObj, temp, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::NotEqual, scopeObj, temp, &skipBarrier);
MOZ_ASSERT(genObj == R2.scratchReg());
masm.call(&postBarrierSlot_);
masm.bind(&skipBarrier);

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

@ -3554,13 +3554,15 @@ CodeGenerator::visitPostWriteBarrierCommonO(LPostBarrierType* lir, OutOfLineCode
// Constant nursery objects cannot appear here, see LIRGenerator::visitPostWriteElementBarrier.
MOZ_ASSERT(!IsInsideNursery(&lir->object()->toConstant()->toObject()));
} else {
masm.branchPtrInNurseryRange(Assembler::Equal, ToRegister(lir->object()), temp,
masm.branchPtrInNurseryChunk(Assembler::Equal, ToRegister(lir->object()), temp,
ool->rejoin());
}
maybeEmitGlobalBarrierCheck(lir->object(), ool);
masm.branchPtrInNurseryRange(Assembler::Equal, ToRegister(lir->value()), temp, ool->entry());
Register valueObj = ToRegister(lir->value());
masm.branchTestPtr(Assembler::Zero, valueObj, valueObj, ool->rejoin());
masm.branchPtrInNurseryChunk(Assembler::Equal, ToRegister(lir->value()), temp, ool->entry());
masm.bind(ool->rejoin());
}
@ -3577,7 +3579,7 @@ CodeGenerator::visitPostWriteBarrierCommonV(LPostBarrierType* lir, OutOfLineCode
// Constant nursery objects cannot appear here, see LIRGenerator::visitPostWriteElementBarrier.
MOZ_ASSERT(!IsInsideNursery(&lir->object()->toConstant()->toObject()));
} else {
masm.branchPtrInNurseryRange(Assembler::Equal, ToRegister(lir->object()), temp,
masm.branchPtrInNurseryChunk(Assembler::Equal, ToRegister(lir->object()), temp,
ool->rejoin());
}

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

@ -994,9 +994,9 @@ class MacroAssembler : public MacroAssemblerSpecific
template <typename T>
inline CodeOffsetJump branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label) PER_SHARED_ARCH;
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
void branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp, Label* label)
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
void branchPtrInNurseryRange(Condition cond, const Address& address, Register temp, Label* label)
void branchPtrInNurseryChunk(Condition cond, const Address& address, Register temp, Label* label)
DEFINED_ON(x86);
void branchValueIsNurseryObject(Condition cond, const Address& address, Register temp, Label* label) PER_ARCH;
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label) PER_ARCH;
@ -1208,8 +1208,7 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchPtrImpl(Condition cond, const T& lhs, const S& rhs, Label* label)
DEFINED_ON(x86_shared);
template <typename T>
void branchPtrInNurseryRangeImpl(Condition cond, const T& ptr, Register temp, Label* label)
void branchPtrInNurseryChunkImpl(Condition cond, Register ptr, Label* label)
DEFINED_ON(x86);
template <typename T>
void branchValueIsNurseryObjectImpl(Condition cond, const T& value, Register temp, Label* label)

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

@ -834,7 +834,7 @@ ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler& masm, Register obj, Val
Register scratch, LiveGeneralRegisterSet saveRegs)
{
Label skipBarrier;
masm.branchPtrInNurseryRange(Assembler::Equal, obj, scratch, &skipBarrier);
masm.branchPtrInNurseryChunk(Assembler::Equal, obj, scratch, &skipBarrier);
masm.branchValueIsNurseryObject(Assembler::NotEqual, val, scratch, &skipBarrier);
// void PostWriteBarrier(JSRuntime* rt, JSObject* obj);

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

@ -5220,7 +5220,7 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
// Branch functions
void
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
MacroAssembler::branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
Label* label)
{
AutoRegisterScope scratch2(*this, secondScratchReg_);
@ -5229,13 +5229,10 @@ MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register t
MOZ_ASSERT(ptr != temp);
MOZ_ASSERT(ptr != scratch2);
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
uintptr_t startChunk = nursery.start() >> Nursery::ChunkShift;
ma_mov(Imm32(startChunk), scratch2);
as_rsb(scratch2, scratch2, lsr(ptr, Nursery::ChunkShift));
branch32(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
scratch2, Imm32(nursery.numChunks()), label);
ma_lsr(Imm32(gc::ChunkShift), ptr, scratch2);
ma_lsl(Imm32(gc::ChunkShift), scratch2, scratch2);
load32(Address(scratch2, gc::ChunkLocationOffset), scratch2);
branch32(cond, scratch2, Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
}
void
@ -5245,10 +5242,10 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, const Address& addres
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
Label done;
branchTestObject(Assembler::NotEqual, address, cond == Assembler::Equal ? &done : label);
loadPtr(address, temp);
branchPtrInNurseryRange(cond, temp, InvalidReg, label);
branchPtrInNurseryChunk(cond, temp, InvalidReg, label);
bind(&done);
}
@ -5260,9 +5257,9 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
branchPtrInNurseryChunk(cond, value.payloadReg(), InvalidReg, label);
bind(&done);
}

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

@ -725,7 +725,7 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
// Branch functions
void
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
MacroAssembler::branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
Label* label)
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
@ -733,11 +733,10 @@ MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register t
MOZ_ASSERT(ptr != ScratchReg && ptr != ScratchReg2); // Both may be used internally.
MOZ_ASSERT(temp != ScratchReg && temp != ScratchReg2);
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
addPtr(ptr, temp);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
temp, ImmWord(nursery.nurserySize()), label);
movePtr(ptr, temp);
orPtr(Imm32(gc::ChunkMask), temp);
branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
}
void
@ -751,7 +750,7 @@ void
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
Label* label)
{
branchValueIsNurseryObjectImpl(cond, value.valueReg(), temp, label);
branchValueIsNurseryObjectImpl(cond, value, temp, label);
}
template <typename T>
@ -759,22 +758,18 @@ void
MacroAssembler::branchValueIsNurseryObjectImpl(Condition cond, const T& value, Register temp,
Label* label)
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
MOZ_ASSERT(temp != ScratchReg && temp != ScratchReg2); // Both may be used internally.
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
// Avoid creating a bogus ObjectValue below.
if (!nursery.exists())
return;
extractObject(value, temp);
orPtr(Imm32(gc::ChunkMask), temp);
branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
// 'Value' representing the start of the nursery tagged as a JSObject
Value start = ObjectValue(*reinterpret_cast<JSObject*>(nursery.start()));
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), temp);
addPtr(value, temp);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
temp, ImmWord(nursery.nurserySize()), label);
bind(&done);
}
void

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

@ -1585,18 +1585,17 @@ MacroAssembler::pushFakeReturnAddress(Register scratch)
}
void
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
MacroAssembler::branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
Label* label)
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
MOZ_ASSERT(ptr != temp);
MOZ_ASSERT(ptr != SecondScratchReg);
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg);
addPtr(ptr, SecondScratchReg);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
SecondScratchReg, Imm32(nursery.nurserySize()), label);
movePtr(ptr, SecondScratchReg);
orPtr(Imm32(gc::ChunkMask), SecondScratchReg);
branch32(cond, Address(SecondScratchReg, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
}
void

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

@ -2175,7 +2175,7 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, const Address& addres
branchTestObject(Assembler::NotEqual, address, cond == Assembler::Equal ? &done : label);
loadPtr(address, temp);
branchPtrInNurseryRange(cond, temp, InvalidReg, label);
branchPtrInNurseryChunk(cond, temp, InvalidReg, label);
bind(&done);
}
@ -2189,7 +2189,7 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
branchPtrInNurseryChunk(cond, value.payloadReg(), temp, label);
bind(&done);
}

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

@ -2280,7 +2280,7 @@ void
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value,
Register temp, Label* label)
{
branchValueIsNurseryObjectImpl(cond, value.valueReg(), temp, label);
branchValueIsNurseryObjectImpl(cond, value, temp, label);
}
template <typename T>
@ -2290,14 +2290,15 @@ MacroAssembler::branchValueIsNurseryObjectImpl(Condition cond, const T& value, R
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
// 'Value' representing the start of the nursery tagged as a JSObject
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
Value start = ObjectValue(*reinterpret_cast<JSObject *>(nursery.start()));
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), SecondScratchReg);
addPtr(value, SecondScratchReg);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
SecondScratchReg, Imm32(nursery.nurserySize()), label);
extractObject(value, temp);
orPtr(Imm32(gc::ChunkMask), temp);
branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
bind(&done);
}
void

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

@ -40,7 +40,7 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared
LDefinition tempToUnbox();
bool needTempForPostBarrier() { return false; }
bool needTempForPostBarrier() { return true; }
void lowerDivI64(MDiv* div);
void lowerModI64(MMod* mod);

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

@ -530,19 +530,18 @@ MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
// Branch functions
void
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
MacroAssembler::branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp, Label* label)
{
ScratchRegisterScope scratch(*this);
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
ScratchRegisterScope scratch(*this);
MOZ_ASSERT(ptr != temp);
MOZ_ASSERT(ptr != scratch);
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), scratch);
addPtr(ptr, scratch);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
scratch, Imm32(nursery.nurserySize()), label);
movePtr(ptr, scratch);
orPtr(Imm32(gc::ChunkMask), scratch);
branch32(cond, Address(scratch, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
}
void
@ -556,7 +555,7 @@ void
MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp,
Label* label)
{
branchValueIsNurseryObjectImpl(cond, value.valueReg(), temp, label);
branchValueIsNurseryObjectImpl(cond, value, temp, label);
}
template <typename T>
@ -565,21 +564,17 @@ MacroAssembler::branchValueIsNurseryObjectImpl(Condition cond, const T& value, R
Label* label)
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
MOZ_ASSERT(temp != InvalidReg);
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
// Avoid creating a bogus ObjectValue below.
if (!nursery.exists())
return;
extractObject(value, temp);
orPtr(Imm32(gc::ChunkMask), temp);
branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
// 'Value' representing the start of the nursery tagged as a JSObject
Value start = ObjectValue(*reinterpret_cast<JSObject*>(nursery.start()));
ScratchRegisterScope scratch(*this);
movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), scratch);
addPtr(value, scratch);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
scratch, Imm32(nursery.nurserySize()), label);
bind(&done);
}
void

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

@ -410,33 +410,32 @@ MacroAssembler::callWithABINoProfiler(const Address& fun, MoveOp::Type result)
// Branch functions
void
MacroAssembler::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
MacroAssembler::branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
Label* label)
{
MOZ_ASSERT(temp != InvalidReg); // A temp register is required for x86.
MOZ_ASSERT(ptr != temp);
branchPtrInNurseryRangeImpl(cond, ptr, temp, label);
movePtr(ptr, temp);
branchPtrInNurseryChunkImpl(cond, temp, label);
}
void
MacroAssembler::branchPtrInNurseryRange(Condition cond, const Address& address, Register temp,
MacroAssembler::branchPtrInNurseryChunk(Condition cond, const Address& address, Register temp,
Label* label)
{
branchPtrInNurseryRangeImpl(cond, address, temp, label);
MOZ_ASSERT(temp != InvalidReg); // A temp register is required for x86.
loadPtr(address, temp);
branchPtrInNurseryChunkImpl(cond, temp, label);
}
template <typename T>
void
MacroAssembler::branchPtrInNurseryRangeImpl(Condition cond, const T& ptr, Register temp,
Label* label)
MacroAssembler::branchPtrInNurseryChunkImpl(Condition cond, Register ptr, Label* label)
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
MOZ_ASSERT(temp != InvalidReg); // A temp register is required for x86.
const Nursery& nursery = GetJitContext()->runtime->gcNursery();
movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp);
addPtr(ptr, temp);
branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual,
temp, Imm32(nursery.nurserySize()), label);
orPtr(Imm32(gc::ChunkMask), ptr);
branch32(cond, Address(ptr, gc::ChunkLocationOffsetFromLastByte),
Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
}
void
@ -448,7 +447,7 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, const Address& addres
Label done;
branchTestObject(Assembler::NotEqual, address, cond == Assembler::Equal ? &done : label);
branchPtrInNurseryRange(cond, address, temp, label);
branchPtrInNurseryChunk(cond, address, temp, label);
bind(&done);
}
@ -462,7 +461,7 @@ MacroAssembler::branchValueIsNurseryObject(Condition cond, ValueOperand value, R
Label done;
branchTestObject(Assembler::NotEqual, value, cond == Assembler::Equal ? &done : label);
branchPtrInNurseryRange(cond, value.payloadReg(), temp, label);
branchPtrInNurseryChunk(cond, value.payloadReg(), temp, label);
bind(&done);
}

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

@ -141,7 +141,7 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group)
Label notObject;
masm.branchTestObject(Assembler::NotEqual, valueAddress, &notObject);
Register valueObject = masm.extractObject(valueAddress, scratch1);
masm.branchPtrInNurseryRange(Assembler::Equal, valueObject, scratch2, &postBarrier);
masm.branchPtrInNurseryChunk(Assembler::Equal, valueObject, scratch2, &postBarrier);
masm.bind(&notObject);
}
}