From 2a79c2bf4d9525a31e180d87d3fa249e98f5683e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 23 Jun 2017 10:40:55 +0200 Subject: Turn QQmlType into a refcounted value type Task-number: QTBUG-61536 Change-Id: If906af2bf3afd09c23a612aaac417a751b06eba4 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlmetatype_p.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 2b615e645a..e3752b7bf8 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -138,11 +138,18 @@ class QHashedCStringRef; class Q_QML_PRIVATE_EXPORT QQmlType { public: + QQmlType(); + QQmlType(const QQmlType &other); + QQmlType &operator =(const QQmlType &other); + ~QQmlType(); + + bool isValid() const { return d != 0; } + QByteArray typeName() const; - const QString &qmlTypeName() const; - const QString &elementName() const; + QString qmlTypeName() const; + QString elementName() const; - const QHashedString &module() const; + QHashedString module() const; int majorVersion() const; int minorVersion() const; @@ -244,7 +251,6 @@ private: QQmlType(int, const QString &, const QQmlPrivate::RegisterType &); QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeType &); QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &); - ~QQmlType(); QQmlTypePrivate *d; }; -- cgit v1.2.3 From a6633e41e7c6795bbbc016ce36e4ff91ec5248ad Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 23 Jun 2017 13:09:03 +0200 Subject: Use QQmlType by value in the type wrapper Task-number: QTBUG-61536 Change-Id: Ie40cb3a6e170331b0ec7ab5deaf7c1d7ef0cdaeb Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlmetatype_p.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index e3752b7bf8..08198340f3 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -141,6 +141,7 @@ public: QQmlType(); QQmlType(const QQmlType &other); QQmlType &operator =(const QQmlType &other); + explicit QQmlType(QQmlTypePrivate *priv); ~QQmlType(); bool isValid() const { return d != 0; } @@ -223,6 +224,10 @@ public: int enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; + + QQmlTypePrivate *handle() const { return d; } + static void refHandle(QQmlTypePrivate *priv); + static void derefHandle(QQmlTypePrivate *priv); private: QQmlType *superType() const; QQmlType *resolveCompositeBaseType(QQmlEnginePrivate *engine) const; -- cgit v1.2.3 From 49a11e882059ee1729f776722e085dd21d378c36 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 23 Jun 2017 13:20:23 +0200 Subject: Use QQmlType by value QQmlType is now refcounted, and we need to use it by value, to control it's lifetime properly. This is required, so we can clean up the QQmlMetaTypeData cache on engine destruction and with trimComponentCache() Task-number: QTBUG-61536 Change-Id: If86391c86ea20a646ded7c9925d8f743f628fb91 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlmetatype_p.h | 52 ++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 08198340f3..d17172a917 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -77,17 +77,17 @@ class Q_QML_PRIVATE_EXPORT QQmlMetaType { public: static QList qmlTypeNames(); - static QList qmlTypes(); - static QList qmlSingletonTypes(); - static QList qmlAllTypes(); - - static QQmlType *qmlType(const QString &qualifiedName, int, int); - static QQmlType *qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int); - static QQmlType *qmlType(const QMetaObject *); - static QQmlType *qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); - static QQmlType *qmlType(int); - static QQmlType *qmlType(const QUrl &url, bool includeNonFileImports = false); - static QQmlType *qmlTypeFromIndex(int); + static QList qmlTypes(); + static QList qmlSingletonTypes(); + static QList qmlAllTypes(); + + static QQmlType qmlType(const QString &qualifiedName, int, int); + static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int); + static QQmlType qmlType(const QMetaObject *); + static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); + static QQmlType qmlType(int); + static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false); + static QQmlType qmlTypeFromIndex(int); static QMetaProperty defaultProperty(const QMetaObject *); static QMetaProperty defaultProperty(QObject *); @@ -144,7 +144,16 @@ public: explicit QQmlType(QQmlTypePrivate *priv); ~QQmlType(); + // ### get rid of these two again + QQmlType(QQmlType *otherPointer); + QQmlType &operator =(QQmlType *otherPointer); + + bool operator ==(const QQmlType &other) const { + return d == other.d; + } + bool isValid() const { return d != 0; } + const QQmlTypePrivate *key() const { return d; } QByteArray typeName() const; QString qmlTypeName() const; @@ -229,8 +238,8 @@ public: static void refHandle(QQmlTypePrivate *priv); static void derefHandle(QQmlTypePrivate *priv); private: - QQmlType *superType() const; - QQmlType *resolveCompositeBaseType(QQmlEnginePrivate *engine) const; + QQmlType superType() const; + QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const; int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; friend class QQmlTypePrivate; friend struct QQmlMetaTypeData; @@ -250,6 +259,7 @@ private: friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &); friend int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &); friend int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &); + friend uint qHash(const QQmlType &t, uint seed); friend Q_QML_EXPORT void qmlClearTypeRegistrations(); QQmlType(int, const QQmlPrivate::RegisterInterface &); QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &); @@ -260,6 +270,12 @@ private: QQmlTypePrivate *d; }; +Q_DECLARE_TYPEINFO(QQmlMetaType, Q_MOVABLE_TYPE); + + +inline uint qHash(const QQmlType &t, uint seed = 0) { return qHash(reinterpret_cast(t.d), seed); } + + class QQmlTypeModulePrivate; class QQmlTypeModule { @@ -270,10 +286,8 @@ public: int minimumMinorVersion() const; int maximumMinorVersion() const; - QQmlType *type(const QHashedStringRef &, int) const; - QQmlType *type(const QV4::String *, int) const; - - QList singletonTypes(int) const; + QQmlType type(const QHashedStringRef &, int) const; + QQmlType type(const QV4::String *, int) const; private: //Used by register functions and creates the QQmlTypeModule for them @@ -299,8 +313,8 @@ public: QQmlTypeModule *module() const; int minorVersion() const; - QQmlType *type(const QHashedStringRef &) const; - QQmlType *type(const QV4::String *) const; + QQmlType type(const QHashedStringRef &) const; + QQmlType type(const QV4::String *) const; private: QQmlTypeModule *m_module; -- cgit v1.2.3 From c6b2dd879d02b21b18f80faab541f8f04286685a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 23 Jun 2017 13:36:13 +0200 Subject: Move property cache from the engine to QQmlType Now that the property cache is independent of a specific engine, we can cache them in QQmlType instead of caching them per engine. This simplifies the logic and avoids duplicated property caches when multiple engines are running. Task-number: QTBUG-61536 Change-Id: I6f082e1e7495ae0f5b92559e8d0a3437c56e303a Reviewed-by: Lars Knoll --- src/qml/qml/qqmlmetatype_p.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index d17172a917..c577a9cc18 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -70,6 +70,7 @@ class QQmlTypeModule; class QHashedString; class QHashedStringRef; class QMutex; +class QQmlPropertyCache; namespace QV4 { struct String; } @@ -89,6 +90,8 @@ public: static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false); static QQmlType qmlTypeFromIndex(int); + static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject); + static QMetaProperty defaultProperty(const QMetaObject *); static QMetaProperty defaultProperty(QObject *); static QMetaMethod defaultMethod(const QMetaObject *); -- cgit v1.2.3 From aa6120cc3524b8d603e92e952aece7494a5d8f02 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 23 Jun 2017 17:19:26 +0200 Subject: Remove QQmlEnginePrivate::typePropertyCache Instead of maintaining a hash per QQmlType and minor version, move the version specific property caches into QQmlType. Task-number: QTBUG-61536 Change-Id: I72f3990cb93e64ac5074060b4ff327043eab7966 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlmetatype_p.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index c577a9cc18..43eda2b4f1 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -91,6 +91,7 @@ public: static QQmlType qmlTypeFromIndex(int); static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject); + static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); static QMetaProperty defaultProperty(const QMetaObject *); static QMetaProperty defaultProperty(QObject *); -- cgit v1.2.3 From e61dca72682c9f65c6ab6254fc7e80b49be3ad43 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Jun 2017 13:45:56 +0200 Subject: Change data structures in QQmlMetaTypeData Make sure any QQmlType stored in the meta type data has a refcount of 1. This should now make it possible to clean out unused types by iterating over the list of types and removing those that have a refcount of 1. Some care is still needed for C++ registered types, that will need to get one more refcount, so we don't accidentally remove them. Task-number: QTBUG-61536 Change-Id: Id2a18dae5ddcb815f34013f5fde1f05d2d9d0214 Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- src/qml/qml/qqmlmetatype_p.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 43eda2b4f1..0077306a64 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -78,9 +78,9 @@ class Q_QML_PRIVATE_EXPORT QQmlMetaType { public: static QList qmlTypeNames(); - static QList qmlTypes(); + static QList qmlTypes(); static QList qmlSingletonTypes(); - static QList qmlAllTypes(); + static QList qmlAllTypes(); static QQmlType qmlType(const QString &qualifiedName, int, int); static QQmlType qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int, int); @@ -148,10 +148,6 @@ public: explicit QQmlType(QQmlTypePrivate *priv); ~QQmlType(); - // ### get rid of these two again - QQmlType(QQmlType *otherPointer); - QQmlType &operator =(QQmlType *otherPointer); - bool operator ==(const QQmlType &other) const { return d == other.d; } @@ -238,7 +234,7 @@ public: int enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; - QQmlTypePrivate *handle() const { return d; } + QQmlTypePrivate *priv() const { return d; } static void refHandle(QQmlTypePrivate *priv); static void derefHandle(QQmlTypePrivate *priv); private: @@ -246,7 +242,6 @@ private: QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const; int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; friend class QQmlTypePrivate; - friend struct QQmlMetaTypeData; enum RegistrationType { CppType = 0, @@ -296,7 +291,7 @@ public: private: //Used by register functions and creates the QQmlTypeModule for them friend QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data); - friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data); + friend void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data); friend struct QQmlMetaTypeData; friend Q_QML_EXPORT void qmlClearTypeRegistrations(); friend class QQmlTypeModulePrivate; -- cgit v1.2.3 From 48c09a85ce397979c7e706e3694c879ffe456e09 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 26 Jun 2017 14:52:22 +0200 Subject: Remove unused types on engine destruction The QML engine destructor as well as trimComponentCache() do now clean out unused composite types that the engine registered internally. This helps avoid 'static' leaks, when more and more types would get registered by the engine. Task-number: QTBUG-61536 Change-Id: I5b32af4b88fbf626de8c0bfbaedb2285b09e3679 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlmetatype_p.h | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 0077306a64..c0fbdd5060 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -77,6 +77,9 @@ namespace QV4 { struct String; } class Q_QML_PRIVATE_EXPORT QQmlMetaType { public: + static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type); + static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type); + static QList qmlTypeNames(); static QList qmlTypes(); static QList qmlSingletonTypes(); @@ -88,11 +91,12 @@ public: static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); static QQmlType qmlType(int); static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false); - static QQmlType qmlTypeFromIndex(int); static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject); static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); + static void freeUnusedTypesAndCaches(); + static QMetaProperty defaultProperty(const QMetaObject *); static QMetaProperty defaultProperty(QObject *); static QMetaMethod defaultMethod(const QMetaObject *); @@ -237,11 +241,6 @@ public: QQmlTypePrivate *priv() const { return d; } static void refHandle(QQmlTypePrivate *priv); static void derefHandle(QQmlTypePrivate *priv); -private: - QQmlType superType() const; - QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const; - int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; - friend class QQmlTypePrivate; enum RegistrationType { CppType = 0, @@ -250,21 +249,28 @@ private: CompositeType = 3, CompositeSingletonType = 4 }; + +private: + QQmlType superType() const; + QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const; + int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; + friend class QQmlTypePrivate; + friend QString registrationTypeString(RegistrationType); friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &, int); - friend int registerType(const QQmlPrivate::RegisterType &); - friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &); - friend int registerInterface(const QQmlPrivate::RegisterInterface &); - friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &); - friend int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &); + friend QQmlType registerType(const QQmlPrivate::RegisterType &); + friend QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &); + friend QQmlType registerInterface(const QQmlPrivate::RegisterInterface &); friend int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &); friend uint qHash(const QQmlType &t, uint seed); friend Q_QML_EXPORT void qmlClearTypeRegistrations(); - QQmlType(int, const QQmlPrivate::RegisterInterface &); - QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &); - QQmlType(int, const QString &, const QQmlPrivate::RegisterType &); - QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeType &); - QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &); + friend class QQmlMetaType; + + QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &); + QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterSingletonType &); + QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterType &); + QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeType &); + QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &); QQmlTypePrivate *d; }; @@ -288,6 +294,7 @@ public: QQmlType type(const QHashedStringRef &, int) const; QQmlType type(const QV4::String *, int) const; + QQmlTypeModulePrivate *priv() { return d; } private: //Used by register functions and creates the QQmlTypeModule for them friend QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data); -- cgit v1.2.3 From d621573d121348fed943dfe73ec9a89b27a92e52 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 27 Jun 2017 08:55:01 +0200 Subject: Move the m_qmlLists member in the QML engine to QQmlMetaType This is a pure metatype id to metatype id mapping, nothing in there is specific to a QML engine instance. Thus move the mapping to QQmlMetaType and make it global for all engines. Task-number: QTBUG-61536 Change-Id: I3792567bc9f585e3e0fbbad94efd1ec3a0db3de0 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlmetatype_p.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index c0fbdd5060..ac2133ba30 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -71,6 +71,7 @@ class QHashedString; class QHashedStringRef; class QMutex; class QQmlPropertyCache; +class QQmlCompiledData; namespace QV4 { struct String; } @@ -80,6 +81,9 @@ public: static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type); static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type); + static void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit); + static void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit); + static QList qmlTypeNames(); static QList qmlTypes(); static QList qmlSingletonTypes(); -- cgit v1.2.3