diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2011-12-12 13:41:25 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-14 09:55:28 +0100 |
commit | f12d2a28d799e95661a50ee70d4c9059377fbfc1 (patch) | |
tree | 28df7d91080a203b0fa6b9d433a8c2850480bcc7 /src/declarative/qml/v8/qv8engine.cpp | |
parent | 17bffaa4d447959f08e16ca9a45885f631a16cc0 (diff) |
Fix leak of v8 context used for implicit strong references.
QV8GCCallback::Referencer keeps strong implicit references for QObjects
owned by C++ (or objects with a CPP owned root parent). The implicit v8
object to express the implicit reference belongs to a dedicated v8 context,
which needs to be disposed properly.
Change-Id: Ic0555cb8d94384a185ebcee9825988d84e74f26b
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Reviewed-by: Chris Adams <christopher.adams@nokia.com>
Diffstat (limited to 'src/declarative/qml/v8/qv8engine.cpp')
-rw-r--r-- | src/declarative/qml/v8/qv8engine.cpp | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index 632a8ea302..5207931776 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -1451,14 +1451,6 @@ void QV8GCCallback::registerGcPrologueCallback() } } -void QV8GCCallback::ThreadData::releaseStrongReferencer() -{ - // NOTE: must be called with a valid current isolate - if (!referencer.strongReferencer.IsEmpty()) { - qPersistentDispose(referencer.strongReferencer); - } -} - void QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData() { // Note that only worker-thread implementations with their @@ -1467,7 +1459,7 @@ void QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData() Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData()", "called after v8::Isolate has exited"); if (threadData.hasLocalData()) { QV8GCCallback::ThreadData *td = threadData.localData(); - td->releaseStrongReferencer(); + td->referencer.dispose(); } } @@ -1483,18 +1475,14 @@ QV8GCCallback::Node::~Node() QV8GCCallback::Referencer::~Referencer() { - if (!strongReferencer.IsEmpty()) { - Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::Referencer::~Referencer()", "called after v8::Isolate has exited"); - // automatically release the strongReferencer if it hasn't - // been explicitly released already. - qPersistentDispose(strongReferencer); - } + dispose(); } QV8GCCallback::Referencer::Referencer() { v8::HandleScope handleScope; - v8::Handle<v8::Context> context = v8::Context::New(); + context = v8::Context::New(); + qPersistentRegister(context); v8::Context::Scope contextScope(context); strongReferencer = qPersistentNew(v8::Object::New()); } @@ -1511,6 +1499,18 @@ void QV8GCCallback::Referencer::addRelationship(QObject *object, QObject *other) } } +void QV8GCCallback::Referencer::dispose() +{ + if (!strongReferencer.IsEmpty()) { + Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::Referencer::~Referencer()", "called after v8::Isolate has exited"); + // automatically release the strongReferencer if it hasn't + // been explicitly released already. + qPersistentDispose(strongReferencer); + } + if (!context.IsEmpty()) + qPersistentDispose(context); +} + void QV8GCCallback::Referencer::addRelationship(QObject *object, v8::Persistent<v8::Value> handle) { if (handle.IsEmpty()) |