aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlengine.cpp
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2023-04-27 14:22:30 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2023-04-28 05:41:06 +0200
commit0a333bc7e5ae9db1d289a65aa7eef46ae7916936 (patch)
treeff16c65ad35dc9f9b183443485d94a7146e5e7c9 /src/qml/qml/qqmlengine.cpp
parent407675b1913a5138c636a730cf3f6a65ffed87fb (diff)
QQmlData: Implement markAsDeleted without recursion
While a normal QML scene should not feature extremely deep object trees, one can still encounter them in some test cases. Those test cases might then run out of (C++) stack space with the previous recursive version of markAsDeleted. Thus, we change the implementation to use an explicit workqueue instead of relying on recursion. This changes the visitation order, but code is not supposed to rely on the order of Component.onDestroyed calls anyway (and we keep at least the order in so far that the parent emits the "signal" before it's children. Pick-to: 6.5 Change-Id: I93b30cc26b984d1a21cff92df1dd68cd45e67477 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/qml/qml/qqmlengine.cpp')
-rw-r--r--src/qml/qml/qqmlengine.cpp14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 9c7d9f302e..d7542c09fc 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -386,11 +386,15 @@ int QQmlData::endpointCount(int index)
void QQmlData::markAsDeleted(QObject *o)
{
- QQmlData::setQueuedForDeletion(o);
-
- QObjectPrivate *p = QObjectPrivate::get(o);
- for (QList<QObject *>::const_iterator it = p->children.constBegin(), end = p->children.constEnd(); it != end; ++it) {
- QQmlData::markAsDeleted(*it);
+ QVarLengthArray<QObject *> workStack;
+ workStack.push_back(o);
+ while (!workStack.isEmpty()) {
+ auto currentObject = workStack.last();
+ workStack.pop_back();
+ QQmlData::setQueuedForDeletion(currentObject);
+ auto currentObjectPriv = QObjectPrivate::get(currentObject);
+ for (QObject *child: std::as_const(currentObjectPriv->children))
+ workStack.push_back(child);
}
}