Details
-
Task
-
Resolution: Done
-
Not Evaluated
-
None
-
None
Description
In the following example, the on-demand rewrite of onCompleted: obj.destroy(); is showing up as a significant cost.
import QtQuick 2.0 Rectangle { width: 240; height: 320 Component { id: numberComponent QtObject { id: obj property real a: 0 NumberAnimation on a { from: 0; to: 1; duration: 16 onCompleted: obj.destroy(); } } } Timer { interval: 16; running: true; repeat: false onTriggered: { for (var i = 0; i < 400; ++i) numberComponent.createObject(); } } Rectangle { width: 20; height: 20 color: "green" SequentialAnimation on x { loops: Animation.Infinite NumberAnimation { from: 0; to: 220; duration: 2000 } NumberAnimation { from: 220; to: 0; duration: 2000 } } } }
A quick fix for this issue would be to move the rewrite to compile time, as the following patch demonstrates:
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index fb98a8c..9eaefdf 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1227,8 +1227,9 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeScript::Object *obj) Instruction::StoreSignal store; store.signalIndex = prop->index; - store.value = - output->indexForString(v->value.asScript().trimmed()); + //store.value = + // output->indexForString(v->value.asScript().trimmed()); + store.value = rewriteBinding(v->value.asScript().trimmed(), QString()); // XXX store.context = v->signalExpressionContextStack; store.name = output->indexForByteArray(prop->name().toUtf8()); store.line = v->location.start.line; diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 52095e3..ef0f86c 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -861,9 +861,10 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors, QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target); QDeclarativeExpression *expr = - new QDeclarativeExpression(CTXT, context, PRIMITIVES.at(instr.value)); - expr->setSourceLocation(COMP->name, instr.line); - static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = QString::fromUtf8(DATAS.at(instr.name)); + new QDeclarativeExpression(CTXT, context, PRIMITIVES.at(instr.value), true, COMP->name, instr.line, *new QDeclarativeExpressionPrivate); + // new QDeclarativeExpression(CTXT, context, PRIMITIVES.at(instr.value)); + //expr->setSourceLocation(COMP->name, instr.line); + //static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = QString::fromUtf8(DATAS.at(instr.name)); bs->setExpression(expr); QML_END_INSTR(StoreSignal)
A more complete solution would likely involve a custom rewriter for signal handlers that 1) didn't generate return statements (as the return value of a signal handler is not used)*, and 2) addressed the issues of QTBUG-10962.
[*] currently QDeclarativeBoundSignal calls the value() function to evaluate the expression, which also forces a conversion of the ultimately unused return value from v8::Value to QVariant.