Bug 921571 - Fix SetElementIC dense element stub to work with double arrays. r=shu

This commit is contained in:
Jan de Mooij 2014-01-20 11:10:15 +01:00
parent 3d0c9385c3
commit d281c50bd5

View File

@ -3528,6 +3528,60 @@ IsTypedArrayElementSetInlineable(JSObject *obj, const Value &idval, const Value
!value.isString() && !value.isObject());
}
static void
StoreDenseElement(MacroAssembler &masm, ConstantOrRegister value, Register elements,
BaseIndex target)
{
// If the ObjectElements::CONVERT_DOUBLE_ELEMENTS flag is set, int32 values
// have to be converted to double first. If the value is not int32, it can
// always be stored directly.
Address elementsFlags(elements, ObjectElements::offsetOfFlags());
if (value.constant()) {
Value v = value.value();
Label done;
if (v.isInt32()) {
Label dontConvert;
masm.branchTest32(Assembler::Zero, elementsFlags,
Imm32(ObjectElements::CONVERT_DOUBLE_ELEMENTS),
&dontConvert);
masm.storeValue(DoubleValue(v.toInt32()), target);
masm.jump(&done);
masm.bind(&dontConvert);
}
masm.storeValue(v, target);
masm.bind(&done);
return;
}
TypedOrValueRegister reg = value.reg();
if (reg.hasTyped() && reg.type() != MIRType_Int32) {
masm.storeTypedOrValue(reg, target);
return;
}
Label convert, storeValue, done;
masm.branchTest32(Assembler::NonZero, elementsFlags,
Imm32(ObjectElements::CONVERT_DOUBLE_ELEMENTS),
&convert);
masm.bind(&storeValue);
masm.storeTypedOrValue(reg, target);
masm.jump(&done);
masm.bind(&convert);
if (reg.hasValue()) {
masm.branchTestInt32(Assembler::NotEqual, reg.valueReg(), &storeValue);
masm.int32ValueToDouble(reg.valueReg(), ScratchFloatReg);
masm.storeDouble(ScratchFloatReg, target);
} else {
JS_ASSERT(reg.type() == MIRType_Int32);
masm.convertInt32ToDouble(reg.typedReg().gpr(), ScratchFloatReg);
masm.storeDouble(ScratchFloatReg, target);
}
masm.bind(&done);
}
static bool
GenerateSetDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
JSObject *obj, const Value &idval, bool guardHoles, Register object,
@ -3609,7 +3663,7 @@ GenerateSetDenseElement(JSContext *cx, MacroAssembler &masm, IonCache::StubAttac
masm.branchTestMagic(Assembler::Equal, target, &failures);
else
masm.bind(&storeElement);
masm.storeConstantOrRegister(value, target);
StoreDenseElement(masm, value, elements, target);
}
attacher.jumpRejoin(masm);