From 4425d6f9b637e7404379b611cef4b22929acbe62 Mon Sep 17 00:00:00 2001 From: Olivier JG Date: Fri, 16 Dec 2016 09:57:37 -0600 Subject: QML: emit messages when breaking bindings Add a new logging category that can be used to debug issues with unexpected binding breakages caused by assignment to previously bound properties. If enabled, outputs a message when a binding is broken with detailed location and property/value information. [ChangeLog][QtQml] The QML engine can now emit informational messages (in the "qt.qml.binding.removal" logging category) whenever a binding is lost due to an imperative assignment. This can be used to debug issues due to broken bindings. Change-Id: Ie31e5a198450b6f998c1266acfc97e8f33a92e3d Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4qobjectwrapper.cpp') diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index e4fb54f0ff..83730d632a 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -75,10 +75,13 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcBindingRemoval, "qt.qml.binding.removal", QtWarningMsg) + // The code in this file does not violate strict aliasing, but GCC thinks it does // so turn off the warnings for us to have a clean build QT_WARNING_DISABLE_GCC("-Wstrict-aliasing") @@ -458,10 +461,23 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP } } - if (newBinding) + if (newBinding) { QQmlPropertyPrivate::setBinding(newBinding); - else + } else { + if (Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) { + if (auto binding = QQmlPropertyPrivate::binding(object, QQmlPropertyIndex(property->coreIndex()))) { + Q_ASSERT(!binding->isValueTypeProxy()); + const auto qmlBinding = static_cast(binding); + const auto stackFrame = engine->currentStackFrame(); + qCInfo(lcBindingRemoval, + "Overwriting binding on %s::%s at %s:%d that was initially bound at %s", + object->metaObject()->className(), qPrintable(property->name(object)), + qPrintable(stackFrame.source), stackFrame.line, + qPrintable(qmlBinding->expressionIdentifier())); + } + } QQmlPropertyPrivate::removeBinding(object, QQmlPropertyIndex(property->coreIndex())); + } if (!newBinding && property->isVarProperty()) { // allow assignment of "special" values (null, undefined, function) to var properties -- cgit v1.2.3 From cae7975a036352ca4bbcf1381a445362f8e01367 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 12 May 2017 15:12:45 +0200 Subject: Move the internalClass field from Heap::Object to Heap::Base And do not store the vtable in Heap::Base anymore. This change makes the internal class the main distinguishing feature of all garbage collected objects. It also saves one pointer on all Objects. No measurable impact on runtime performance. Change-Id: I040a28b7581b993f1886b5219e279173dfa567e8 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/qml/jsruntime/qv4qobjectwrapper.cpp') diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 67b1356e65..f484d56040 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -997,7 +997,6 @@ void QObjectWrapper::destroyObject(bool lastCall) } } - h->internalClass = 0; h->~Data(); } -- cgit v1.2.3 From 8bc243f569e3feb1005fbca426bf24f59c38af2e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 19 May 2017 15:50:22 +0200 Subject: Move the engine() accessor from Object to Managed We can easily do this now that Managed has a pointer to an internal class (which always has a back pointer to the ExecutionEngine). Remove the extra engine pointer from ExecutionContext, and clean up tow methods in String. Change-Id: I98d750b1afbdeadf42e66ae0c92c48db1a7adc31 Reviewed-by: Robin Burchell --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime/qv4qobjectwrapper.cpp') diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index f484d56040..d7978cc212 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1688,7 +1688,7 @@ QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine) ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, int index) { Scope valueScope(scope); - Scoped method(valueScope, scope->d()->engine->memoryManager->allocObject(scope)); + Scoped method(valueScope, valueScope.engine->memoryManager->allocObject(scope)); method->d()->setObject(object); if (QQmlData *ddata = QQmlData::get(object)) @@ -1739,7 +1739,7 @@ QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) co result = QLatin1String("null"); } - return ctx->d()->engine->newString(result)->asReturnedValue(); + return ctx->engine()->newString(result)->asReturnedValue(); } QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const -- cgit v1.2.3