diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2024-01-05 19:06:05 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-01-11 00:42:17 +0100 |
commit | 953f0d44871b93a7a165e7026e48eaaadccf8d98 (patch) | |
tree | ef874e14059ee4ba958514fd7d98f5d1f0375ace /src/qml/qml/qqmlmetatype.cpp | |
parent | 809292e9b801fb5eb47dd7049bddc0fd776ab872 (diff) |
QtQml: Clear stale compilation units more thoroughly
There are various places where we can still hold references. Clean them
up when asked to do so. Also, free unused types and caches outside the
type loader mutex, and only once on engine shutdown.
Change-Id: Iae77cd6f50ad847d29a7eae4ac5c7c1c2524065d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 10b69cf850..a8995d9a4a 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1535,6 +1535,27 @@ static bool hasActiveInlineComponents(const QQmlMetaTypeData *data, const QQmlTy return false; } +static int doCountInternalCompositeTypeSelfReferences( + QQmlMetaTypeData *data, + const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) +{ + int result = 0; + auto doCheck = [&](const QtPrivate::QMetaTypeInterface *iface) { + if (!iface) + return; + + const auto it = data->compositeTypes.constFind(iface); + if (it != data->compositeTypes.constEnd() && *it == compilationUnit) + ++result; + }; + + doCheck(compilationUnit->qmlType.typeId().iface()); + for (auto &&inlineData: compilationUnit->inlineComponentData) + doCheck(inlineData.qmlType.typeId().iface()); + + return result; +} + void QQmlMetaType::freeUnusedTypesAndCaches() { QQmlMetaTypeDataPtr data; @@ -1543,6 +1564,21 @@ void QQmlMetaType::freeUnusedTypesAndCaches() if (!data.isValid()) return; + bool droppedAtLeastOneComposite; + do { + droppedAtLeastOneComposite = false; + auto it = data->compositeTypes.begin(); + while (it != data->compositeTypes.end()) { + if (!(*it)->engine + || (*it)->count() <= doCountInternalCompositeTypeSelfReferences(data, *it)) { + it = data->compositeTypes.erase(it); + droppedAtLeastOneComposite = true; + } else { + ++it; + } + } + } while (droppedAtLeastOneComposite); + bool deletedAtLeastOneType; do { deletedAtLeastOneType = false; @@ -1931,22 +1967,7 @@ int QQmlMetaType::countInternalCompositeTypeSelfReferences( const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) { QQmlMetaTypeDataPtr data; - - int result = 0; - auto doCheck = [&](const QtPrivate::QMetaTypeInterface *iface) { - if (!iface) - return; - - const auto it = data->compositeTypes.constFind(iface); - if (it != data->compositeTypes.constEnd() && *it == compilationUnit) - ++result; - }; - - doCheck(compilationUnit->qmlType.typeId().iface()); - for (auto &&inlineData: compilationUnit->inlineComponentData) - doCheck(inlineData.qmlType.typeId().iface()); - - return result; + return doCountInternalCompositeTypeSelfReferences(data, compilationUnit); } QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlMetaType::obtainExecutableCompilationUnit( |