diff options
author | Ulf Hermann <[email protected]> | 2025-04-17 14:12:04 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2025-05-13 18:07:10 +0200 |
commit | 18c421fe6159dc921643c72ae335cf189eb1cc3a (patch) | |
tree | e025e22824995e60b0868638b1d1f76d963fba38 | |
parent | f21ad4788b9dd918f19cb94dc585a260bc718d10 (diff) |
QtQml: Remove dependency hashing
Since we don't store any property indices in the compilation units
anymore, we don't need to hash the dependencies anymore.
Task-number: QTBUG-135286
Change-Id: I2ea05c920475749f2a2d6cf309d0956a74d6c688
Reviewed-by: Fabian Kosmale <[email protected]>
-rw-r--r-- | src/qml/common/qv4compileddata.cpp | 38 | ||||
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 11 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 10 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4resolvedtypereference.cpp | 29 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4resolvedtypereference_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache.cpp | 211 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 29 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 38 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloaderdata_p.h | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp | 20 | ||||
-rw-r--r-- | tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp | 147 |
18 files changed, 34 insertions, 526 deletions
diff --git a/src/qml/common/qv4compileddata.cpp b/src/qml/common/qv4compileddata.cpp index 9ce5f5058f..4fbd05d060 100644 --- a/src/qml/common/qv4compileddata.cpp +++ b/src/qml/common/qv4compileddata.cpp @@ -50,29 +50,6 @@ bool Unit::verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString) return true; } -/*! - \internal - 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, QHash<quintptr, QByteArray> *checksums) const -{ - std::vector<int> keys (size()); - int i = 0; - for (auto it = constBegin(), end = constEnd(); it != end; ++it) { - keys[i] = it.key(); - ++i; - } - std::sort(keys.begin(), keys.end()); - for (int key: keys) { - if (!this->operator[](key)->addToHash(hash, checksums)) - return false; - } - - return true; -} - CompilationUnit::CompilationUnit( const Unit *unitData, const QString &fileName, const QString &finalUrlString) { @@ -354,21 +331,6 @@ int CompilationUnit::totalParserStatusCount(const QString &inlineComponentRootNa return inlineComponentData[inlineComponentRootName].totalParserStatusCount; } -bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHasher) const -{ - if (!dependencyHasher) { - for (size_t i = 0; i < sizeof(data->dependencyMD5Checksum); ++i) { - if (data->dependencyMD5Checksum[i] != 0) - return false; - } - return true; - } - const QByteArray checksum = dependencyHasher(); - return checksum.size() == sizeof(data->dependencyMD5Checksum) - && memcmp(data->dependencyMD5Checksum, checksum.constData(), - sizeof(data->dependencyMD5Checksum)) == 0; -} - QQmlType CompilationUnit::qmlTypeForComponent(const QString &inlineComponentName) const { if (inlineComponentName.isEmpty()) diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 3990bf6989..3e29ec7aef 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -85,10 +85,7 @@ namespace CompiledData { using BindingPropertyData = QVector<const QQmlPropertyData *>; // map from name index -struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*> -{ - bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const; -}; +using ResolvedTypeReferenceMap = QHash<int, ResolvedTypeReference*>; struct String; struct Function; @@ -1210,7 +1207,7 @@ struct Unit quint32_le unitSize; // Size of the Unit and any depending data. char md5Checksum[16]; // checksum of all bytes following this field. - char dependencyMD5Checksum[16]; + char reserved2[16]; // Was dependency checksum. 0 means "No checksum needed" to old versions. enum : unsigned int { IsJavascript = 0x1, @@ -1442,8 +1439,6 @@ struct TypeReferenceMap : QHash<int, TypeReference> } }; -using DependentTypesHasher = std::function<QByteArray()>; - struct InlineComponentData { InlineComponentData() = default; @@ -1674,8 +1669,6 @@ public: void finalizeCompositeType(const QQmlType &type); - bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const; - enum class ListPropertyAssignBehavior { Append, Replace, ReplaceIfNotDefault }; ListPropertyAssignBehavior listPropertyAssignBehavior() const { diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index cdfa698ff6..094df48a2a 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1645,7 +1645,7 @@ bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *prope return QQmlJS::AST::cast<QQmlJS::AST::NullExpression *>(expr); } -void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher) +void QmlUnitGenerator::generate(Document &output) { using namespace QV4::CompiledData; @@ -1740,14 +1740,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen } } - if (dependencyHasher) { - const QByteArray checksum = dependencyHasher(); - if (checksum.size() == sizeof(createdUnit->dependencyMD5Checksum)) { - memcpy(createdUnit->dependencyMD5Checksum, checksum.constData(), - sizeof(createdUnit->dependencyMD5Checksum)); - } - } - createdUnit->sourceFileIndex = output.jsGenerator.stringTable.getStringId(output.jsModule.fileName); createdUnit->finalUrlIndex = output.jsGenerator.stringTable.getStringId(output.jsModule.finalUrl); } diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index d4cdcf62f0..36c9c33561 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -622,7 +622,7 @@ public: struct Q_QML_COMPILER_EXPORT QmlUnitGenerator { - void generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher = QV4::CompiledData::DependentTypesHasher()); + void generate(Document &output); private: typedef bool (Binding::*BindingFilter)() const; diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index c2c7426bd2..2ef93cf7d2 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -632,8 +632,9 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp unit.flags = QV4::CompiledData::Unit::IsJavascript; unit.flags |= module->unitFlags; unit.version = QV4_DATA_STRUCTURE_VERSION; + unit.reserved = 0; memset(unit.md5Checksum, 0, sizeof(unit.md5Checksum)); - memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum)); + memset(unit.reserved2, 0, sizeof(unit.reserved2)); quint32 nextOffset = sizeof(CompiledData::Unit); diff --git a/src/qml/jsruntime/qv4resolvedtypereference.cpp b/src/qml/jsruntime/qv4resolvedtypereference.cpp index 7dcf2cd0b8..0f55660048 100644 --- a/src/qml/jsruntime/qv4resolvedtypereference.cpp +++ b/src/qml/jsruntime/qv4resolvedtypereference.cpp @@ -64,35 +64,6 @@ QQmlPropertyCache::ConstPtr ResolvedTypeReference::createPropertyCache() } } -bool ResolvedTypeReference::addToHash( - QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) -{ - if (m_type.isInlineComponentType()) { - - // A reference to an inline component in the same file will have - // - no compilation unit since we cannot resolve the compilation unit before it's built. - // - a property cache since we've assigned one in buildMetaObjectsIncrementally(). - // - a QQmlType that says it's an inline component. - // We don't have to add such a thing to the hash since if it changes, the QML document - // itself changes, leading to a new timestamp, which is checked before the checksum. - if (!m_compilationUnit) - return !m_typePropertyCache.isNull(); - - } else if (m_type.isValid()) { - bool ok = false; - if (QQmlPropertyCache::ConstPtr propertyCache = createPropertyCache()) - hash->addData(propertyCache->checksum(checksums, &ok)); - else - Q_ASSERT(m_type.module() == QLatin1String("QML")); // a builtin without metaobject - return ok; - } - if (!m_compilationUnit) - return false; - hash->addData({m_compilationUnit->unitData()->md5Checksum, - sizeof(m_compilationUnit->unitData()->md5Checksum)}); - return true; -} - } // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4resolvedtypereference_p.h b/src/qml/jsruntime/qv4resolvedtypereference_p.h index 4aaafdd71c..fce71ea0ad 100644 --- a/src/qml/jsruntime/qv4resolvedtypereference_p.h +++ b/src/qml/jsruntime/qv4resolvedtypereference_p.h @@ -39,7 +39,6 @@ public: QQmlPropertyCache::ConstPtr propertyCache() const; QQmlPropertyCache::ConstPtr createPropertyCache(); - bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums); void doDynamicTypeCheck(); diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index fc7c5d510f..31f9af3375 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -927,15 +927,6 @@ const QQmlPropertyData *QQmlPropertyCache::property( return qQmlPropertyCacheProperty<const QLatin1String &>(obj, name, context, local); } -// this function is copied from qmetaobject.cpp -static inline const QByteArray stringData(const QMetaObject *mo, int index) -{ - uint offset = mo->d.stringdata[2*index]; - uint length = mo->d.stringdata[2*index + 1]; - const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset; - return QByteArray::fromRawData(string, length); -} - const char *QQmlPropertyCache::className() const { if (const QMetaObject *mo = _metaObject.metaObject()) @@ -1078,209 +1069,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) const builder.addClassInfo("QML.ListPropertyAssignBehavior", _listPropertyAssignBehavior); } -namespace { -template <typename StringVisitor, typename TypeInfoVisitor> -int visitMethods(const QMetaObject &mo, int methodOffset, int methodCount, - StringVisitor visitString, TypeInfoVisitor visitTypeInfo) -{ - int fieldsForParameterData = 0; - - bool hasOldStyleRevisionedMethods = false; - - for (int i = 0; i < methodCount; ++i) { - const int handle = methodOffset + i * QMetaObjectPrivate::IntsPerMethod; - - const uint flags = mo.d.data[handle + 4]; - if (flags & MethodRevisioned) { - if (mo.d.data[0] < 13) - hasOldStyleRevisionedMethods = true; - else - fieldsForParameterData += 1; // revision - } - - visitString(mo.d.data[handle + 0]); // name - visitString(mo.d.data[handle + 3]); // tag - - const int argc = mo.d.data[handle + 1]; - const int paramIndex = mo.d.data[handle + 2]; - - fieldsForParameterData += argc * 2; // type and name - fieldsForParameterData += 1; // + return type - - // return type + args - for (int i = 0; i < 1 + argc; ++i) { - // type name (maybe) - visitTypeInfo(mo.d.data[paramIndex + i]); - - // parameter name - if (i > 0) - visitString(mo.d.data[paramIndex + argc + i]); - } - } - - int fieldsForRevisions = 0; - if (hasOldStyleRevisionedMethods) - fieldsForRevisions = methodCount; - - return methodCount * QMetaObjectPrivate::IntsPerMethod - + fieldsForRevisions + fieldsForParameterData; -} - -template <typename StringVisitor, typename TypeInfoVisitor> -int visitProperties(const QMetaObject &mo, StringVisitor visitString, TypeInfoVisitor visitTypeInfo) -{ - const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data); - - for (int i = 0; i < priv->propertyCount; ++i) { - const int handle = priv->propertyData + i * QMetaObjectPrivate::IntsPerProperty; - - visitString(mo.d.data[handle]); // name - visitTypeInfo(mo.d.data[handle + 1]); - } - - return priv->propertyCount * QMetaObjectPrivate::IntsPerProperty; -} - -template <typename StringVisitor> -int visitClassInfo(const QMetaObject &mo, StringVisitor visitString) -{ - const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data); - const int intsPerClassInfo = 2; - - for (int i = 0; i < priv->classInfoCount; ++i) { - const int handle = priv->classInfoData + i * intsPerClassInfo; - - visitString(mo.d.data[handle]); // key - visitString(mo.d.data[handle + 1]); // value - } - - return priv->classInfoCount * intsPerClassInfo; -} - -template <typename StringVisitor> -int visitEnumerations(const QMetaObject &mo, StringVisitor visitString) -{ - const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data); - - int fieldCount = priv->enumeratorCount * QMetaObjectPrivate::IntsPerEnum; - - for (int i = 0; i < priv->enumeratorCount; ++i) { - const uint *enumeratorData = mo.d.data + priv->enumeratorData + i * QMetaObjectPrivate::IntsPerEnum; - - const uint keyCount = enumeratorData[3]; - fieldCount += keyCount * 2; - - visitString(enumeratorData[0]); // name - visitString(enumeratorData[1]); // enum name - - const uint keyOffset = enumeratorData[4]; - - for (uint j = 0; j < keyCount; ++j) { - visitString(mo.d.data[keyOffset + 2 * j]); - } - } - - return fieldCount; -} - -template <typename StringVisitor> -int countMetaObjectFields(const QMetaObject &mo, StringVisitor stringVisitor) -{ - const QMetaObjectPrivate *const priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data); - - const auto typeInfoVisitor = [&stringVisitor](uint typeInfo) { - if (typeInfo & IsUnresolvedType) - stringVisitor(typeInfo & TypeNameIndexMask); - }; - - int fieldCount = MetaObjectPrivateFieldCount; - - fieldCount += visitMethods(mo, priv->methodData, priv->methodCount, stringVisitor, - typeInfoVisitor); - fieldCount += visitMethods(mo, priv->constructorData, priv->constructorCount, stringVisitor, - typeInfoVisitor); - - fieldCount += visitProperties(mo, stringVisitor, typeInfoVisitor); - fieldCount += visitClassInfo(mo, stringVisitor); - fieldCount += visitEnumerations(mo, stringVisitor); - - return fieldCount; -} - -} // anonymous namespace -static_assert(QMetaObjectPrivate::OutputRevision == 13, "Check and adjust determineMetaObjectSizes"); - -bool QQmlPropertyCache::determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, - int *stringCount) -{ - const QMetaObjectPrivate *priv = reinterpret_cast<const QMetaObjectPrivate*>(mo.d.data); - if (priv->revision != QMetaObjectPrivate::OutputRevision) - return false; - - uint highestStringIndex = 0; - const auto stringIndexVisitor = [&highestStringIndex](uint index) { - highestStringIndex = qMax(highestStringIndex, index); - }; - - *fieldCount = countMetaObjectFields(mo, stringIndexVisitor); - *stringCount = highestStringIndex + 1; - - return true; -} - -bool QQmlPropertyCache::addToHash(QCryptographicHash &hash, const QMetaObject &mo) -{ - int fieldCount = 0; - int stringCount = 0; - if (!determineMetaObjectSizes(mo, &fieldCount, &stringCount)) { - return false; - } - - hash.addData({reinterpret_cast<const char *>(mo.d.data), qsizetype(fieldCount * sizeof(uint))}); - for (int i = 0; i < stringCount; ++i) { - hash.addData(stringData(&mo, i)); - } - - return true; -} - -QByteArray QQmlPropertyCache::checksum(QHash<quintptr, QByteArray> *checksums, bool *ok) const -{ - auto it = checksums->constFind(quintptr(this)); - if (it != checksums->constEnd()) { - *ok = true; - return *it; - } - - // Generate a checksum on the meta-object data only on C++ types. - if (_metaObject.isShared()) { - *ok = false; - return QByteArray(); - } - - QCryptographicHash hash(QCryptographicHash::Md5); - - if (_parent) { - hash.addData(_parent->checksum(checksums, ok)); - if (!*ok) - return QByteArray(); - } - - if (!addToHash(hash, *_metaObject.metaObject())) { - *ok = false; - return QByteArray(); - } - - const QByteArray result = hash.result(); - if (result.isEmpty()) { - *ok = false; - } else { - *ok = true; - checksums->insert(quintptr(this), result); - } - return result; -} /*! \internal \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()). diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 60cfbb4393..5b75bf48f3 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -227,11 +227,6 @@ public: inline bool callJSFactoryMethod(QObject *object, void **args) const; - static bool determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, int *stringCount); - static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo); - - 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; } diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index bc4a032fc6..4f091eafe8 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -26,11 +26,9 @@ Q_LOGGING_CATEGORY(lcQmlTypeCompiler, "qt.qml.typecompiler"); QQmlTypeCompiler::QQmlTypeCompiler( QQmlTypeLoader *typeLoader, QQmlTypeData *typeData, QmlIR::Document *parsedQML, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, - const QV4::CompiledData::DependentTypesHasher &dependencyHasher) + QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache) : resolvedTypes(resolvedTypeCache) , loader(typeLoader) - , dependencyHasher(dependencyHasher) , document(parsedQML) , typeData(typeData) { @@ -138,7 +136,7 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile() // Generate QML compiled type data structures QmlIR::QmlUnitGenerator qmlGenerator; - qmlGenerator.generate(*document, dependencyHasher); + qmlGenerator.generate(*document); if (!errors.isEmpty()) return nullptr; diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index ecf449f549..1c14980988 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -46,8 +46,7 @@ public: QQmlTypeCompiler(QQmlTypeLoader *typeLoader, QQmlTypeData *typeData, QmlIR::Document *document, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, - const QV4::CompiledData::DependentTypesHasher &dependencyHasher); + QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache); // --- interface used by QQmlPropertyCacheCreator typedef QmlIR::Object CompiledObject; @@ -121,7 +120,6 @@ public: private: QList<QQmlError> errors; QQmlTypeLoader *loader; - const QV4::CompiledData::DependentTypesHasher &dependencyHasher; QmlIR::Document *document; // index is string index of type name (use obj->inheritedTypeNameIndex) QHash<int, QQmlCustomParser*> customParsers; diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index 3d6811fbd8..b07ed3b753 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -541,27 +541,16 @@ void QQmlTypeData::done() } } - const auto dependencyHasher = [&resolvedTypeCache, this]() { - return typeLoader()->hashDependencies(&resolvedTypeCache, m_compositeSingletons); - }; - // verify if any dependencies changed if we're using a cache if (m_document.isNull() && verifyCaches) { const QQmlError error = createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache); - if (!error.isValid() && m_compiledData->verifyChecksum(dependencyHasher)) { + if (!error.isValid()) { setCompileUnit(m_compiledData); } else { - - if (error.isValid()) { - qCDebug(DBG_DISK_CACHE) - << "Failed to create property caches for" - << m_compiledData->fileName() - << "because" << error.description(); - } else { - qCDebug(DBG_DISK_CACHE) - << "Checksum mismatch for cached version of" - << m_compiledData->fileName(); - } + qCDebug(DBG_DISK_CACHE) + << "Failed to create property caches for" + << m_compiledData->fileName() + << "because" << error.description(); if (!loadFromSource()) return; @@ -591,7 +580,7 @@ void QQmlTypeData::done() if (!m_document.isNull()) { Q_ASSERT(verifyCaches); // Compile component - compile(typeNameCache, &resolvedTypeCache, dependencyHasher); + compile(typeNameCache, &resolvedTypeCache); if (isError()) return; else @@ -922,8 +911,7 @@ QString QQmlTypeData::stringAt(int index) const } void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, - const QV4::CompiledData::DependentTypesHasher &dependencyHasher) + QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache) { assertTypeLoaderThread(); @@ -935,8 +923,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach && (m_document->javaScriptCompilationUnit->unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation); - QQmlTypeCompiler compiler( - typeLoader(), this, m_document.data(), resolvedTypeCache, dependencyHasher); + QQmlTypeCompiler compiler(typeLoader(), this, m_document.data(), resolvedTypeCache); auto compilationUnit = compiler.compile(); if (!compilationUnit) { qDeleteAll(*resolvedTypeCache); diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h index ba04ee1ad2..4cd9ff64ed 100644 --- a/src/qml/qml/qqmltypedata_p.h +++ b/src/qml/qml/qqmltypedata_p.h @@ -97,8 +97,7 @@ private: QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache ) const; void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, - const QV4::CompiledData::DependentTypesHasher &dependencyHasher); + QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache); QQmlError createTypeAndPropertyCaches( const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 7420a1654c..3296b1ec1a 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1732,7 +1732,6 @@ void QQmlTypeLoader::clearCache() QQmlTypeLoaderThreadDataPtr threadData(&m_data); qDeleteAll(threadData->importQmlDirCache); - threadData->checksumCache.clear(); threadData->importQmlDirCache.clear(); QQmlTypeLoaderSharedDataPtr data(&m_data); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 47df026a07..fd8f026b59 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -44,7 +44,6 @@ class Q_QML_EXPORT QQmlTypeLoader { Q_DECLARE_TR_FUNCTIONS(QQmlTypeLoader) public: - using ChecksumCache = QQmlTypeLoaderThreadData::ChecksumCache; enum Mode { PreferSynchronous, Asynchronous, Synchronous }; class Q_QML_EXPORT Blob : public QQmlDataBlob @@ -161,23 +160,6 @@ public: } } - // We can't include QQmlTypeData here. - // Use a template specialized only for QQmlTypeData::TypeReference instead. - template<typename TypeReference> - QByteArray hashDependencies( - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, - const QList<TypeReference> &compositeSingletons) - { - QQmlTypeLoaderThreadDataPtr data(&m_data); - - QCryptographicHash hash(QCryptographicHash::Md5); - return (resolvedTypeCache->addToHash(&hash, &data->checksumCache) - && addTypeReferenceChecksumsToHash( - compositeSingletons, &data->checksumCache, &hash)) - ? hash.result() - : QByteArray(); - } - static QUrl normalize(const QUrl &unNormalizedUrl); QQmlRefPointer<QQmlTypeData> getType( @@ -342,26 +324,6 @@ private: void doLoad(const Loader &loader, const QQmlDataBlob::Ptr &blob, Mode mode); void updateTypeCacheTrimThreshold(const QQmlTypeLoaderSharedDataPtr &data); - template<typename TypeReference> - static bool addTypeReferenceChecksumsToHash( - const QList<TypeReference> &typeRefs, - QHash<quintptr, QByteArray> *checksums, QCryptographicHash *hash) - { - for (const auto &typeRef: typeRefs) { - if (typeRef.typeData) { - const auto unit = typeRef.typeData->compilationUnit()->unitData(); - hash->addData({unit->md5Checksum, sizeof(unit->md5Checksum)}); - } else if (const QMetaObject *mo = typeRef.type.metaObject()) { - const auto propertyCache = QQmlMetaType::propertyCache(mo); - bool ok = false; - hash->addData(propertyCache->checksum(checksums, &ok)); - if (!ok) - return false; - } - } - return true; - } - QQmlMetaType::CacheMode aotCacheMode(); QQmlTypeLoaderLockedData m_data; diff --git a/src/qml/qml/qqmltypeloaderdata_p.h b/src/qml/qml/qqmltypeloaderdata_p.h index f9ab346cbb..f9cc20137f 100644 --- a/src/qml/qml/qqmltypeloaderdata_p.h +++ b/src/qml/qml/qqmltypeloaderdata_p.h @@ -58,7 +58,6 @@ class QQmlTypeLoaderThreadData { Q_DISABLE_COPY_MOVE(QQmlTypeLoaderThreadData) public: - using ChecksumCache = QHash<quintptr, QByteArray>; using ImportQmlDirCache = QStringHash<QQmlTypeLoaderQmldirContent *>; struct QmldirInfo { @@ -71,7 +70,6 @@ public: QQmlTypeLoaderThreadData() = default; ImportQmlDirCache importQmlDirCache; - ChecksumCache checksumCache; // Maps from an import to a linked list of qmldir info. // Used in locateLocalQmldir() diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index a6ea3b2e97..98082daac6 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -443,7 +443,7 @@ class TypeVersion1 : public QObject public: - int m_value = 0; + int m_value = 14; int value() const { return m_value; } void setValue(int v) { m_value = v; emit valueChanged(); } @@ -459,7 +459,7 @@ class TypeVersion2 : public QObject public: - QString m_value; + QString m_value = QLatin1StringView("hello"); QString value() const { return m_value; } void setValue(QString v) { m_value = v; emit valueChanged(); } @@ -492,6 +492,7 @@ void tst_qmldiskcache::recompileAfterChange() CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion1> obj(qobject_cast<TypeVersion1*>(component.create())); QVERIFY(!obj.isNull()); + QCOMPARE(obj->value(), 14); QCOMPARE(QFileInfo(testCompiler.cacheFilePath).lastModified(), initialCacheTimeStamp); } @@ -501,6 +502,7 @@ void tst_qmldiskcache::recompileAfterChange() CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion1> obj(qobject_cast<TypeVersion1*>(component.create())); QVERIFY(!obj.isNull()); + QCOMPARE(obj->value(), 14); QCOMPARE(QFileInfo(testCompiler.cacheFilePath).lastModified(), initialCacheTimeStamp); } @@ -514,7 +516,7 @@ void tst_qmldiskcache::recompileAfterChange() CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion2> obj(qobject_cast<TypeVersion2*>(component.create())); QVERIFY(!obj.isNull()); - QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp); + QCOMPARE(obj->value(), QLatin1StringView("hello")); } } @@ -863,9 +865,11 @@ void tst_qmldiskcache::stableOrderOfDependentCompositeTypes() } { + // We don't need to re-generate the cache for testFilePath. + // It's independent of FirstDependentType.qml QVERIFY(QFile::exists(testFileCachePath)); QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); - QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString())); + QCOMPARE(newCacheTimeStamp, initialCacheTimeStamp); } } @@ -916,9 +920,11 @@ void tst_qmldiskcache::singletonDependency() } { + // We don't need to re-generate the cache for testFilePath. + // It's independent of the singleton QVERIFY(QFile::exists(testFileCachePath)); QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); - QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString())); + QCOMPARE(newCacheTimeStamp, initialCacheTimeStamp); } } @@ -972,9 +978,11 @@ void tst_qmldiskcache::cppRegisteredSingletonDependency() QVERIFY(!obj.isNull()); { + // We don't need to re-generate the cache for testFilePath. + // It's independent of the singleton QVERIFY(QFile::exists(testFileCachePath)); QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); - QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString())); + QCOMPARE(newCacheTimeStamp, initialCacheTimeStamp); } QVariant value; diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index 5f6997467a..e816f5b331 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -28,9 +28,6 @@ private slots: void signalHandlersDerived(); void passForeignEnums(); void passQGadget(); - void metaObjectSize_data(); - void metaObjectSize(); - void metaObjectChecksum(); void metaObjectsForRootElements(); void derivedGadgetMethod(); void restrictRegistrationVersion(); @@ -508,148 +505,6 @@ void tst_qqmlpropertycache::passQGadget() QVERIFY(after.toBool()); } -class TestClass : public QObject -{ - Q_OBJECT - Q_PROPERTY(int prop READ prop WRITE setProp NOTIFY propChanged) - int m_prop; - -public: - enum MyEnum { - First, Second - }; - Q_ENUM(MyEnum) - - Q_CLASSINFO("Foo", "Bar") - - TestClass() {} - - int prop() const - { - return m_prop; - } - -public slots: - void setProp(int prop) - { - if (m_prop == prop) - return; - - m_prop = prop; - emit propChanged(prop); - } -signals: - void propChanged(int prop); -}; - -class TestClassWithParameters : public QObject -{ - Q_OBJECT - -public: - Q_INVOKABLE void slotWithArguments(int firstArg) { - Q_UNUSED(firstArg); - } -}; - -class TestClassWithClassInfo : public QObject -{ - Q_OBJECT - Q_CLASSINFO("Key", "Value") -}; - -#include "tst_qqmlpropertycache.moc" - -template <typename T, typename = void> -struct SizeofOffsetsAndSizes_helper -{ - static constexpr size_t value = sizeof(T::offsetsAndSize); // old moc -}; - -template <typename T> -struct SizeofOffsetsAndSizes_helper<T, std::void_t<decltype(T::offsetsAndSizes)>> -{ - static constexpr size_t value = sizeof(T::offsetsAndSizes); // new moc -}; - -template <typename T> -constexpr size_t sizeofOffsetsAndSizes(const T &) -{ - return SizeofOffsetsAndSizes_helper<T>::value; -} - -// NOTE: ScopeCounter might change new metaobjects are added -// check the moc file and adjust as necessary if tests fails to compile -#define TEST_CLASS(Class, Fields, Strings) \ - QTest::newRow(#Class) \ - << &Class::staticMetaObject \ - << Fields \ - << Strings - -Q_DECLARE_METATYPE(const QMetaObject*); - -void tst_qqmlpropertycache::metaObjectSize_data() -{ - QTest::addColumn<const QMetaObject*>("metaObject"); - QTest::addColumn<int>("expectedFieldCount"); - QTest::addColumn<int>("expectedStringCount"); - - TEST_CLASS(TestClass, 49, 10); - TEST_CLASS(TestClassWithParameters, 24, 4); - TEST_CLASS(TestClassWithClassInfo, 17, 3); -} - -void tst_qqmlpropertycache::metaObjectSize() -{ - QFETCH(const QMetaObject *, metaObject); - QFETCH(int, expectedFieldCount); - QFETCH(int, expectedStringCount); - - int size = 0; - int stringDataSize = 0; - bool valid = QQmlPropertyCache::determineMetaObjectSizes(*metaObject, &size, &stringDataSize); - QVERIFY(valid); - - QCOMPARE(size, expectedFieldCount - 1); // Remove trailing zero field until fixed in moc. - QCOMPARE(stringDataSize, expectedStringCount); -} - -void tst_qqmlpropertycache::metaObjectChecksum() -{ - QMetaObjectBuilder builder; - builder.setClassName("Test"); - builder.addClassInfo("foo", "bar"); - - QCryptographicHash hash(QCryptographicHash::Md5); - - QScopedPointer<QMetaObject, QScopedPointerPodDeleter> mo(builder.toMetaObject()); - QVERIFY(!mo.isNull()); - - QVERIFY(QQmlPropertyCache::addToHash(hash, *mo.data())); - QByteArray initialHash = hash.result(); - QVERIFY(!initialHash.isEmpty()); - hash.reset(); - - { - QVERIFY(QQmlPropertyCache::addToHash(hash, *mo.data())); - QByteArray nextHash = hash.result(); - QVERIFY(!nextHash.isEmpty()); - hash.reset(); - QCOMPARE(initialHash, nextHash); - } - - builder.addProperty("testProperty", "int", -1); - - mo.reset(builder.toMetaObject()); - { - QVERIFY(QQmlPropertyCache::addToHash(hash, *mo.data())); - QByteArray nextHash = hash.result(); - QVERIFY(!nextHash.isEmpty()); - hash.reset(); - QVERIFY(initialHash != nextHash); - } -} - void tst_qqmlpropertycache::metaObjectsForRootElements() { QQmlEngine engine; @@ -790,3 +645,5 @@ void tst_qqmlpropertycache::duplicateIdsAndGeneralizedGroupProperties() } QTEST_MAIN(tst_qqmlpropertycache) + +#include "tst_qqmlpropertycache.moc" |