diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-08-05 22:48:35 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-07 14:20:52 +0200 |
commit | e8e7fff1f50d3517acaee8242180a89600334da3 (patch) | |
tree | eb310f6dbebb227a9a11d52fdfd4b27ed1e7a920 /src | |
parent | 9f91904bc9306af7c67fada20fb4f9cb0f1940b0 (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.cpp | 18 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4runtime.cpp | 17 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4runtime_p.h | 81 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4value_def_p.h | 3 |
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, |