aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-08-05 22:48:35 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-07 14:20:52 +0200
commite8e7fff1f50d3517acaee8242180a89600334da3 (patch)
treeeb310f6dbebb227a9a11d52fdfd4b27ed1e7a920 /src
parent9f91904bc9306af7c67fada20fb4f9cb0f1940b0 (diff)
Speed up JS comparison operations
Remove the not used context parameter where possible, and simplify the NaN != NaN case. Change-Id: I05e9639f7bac4bb1db2f33d70f063c71561ffd34 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/v4/qv4isel_masm.cpp18
-rw-r--r--src/qml/qml/v4/qv4runtime.cpp17
-rw-r--r--src/qml/qml/v4/qv4runtime_p.h81
-rw-r--r--src/qml/qml/v4/qv4value_def_p.h3
4 files changed, 64 insertions, 55 deletions
diff --git a/src/qml/qml/v4/qv4isel_masm.cpp b/src/qml/qml/v4/qv4isel_masm.cpp
index af77a7cb17..23688dbb82 100644
--- a/src/qml/qml/v4/qv4isel_masm.cpp
+++ b/src/qml/qml/v4/qv4isel_masm.cpp
@@ -1082,6 +1082,8 @@ void InstructionSelection::copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetT
#define setOp(op, opName, operation) \
do { op = operation; opName = isel_stringIfy(operation); } while (0)
+#define setOpContext(op, opName, operation) \
+ do { opContext = operation; opName = isel_stringIfy(operation); } while (0)
void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp)
{
@@ -1309,6 +1311,7 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
} else if (V4IR::Binop *b = s->cond->asBinop()) {
if (b->left->asTemp() && b->right->asTemp()) {
CmpOp op = 0;
+ CmpOpContext opContext = 0;
const char *opName = 0;
switch (b->op) {
default: Q_UNREACHABLE(); assert(!"todo"); break;
@@ -1320,13 +1323,18 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
case V4IR::OpNotEqual: setOp(op, opName, __qmljs_cmp_ne); break;
case V4IR::OpStrictEqual: setOp(op, opName, __qmljs_cmp_se); break;
case V4IR::OpStrictNotEqual: setOp(op, opName, __qmljs_cmp_sne); break;
- case V4IR::OpInstanceof: setOp(op, opName, __qmljs_cmp_instanceof); break;
- case V4IR::OpIn: setOp(op, opName, __qmljs_cmp_in); break;
+ case V4IR::OpInstanceof: setOpContext(op, opName, __qmljs_cmp_instanceof); break;
+ case V4IR::OpIn: setOpContext(op, opName, __qmljs_cmp_in); break;
} // switch
- _as->generateFunctionCallImp(Assembler::ReturnValueRegister, opName, op, Assembler::ContextRegister,
- Assembler::Reference(b->left->asTemp()),
- Assembler::Reference(b->right->asTemp()));
+ if (opContext)
+ _as->generateFunctionCallImp(Assembler::ReturnValueRegister, opName, opContext, Assembler::ContextRegister,
+ Assembler::Reference(b->left->asTemp()),
+ Assembler::Reference(b->right->asTemp()));
+ else
+ _as->generateFunctionCallImp(Assembler::ReturnValueRegister, opName, op,
+ Assembler::Reference(b->left->asTemp()),
+ Assembler::Reference(b->right->asTemp()));
Assembler::Jump target = _as->branch32(Assembler::NotEqual, Assembler::ReturnValueRegister, Assembler::TrustedImm32(0));
_as->addPatch(s->iftrue, target);
diff --git a/src/qml/qml/v4/qv4runtime.cpp b/src/qml/qml/v4/qv4runtime.cpp
index deccb3d4ea..d974ad5296 100644
--- a/src/qml/qml/v4/qv4runtime.cpp
+++ b/src/qml/qml/v4/qv4runtime.cpp
@@ -740,15 +740,14 @@ Bool __qmljs_strict_equal(const Value &x, const Value &y)
{
TRACE2(x, y);
- if (x.rawValue() == y.rawValue()) {
- if (x.isDouble())
- return !std::isnan(x.doubleValue());
- return true;
- }
- if (x.isNumber() && y.isNumber())
- return x.asDouble() == y.asDouble();
- if (x.isString() && y.isString())
- return x.stringValue()->isEqualTo(y.stringValue());
+ if (x.rawValue() == y.rawValue())
+ // NaN != NaN
+ return (x.tag & QV4::Value::NotDouble_Mask) != QV4::Value::NaN_Mask;
+
+ if (x.isNumber())
+ return y.isNumber() && x.asDouble() == y.asDouble();
+ if (x.isString())
+ return y.isString() && x.stringValue()->isEqualTo(y.stringValue());
return false;
}
diff --git a/src/qml/qml/v4/qv4runtime_p.h b/src/qml/qml/v4/qv4runtime_p.h
index e6e6e0f3a0..fb346029f0 100644
--- a/src/qml/qml/v4/qv4runtime_p.h
+++ b/src/qml/qml/v4/qv4runtime_p.h
@@ -202,12 +202,12 @@ void __qmljs_mod(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &
void __qmljs_shl(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
void __qmljs_shr(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
void __qmljs_ushr(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
-void __qmljs_gt(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
-void __qmljs_lt(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
-void __qmljs_ge(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
-void __qmljs_le(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
-void __qmljs_eq(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
-void __qmljs_ne(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
+void __qmljs_gt(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
+void __qmljs_lt(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
+void __qmljs_ge(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
+void __qmljs_le(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
+void __qmljs_eq(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
+void __qmljs_ne(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
void __qmljs_se(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
void __qmljs_sne(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right);
@@ -253,15 +253,17 @@ void __qmljs_inplace_shl_member(QV4::ExecutionContext *ctx, const QV4::Value &ba
void __qmljs_inplace_shr_member(QV4::ExecutionContext *ctx, const QV4::Value &base, QV4::String *name, const QV4::Value &rhs);
void __qmljs_inplace_ushr_member(QV4::ExecutionContext *ctx, const QV4::Value &base, QV4::String *name, const QV4::Value &rhs);
-typedef QV4::Bool (*CmpOp)(QV4::ExecutionContext *ctx, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_gt(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_lt(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_ge(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_le(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_eq(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_ne(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_se(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
-QV4::Bool __qmljs_cmp_sne(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right);
+typedef QV4::Bool (*CmpOp)(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_gt(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_lt(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_ge(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_le(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_eq(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_ne(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_se(const QV4::Value &left, const QV4::Value &right);
+QV4::Bool __qmljs_cmp_sne(const QV4::Value &left, const QV4::Value &right);
+
+typedef QV4::Bool (*CmpOpContext)(QV4::ExecutionContext *ctx, const QV4::Value &left, const QV4::Value &right);
QV4::Bool __qmljs_cmp_instanceof(QV4::ExecutionContext *ctx, const QV4::Value &left, const QV4::Value &right);
QV4::Bool __qmljs_cmp_in(QV4::ExecutionContext *ctx, const QV4::Value &left, const QV4::Value &right);
@@ -518,46 +520,46 @@ inline void __qmljs_ushr(QV4::ExecutionContext *, QV4::Value *result, const QV4:
*result = QV4::Value::fromInt32(res);
}
-inline void __qmljs_gt(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
+inline void __qmljs_gt(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_gt(ctx, left, right));
+ *result = QV4::Value::fromBoolean(__qmljs_cmp_gt(left, right));
}
-inline void __qmljs_lt(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
+inline void __qmljs_lt(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_lt(ctx, left, right));
+ *result = QV4::Value::fromBoolean(__qmljs_cmp_lt(left, right));
}
-inline void __qmljs_ge(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
+inline void __qmljs_ge(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_ge(ctx, left, right));
+ *result = QV4::Value::fromBoolean(__qmljs_cmp_ge(left, right));
}
-inline void __qmljs_le(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
+inline void __qmljs_le(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_le(ctx, left, right));
+ *result = QV4::Value::fromBoolean(__qmljs_cmp_le(left, right));
}
-inline void __qmljs_eq(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
+inline void __qmljs_eq(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_eq(ctx, left, right));
+ *result = QV4::Value::fromBoolean(__qmljs_cmp_eq(left, right));
}
-inline void __qmljs_ne(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
+inline void __qmljs_ne(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(!__qmljs_cmp_eq(ctx, left, right));
+ *result = QV4::Value::fromBoolean(!__qmljs_cmp_eq(left, right));
}
inline void __qmljs_se(QV4::ExecutionContext *, QV4::Value *result, const QV4::Value &left, const QV4::Value &right)
@@ -576,7 +578,7 @@ inline void __qmljs_sne(QV4::ExecutionContext *, QV4::Value *result, const QV4::
*result = QV4::Value::fromBoolean(r);
}
-inline QV4::Bool __qmljs_cmp_gt(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_gt(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
if (QV4::Value::integerCompatible(left, right))
@@ -596,7 +598,7 @@ inline QV4::Bool __qmljs_cmp_gt(QV4::ExecutionContext *, const QV4::Value &left,
}
}
-inline QV4::Bool __qmljs_cmp_lt(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_lt(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
if (QV4::Value::integerCompatible(left, right))
@@ -616,7 +618,7 @@ inline QV4::Bool __qmljs_cmp_lt(QV4::ExecutionContext *, const QV4::Value &left,
}
}
-inline QV4::Bool __qmljs_cmp_ge(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_ge(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
if (QV4::Value::integerCompatible(left, right))
@@ -636,7 +638,7 @@ inline QV4::Bool __qmljs_cmp_ge(QV4::ExecutionContext *, const QV4::Value &left,
}
}
-inline QV4::Bool __qmljs_cmp_le(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_le(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
if (QV4::Value::integerCompatible(left, right))
@@ -656,36 +658,35 @@ inline QV4::Bool __qmljs_cmp_le(QV4::ExecutionContext *, const QV4::Value &left,
}
}
-inline QV4::Bool __qmljs_cmp_eq(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_eq(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- // need to test for doubles first as NaN != NaN
- if (QV4::Value::bothDouble(left, right))
- return left.doubleValue() == right.doubleValue();
if (left.val == right.val)
- return true;
+ // NaN != NaN
+ return (left.tag & QV4::Value::NotDouble_Mask) != QV4::Value::NaN_Mask;
+
if (left.isString() && right.isString())
return left.stringValue()->isEqualTo(right.stringValue());
return __qmljs_equal(left, right);
}
-inline QV4::Bool __qmljs_cmp_ne(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_ne(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
- return !__qmljs_cmp_eq(0, left, right);
+ return !__qmljs_cmp_eq(left, right);
}
-inline QV4::Bool __qmljs_cmp_se(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_se(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
return __qmljs_strict_equal(left, right);
}
-inline QV4::Bool __qmljs_cmp_sne(QV4::ExecutionContext *, const QV4::Value &left, const QV4::Value &right)
+inline QV4::Bool __qmljs_cmp_sne(const QV4::Value &left, const QV4::Value &right)
{
TRACE2(left, right);
diff --git a/src/qml/qml/v4/qv4value_def_p.h b/src/qml/qml/v4/qv4value_def_p.h
index 2e3a9c0425..89f6647e22 100644
--- a/src/qml/qml/v4/qv4value_def_p.h
+++ b/src/qml/qml/v4/qv4value_def_p.h
@@ -75,7 +75,8 @@ struct Q_QML_EXPORT Value
};
enum Masks {
- NotDouble_Mask = 0xfffc0000,
+ NaN_Mask = 0x7ff80000,
+ NotDouble_Mask = 0x7ffc0000,
Type_Mask = 0xffff8000,
Immediate_Mask = NotDouble_Mask | 0x00008000,
Special_Mask = Immediate_Mask | 0x20000,