From 5b94de09cc738837d1539e28b3c0dccd17c18d29 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 9 Mar 2017 15:24:59 +0100 Subject: Fix caching of QML singleton types When a QML file depends on a QML singleton, we failed to include it in the dependency hash. Thus changes to the QML singleton did not result in a re-creation of the caches of files that use it. The list of singletons comes from random-ordered hashes in the qml import handling. We provide an order to the direct dependencies by sorting by the singleton type names. Task-number: QTBUG-58486 Change-Id: Ie7e9d006f9bf3a60af1f819ee439c29bc234bd8a Reviewed-by: Lars Knoll --- src/qml/qml/qqmltypeloader.cpp | 37 +++++++++++++++++++++++++++++++++++-- src/qml/qml/qqmltypeloader_p.h | 1 + 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index dea8f3ed6f..3004fd2196 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2007,6 +2007,16 @@ QQmlTypeData::TypeDataCallback::~TypeDataCallback() { } +QString QQmlTypeData::TypeReference::qualifiedName() const +{ + QString result; + if (!prefix.isEmpty()) { + result = prefix + QLatin1Char('.'); + } + result.append(type->qmlTypeName()); + return result; +} + QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader *manager) : QQmlTypeLoader::Blob(url, QmlFile, manager), m_typesResolved(false), m_implicitImportLoaded(false) @@ -2147,6 +2157,23 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer &typeRefs, QCryptographicHash *hash, QQmlEngine *engine) +{ + for (const auto &typeRef: typeRefs) { + if (typeRef.typeData) { + const auto unit = typeRef.typeData->compilationUnit(); + hash->addData(unit->data->md5Checksum, sizeof(unit->data->md5Checksum)); + } else if (typeRef.type) { + const auto propertyCache = QQmlEnginePrivate::get(engine)->cache(typeRef.type->metaObject()); + bool ok = false; + hash->addData(propertyCache->checksum(&ok)); + if (!ok) + return false; + } + } + return true; +} + void QQmlTypeData::done() { QDeferredCleanup cleanup([this]{ @@ -2227,8 +2254,10 @@ void QQmlTypeData::done() QQmlEngine *const engine = typeLoader()->engine(); - const auto dependencyHasher = [engine, resolvedTypeCache](QCryptographicHash *hash) { - return resolvedTypeCache.addToHash(hash, engine); + const auto dependencyHasher = [engine, resolvedTypeCache, this](QCryptographicHash *hash) { + if (!resolvedTypeCache.addToHash(hash, engine)) + return false; + return ::addTypeReferenceChecksumsToHash(m_compositeSingletons, hash, engine); }; // verify if any dependencies changed if we're using a cache @@ -2568,6 +2597,10 @@ void QQmlTypeData::resolveTypes() } } + std::stable_sort(m_compositeSingletons.begin(), m_compositeSingletons.end(), [](const TypeReference &lhs, const TypeReference &rhs){ + return lhs.qualifiedName() < rhs.qualifiedName(); + }); + for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = m_typeReferences.constBegin(), end = m_typeReferences.constEnd(); unresolvedRef != end; ++unresolvedRef) { diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index d85346c23e..e3c4a52c45 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -400,6 +400,7 @@ public: int minorVersion; QQmlTypeData *typeData; QString prefix; // used by CompositeSingleton types + QString qualifiedName() const; bool needsCreation; }; -- cgit v1.2.3