diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-11-20 11:03:46 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-11-22 08:51:59 +0000 |
commit | 9926a4a49e8211a996667b467fd98b915e9f9d34 (patch) | |
tree | d514b131de6da988bc39c40753d2298b0cdccb09 /tests/auto/qml/qv4mm | |
parent | 33c13efd91954fb50019e82f3ab8e8e1d8458332 (diff) |
V4: Avoid copying WeakValues with wrapped QObjects
Such WeakValues are kept alive until the respective QObject is deleted.
Therefore they are quite expensive. In this case we don't actually need
a copy as on retrieval we only want a ReturnValue and on inserting we
just want to replace the value in the map.
Fixes: QTBUG-71817
Change-Id: I385c55140337d468289046243941077ba1ff61a3
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'tests/auto/qml/qv4mm')
-rw-r--r-- | tests/auto/qml/qv4mm/tst_qv4mm.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp index 07f8e9f1d1..d8f4ed12e8 100644 --- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp +++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp @@ -30,6 +30,7 @@ #include <QQmlEngine> #include <QLoggingCategory> #include <private/qv4mm_p.h> +#include <private/qv4qobjectwrapper_p.h> class tst_qv4mm : public QObject { @@ -37,6 +38,7 @@ class tst_qv4mm : public QObject private slots: void gcStats(); + void multiWrappedQObjects(); }; void tst_qv4mm::gcStats() @@ -46,6 +48,44 @@ void tst_qv4mm::gcStats() engine.collectGarbage(); } +void tst_qv4mm::multiWrappedQObjects() +{ + QV4::ExecutionEngine engine1; + QV4::ExecutionEngine engine2; + { + QObject object; + for (int i = 0; i < 10; ++i) + QV4::QObjectWrapper::wrap(i % 2 ? &engine1 : &engine2, &object); + + QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); + QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); + { + QV4::WeakValue value; + value.set(&engine1, QV4::QObjectWrapper::wrap(&engine1, &object)); + } + + QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1); + QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); + + // Moves the additional WeakValue from m_multiplyWrappedQObjects to + // m_pendingFreedObjectWrapperValue. It's still alive after all. + engine1.memoryManager->runGC(); + QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2); + + // engine2 doesn't own the object as engine1 was the first to wrap it above. + // Therefore, no effect here. + engine2.memoryManager->runGC(); + QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); + } + + // Clears m_pendingFreedObjectWrapperValue. Now it's really dead. + engine1.memoryManager->runGC(); + QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); + + engine2.memoryManager->runGC(); + QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); +} + QTEST_MAIN(tst_qv4mm) #include "tst_qv4mm.moc" |