mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Try converting known doubles to integers in GETELEM/SETELEM paths, bug 678687. r=dvander
This commit is contained in:
parent
a9d4865e7b
commit
72819628ee
@ -601,6 +601,12 @@ private:
|
||||
/* Convert fe from a double to integer (per ValueToECMAInt32) in place. */
|
||||
void truncateDoubleToInt32(FrameEntry *fe, Uses uses);
|
||||
|
||||
/*
|
||||
* Try to convert a double fe to an integer, with no truncation performed,
|
||||
* or jump to the slow path per uses.
|
||||
*/
|
||||
void tryConvertInteger(FrameEntry *fe, Uses uses);
|
||||
|
||||
/* Opcode handlers. */
|
||||
bool jumpAndTrace(Jump j, jsbytecode *target, Jump *slow = NULL, bool *trampoline = NULL);
|
||||
bool startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget);
|
||||
|
@ -1038,9 +1038,11 @@ IsCacheableSetElem(FrameEntry *obj, FrameEntry *id, FrameEntry *value)
|
||||
{
|
||||
if (obj->isNotType(JSVAL_TYPE_OBJECT))
|
||||
return false;
|
||||
if (id->isNotType(JSVAL_TYPE_INT32))
|
||||
if (id->isNotType(JSVAL_TYPE_INT32) && id->isNotType(JSVAL_TYPE_DOUBLE))
|
||||
return false;
|
||||
if (id->isConstant()) {
|
||||
if (id->isNotType(JSVAL_TYPE_INT32))
|
||||
return false;
|
||||
if (id->getValue().toInt32() < 0)
|
||||
return false;
|
||||
if (id->getValue().toInt32() + 1 < 0) // watch for overflow in hole paths
|
||||
@ -1070,6 +1072,9 @@ mjit::Compiler::jsop_setelem_dense()
|
||||
stubcc.linkExit(guard, Uses(3));
|
||||
}
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE))
|
||||
tryConvertInteger(id, Uses(2));
|
||||
|
||||
// Test for integer index.
|
||||
if (!id->isTypeKnown()) {
|
||||
Jump guard = frame.testInt32(Assembler::NotEqual, id);
|
||||
@ -1354,6 +1359,9 @@ mjit::Compiler::jsop_setelem_typed(int atype)
|
||||
stubcc.linkExit(guard, Uses(3));
|
||||
}
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE))
|
||||
tryConvertInteger(id, Uses(2));
|
||||
|
||||
// Test for integer index.
|
||||
if (!id->isTypeKnown()) {
|
||||
Jump guard = frame.testInt32(Assembler::NotEqual, id);
|
||||
@ -1433,6 +1441,22 @@ mjit::Compiler::jsop_setelem_typed(int atype)
|
||||
}
|
||||
#endif /* JS_METHODJIT_TYPED_ARRAY */
|
||||
|
||||
void
|
||||
mjit::Compiler::tryConvertInteger(FrameEntry *fe, Uses uses)
|
||||
{
|
||||
JS_ASSERT(fe->isType(JSVAL_TYPE_DOUBLE));
|
||||
|
||||
JumpList isDouble;
|
||||
FPRegisterID fpreg = frame.tempFPRegForData(fe);
|
||||
RegisterID reg = frame.allocReg();
|
||||
masm.branchConvertDoubleToInt32(fpreg, reg, isDouble, Registers::FPConversionTemp);
|
||||
Jump j = masm.jump();
|
||||
isDouble.linkTo(masm.label(), &masm);
|
||||
stubcc.linkExit(masm.jump(), uses);
|
||||
j.linkTo(masm.label(), &masm);
|
||||
frame.learnType(fe, JSVAL_TYPE_INT32, reg);
|
||||
}
|
||||
|
||||
bool
|
||||
mjit::Compiler::jsop_setelem(bool popGuaranteed)
|
||||
{
|
||||
@ -1449,7 +1473,7 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
|
||||
|
||||
// If the object is definitely a dense array or a typed array we can generate
|
||||
// code directly without using an inline cache.
|
||||
if (cx->typeInferenceEnabled() && id->mightBeType(JSVAL_TYPE_INT32)) {
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
types::TypeSet *types = analysis->poppedTypes(PC, 2);
|
||||
|
||||
if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY) &&
|
||||
@ -1472,6 +1496,11 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE)) {
|
||||
jsop_setelem_slow();
|
||||
return true;
|
||||
}
|
||||
|
||||
SetElementICInfo ic = SetElementICInfo(JSOp(*PC));
|
||||
|
||||
// One by one, check if the most important stack entries have registers,
|
||||
@ -1631,15 +1660,18 @@ static inline bool
|
||||
IsCacheableGetElem(FrameEntry *obj, FrameEntry *id)
|
||||
{
|
||||
if (id->isTypeKnown() &&
|
||||
!(id->getKnownType() == JSVAL_TYPE_INT32
|
||||
!(id->isType(JSVAL_TYPE_INT32) || id->isType(JSVAL_TYPE_DOUBLE)
|
||||
#if defined JS_POLYIC
|
||||
|| id->getKnownType() == JSVAL_TYPE_STRING
|
||||
|| id->isType(JSVAL_TYPE_STRING)
|
||||
#endif
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id->isTypeKnown() && id->getKnownType() == JSVAL_TYPE_INT32 && id->isConstant() &&
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE) && id->isConstant())
|
||||
return false;
|
||||
|
||||
if (id->isType(JSVAL_TYPE_INT32) && id->isConstant() &&
|
||||
id->getValue().toInt32() < 0) {
|
||||
return false;
|
||||
}
|
||||
@ -1664,6 +1696,9 @@ mjit::Compiler::jsop_getelem_dense(bool isPacked)
|
||||
stubcc.linkExit(guard, Uses(2));
|
||||
}
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE))
|
||||
tryConvertInteger(id, Uses(2));
|
||||
|
||||
// Test for integer index.
|
||||
if (!id->isTypeKnown()) {
|
||||
Jump guard = frame.testInt32(Assembler::NotEqual, id);
|
||||
@ -1780,6 +1815,9 @@ mjit::Compiler::jsop_getelem_args()
|
||||
{
|
||||
FrameEntry *id = frame.peek(-1);
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE))
|
||||
tryConvertInteger(id, Uses(2));
|
||||
|
||||
// Test for integer index.
|
||||
if (!id->isTypeKnown()) {
|
||||
Jump guard = frame.testInt32(Assembler::NotEqual, id);
|
||||
@ -1887,6 +1925,9 @@ mjit::Compiler::jsop_getelem_typed(int atype)
|
||||
stubcc.linkExit(guard, Uses(2));
|
||||
}
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE))
|
||||
tryConvertInteger(id, Uses(2));
|
||||
|
||||
// Test for integer index.
|
||||
if (!id->isTypeKnown()) {
|
||||
Jump guard = frame.testInt32(Assembler::NotEqual, id);
|
||||
@ -2007,7 +2048,7 @@ mjit::Compiler::jsop_getelem(bool isCall)
|
||||
|
||||
// If the object is definitely an arguments object, a dense array or a typed array
|
||||
// we can generate code directly without using an inline cache.
|
||||
if (cx->typeInferenceEnabled() && id->mightBeType(JSVAL_TYPE_INT32) && !isCall) {
|
||||
if (cx->typeInferenceEnabled() && !id->isType(JSVAL_TYPE_STRING) && !isCall) {
|
||||
types::TypeSet *types = analysis->poppedTypes(PC, 1);
|
||||
if (types->isLazyArguments(cx) && !outerScript->analysis()->modifiesArguments()) {
|
||||
// Inline arguments path.
|
||||
@ -2040,6 +2081,14 @@ mjit::Compiler::jsop_getelem(bool isCall)
|
||||
|
||||
frame.forgetMismatchedObject(obj);
|
||||
|
||||
if (id->isType(JSVAL_TYPE_DOUBLE)) {
|
||||
if (isCall)
|
||||
jsop_callelem_slow();
|
||||
else
|
||||
jsop_getelem_slow();
|
||||
return true;
|
||||
}
|
||||
|
||||
GetElementICInfo ic = GetElementICInfo(JSOp(*PC));
|
||||
|
||||
// Pin the top of the stack to avoid spills, before allocating registers.
|
||||
|
Loading…
Reference in New Issue
Block a user