Bug 855514: IonMonkey: Add fastpath for JSOP_TOID for ints and doubles that fit into an int, r=jandem

This commit is contained in:
Hannes Verschore 2013-04-08 14:54:20 +02:00
parent 6bf2df1c9a
commit d582580d48
4 changed files with 67 additions and 12 deletions

View File

@ -5193,11 +5193,33 @@ static const VMFunction ToIdInfo = FunctionInfo<ToIdFn>(ToIdOperation);
bool
CodeGenerator::visitToIdV(LToIdV *lir)
{
pushArg(ToValue(lir, LToIdV::Index));
pushArg(ToValue(lir, LToIdV::Object));
pushArg(ImmWord(lir->mir()->resumePoint()->pc()));
pushArg(ImmGCPtr(current->mir()->info().script()));
return callVM(ToIdInfo, lir);
Label notInt32;
FloatRegister temp = ToFloatRegister(lir->tempFloat());
const ValueOperand out = ToOutValue(lir);
ValueOperand index = ToValue(lir, LToIdV::Index);
OutOfLineCode *ool = oolCallVM(ToIdInfo, lir,
(ArgList(),
ImmGCPtr(current->mir()->info().script()),
ImmWord(lir->mir()->resumePoint()->pc()),
ToValue(lir, LToIdV::Object),
ToValue(lir, LToIdV::Index)),
StoreValueTo(out));
Register tag = masm.splitTagForTest(index);
masm.branchTestInt32(Assembler::NotEqual, tag, &notInt32);
masm.moveValue(index, out);
masm.jump(ool->rejoin());
masm.bind(&notInt32);
masm.branchTestDouble(Assembler::NotEqual, tag, ool->entry());
masm.unboxDouble(index, temp);
masm.convertDoubleToInt32(temp, out.scratchReg(), ool->entry(), true);
masm.tagValue(JSVAL_TYPE_INT32, out.scratchReg(), out);
masm.bind(ool->rejoin());
return true;
}
bool

View File

@ -607,10 +607,16 @@ class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 0>
}
};
class LToIdV : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0>
class LToIdV : public LInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 1>
{
public:
LIR_HEADER(ToIdV)
BOX_OUTPUT_ACCESSORS()
LToIdV(const LDefinition &temp)
{
setTemp(0, temp);
}
static const size_t Object = 0;
static const size_t Index = BOX_PIECES;
@ -618,6 +624,10 @@ class LToIdV : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0>
MToId *mir() const {
return mir_->toToId();
}
const LDefinition *tempFloat() {
return getTemp(0);
}
};
// Allocate an object for |new| on the caller-side,

View File

@ -875,14 +875,12 @@ LIRGenerator::visitTypeOf(MTypeOf *ins)
bool
LIRGenerator::visitToId(MToId *ins)
{
LToIdV *lir = new LToIdV();
if (!useBoxAtStart(lir, LToIdV::Object, ins->lhs()))
LToIdV *lir = new LToIdV(tempFloat());
if (!useBox(lir, LToIdV::Object, ins->lhs()))
return false;
if (!useBoxAtStart(lir, LToIdV::Index, ins->rhs()))
if (!useBox(lir, LToIdV::Index, ins->rhs()))
return false;
if (!defineReturn(lir, ins))
return false;
return assignSafepoint(lir, ins);
return defineBox(lir, ins) && assignSafepoint(lir, ins);
}
bool

View File

@ -0,0 +1,25 @@
var b = 1.5;
var arr;
function f_int(arr, index) {
for (var i=0; i<100; i++) {
arr[index]++;
}
}
arr = [1, 2, 3];
f_int(arr, "1");
assertEq(arr[1], 102);
arr = [1, 2, 3];
f_int(arr, 1);
assertEq(arr[1], 102);
function f_double(arr, index) {
for (var i=0; i<100; i++) {
arr[+Math.pow(index,1.0)*1.5/b]++;
}
}
arr = [1, 2, 3];
f_double(arr, 1.0);
assertEq(arr[1], 102);
arr = [1, 2, 3];
f_double(arr, NaN);
assertEq(arr[1], 2);