Bug 911254 - Odinmonkey: (ARM) use the 'compare immediate' instruction for bounds checks. r=mjrosenb

This commit is contained in:
Douglas Crosher 2013-09-07 10:53:03 +10:00
parent 66808396a3
commit 6036d9fe79
4 changed files with 29 additions and 27 deletions

View File

@ -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_);

View File

@ -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!
}

View File

@ -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()));
}

View File

@ -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) {