diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-02-08 16:43:08 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-02-09 14:46:07 +0000 |
commit | d4ff2907162e20e2288357c428b0df88f7396f92 (patch) | |
tree | 4074cbba244a8f6a572d524f0f23d0347a48d136 /src/qml/jsruntime | |
parent | 94afe0db3223dda9d26ddfbea04048695dcd5134 (diff) |
Fix memory leak with JS imports
Strictly speaking this is a regression introduced with commit
e22b624d9ab1f36021adb9cdbfa9b37054282bb8, making the QQmlContextData
objects reference counted, especially from the V4 QML context wrapper
objects.
That change (correct as it is) introduced an accidental circular
dependency in the simple scenario of importing a .js file in a .qml
file:
Each time the type in the .qml file is instantiated, we create a
dedicated QQmlContextData for the .js file. If the .js file has no
imports itself, that new context will get the same ctx->importedScripts
JS array as the QML context of the .qml file. That is a strong reference
via QV4::PersistentValue. That array in turn contains the
QV4::QmlContextWrapper that belongs to the imported script, which in
turn holds a strong reference (via refcount) to the script's context.
This patch breaks the circular reference when we perform context
invalidation, as the least intrusive measure.
For the auto-test to work, we must also clear the qmlContext persistent
of the QV4::Script that's used to evaluate the .js file. In subsequent
imports that persistent will be initialized to new values, so it will
only hold a strong reference to the last import, but strictly speaking
that is still a leak - hence also part of this fix.
Change-Id: I3e543c946e5e683425072dc3df7e49ca0e0c0215
Task-number: QTBUG-66189
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext.cpp | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index d97d44379d..c7254e5989 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -138,7 +138,9 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr *hasProperty = true; if (r.scriptIndex != -1) { QV4::ScopedObject scripts(scope, context->importedScripts.valueRef()); - return scripts->getIndexed(r.scriptIndex); + if (scripts) + return scripts->getIndexed(r.scriptIndex); + return QV4::Encode::null(); } else if (r.type.isValid()) { return QmlTypeWrapper::create(v4, scopeObject, r.type); } else if (r.importNamespace) { |