aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2024-09-27 18:19:34 +0200
committerUlf Hermann <ulf.hermann@qt.io>2024-09-30 20:26:35 +0200
commit76ce5e4799f07e7cf4b9ffccf7cdfb5bc07de3c4 (patch)
tree27d550d2118d9d7d542631eed033035bdba16440 /src
parentf8e68c4cd00d3ec36c21acc1cd089ae25af1c17d (diff)
QmlCompiler: Do not cache composite metatypes in static members
The metatypes from any old engines may have been deleted. Retrieve the types from the ResolveTypeReferenceMap instead. That is much cheaper than doing a full type search and the CU should know the types it's dealing with. Sometimes, however, the CU does not pre-resolve the types. In particular, types only used in function signatures do not end up in the ResolvedTypeReferenceMap. In those cases, still do the full type search. Amends commit 8bf5aae19b77b618f3f7a55a59e87c8a319475a8. Pick-to: 6.8.0 6.8 Task-number: QTBUG-129388 Change-Id: I27f25e1c68de3c752d00345c6d94016fb315e16c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/qml/qqml.cpp12
-rw-r--r--src/qml/qml/qqmlprivate.h4
-rw-r--r--src/qml/qml/qqmltype_p_p.h56
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp12
5 files changed, 48 insertions, 40 deletions
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 82646e2822..02c17d5de3 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -158,9 +158,7 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
if (type == 0 || !typeLoader)
return QQmlType();
- const auto &base = unit->baseCompilationUnit();
- const QQmlType qmltype = QQmlTypePrivate::compositeQmlType(
- base, typeLoader, base->stringAt(type));
+ const QQmlType qmltype = QQmlTypePrivate::visibleQmlTypeByName(unit, type, typeLoader);
return qmltype.typeId().isValid() ? qmltype : QQmlType();
};
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 0642cb28e3..8479dadd42 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -174,19 +174,15 @@ void QQmlPrivate::qmlRegistrationWarning(
}
QMetaType QQmlPrivate::compositeMetaType(
- QV4::ExecutableCompilationUnit *unit, const QString &elementName)
+ QV4::ExecutableCompilationUnit *unit, int elementNameId)
{
- return QQmlTypePrivate::compositeQmlType(
- unit->baseCompilationUnit(), unit->engine->typeLoader(), elementName)
- .typeId();
+ return QQmlTypePrivate::visibleQmlTypeByName(unit, elementNameId).typeId();
}
QMetaType QQmlPrivate::compositeListMetaType(
- QV4::ExecutableCompilationUnit *unit, const QString &elementName)
+ QV4::ExecutableCompilationUnit *unit, int elementNameId)
{
- return QQmlTypePrivate::compositeQmlType(
- unit->baseCompilationUnit(), unit->engine->typeLoader(), elementName)
- .qListTypeId();
+ return QQmlTypePrivate::visibleQmlTypeByName(unit, elementNameId).qListTypeId();
}
int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 92c9765509..71c8c78e31 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -1153,9 +1153,9 @@ namespace QQmlPrivate
Q_QML_EXPORT void qmlRegistrationWarning(QmlRegistrationWarning warning, QMetaType type);
Q_QML_EXPORT QMetaType compositeMetaType(
- QV4::ExecutableCompilationUnit *unit, const QString &elementName);
+ QV4::ExecutableCompilationUnit *unit, int elementNameId);
Q_QML_EXPORT QMetaType compositeListMetaType(
- QV4::ExecutableCompilationUnit *unit, const QString &elementName);
+ QV4::ExecutableCompilationUnit *unit, int elementNameId);
} // namespace QQmlPrivate
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index 2bf83ddb8b..a642e2ca27 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -15,15 +15,17 @@
// We mean it.
//
-#include <private/qqmltype_p.h>
-#include <private/qstringhash_p.h>
+#include <private/qqmlengine_p.h>
+#include <private/qqmlmetatype_p.h>
+#include <private/qqmlpropertycache_p.h>
#include <private/qqmlproxymetaobject_p.h>
#include <private/qqmlrefcount_p.h>
-#include <private/qqmlpropertycache_p.h>
-#include <private/qqmlmetatype_p.h>
+#include <private/qqmltype_p.h>
#include <private/qqmltypeloader_p.h>
-#include <private/qv4executablecompilationunit_p.h>
+#include <private/qstringhash_p.h>
#include <private/qv4engine_p.h>
+#include <private/qv4executablecompilationunit_p.h>
+#include <private/qv4resolvedtypereference_p.h>
#include <QAtomicInteger>
@@ -234,25 +236,41 @@ public:
return nullptr;
}
- static QQmlType compositeQmlType(
- const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit,
- QQmlTypeLoader *typeLoader, const QString &type)
+ // Tries the base unit's resolvedTypes first. If successful, that is cheap
+ // because it's just a hash. Otherwise falls back to typeNameCache.
+ // typeNameCache is slower because it will do a generic type search on all imports.
+ // This can involve iterating all the types of an import or querying QQmlMetaType for
+ // further details.
+ // TODO: Not all referenced types are pre-resolved when loading. That should be fixed.
+ // In particular, types only used in function signatures are not resolved.
+ static QQmlType visibleQmlTypeByName(
+ const QV4::ExecutableCompilationUnit *unit, int elementNameId,
+ QQmlTypeLoader *typeLoader = nullptr)
{
- Q_ASSERT(typeLoader);
+ const auto &base = unit->baseCompilationUnit();
+ const auto it = base->resolvedTypes.constFind(elementNameId);
+ if (it == base->resolvedTypes.constEnd()) {
+ const QQmlType qmltype = base->typeNameCache->query<QQmlImport::AllowRecursion>(
+ base->stringAt(elementNameId),
+ typeLoader ? typeLoader : unit->engine->typeLoader()).type;
+
+ if (qmltype.isValid() && qmltype.isInlineComponentType()
+ && !QQmlMetaType::obtainCompilationUnit(qmltype.typeId())) {
+ // If it seems to be an IC type, make sure there is an actual
+ // compilation unit for it. We create inline component types speculatively.
+ return QQmlType();
+ }
- const QQmlType qmltype
- = unit->typeNameCache->query<QQmlImport::AllowRecursion>(type, typeLoader).type;
- if (!qmltype.isValid())
return qmltype;
-
- if (qmltype.isInlineComponentType()
- && !QQmlMetaType::obtainCompilationUnit(qmltype.typeId())) {
- // If it seems to be an IC type, make sure there is an actual
- // compilation unit for it. We create inline component types speculatively.
- return QQmlType();
}
- return qmltype;
+ if (const QQmlType type = (*it)->type(); type.isValid())
+ return type;
+
+ if (const auto cu = (*it)->compilationUnit())
+ return cu->qmlType;
+
+ return QQmlType();
}
private:
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index dba9cfbd2f..d80325895f 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -77,18 +77,14 @@ QString QQmlJSCodeGenerator::metaTypeFromName(const QQmlJSScope::ConstPtr &type)
QString QQmlJSCodeGenerator::compositeListMetaType(const QString &elementName) const
{
- return u"[](auto *aotContext) { static const auto t = QQmlPrivate::compositeListMetaType("
- "aotContext->compilationUnit, QStringLiteral(\""_s
- + elementName
- + u"\")); return t; }(aotContext)"_s;
+ return u"QQmlPrivate::compositeListMetaType(aotContext->compilationUnit, "_s
+ + QString::number(m_jsUnitGenerator->getStringId(elementName)) + u")"_s;
}
QString QQmlJSCodeGenerator::compositeMetaType(const QString &elementName) const
{
- return u"[](auto *aotContext) { static const auto t = QQmlPrivate::compositeMetaType("
- "aotContext->compilationUnit, QStringLiteral(\""_s
- + elementName
- + u"\")); return t; }(aotContext)"_s;
+ return u"QQmlPrivate::compositeMetaType(aotContext->compilationUnit, "_s
+ + QString::number(m_jsUnitGenerator->getStringId(elementName)) + u")"_s;
}
QString QQmlJSCodeGenerator::metaObject(const QQmlJSScope::ConstPtr &objectType)