diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-05 12:43:18 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-06 22:41:48 +0100 |
commit | 68b9ab7b93320a975c2f20c09eddccf0fdb275b7 (patch) | |
tree | a5fbfac67de97a30c2c024c1c98948fcc77596df /tests/auto/qml/qv4mm | |
parent | e5b14cd18e84b5c9f2a85d82c2af8ffba376988e (diff) |
V4: Prevent heap objects from getting immediately swept by GC
A destruction handler can cause a new object to be allocated during
garbage collection. Depending on where in the heap the object ends up,
it may be found during the sweep pass. As the mark pass had no chance to
mark the object, we need to set the mark bit right at allocation time in
this case.
Change-Id: Ie43eeb548e78bd375b001b3a6bb4ef6596f91980
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml/qv4mm')
-rw-r--r-- | tests/auto/qml/qv4mm/data/createobjects.qml | 81 | ||||
-rw-r--r-- | tests/auto/qml/qv4mm/tst_qv4mm.cpp | 12 |
2 files changed, 93 insertions, 0 deletions
diff --git a/tests/auto/qml/qv4mm/data/createobjects.qml b/tests/auto/qml/qv4mm/data/createobjects.qml new file mode 100644 index 0000000000..5196855eca --- /dev/null +++ b/tests/auto/qml/qv4mm/data/createobjects.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml 2.2 + +QtObject { + property var objects: [] + property int numChecked: 0 + property var c: null + property bool ok: false + + function container() { + var objs + + return { + "check": function() { + for (var i = 0; i < 1000; ++i) { + if (objs[i][0] !== 1 || objs[i][1] !== 2 || objs[i][2] !== 3) + return false; + } + return true; + }, + + "generate": function() { + objs = []; + for (var i = 0; i < 1000; ++i) + objs[i] = [1, 2, 3] + } + } + } + + property Component itemComponent: Component { + QtObject {} + } + + property Component triggerComponent: Component { + QtObject { + Component.onDestruction: { + for (var i = 0; i < 1000; ++i) + objects[i] = itemComponent.createObject(); + c = container(); + c.generate(); + } + } + } + + Component.onCompleted: { + triggerComponent.createObject(); + gc(); + for (var i = 0; i < 1000; ++i) { + if (objects[i] !== undefined) + ++numChecked; + } + ok = c.check(); + } +} diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp index 5d635aa63b..b6a5753e56 100644 --- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp +++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp @@ -48,6 +48,7 @@ private slots: void multiWrappedQObjects(); void accessParentOnDestruction(); void clearICParent(); + void createObjectsOnDestruction(); }; void tst_qv4mm::gcStats() @@ -148,6 +149,17 @@ void tst_qv4mm::clearICParent() QFAIL("Garbage collector was not triggered by large amount of InternalClasses"); } +void tst_qv4mm::createObjectsOnDestruction() +{ + QLoggingCategory::setFilterRules("qt.qml.gc.*=false"); + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("createobjects.qml")); + std::unique_ptr<QObject> obj(component.create()); + QVERIFY(obj); + QCOMPARE(obj->property("numChecked").toInt(), 1000); + QCOMPARE(obj->property("ok").toBool(), true); +} + QTEST_MAIN(tst_qv4mm) #include "tst_qv4mm.moc" |