From 7cb6dce1f3e140ea68d6b05281950f212fc99d38 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 14 May 2018 15:21:10 +0200 Subject: Remove bindings that have no dependencies After the initial enabling of a binding we can quickly determine if there is a chance whether this binding will be re-evaluated again in the future as a consequence of dependency changes (properties or translations). If that is not the case, then we can save memory by removing that binding again. One implementation consequence of this change is that such constant bindings used with the "when" property of states require a proper reference count increase, which was previously implicit through the binding association with the target object. In tst_qqmlecmascript a test that verifies that we don't create run-time bindings for assignments of literal "null" to QObject pointer properties now also covers the more complex case where we don't know the property at parse time. We still evaluate the binding once though and perform one property assignment. Similarly on the QtQuick Designer Support API test side a binding such as x: Math.max(0, 200) will not create a persistent binding anymore and needs a tweak to remain. On a large scale application this optimization saved up to 5% of all bindings on start-up (~9000 of ~180000). On Linux x86-64 one binding is approximately 144 bytes, so the savings are in the range of ~1.2 MB of heap, as well as reduced fragmentation. Task-number: QTBUG-64541 Change-Id: Id3653008346fdf36611f5b4c4e82f5f78b5319aa Reviewed-by: Lars Knoll --- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/qml/qml/v8/qqmlbuiltinfunctions.cpp') diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 571f0af9d4..4ae78645ea 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1853,6 +1853,10 @@ ReturnedValue GlobalExtensions::method_qsTranslate(const FunctionObject *b, cons if (argc > i) n = argv[i].toInt32(); + if (QQmlEnginePrivate *ep = (scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) : nullptr)) + if (ep->propertyCapture) + ep->propertyCapture->captureTranslation(); + QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(), comment.toUtf8().constData(), @@ -1956,6 +1960,10 @@ ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value if (argc > 2) n = argv[2].toInt32(); + if (QQmlEnginePrivate *ep = (scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) : nullptr)) + if (ep->propertyCapture) + ep->propertyCapture->captureTranslation(); + QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(), comment.toUtf8().constData(), n); @@ -2036,6 +2044,10 @@ ReturnedValue GlobalExtensions::method_qsTrId(const FunctionObject *b, const Val if (argc > 1) n = argv[1].toInt32(); + if (QQmlEnginePrivate *ep = (scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) : nullptr)) + if (ep->propertyCapture) + ep->propertyCapture->captureTranslation(); + return Encode(scope.engine->newString(qtTrId(argv[0].toQStringNoThrow().toUtf8().constData(), n))); } -- cgit v1.2.3