aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2025-04-17 14:12:04 +0200
committerUlf Hermann <[email protected]>2025-05-13 18:07:10 +0200
commit18c421fe6159dc921643c72ae335cf189eb1cc3a (patch)
treee025e22824995e60b0868638b1d1f76d963fba38
parentf21ad4788b9dd918f19cb94dc585a260bc718d10 (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.cpp38
-rw-r--r--src/qml/common/qv4compileddata_p.h11
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp10
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h2
-rw-r--r--src/qml/compiler/qv4compiler.cpp3
-rw-r--r--src/qml/jsruntime/qv4resolvedtypereference.cpp29
-rw-r--r--src/qml/jsruntime/qv4resolvedtypereference_p.h1
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp211
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h5
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp6
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h4
-rw-r--r--src/qml/qml/qqmltypedata.cpp29
-rw-r--r--src/qml/qml/qqmltypedata_p.h3
-rw-r--r--src/qml/qml/qqmltypeloader.cpp1
-rw-r--r--src/qml/qml/qqmltypeloader_p.h38
-rw-r--r--src/qml/qml/qqmltypeloaderdata_p.h2
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp20
-rw-r--r--tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp147
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"