aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp8
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp60
-rw-r--r--src/qml/qml/qqmlengine_p.h7
-rw-r--r--src/qml/qml/qqmlmetatype.cpp55
-rw-r--r--src/qml/qml/qqmlmetatype_p.h5
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp3
-rw-r--r--src/qml/qml/qqmlmetatypedata_p.h1
-rw-r--r--src/qml/qml/qqmltypedata.cpp3
9 files changed, 74 insertions, 70 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index f1253aa6f8..5884640287 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -306,11 +306,9 @@ void ExecutableCompilationUnit::unlink()
if (engine)
nextCompilationUnit.remove();
- if (isRegisteredWithEngine) {
+ if (isRegistered) {
Q_ASSERT(data && propertyCaches.count() > 0 && propertyCaches.at(/*root object*/0));
- if (qmlEngine)
- qmlEngine->unregisterInternalCompositeType(this);
- isRegisteredWithEngine = false;
+ QQmlMetaType::unregisterInternalCompositeType(this);
}
propertyCaches.clear();
@@ -404,7 +402,7 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
if (!types.isValid())
types = CompositeMetaTypeIds::fromCompositeName(rootPropertyCache()->className());
typeIds = types;
- qmlEngine->registerInternalCompositeType(this);
+ QQmlMetaType::registerInternalCompositeType(this);
} else {
const QV4::CompiledData::Object *obj = objectAt(/*root object*/0);
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index e4670553cb..962517f6f4 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -181,7 +181,7 @@ public:
CompositeMetaTypeIds typeIdsForComponent(int objectid = 0) const;
CompositeMetaTypeIds typeIds;
- bool isRegisteredWithEngine = false;
+ bool isRegistered = false;
QHash<int, InlineComponentData> inlineComponentData;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 119eb50421..7c64988905 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -247,8 +247,6 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
QQmlMetaType::freeUnusedTypesAndCaches();
- for (auto iter = m_compositeTypes.cbegin(), end = m_compositeTypes.cend(); iter != end; ++iter)
- iter.value()->isRegisteredWithEngine = false;
#if QT_CONFIG(qml_debug)
delete profiler;
#endif
@@ -1696,17 +1694,6 @@ QString QQmlEnginePrivate::offlineStorageDatabaseDirectory() const
return q->offlineStoragePath() + QDir::separator() + QLatin1String("Databases") + QDir::separator();
}
-static QQmlRefPointer<QQmlPropertyCache> propertyCacheForPotentialInlineComponentType(
- int t, const QHash<int, QV4::ExecutableCompilationUnit *>::const_iterator &iter) {
- if (t != (*iter)->typeIds.id.id()) {
- // this is an inline component, and what we have in the iterator is currently the parent compilation unit
- for (auto &&icDatum: (*iter)->inlineComponentData)
- if (icDatum.typeIds.id.id() == t)
- return (*iter)->propertyCaches.at(icDatum.objectIndex);
- }
- return (*iter)->rootPropertyCache();
-}
-
/*!
* \internal
*
@@ -1714,7 +1701,7 @@ static QQmlRefPointer<QQmlPropertyCache> propertyCacheForPotentialInlineComponen
*/
QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(QMetaType metaType) const
{
- if (auto composite = findPropertyCacheInCompositeTypes(metaType.id()))
+ if (auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
return QQmlMetaObject(composite);
return QQmlMetaObject(QQmlMetaType::qmlType(metaType).baseMetaObject());
@@ -1727,7 +1714,7 @@ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(QMetaType metaType) const
*/
QQmlMetaObject QQmlEnginePrivate::metaObjectForType(QMetaType metaType) const
{
- if (auto composite = findPropertyCacheInCompositeTypes(metaType.id()))
+ if (auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
return QQmlMetaObject(composite);
return QQmlMetaObject(QQmlMetaType::qmlType(metaType).metaObject());
@@ -1740,7 +1727,7 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(QMetaType metaType) const
*/
QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::propertyCacheForType(QMetaType metaType)
{
- if (auto composite = findPropertyCacheInCompositeTypes(metaType.id()))
+ if (auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
return composite;
const QQmlType type = QQmlMetaType::qmlType(metaType);
@@ -1758,7 +1745,7 @@ QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::propertyCacheForType(QMetaT
*/
QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::rawPropertyCacheForType(QMetaType metaType)
{
- if (auto composite = findPropertyCacheInCompositeTypes(metaType.id()))
+ if (auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
return composite;
const QQmlType type = QQmlMetaType::qmlType(metaType);
@@ -1776,7 +1763,7 @@ QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::rawPropertyCacheForType(QMe
QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::rawPropertyCacheForType(
QMetaType metaType, QTypeRevision version)
{
- if (auto composite = findPropertyCacheInCompositeTypes(metaType.id()))
+ if (auto composite = QQmlMetaType::findPropertyCacheInCompositeTypes(metaType))
return composite;
const QQmlType type = QQmlMetaType::qmlType(metaType);
@@ -1792,43 +1779,6 @@ QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::rawPropertyCacheForType(
return QQmlRefPointer<QQmlPropertyCache>();
}
-QQmlRefPointer<QQmlPropertyCache> QQmlEnginePrivate::findPropertyCacheInCompositeTypes(int t) const
-{
- QMutexLocker locker(&this->mutex);
- auto iter = m_compositeTypes.constFind(t);
- return (iter == m_compositeTypes.constEnd())
- ? QQmlRefPointer<QQmlPropertyCache>()
- : propertyCacheForPotentialInlineComponentType(t, iter);
-}
-
-void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
-{
- compilationUnit->isRegisteredWithEngine = true;
-
- QMutexLocker locker(&this->mutex);
- // The QQmlCompiledData is not referenced here, but it is removed from this
- // hash in the QQmlCompiledData destructor
- m_compositeTypes.insert(compilationUnit->typeIds.id.id(), compilationUnit);
- for (auto &&data: compilationUnit->inlineComponentData)
- m_compositeTypes.insert(data.typeIds.id.id(), compilationUnit);
-}
-
-void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
-{
- compilationUnit->isRegisteredWithEngine = false;
-
- QMutexLocker locker(&this->mutex);
- m_compositeTypes.remove(compilationUnit->typeIds.id.id());
- for (auto&& icDatum: compilationUnit->inlineComponentData)
- m_compositeTypes.remove(icDatum.typeIds.id.id());
-}
-
-QV4::ExecutableCompilationUnit *QQmlEnginePrivate::obtainExecutableCompilationUnit(int typeId)
-{
- QMutexLocker locker(&this->mutex);
- return m_compositeTypes.value(typeId, nullptr);
-}
-
template<>
QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type)
{
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 58bc61dcf0..249ad74d92 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -218,9 +218,6 @@ public:
QQmlRefPointer<QQmlPropertyCache> rawPropertyCacheForType(QMetaType metaType);
QQmlRefPointer<QQmlPropertyCache> rawPropertyCacheForType(
QMetaType metaType, QTypeRevision version);
- void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
- void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
- QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(int typeId);
bool isTypeLoaded(const QUrl &url) const;
bool isScriptLoaded(const QUrl &url) const;
@@ -329,13 +326,9 @@ private:
SingletonInstances singletonInstances;
QHash<int, QQmlGadgetPtrWrapper *> cachedValueTypeInstances;
- // These members must be protected by the engine's mutex as they are required by
- // the threaded loader. Only access them through their respective accessor methods.
- QHash<int, QV4::ExecutableCompilationUnit *> m_compositeTypes;
static bool s_designerMode;
void cleanupScarceResources();
- QQmlRefPointer<QQmlPropertyCache> findPropertyCacheInCompositeTypes(int t) const;
};
/*
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index b5d1326ae0..44c005c2da 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -591,6 +591,10 @@ CompositeMetaTypeIds QQmlMetaType::registerInternalCompositeType(const QByteArra
QMetaType ptr_type(new QQmlMetaTypeInterface(ptr, (QObject **)nullptr));
QMetaType lst_type(new QQmlListMetaTypeInterface(lst, (QQmlListProperty<QObject> *)nullptr, ptr_type.iface()));
+ // Retrieve the IDs once, so that the types are added to QMetaType's custom type registry.
+ ptr_type.id();
+ lst_type.id();
+
return {ptr_type, lst_type};
}
@@ -1650,4 +1654,55 @@ QQmlValueType *QQmlMetaType::valueType(QMetaType type)
return *data->metaTypeToValueType.insert(type.id(), nullptr);
}
+static QQmlRefPointer<QQmlPropertyCache> propertyCacheForPotentialInlineComponentType(
+ QMetaType t, const QHash<const QtPrivate::QMetaTypeInterface *,
+ QV4::ExecutableCompilationUnit *>::const_iterator &iter) {
+ if (t != (*iter)->typeIds.id) {
+ // this is an inline component, and what we have in the iterator is currently the parent compilation unit
+ for (auto &&icDatum: (*iter)->inlineComponentData)
+ if (icDatum.typeIds.id == t)
+ return (*iter)->propertyCaches.at(icDatum.objectIndex);
+ }
+ return (*iter)->rootPropertyCache();
+}
+
+QQmlRefPointer<QQmlPropertyCache> QQmlMetaType::findPropertyCacheInCompositeTypes(QMetaType t)
+{
+ const QQmlMetaTypeDataPtr data;
+
+ auto iter = data->compositeTypes.constFind(t.iface());
+ return (iter == data->compositeTypes.constEnd())
+ ? QQmlRefPointer<QQmlPropertyCache>()
+ : propertyCacheForPotentialInlineComponentType(t, iter);
+}
+
+void QQmlMetaType::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
+{
+ compilationUnit->isRegistered = true;
+
+ QQmlMetaTypeDataPtr data;
+
+ // The QQmlCompiledData is not referenced here, but it is removed from this
+ // hash in the QQmlCompiledData destructor
+ data->compositeTypes.insert(compilationUnit->typeIds.id.iface(), compilationUnit);
+ for (auto &&inlineData: compilationUnit->inlineComponentData)
+ data->compositeTypes.insert(inlineData.typeIds.id.iface(), compilationUnit);
+}
+
+void QQmlMetaType::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit)
+{
+ compilationUnit->isRegistered = false;
+
+ QQmlMetaTypeDataPtr data;
+ data->compositeTypes.remove(compilationUnit->typeIds.id.iface());
+ for (auto&& icDatum: compilationUnit->inlineComponentData)
+ data->compositeTypes.remove(icDatum.typeIds.id.iface());
+}
+
+QV4::ExecutableCompilationUnit *QQmlMetaType::obtainExecutableCompilationUnit(QMetaType type)
+{
+ const QQmlMetaTypeDataPtr data;
+ return data->compositeTypes.value(type.iface());
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 2b00b75dc6..57e5ece326 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -254,6 +254,11 @@ public:
static bool isValueType(QMetaType type);
static QQmlValueType *valueType(QMetaType metaType);
static const QMetaObject *metaObjectForValueType(QMetaType type);
+
+ static QQmlRefPointer<QQmlPropertyCache> findPropertyCacheInCompositeTypes(QMetaType t);
+ static void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
+ static void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit);
+ static QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(QMetaType type);
};
Q_DECLARE_TYPEINFO(QQmlMetaType, Q_RELOCATABLE_TYPE);
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 6bac4ca8c5..5607b0f5cb 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -51,6 +51,9 @@ QQmlMetaTypeData::QQmlMetaTypeData()
QQmlMetaTypeData::~QQmlMetaTypeData()
{
+ for (auto iter = compositeTypes.cbegin(), end = compositeTypes.cend(); iter != end; ++iter)
+ iter.value()->isRegistered = false;
+
propertyCaches.clear();
// Do this before the attached properties disappear.
types.clear();
diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h
index d21a76b223..05681c0144 100644
--- a/src/qml/qml/qqmlmetatypedata_p.h
+++ b/src/qml/qml/qqmlmetatypedata_p.h
@@ -85,6 +85,7 @@ struct QQmlMetaTypeData
MetaObjects metaObjectToType;
QVector<QHash<QTypeRevision, QQmlRefPointer<QQmlPropertyCache>>> typePropertyCaches;
QHash<int, QQmlValueType *> metaTypeToValueType;
+ QHash<const QtPrivate::QMetaTypeInterface *, QV4::ExecutableCompilationUnit *> compositeTypes;
struct VersionedUri {
VersionedUri() = default;
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index 89bccc0c39..6698b6d78e 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -931,8 +931,7 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches(
if (qmlType.isValid()) {
// this is required for inline components in singletons
auto type = qmlType.lookupInlineComponentById(qmlType.inlineComponentId()).typeId();
- auto exUnit = engine->obtainExecutableCompilationUnit(
- type.isValid() ? type.id() : -1);
+ auto exUnit = QQmlMetaType::obtainExecutableCompilationUnit(type);
if (exUnit) {
ref->setCompilationUnit(exUnit);
ref->setTypePropertyCache(engine->propertyCacheForType(type));