Bug 914899 - Reinstate the OOL double truncation path in truncating values to int32. (r=jandem)

This commit is contained in:
Shu-yu Guo 2013-09-11 15:15:45 -07:00
parent eb0bc54bee
commit 1f4ea797ab
5 changed files with 68 additions and 33 deletions

View File

@ -166,20 +166,31 @@ CodeGenerator::visitValueToInt32(LValueToInt32 *lir)
Label fails;
if (lir->mode() == LValueToInt32::TRUNCATE) {
OutOfLineCode *oolDouble = oolTruncateDouble(temp, output);
if (!oolDouble)
return false;
// We can only handle strings in truncation contexts, like bitwise
// operations.
Label *stringEntry, *stringRejoin;
Register stringReg;
if (input->mightBeType(MIRType_String)) {
Register stringReg = ToRegister(lir->temp());
OutOfLineCode *ool = oolCallVM(StringToNumberInfo, lir, (ArgList(), stringReg),
StoreFloatRegisterTo(temp));
if (!ool)
stringReg = ToRegister(lir->temp());
OutOfLineCode *oolString = oolCallVM(StringToNumberInfo, lir, (ArgList(), stringReg),
StoreFloatRegisterTo(temp));
if (!oolString)
return false;
masm.truncateValueToInt32(operand, input, ool->entry(), ool->rejoin(), stringReg,
temp, output, &fails);
stringEntry = oolString->entry();
stringRejoin = oolString->rejoin();
} else {
masm.truncateValueToInt32(operand, input, temp, output, &fails);
stringReg = InvalidReg;
stringEntry = NULL;
stringRejoin = NULL;
}
masm.truncateValueToInt32(operand, input, stringEntry, stringRejoin, oolDouble->entry(),
stringReg, temp, output, &fails);
masm.bind(oolDouble->rejoin());
} else {
masm.convertValueToInt32(operand, input, temp, output, &fails,
lir->mirNormal()->canBeNegativeZero());
@ -6779,16 +6790,28 @@ CodeGenerator::visitClampVToUint8(LClampVToUint8 *lir)
Register output = ToRegister(lir->output());
MDefinition *input = lir->mir()->input();
Label fails;
if (input->mightBeType(MIRType_String)) {
OutOfLineCode *ool = oolCallVM(StringToNumberInfo, lir, (ArgList(), output),
StoreFloatRegisterTo(tempFloat));
masm.clampValueToUint8(operand, input, ool->entry(), ool->rejoin(), output,
tempFloat, output, &fails);
OutOfLineCode *oolDouble = oolTruncateDouble(tempFloat, output);
if (!oolDouble)
return false;
Label *stringEntry, *stringRejoin;
if (input->mightBeType(MIRType_String)) {
OutOfLineCode *oolString = oolCallVM(StringToNumberInfo, lir, (ArgList(), output),
StoreFloatRegisterTo(tempFloat));
if (!oolString)
return false;
stringEntry = oolString->entry();
stringRejoin = oolString->rejoin();
} else {
masm.clampValueToUint8(operand, input, tempFloat, output, &fails);
stringEntry = NULL;
stringRejoin = NULL;
}
Label fails;
masm.clampValueToUint8(operand, input,
stringEntry, stringRejoin, oolDouble->entry(),
output, tempFloat, output, &fails);
if (!bailoutFrom(&fails, lir->snapshot()))
return false;

View File

@ -1535,8 +1535,8 @@ MacroAssembler::convertTypedOrValueToDouble(TypedOrValueRegister src, FloatRegis
}
void
MacroAssembler::convertDoubleToInt(FloatRegister src, Register output, Label *fail,
IntConversionBehavior behavior)
MacroAssembler::convertDoubleToInt(FloatRegister src, Register output, Label *truncateFail,
Label *fail, IntConversionBehavior behavior)
{
switch (behavior) {
case IntConversion_Normal:
@ -1544,7 +1544,7 @@ MacroAssembler::convertDoubleToInt(FloatRegister src, Register output, Label *fa
convertDoubleToInt32(src, output, fail, behavior == IntConversion_NegativeZeroCheck);
break;
case IntConversion_Truncate:
branchTruncateDouble(src, output, fail);
branchTruncateDouble(src, output, truncateFail ? truncateFail : fail);
break;
case IntConversion_ClampToUint8:
clampDoubleToUint8(src, output);
@ -1555,6 +1555,7 @@ MacroAssembler::convertDoubleToInt(FloatRegister src, Register output, Label *fa
void
MacroAssembler::convertValueToInt(ValueOperand value, MDefinition *maybeInput,
Label *handleStringEntry, Label *handleStringRejoin,
Label *truncateDoubleSlow,
Register stringReg, FloatRegister temp, Register output,
Label *fail, IntConversionBehavior behavior)
{
@ -1613,7 +1614,7 @@ MacroAssembler::convertValueToInt(ValueOperand value, MDefinition *maybeInput,
if (handleStrings)
bind(handleStringRejoin);
convertDoubleToInt(temp, output, fail, behavior);
convertDoubleToInt(temp, output, truncateDoubleSlow, fail, behavior);
jump(&done);
}
@ -1724,7 +1725,7 @@ MacroAssembler::convertTypedOrValueToInt(TypedOrValueRegister src, FloatRegister
move32(src.typedReg().gpr(), output);
break;
case MIRType_Double:
convertDoubleToInt(src.typedReg().fpu(), output, fail, behavior);
convertDoubleToInt(src.typedReg().fpu(), output, NULL, fail, behavior);
break;
case MIRType_String:
case MIRType_Object:

View File

@ -1013,7 +1013,7 @@ class MacroAssembler : public MacroAssemblerSpecific
//
// Functions for converting values to int.
//
void convertDoubleToInt(FloatRegister src, Register output, Label *fail,
void convertDoubleToInt(FloatRegister src, Register output, Label *truncateFail, Label *fail,
IntConversionBehavior behavior);
// Strings may be handled by providing labels to jump to when the behavior
@ -1022,12 +1022,13 @@ class MacroAssembler : public MacroAssemblerSpecific
// double store into |temp|.
void convertValueToInt(ValueOperand value, MDefinition *input,
Label *handleStringEntry, Label *handleStringRejoin,
Label *truncateDoubleSlow,
Register stringReg, FloatRegister temp, Register output,
Label *fail, IntConversionBehavior behavior);
void convertValueToInt(ValueOperand value, FloatRegister temp, Register output, Label *fail,
IntConversionBehavior behavior)
{
convertValueToInt(value, NULL, NULL, NULL, InvalidReg, temp, output, fail, behavior);
convertValueToInt(value, NULL, NULL, NULL, NULL, InvalidReg, temp, output, fail, behavior);
}
bool convertValueToInt(JSContext *cx, const Value &v, Register output, Label *fail,
IntConversionBehavior behavior);
@ -1050,7 +1051,7 @@ class MacroAssembler : public MacroAssemblerSpecific
FloatRegister temp, Register output, Label *fail,
bool negativeZeroCheck)
{
convertValueToInt(value, input, NULL, NULL, InvalidReg, temp, output, fail,
convertValueToInt(value, input, NULL, NULL, NULL, InvalidReg, temp, output, fail,
negativeZeroCheck
? IntConversion_NegativeZeroCheck
: IntConversion_Normal);
@ -1085,16 +1086,16 @@ class MacroAssembler : public MacroAssemblerSpecific
}
void truncateValueToInt32(ValueOperand value, MDefinition *input,
Label *handleStringEntry, Label *handleStringRejoin,
Register stringReg, FloatRegister temp, Register output,
Label *fail)
Label *truncateDoubleSlow,
Register stringReg, FloatRegister temp, Register output, Label *fail)
{
convertValueToInt(value, input, handleStringEntry, handleStringRejoin,
convertValueToInt(value, input, handleStringEntry, handleStringRejoin, truncateDoubleSlow,
stringReg, temp, output, fail, IntConversion_Truncate);
}
void truncateValueToInt32(ValueOperand value, MDefinition *input,
FloatRegister temp, Register output, Label *fail)
{
convertValueToInt(value, input, NULL, NULL, InvalidReg, temp, output, fail,
convertValueToInt(value, input, NULL, NULL, NULL, InvalidReg, temp, output, fail,
IntConversion_Truncate);
}
bool truncateValueToInt32(JSContext *cx, const Value &v, Register output, Label *fail) {
@ -1117,16 +1118,16 @@ class MacroAssembler : public MacroAssemblerSpecific
}
void clampValueToUint8(ValueOperand value, MDefinition *input,
Label *handleStringEntry, Label *handleStringRejoin,
Register stringReg, FloatRegister temp, Register output,
Label *fail)
Label *truncateDoubleSlow,
Register stringReg, FloatRegister temp, Register output, Label *fail)
{
convertValueToInt(value, input, handleStringEntry, handleStringRejoin,
convertValueToInt(value, input, handleStringEntry, handleStringRejoin, truncateDoubleSlow,
stringReg, temp, output, fail, IntConversion_ClampToUint8);
}
void clampValueToUint8(ValueOperand value, MDefinition *input,
FloatRegister temp, Register output, Label *fail)
{
convertValueToInt(value, input, NULL, NULL, InvalidReg, temp, output, fail,
convertValueToInt(value, input, NULL, NULL, NULL, InvalidReg, temp, output, fail,
IntConversion_ClampToUint8);
}
bool clampValueToUint8(JSContext *cx, const Value &v, Register output, Label *fail) {

View File

@ -675,11 +675,20 @@ class OutOfLineTruncateSlow : public OutOfLineCodeBase<CodeGeneratorShared>
}
};
bool
CodeGeneratorShared::emitTruncateDouble(const FloatRegister &src, const Register &dest)
OutOfLineCode *
CodeGeneratorShared::oolTruncateDouble(const FloatRegister &src, const Register &dest)
{
OutOfLineTruncateSlow *ool = new OutOfLineTruncateSlow(src, dest);
if (!addOutOfLineCode(ool))
return NULL;
return ool;
}
bool
CodeGeneratorShared::emitTruncateDouble(const FloatRegister &src, const Register &dest)
{
OutOfLineCode *ool = oolTruncateDouble(src, dest);
if (!ool)
return false;
masm.branchTruncateDouble(src, dest, ool->entry());

View File

@ -283,6 +283,7 @@ class CodeGeneratorShared : public LInstructionVisitor
// an invalidation marker.
void ensureOsiSpace();
OutOfLineCode *oolTruncateDouble(const FloatRegister &src, const Register &dest);
bool emitTruncateDouble(const FloatRegister &src, const Register &dest);
void emitPreBarrier(Register base, const LAllocation *index, MIRType type);