aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-03-27 10:27:56 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-03-27 10:27:56 +0100
commit187b2e0efccb9e803a72fc87a3659d8b76a73ca9 (patch)
treee6db37dc0839e50826935362d39979e6cdaa80cc /tests/auto/qml
parent82247946b2733bcd5bb3740a31c7d38fb90f6ddd (diff)
parentd8110b53ed9ee4d69b92e602e812c6311c1b863b (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'tests/auto/qml')
-rw-r--r--tests/auto/qml/qv4mm/tst_qv4mm.cpp54
1 files changed, 34 insertions, 20 deletions
diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
index b57b716ed6..1e34b79954 100644
--- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
@@ -112,26 +112,40 @@ void tst_qv4mm::accessParentOnDestruction()
void tst_qv4mm::clearICParent()
{
- QJSEngine engine;
- QJSValue value = engine.evaluate(
- "(function() {\n"
- " var test = Object.create(null);\n"
- " for (var i = 0; i < 100; i++)\n"
- " test[(\"key_\"+i)] = true;\n"
- " for (var i = 0; i < 100; i++)\n"
- " delete test[\"key_\" + i];\n"
- " return test;\n"
- "})();"
- );
- engine.collectGarbage();
- QV4::Value *v4Value = QJSValuePrivate::getValue(&value);
- QVERIFY(v4Value);
- QV4::Heap::Object *v4Object = v4Value->toObject(engine.handle());
- QVERIFY(v4Object);
-
- // It should garbage collect the parents of the internalClass,
- // as those aren't used anywhere else.
- QCOMPARE(v4Object->internalClass->parent, nullptr);
+ QV4::ExecutionEngine engine;
+ QV4::Scope scope(engine.rootContext());
+ QV4::ScopedObject object(scope, engine.newObject());
+
+ // Keep identifiers in a separate array so that we don't have to allocate them in the loop that
+ // should test the GC on InternalClass allocations.
+ QV4::ScopedArrayObject identifiers(scope, engine.newArrayObject());
+ for (uint i = 0; i < 16 * 1024; ++i) {
+ QV4::Scope scope(&engine);
+ QV4::ScopedString s(scope);
+ s = engine.newIdentifier(QString::fromLatin1("key%1").arg(i));
+ identifiers->push_back(s);
+
+ QV4::ScopedValue v(scope);
+ v->setDouble(i);
+ object->insertMember(s, v);
+ }
+
+ // When allocating the InternalClass objects required for deleting properties, the GC should
+ // eventually run and remove all but the last two.
+ // If we ever manage to avoid allocating the InternalClasses in the first place we will need
+ // to change this test.
+ for (uint i = 0; i < 16 * 1024; ++i) {
+ QV4::Scope scope(&engine);
+ QV4::ScopedString s(scope, identifiers->getIndexed(i));
+ QV4::Scoped<QV4::InternalClass> ic(scope, object->internalClass());
+ QVERIFY(ic->d()->parent != nullptr);
+ object->deleteProperty(s->toPropertyKey());
+ QVERIFY(object->internalClass() != ic->d());
+ QCOMPARE(object->internalClass()->parent, ic->d());
+ if (ic->d()->parent == nullptr)
+ return;
+ }
+ QFAIL("Garbage collector was not triggered by large amount of InternalClasses");
}
QTEST_MAIN(tst_qv4mm)