diff options
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 60 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 55 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatypedata.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatypedata_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 3 |
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)); |