This commit is contained in:
parent
e4f46ec826
commit
f4cb7ec09e
@ -1,239 +0,0 @@
|
|||||||
From 5b5f6d7b4b00e8e64280b7d66bcc1f63b40edf1c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ulf Hermann <ulf.hermann@qt.io>
|
|
||||||
Date: Mon, 9 Sep 2024 16:58:24 +0200
|
|
||||||
Subject: [PATCH] QtQml: Re-use memory-cached compilation units across engines
|
|
||||||
|
|
||||||
Since we've eliminated all engine-specific data from these compilation
|
|
||||||
units, we can now do so without fearing crosstalk between the engines.
|
|
||||||
By not re-compiling the CUs we also do not create duplicate property
|
|
||||||
caches which can otherwise show up in inconvenient places and make
|
|
||||||
otherwise equal types mismatch.
|
|
||||||
|
|
||||||
Fixes: QTBUG-128789
|
|
||||||
Change-Id: Ia8a6fefb9a1455f6139265aa3708036adea902f6
|
|
||||||
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
|
||||||
(cherry picked from commit 27c2c989a3d10557da15de3d45bb5bd7b96d14e8)
|
|
||||||
---
|
|
||||||
src/qml/qml/qqmltypedata.cpp | 22 ++++++++++--
|
|
||||||
src/qml/qml/qqmltypedata_p.h | 1 +
|
|
||||||
tests/auto/qml/qqmllanguage/CMakeLists.txt | 22 +++++-------
|
|
||||||
.../qml/qqmllanguage/data/InnerObject.qml | 5 +++
|
|
||||||
.../qqmllanguage/data/ObjectWithProperty.qml | 5 +++
|
|
||||||
.../qml/qqmllanguage/data/outerObject.qml | 15 ++++++++
|
|
||||||
.../qml/qqmllanguage/tst_qqmllanguage.cpp | 36 +++++++++++++++++++
|
|
||||||
7 files changed, 90 insertions(+), 16 deletions(-)
|
|
||||||
create mode 100644 tests/auto/qml/qqmllanguage/data/InnerObject.qml
|
|
||||||
create mode 100644 tests/auto/qml/qqmllanguage/data/ObjectWithProperty.qml
|
|
||||||
create mode 100644 tests/auto/qml/qqmllanguage/data/outerObject.qml
|
|
||||||
|
|
||||||
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
|
|
||||||
index 2b189cd2644d..d0e054c5f8d2 100644
|
|
||||||
--- a/src/qml/qml/qqmltypedata.cpp
|
|
||||||
+++ b/src/qml/qml/qqmltypedata.cpp
|
|
||||||
@@ -95,7 +95,12 @@ bool QQmlTypeData::tryLoadFromDiskCache()
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
- m_compiledData = std::move(unit);
|
|
||||||
+ return loadFromDiskCache(unit);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+bool QQmlTypeData::loadFromDiskCache(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit)
|
|
||||||
+{
|
|
||||||
+ m_compiledData = unit;
|
|
||||||
|
|
||||||
QVector<QV4::CompiledData::InlineComponent> ics;
|
|
||||||
for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) {
|
|
||||||
@@ -450,7 +455,12 @@ void QQmlTypeData::done()
|
|
||||||
|
|
||||||
QV4::CompiledData::ResolvedTypeReferenceMap resolvedTypeCache;
|
|
||||||
QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
|
|
||||||
- {
|
|
||||||
+
|
|
||||||
+ // If we've pulled the CU from the memory cache, we don't need to do any verification.
|
|
||||||
+ const bool verifyCaches = !m_compiledData
|
|
||||||
+ || (m_compiledData->resolvedTypes.isEmpty() && !m_compiledData->typeNameCache);
|
|
||||||
+
|
|
||||||
+ if (verifyCaches) {
|
|
||||||
QQmlError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
|
|
||||||
if (error.isValid()) {
|
|
||||||
setError(error);
|
|
||||||
@@ -469,7 +479,7 @@ void QQmlTypeData::done()
|
|
||||||
};
|
|
||||||
|
|
||||||
// verify if any dependencies changed if we're using a cache
|
|
||||||
- if (m_document.isNull()) {
|
|
||||||
+ if (m_document.isNull() && verifyCaches) {
|
|
||||||
const QQmlError error = createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache);
|
|
||||||
if (!error.isValid() && m_compiledData->verifyChecksum(dependencyHasher)) {
|
|
||||||
setCompileUnit(m_compiledData);
|
|
||||||
@@ -512,6 +522,7 @@ void QQmlTypeData::done()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_document.isNull()) {
|
|
||||||
+ Q_ASSERT(verifyCaches);
|
|
||||||
// Compile component
|
|
||||||
compile(typeNameCache, &resolvedTypeCache, dependencyHasher);
|
|
||||||
if (isError())
|
|
||||||
@@ -656,6 +667,11 @@ void QQmlTypeData::dataReceived(const SourceCodeData &data)
|
|
||||||
|
|
||||||
void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
|
|
||||||
{
|
|
||||||
+ if (auto cu = QQmlMetaType::obtainCompilationUnit(finalUrl())) {
|
|
||||||
+ if (loadFromDiskCache(cu))
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
m_document.reset(new QmlIR::Document(isDebugging()));
|
|
||||||
QQmlIRLoader loader(unit->qmlData, m_document.data());
|
|
||||||
loader.load();
|
|
||||||
diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h
|
|
||||||
index 97419b916bc8..8ca1c4e96104 100644
|
|
||||||
--- a/src/qml/qml/qqmltypedata_p.h
|
|
||||||
+++ b/src/qml/qml/qqmltypedata_p.h
|
|
||||||
@@ -84,6 +84,7 @@ private:
|
|
||||||
using InlineComponentData = QV4::CompiledData::InlineComponentData;
|
|
||||||
|
|
||||||
bool tryLoadFromDiskCache();
|
|
||||||
+ bool loadFromDiskCache(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit);
|
|
||||||
bool loadFromSource();
|
|
||||||
void restoreIR(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit);
|
|
||||||
void continueLoadFromIR();
|
|
||||||
diff --git a/tests/auto/qml/qqmllanguage/CMakeLists.txt b/tests/auto/qml/qqmllanguage/CMakeLists.txt
|
|
||||||
index 9fff8f211872..bf5166a66505 100644
|
|
||||||
--- a/tests/auto/qml/qqmllanguage/CMakeLists.txt
|
|
||||||
+++ b/tests/auto/qml/qqmllanguage/CMakeLists.txt
|
|
||||||
@@ -35,14 +35,6 @@ qt_internal_add_test(tst_qqmllanguage
|
|
||||||
|
|
||||||
add_subdirectory(testhelper)
|
|
||||||
|
|
||||||
-#### Keys ignored in scope 1:.:.:qqmllanguage.pro:<TRUE>:
|
|
||||||
-# OTHER_FILES = "data/readonlyObjectProperty.qml"
|
|
||||||
-# QML_IMPORT_NAME = "StaticTest"
|
|
||||||
-# QML_IMPORT_VERSION = "1.0"
|
|
||||||
-
|
|
||||||
-## Scopes:
|
|
||||||
-#####################################################################
|
|
||||||
-
|
|
||||||
if(ANDROID)
|
|
||||||
# Resources:
|
|
||||||
set_source_files_properties("data/I18nType30.qml"
|
|
||||||
@@ -70,9 +62,13 @@ qt_internal_extend_target(tst_qqmllanguage CONDITION NOT ANDROID AND NOT IOS
|
|
||||||
QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
|
|
||||||
)
|
|
||||||
|
|
||||||
-set_target_properties(tst_qqmllanguage PROPERTIES
|
|
||||||
- QT_QML_MODULE_VERSION 1.0
|
|
||||||
- QT_QML_MODULE_URI StaticTest
|
|
||||||
+qt6_add_qml_module(tst_qqmllanguage
|
|
||||||
+ URI StaticTest
|
|
||||||
+ VERSION 1.0
|
|
||||||
+ QML_FILES
|
|
||||||
+ data/InnerObject.qml
|
|
||||||
+ data/ObjectWithProperty.qml
|
|
||||||
+ data/outerObject.qml
|
|
||||||
+ RESOURCE_PREFIX "/"
|
|
||||||
+ NO_GENERATE_EXTRA_QMLDIRS
|
|
||||||
)
|
|
||||||
-
|
|
||||||
-_qt_internal_qml_type_registration(tst_qqmllanguage)
|
|
||||||
diff --git a/tests/auto/qml/qqmllanguage/data/InnerObject.qml b/tests/auto/qml/qqmllanguage/data/InnerObject.qml
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..8598b5b8d243
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/auto/qml/qqmllanguage/data/InnerObject.qml
|
|
||||||
@@ -0,0 +1,5 @@
|
|
||||||
+import QtQml
|
|
||||||
+
|
|
||||||
+QtObject {
|
|
||||||
+ required property ObjectWithProperty objectWithProperty
|
|
||||||
+}
|
|
||||||
diff --git a/tests/auto/qml/qqmllanguage/data/ObjectWithProperty.qml b/tests/auto/qml/qqmllanguage/data/ObjectWithProperty.qml
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..31089f7dbd05
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/auto/qml/qqmllanguage/data/ObjectWithProperty.qml
|
|
||||||
@@ -0,0 +1,5 @@
|
|
||||||
+import QtQml
|
|
||||||
+
|
|
||||||
+QtObject {
|
|
||||||
+ property int a: 5
|
|
||||||
+}
|
|
||||||
diff --git a/tests/auto/qml/qqmllanguage/data/outerObject.qml b/tests/auto/qml/qqmllanguage/data/outerObject.qml
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..ff074fd50988
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/auto/qml/qqmllanguage/data/outerObject.qml
|
|
||||||
@@ -0,0 +1,15 @@
|
|
||||||
+import QtQml
|
|
||||||
+
|
|
||||||
+QtObject {
|
|
||||||
+ id: self
|
|
||||||
+
|
|
||||||
+ property Component delegate
|
|
||||||
+
|
|
||||||
+ property ObjectWithProperty objectWithProperty: ObjectWithProperty {}
|
|
||||||
+
|
|
||||||
+ property InnerObject innerObject: null
|
|
||||||
+
|
|
||||||
+ function doInstantiate() {
|
|
||||||
+ innerObject = delegate.createObject(self, {objectWithProperty: objectWithProperty})
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
|
|
||||||
index ed205447ddb1..4fabc4f64d9a 100644
|
|
||||||
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
|
|
||||||
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
|
|
||||||
@@ -466,6 +466,8 @@ private slots:
|
|
||||||
|
|
||||||
void overrideInnerBinding();
|
|
||||||
|
|
||||||
+ void engineTypeCrossTalk();
|
|
||||||
+
|
|
||||||
private:
|
|
||||||
QQmlEngine engine;
|
|
||||||
QStringList defaultImportPathList;
|
|
||||||
@@ -8994,6 +8996,40 @@ void tst_qqmllanguage::overrideInnerBinding()
|
|
||||||
QCOMPARE(o->property("innerWidth").toReal(), 20.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
+class EngineAndObject
|
|
||||||
+{
|
|
||||||
+public:
|
|
||||||
+ EngineAndObject(const QUrl &outer)
|
|
||||||
+ {
|
|
||||||
+ QQmlComponent component(&engine, outer);
|
|
||||||
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
|
|
||||||
+ object.reset(component.create());
|
|
||||||
+ QVERIFY(object);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ void wreck(const QUrl &inner) {
|
|
||||||
+ QQmlComponent component(&engine, inner);
|
|
||||||
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
|
|
||||||
+ object->setProperty("delegate", QVariant::fromValue(&component));
|
|
||||||
+ QMetaObject::invokeMethod(object.get(), "doInstantiate");
|
|
||||||
+ QVERIFY(object->property("innerObject").value<QObject *>() != nullptr);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ QQmlEngine engine;
|
|
||||||
+ std::unique_ptr<QObject> object;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+void tst_qqmllanguage::engineTypeCrossTalk()
|
|
||||||
+{
|
|
||||||
+ const QUrl outer("qrc:/StaticTest/data/outerObject.qml");
|
|
||||||
+ EngineAndObject first(outer);
|
|
||||||
+ EngineAndObject second(outer);
|
|
||||||
+
|
|
||||||
+ const QUrl inner("qrc:/StaticTest/data/InnerObject.qml");
|
|
||||||
+ first.wreck(inner);
|
|
||||||
+ second.wreck(inner);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
QTEST_MAIN(tst_qqmllanguage)
|
|
||||||
|
|
||||||
#include "tst_qqmllanguage.moc"
|
|
||||||
--
|
|
||||||
2.47.0
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user