diff options
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4resolvedtypereference.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4resolvedtypereference_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache.cpp | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 4 |
9 files changed, 39 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index 68e2787cc0..eee826e87e 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -860,7 +860,8 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt This function creates a temporary key vector and sorts it to guarantuee a stable hash. This is used to calculate a check-sum on dependent meta-objects. */ -bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *engine) const +bool ResolvedTypeReferenceMap::addToHash( + QCryptographicHash *hash, QQmlEngine *engine, QHash<quintptr, QByteArray> *checksums) const { std::vector<int> keys (count()); int i = 0; @@ -870,7 +871,7 @@ bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *e } std::sort(keys.begin(), keys.end()); for (int key: keys) { - if (!this->operator[](key)->addToHash(hash, engine)) + if (!this->operator[](key)->addToHash(hash, engine, checksums)) return false; } diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index e4670553cb..48fd339a4e 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -94,7 +94,8 @@ class ResolvedTypeReference; // map from name index struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*> { - bool addToHash(QCryptographicHash *hash, QQmlEngine *engine) const; + bool addToHash(QCryptographicHash *hash, QQmlEngine *engine, + QHash<quintptr, QByteArray> *checksums) const; }; class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final: public CompiledData::CompilationUnit, diff --git a/src/qml/jsruntime/qv4resolvedtypereference.cpp b/src/qml/jsruntime/qv4resolvedtypereference.cpp index d81f512391..e78a1d3244 100644 --- a/src/qml/jsruntime/qv4resolvedtypereference.cpp +++ b/src/qml/jsruntime/qv4resolvedtypereference.cpp @@ -96,11 +96,12 @@ QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQm } } -bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engine) +bool ResolvedTypeReference::addToHash( + QCryptographicHash *hash, QQmlEngine *engine, QHash<quintptr, QByteArray> *checksums) { if (m_type.isValid() && !m_type.isInlineComponentType()) { bool ok = false; - hash->addData(createPropertyCache(engine)->checksum(&ok)); + hash->addData(createPropertyCache(engine)->checksum(checksums, &ok)); return ok; } if (!m_compilationUnit) diff --git a/src/qml/jsruntime/qv4resolvedtypereference_p.h b/src/qml/jsruntime/qv4resolvedtypereference_p.h index 7e8bedad62..ce13e3afcb 100644 --- a/src/qml/jsruntime/qv4resolvedtypereference_p.h +++ b/src/qml/jsruntime/qv4resolvedtypereference_p.h @@ -75,7 +75,8 @@ public: QQmlRefPointer<QQmlPropertyCache> propertyCache() const; QQmlRefPointer<QQmlPropertyCache> createPropertyCache(QQmlEngine *); - bool addToHash(QCryptographicHash *hash, QQmlEngine *engine); + bool addToHash(QCryptographicHash *hash, QQmlEngine *engine, QHash<quintptr, + QByteArray> *checksums); void doDynamicTypeCheck(); diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 9b01b2d8fb..191944b2d5 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -1259,35 +1259,41 @@ bool QQmlPropertyCache::addToHash(QCryptographicHash &hash, const QMetaObject &m return true; } -QByteArray QQmlPropertyCache::checksum(bool *ok) +QByteArray QQmlPropertyCache::checksum(QHash<quintptr, QByteArray> *checksums, bool *ok) const { - if (!_checksum.isEmpty()) { + auto it = checksums->constFind(quintptr(this)); + if (it != checksums->constEnd()) { *ok = true; - return _checksum; + return *it; } // Generate a checksum on the meta-object data only on C++ types. if (!_metaObject || _metaObject.isShared()) { *ok = false; - return _checksum; + return QByteArray(); } QCryptographicHash hash(QCryptographicHash::Md5); if (_parent) { - hash.addData(_parent->checksum(ok)); + hash.addData(_parent->checksum(checksums, ok)); if (!*ok) return QByteArray(); } - if (!addToHash(hash, *createMetaObject())) { + if (!addToHash(hash, *_metaObject)) { *ok = false; return QByteArray(); } - _checksum = hash.result(); - *ok = !_checksum.isEmpty(); - return _checksum; + const QByteArray result = hash.result(); + if (result.isEmpty()) { + *ok = false; + } else { + *ok = true; + checksums->insert(quintptr(this), result); + } + return result; } /*! \internal diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 46ecd0b5d2..2e3368ebaa 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -244,7 +244,7 @@ public: static bool determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, int *stringCount); static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo); - QByteArray checksum(bool *ok); + QByteArray checksum(QHash<quintptr, QByteArray> *checksums, bool *ok) const; QTypeRevision allowedRevision(int index) const { return allowedRevisionCache[index]; } void setAllowedRevision(int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; } @@ -330,7 +330,6 @@ private: QByteArray _listPropertyAssignBehavior; QString _defaultPropertyName; QQmlPropertyCacheMethodArguments *argumentsCache = nullptr; - QByteArray _checksum; int methodIndexCacheStart = 0; int signalHandlerIndexCacheStart = 0; int _jsFactoryMethodIndex = -1; diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index 89bccc0c39..51564e2429 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -252,7 +252,10 @@ void QQmlTypeData::createTypeAndPropertyCaches( pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_compiledData->propertyCaches); } -static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeReference> &typeRefs, QCryptographicHash *hash, QQmlEngine *engine) +static bool addTypeReferenceChecksumsToHash( + const QList<QQmlTypeData::TypeReference> &typeRefs, + QCryptographicHash *hash, QQmlEngine *engine, + QHash<quintptr, QByteArray> *checksums) { for (const auto &typeRef: typeRefs) { if (typeRef.typeData) { @@ -261,7 +264,7 @@ static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeRefere } else if (typeRef.type.isValid()) { const auto propertyCache = QQmlEnginePrivate::get(engine)->cache(typeRef.type.metaObject()); bool ok = false; - hash->addData(propertyCache->checksum(&ok)); + hash->addData(propertyCache->checksum(checksums, &ok)); if (!ok) return false; } @@ -421,8 +424,9 @@ void QQmlTypeData::done() const auto dependencyHasher = [engine, &resolvedTypeCache, this]() { QCryptographicHash hash(QCryptographicHash::Md5); - return (resolvedTypeCache.addToHash(&hash, engine) - && ::addTypeReferenceChecksumsToHash(m_compositeSingletons, &hash, engine)) + return (resolvedTypeCache.addToHash(&hash, engine, typeLoader()->checksumCache()) + && ::addTypeReferenceChecksumsToHash(m_compositeSingletons, &hash, engine, + typeLoader()->checksumCache())) ? hash.result() : QByteArray(); }; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 59c9f858f6..b41f15a7c2 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1220,6 +1220,7 @@ void QQmlTypeLoader::clearCache() m_qmldirCache.clear(); m_importDirCache.clear(); m_importQmlDirCache.clear(); + m_checksumCache.clear(); QQmlMetaType::freeUnusedTypesAndCaches(); } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index eb6e549911..10f96df735 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -78,6 +78,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTypeLoader { Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader) public: + using ChecksumCache = QHash<quintptr, QByteArray>; enum Mode { PreferSynchronous, Asynchronous, Synchronous }; class Q_QML_PRIVATE_EXPORT Blob : public QQmlDataBlob @@ -141,6 +142,8 @@ public: ~QQmlTypeLoader(); QQmlImportDatabase *importDatabase() const; + ChecksumCache *checksumCache() { return &m_checksumCache; } + const ChecksumCache *checksumCache() const { return &m_checksumCache; } static QUrl normalize(const QUrl &unNormalizedUrl); @@ -247,6 +250,7 @@ private: QmldirCache m_qmldirCache; ImportDirCache m_importDirCache; ImportQmlDirCache m_importQmlDirCache; + ChecksumCache m_checksumCache; template<typename Loader> void doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode); |