mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 911254 - Odinmonkey: (ARM) use the 'compare immediate' instruction for bounds checks. r=mjrosenb
This commit is contained in:
parent
66808396a3
commit
6036d9fe79
@ -37,9 +37,11 @@ AsmJSModule::patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx)
|
||||
JSC::X86Assembler::setPointer(addr, (void *)(heapOffset + disp));
|
||||
}
|
||||
#elif defined(JS_CPU_ARM)
|
||||
uint32_t bits = mozilla::CeilingLog2(heap->byteLength());
|
||||
for (unsigned i = 0; i < heapAccesses_.length(); i++)
|
||||
jit::Assembler::updateBoundsCheck(bits, (jit::Instruction*)(heapAccesses_[i].offset() + code_));
|
||||
uint32_t heapLength = heap->byteLength();
|
||||
for (unsigned i = 0; i < heapAccesses_.length(); i++) {
|
||||
jit::Assembler::updateBoundsCheck(heapLength,
|
||||
(jit::Instruction*)(heapAccesses_[i].offset() + code_));
|
||||
}
|
||||
// We already know the exact extent of areas that need to be patched, just make sure we
|
||||
// flush all of them at once.
|
||||
jit::AutoFlushCache::updateTop(uintptr_t(code_), pod.codeBytes_);
|
||||
|
@ -2725,22 +2725,21 @@ Assembler::ToggleCall(CodeLocationLabel inst_, bool enabled)
|
||||
AutoFlushCache::updateTop(uintptr_t(inst), 4);
|
||||
}
|
||||
|
||||
void Assembler::updateBoundsCheck(uint32_t logHeapSize, Instruction *inst)
|
||||
void Assembler::updateBoundsCheck(uint32_t heapSize, Instruction *inst)
|
||||
{
|
||||
JS_ASSERT(inst->is<InstMOV>());
|
||||
InstMOV *mov = inst->as<InstMOV>();
|
||||
JS_ASSERT(mov->checkDest(ScratchRegister));
|
||||
JS_ASSERT(inst->is<InstCMP>());
|
||||
InstCMP *cmp = inst->as<InstCMP>();
|
||||
|
||||
Operand2 op = mov->extractOp2();
|
||||
JS_ASSERT(op.isO2Reg());
|
||||
|
||||
Op2Reg reg = op.toOp2Reg();
|
||||
Register index;
|
||||
reg.getRM(&index);
|
||||
JS_ASSERT(reg.isO2RegImmShift());
|
||||
// O2RegImmShift shift = reg.toO2RegImmShift();
|
||||
cmp->extractOp1(&index);
|
||||
|
||||
*inst = InstALU(ScratchRegister, InvalidReg, lsr(index, logHeapSize), op_mov, SetCond, Always);
|
||||
Operand2 op = cmp->extractOp2();
|
||||
JS_ASSERT(op.isImm8());
|
||||
|
||||
Imm8 imm8 = Imm8(heapSize);
|
||||
JS_ASSERT(!imm8.invalid);
|
||||
|
||||
*inst = InstALU(InvalidReg, index, imm8, op_cmp, SetCond, Always);
|
||||
// NOTE: we don't update the Auto Flush Cache! this function is currently only called from
|
||||
// within AsmJSModule::patchHeapAccesses, which does that for us. Don't call this!
|
||||
}
|
||||
|
@ -1831,18 +1831,19 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
|
||||
|
||||
BufferOffset bo = masm.ma_BoundsCheck(ptrReg);
|
||||
if (isFloat) {
|
||||
VFPRegister vd(ToFloatRegister(ins->output()));
|
||||
FloatRegister dst = ToFloatRegister(ins->output());
|
||||
masm.ma_vmov(NANReg, dst, Assembler::AboveOrEqual);
|
||||
VFPRegister vd(dst);
|
||||
if (size == 32) {
|
||||
masm.ma_vldr(vd.singleOverlay(), HeapReg, ptrReg, 0, Assembler::Zero);
|
||||
masm.as_vcvt(vd, vd.singleOverlay(), false, Assembler::Zero);
|
||||
masm.ma_vldr(vd.singleOverlay(), HeapReg, ptrReg, 0, Assembler::Below);
|
||||
masm.as_vcvt(vd, vd.singleOverlay(), false, Assembler::Below);
|
||||
} else {
|
||||
masm.ma_vldr(vd, HeapReg, ptrReg, 0, Assembler::Zero);
|
||||
masm.ma_vldr(vd, HeapReg, ptrReg, 0, Assembler::Below);
|
||||
}
|
||||
masm.ma_vmov(NANReg, ToFloatRegister(ins->output()), Assembler::NonZero);
|
||||
} else {
|
||||
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg,
|
||||
ToRegister(ins->output()), Offset, Assembler::Zero);
|
||||
masm.ma_mov(Imm32(0), ToRegister(ins->output()), NoSetCond, Assembler::NonZero);
|
||||
Register d = ToRegister(ins->output());
|
||||
masm.ma_mov(Imm32(0), d, NoSetCond, Assembler::AboveOrEqual);
|
||||
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below);
|
||||
}
|
||||
return gen->noteHeapAccess(AsmJSHeapAccess(bo.getOffset()));
|
||||
}
|
||||
@ -1906,12 +1907,12 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
|
||||
if (isFloat) {
|
||||
VFPRegister vd(ToFloatRegister(ins->value()));
|
||||
if (size == 32)
|
||||
masm.storeFloat(vd, HeapReg, ptrReg, Assembler::Zero);
|
||||
masm.storeFloat(vd, HeapReg, ptrReg, Assembler::Below);
|
||||
else
|
||||
masm.ma_vstr(vd, HeapReg, ptrReg, 0, Assembler::Zero);
|
||||
masm.ma_vstr(vd, HeapReg, ptrReg, 0, Assembler::Below);
|
||||
} else {
|
||||
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
|
||||
ToRegister(ins->value()), Offset, Assembler::Zero);
|
||||
ToRegister(ins->value()), Offset, Assembler::Below);
|
||||
}
|
||||
return gen->noteHeapAccess(AsmJSHeapAccess(bo.getOffset()));
|
||||
}
|
||||
|
@ -1364,7 +1364,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
ma_str(lr, dest);
|
||||
}
|
||||
BufferOffset ma_BoundsCheck(Register bounded) {
|
||||
return as_mov(ScratchRegister, lsl(bounded, 0), SetCond);
|
||||
return as_cmp(bounded, Imm8(0));
|
||||
}
|
||||
|
||||
void storeFloat(VFPRegister src, Register base, Register index, Condition cond) {
|
||||
|
Loading…
Reference in New Issue
Block a user