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 --- tools/qmlplugindump/main.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tools/qmlplugindump/main.cpp') diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index dd7ae36c5d..911ef9e9a4 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -144,11 +144,11 @@ void collectReachableMetaObjects(QObject *object, QSet *met } } -void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType *ty, QSet *metas) +void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType &ty, QSet *metas) { - collectReachableMetaObjects(ty->metaObject(), metas, ty->isExtendedType()); - if (ty->attachedPropertiesType(engine)) - collectReachableMetaObjects(ty->attachedPropertiesType(engine), metas); + collectReachableMetaObjects(ty.metaObject(), metas, ty.isExtendedType()); + if (ty.attachedPropertiesType(engine)) + collectReachableMetaObjects(ty.attachedPropertiesType(engine), metas); } /* We want to add the MetaObject for 'Qt' to the list, this is a @@ -216,7 +216,7 @@ void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSetmetaObject()) ) { if (!ty->isComposite()) { - collectReachableMetaObjects(engine, ty, &metas); + collectReachableMetaObjects(engine, *ty, &metas); } else { qmlTypesByCompositeName[ty->elementName()].insert(ty); } @@ -243,7 +243,7 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, qmlTypesByCppName[ty->metaObject()->className()].insert(ty); if (ty->isExtendedType()) extensions[ty->typeName()].insert(ty->metaObject()->className()); - collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas); + collectReachableMetaObjects(QQmlEnginePrivate::get(engine), *ty, &metas); } else { qmlTypesByCompositeName[ty->elementName()].insert(ty); } @@ -1226,16 +1226,16 @@ int main(int argc, char *argv[]) } else { // find a valid QtQuick import QByteArray importCode; - QQmlType *qtObjectType = QQmlMetaType::qmlType(&QObject::staticMetaObject); - if (!qtObjectType) { + QQmlType qtObjectType = QQmlMetaType::qmlType(&QObject::staticMetaObject); + if (!qtObjectType.isValid()) { std::cerr << "Could not find QtObject type" << std::endl; importCode = qtQmlImportString.toUtf8(); } else { - QString module = qtObjectType->qmlTypeName(); + QString module = qtObjectType.qmlTypeName(); module = module.mid(0, module.lastIndexOf(QLatin1Char('/'))); importCode = QString("import %1 %2.%3").arg(module, - QString::number(qtObjectType->majorVersion()), - QString::number(qtObjectType->minorVersion())).toUtf8(); + QString::number(qtObjectType.majorVersion()), + QString::number(qtObjectType.minorVersion())).toUtf8(); } // avoid importing dependencies? for (const QString &moduleToImport : qAsConst(dependencies)) { -- 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 --- tools/qmlplugindump/main.cpp | 110 +++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 55 deletions(-) (limited to 'tools/qmlplugindump/main.cpp') diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 911ef9e9a4..982936011d 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -164,11 +164,11 @@ public: To do this, we need to find the QQmlTypes associated with this QMetaObject. */ -static QHash > qmlTypesByCppName; +static QHash > qmlTypesByCppName; /* A composite type is completely specified by name, major version and minor version. */ -static QMap > qmlTypesByCompositeName; +static QMap > qmlTypesByCompositeName; static QHash cppToId; @@ -213,12 +213,12 @@ QByteArray convertToId(const QMetaObject *mo) // Collect all metaobjects for types registered with qmlRegisterType() without parameters void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet& metas ) { const auto qmlAllTypes = QQmlMetaType::qmlAllTypes(); - for (const QQmlType *ty : qmlAllTypes) { - if ( ! metas.contains(ty->metaObject()) ) { - if (!ty->isComposite()) { - collectReachableMetaObjects(engine, *ty, &metas); + for (const QQmlType &ty : qmlAllTypes) { + if ( ! metas.contains(ty.metaObject()) ) { + if (!ty.isComposite()) { + collectReachableMetaObjects(engine, ty, &metas); } else { - qmlTypesByCompositeName[ty->elementName()].insert(ty); + qmlTypesByCompositeName[ty.elementName()].insert(ty); } } } @@ -227,25 +227,25 @@ void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet collectReachableMetaObjects(QQmlEngine *engine, QSet &noncreatables, QSet &singletons, - const QList &skip = QList()) + const QList &skip = QList()) { QSet metas; metas.insert(FriendlyQObject::qtMeta()); QHash > extensions; const auto qmlTypes = QQmlMetaType::qmlTypes(); - for (const QQmlType *ty : qmlTypes) { - if (!ty->isCreatable()) - noncreatables.insert(ty->metaObject()); - if (ty->isSingleton()) - singletons.insert(ty->metaObject()); - if (!ty->isComposite()) { - qmlTypesByCppName[ty->metaObject()->className()].insert(ty); - if (ty->isExtendedType()) - extensions[ty->typeName()].insert(ty->metaObject()->className()); - collectReachableMetaObjects(QQmlEnginePrivate::get(engine), *ty, &metas); + for (const QQmlType &ty : qmlTypes) { + if (!ty.isCreatable()) + noncreatables.insert(ty.metaObject()); + if (ty.isSingleton()) + singletons.insert(ty.metaObject()); + if (!ty.isComposite()) { + qmlTypesByCppName[ty.metaObject()->className()].insert(ty); + if (ty.isExtendedType()) + extensions[ty.typeName()].insert(ty.metaObject()->className()); + collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas); } else { - qmlTypesByCompositeName[ty->elementName()].insert(ty); + qmlTypesByCompositeName[ty.elementName()].insert(ty); } } @@ -254,21 +254,21 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, // Example: QDeclarativeGraphicsWidget overrides the QtQuick/QGraphicsWidget export // of QGraphicsWidget. for (auto it = extensions.cbegin(), end = extensions.cend(); it != end; ++it) { - QSet baseExports = qmlTypesByCppName.value(it.key()); + QSet baseExports = qmlTypesByCppName.value(it.key()); const QSet extensionCppNames = it.value(); for (const QByteArray &extensionCppName : extensionCppNames) { - const QSet extensionExports = qmlTypesByCppName.value(extensionCppName); + const QSet extensionExports = qmlTypesByCppName.value(extensionCppName); // remove extension exports from base imports // unfortunately the QQmlType pointers don't match, so can't use QSet::subtract - QSet newBaseExports; - for (const QQmlType *baseExport : qAsConst(baseExports)) { + QSet newBaseExports; + for (const QQmlType &baseExport : qAsConst(baseExports)) { bool match = false; - for (const QQmlType *extensionExport : extensionExports) { - if (baseExport->qmlTypeName() == extensionExport->qmlTypeName() - && baseExport->majorVersion() == extensionExport->majorVersion() - && baseExport->minorVersion() == extensionExport->minorVersion()) { + for (const QQmlType &extensionExport : extensionExports) { + if (baseExport.qmlTypeName() == extensionExport.qmlTypeName() + && baseExport.majorVersion() == extensionExport.majorVersion() + && baseExport.minorVersion() == extensionExport.minorVersion()) { match = true; break; } @@ -284,17 +284,17 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, if (creatable) { // find even more QMetaObjects by instantiating QML types and running // over the instances - for (QQmlType *ty : qmlTypes) { + for (const QQmlType &ty : qmlTypes) { if (skip.contains(ty)) continue; - if (ty->isExtendedType()) + if (ty.isExtendedType()) continue; - if (!ty->isCreatable()) + if (!ty.isCreatable()) continue; - if (ty->typeName() == "QQmlComponent") + if (ty.typeName() == "QQmlComponent") continue; - QString tyName = ty->qmlTypeName(); + QString tyName = ty.qmlTypeName(); tyName = tyName.mid(tyName.lastIndexOf(QLatin1Char('/')) + 1); if (tyName.isEmpty()) continue; @@ -302,11 +302,11 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, inObjectInstantiation = tyName; QObject *object = 0; - if (ty->isSingleton()) { - QQmlType::SingletonInstanceInfo *siinfo = ty->singletonInstanceInfo(); + if (ty.isSingleton()) { + QQmlType::SingletonInstanceInfo *siinfo = ty.singletonInstanceInfo(); if (!siinfo) { std::cerr << "Internal error, " << qPrintable(tyName) - << "(" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" + << "(" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << " is singleton, but has no singletonInstanceInfo" << std::endl; continue; } @@ -324,8 +324,8 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, } else { if (verbose) std::cerr << "Trying to create object " << qPrintable( tyName ) - << " (" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" << std::endl; - object = ty->create(); + << " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl; + object = ty.create(); } inObjectInstantiation.clear(); @@ -333,7 +333,7 @@ QSet collectReachableMetaObjects(QQmlEngine *engine, if (object) { if (verbose) std::cerr << "Got " << qPrintable( tyName ) - << " (" << qPrintable( QString::fromUtf8(ty->typeName()) ) << ")" << std::endl; + << " (" << qPrintable( QString::fromUtf8(ty.typeName()) ) << ")" << std::endl; collectReachableMetaObjects(object, &metas); object->deleteLater(); } else { @@ -476,17 +476,17 @@ public: return prototypeName; } - void dumpComposite(QQmlEngine *engine, const QSet &compositeType, QSet &defaultReachableNames) + void dumpComposite(QQmlEngine *engine, const QSet &compositeType, QSet &defaultReachableNames) { - for (const QQmlType *type : compositeType) + for (const QQmlType &type : compositeType) dumpCompositeItem(engine, type, defaultReachableNames); } - void dumpCompositeItem(QQmlEngine *engine, const QQmlType *compositeType, QSet &defaultReachableNames) + void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, QSet &defaultReachableNames) { - QQmlComponent e(engine, compositeType->sourceUrl()); + QQmlComponent e(engine, compositeType.sourceUrl()); if (!e.isReady()) { - std::cerr << "WARNING: skipping module " << compositeType->elementName().toStdString() + std::cerr << "WARNING: skipping module " << compositeType.elementName().toStdString() << std::endl << e.errorString().toStdString() << std::endl; return; } @@ -507,14 +507,14 @@ public: &objectsToMerge); qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName)); - QString qmlTyName = compositeType->qmlTypeName(); - const QString exportString = getExportString(qmlTyName, compositeType->majorVersion(), compositeType->minorVersion()); + QString qmlTyName = compositeType.qmlTypeName(); + const QString exportString = getExportString(qmlTyName, compositeType.majorVersion(), compositeType.minorVersion()); qml->writeScriptBinding(QLatin1String("name"), exportString); qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString); - qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType->minorVersion())); + qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion())); qml->writeBooleanBinding(QLatin1String("isComposite"), true); - if (compositeType->isSingleton()) { + if (compositeType.isSingleton()) { qml->writeBooleanBinding(QLatin1String("isCreatable"), false); qml->writeBooleanBinding(QLatin1String("isSingleton"), true); } @@ -551,12 +551,12 @@ public: if (meta->superClass()) qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass()))); - const QSet qmlTypes = qmlTypesByCppName.value(meta->className()); + const QSet qmlTypes = qmlTypesByCppName.value(meta->className()); if (!qmlTypes.isEmpty()) { - QHash exports; + QHash exports; - for (const QQmlType *qmlTy : qmlTypes) { - const QString exportString = getExportString(qmlTy->qmlTypeName(), qmlTy->majorVersion(), qmlTy->minorVersion()); + for (const QQmlType &qmlTy : qmlTypes) { + const QString exportString = getExportString(qmlTy.qmlTypeName(), qmlTy.majorVersion(), qmlTy.minorVersion()); exports.insert(exportString, qmlTy); } @@ -574,12 +574,12 @@ public: // write meta object revisions QStringList metaObjectRevisions; for (const QString &exportString : qAsConst(exportStrings)) { - int metaObjectRevision = exports[exportString]->metaObjectRevision(); + int metaObjectRevision = exports[exportString].metaObjectRevision(); metaObjectRevisions += QString::number(metaObjectRevision); } qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), metaObjectRevisions); - if (const QMetaObject *attachedType = (*qmlTypes.begin())->attachedPropertiesType(engine)) { + if (const QMetaObject *attachedType = (*qmlTypes.begin()).attachedPropertiesType(engine)) { // Can happen when a type is registered that returns itself as attachedPropertiesType() // because there is no creatable type to attach to. if (attachedType != meta) { @@ -1185,7 +1185,7 @@ int main(int argc, char *argv[]) QSet uncreatableMetas; QSet singletonMetas; QSet defaultReachable = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas); - QList defaultTypes = QQmlMetaType::qmlTypes(); + QList defaultTypes = QQmlMetaType::qmlTypes(); // add some otherwise unreachable QMetaObjects defaultReachable.insert(&QQuickMouseEvent::staticMetaObject); @@ -1324,7 +1324,7 @@ int main(int argc, char *argv[]) dumper.dump(QQmlEnginePrivate::get(&engine), meta, uncreatableMetas.contains(meta), singletonMetas.contains(meta)); } - QMap >::const_iterator iter = qmlTypesByCompositeName.constBegin(); + QMap >::const_iterator iter = qmlTypesByCompositeName.constBegin(); for (; iter != qmlTypesByCompositeName.constEnd(); ++iter) dumper.dumpComposite(&engine, iter.value(), defaultReachableNames); -- cgit v1.2.3