diff options
author | Jędrzej Nowacki <jedrzej.nowacki@nokia.com> | 2012-04-19 14:38:38 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-27 10:38:58 +0200 |
commit | b765e3a84bc531878a5cc0d451451a94565b13f8 (patch) | |
tree | 4c506d229c76924a2c72de31464efa8b440f005f /src/qml/qml/v8/qv8qobjectwrapper_p.h | |
parent | 7ec674ee9a8e51cb1cb7ef60b1d27845349b8dec (diff) |
Avoid calling gc in QQmlEngine destructor.
GC may be expensive. GC call in QQmlEngine doesn't have much sense
because V8 will destroy all objects living in a current context.
The only problem is that V8 may decide to not invoke weak callbacks
which may cause a memory leak. To avoid that we track all QObjects that
have JavaScript ownership set and we delete them explicitly.
The change reduce time of destroying QQmlEngine by 75%, which is really
visible in qquicklistmodel test.
Change-Id: I2a3668fd23630669114baee8c241a7ecc4100e33
Reviewed-by: Chris Adams <christopher.adams@nokia.com>
Diffstat (limited to 'src/qml/qml/v8/qv8qobjectwrapper_p.h')
-rw-r--r-- | src/qml/qml/v8/qv8qobjectwrapper_p.h | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/qml/qml/v8/qv8qobjectwrapper_p.h b/src/qml/qml/v8/qv8qobjectwrapper_p.h index f7b965690b..ab037eee14 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper_p.h +++ b/src/qml/qml/v8/qv8qobjectwrapper_p.h @@ -61,6 +61,8 @@ #include <private/qhashedstring_p.h> #include <private/qqmldata_p.h> #include <private/qqmlpropertycache_p.h> +#include <private/qintrusivelist_p.h> +#include "qv8objectresource_p.h" QT_BEGIN_NAMESPACE @@ -71,6 +73,18 @@ class QV8ObjectResource; class QV8QObjectInstance; class QV8QObjectConnectionList; class QQmlPropertyCache; + +class QV8QObjectResource : public QV8ObjectResource +{ + V8_RESOURCE_TYPE(QObjectType); + +public: + QV8QObjectResource(QV8Engine *engine, QObject *object); + + QQmlGuard<QObject> object; + QIntrusiveListNode weakResource; +}; + class Q_QML_EXPORT QV8QObjectWrapper { public: @@ -89,12 +103,23 @@ public: inline v8::Handle<v8::Value> getProperty(QObject *, const QHashedV8String &, RevisionMode); inline bool setProperty(QObject *, const QHashedV8String &, v8::Handle<v8::Value>, RevisionMode); + void registerWeakQObjectReference(QV8QObjectResource *resource) + { + m_javaScriptOwnedWeakQObjects.insert(resource); + } + + void unregisterWeakQObjectReference(QV8QObjectResource *resource) + { + m_javaScriptOwnedWeakQObjects.remove(resource); + } + private: friend class QQmlPropertyCache; friend class QV8QObjectConnectionList; friend class QV8QObjectInstance; v8::Local<v8::Object> newQObject(QObject *, QQmlData *, QV8Engine *); + void deleteWeakQObject(QV8QObjectResource *resource); static v8::Handle<v8::Value> GetProperty(QV8Engine *, QObject *, v8::Handle<v8::Value> *, const QHashedV8String &, QV8QObjectWrapper::RevisionMode); static bool SetProperty(QV8Engine *, QObject *, const QHashedV8String &, @@ -112,6 +137,7 @@ private: static v8::Handle<v8::Value> Invoke(const v8::Arguments &args); static QPair<QObject *, int> ExtractQtMethod(QV8Engine *, v8::Handle<v8::Function>); static QPair<QObject *, int> ExtractQtSignal(QV8Engine *, v8::Handle<v8::Object>); + static void WeakQObjectReferenceCallback(v8::Persistent<v8::Value> handle, void *wrapper); QV8Engine *m_engine; quint32 m_id; @@ -126,6 +152,7 @@ private: QHash<QObject *, QV8QObjectConnectionList *> m_connections; typedef QHash<QObject *, QV8QObjectInstance *> TaintedHash; TaintedHash m_taintedObjects; + QIntrusiveList<QV8QObjectResource, &QV8QObjectResource::weakResource> m_javaScriptOwnedWeakQObjects; }; v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &string, |