diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-12-20 15:47:43 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-01-08 22:30:11 +0100 |
commit | 933f80f345cb04df6ecafe9c76f262553a5a198c (patch) | |
tree | 336ab12536d67c5e6f38b7428cc9d940a75eca0d | |
parent | 796dd2ab8c7b0e85f2469df9b79f65ca62719c8b (diff) |
QtQml: Move engine-specific data out of base compilation unit
We want to re-use the base compilation unit for different engines. To do
that, we cannot have data in there that belongs to a specific engine.
Pick-to: 6.7
Task-number: QTBUG-120189
Change-Id: I8e43e7ec6c1cd33249dc4ed15fec16babc6d06fb
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 64 | ||||
-rw-r--r-- | src/qml/jit/qv4assemblercommon_p.h | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4baselineassembler.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 36 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlbuiltinfunctions.cpp | 3 | ||||
-rw-r--r-- | tests/auto/toolsupport/tst_toolsupport.cpp | 7 |
8 files changed, 58 insertions, 71 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 1a97ddc5a5..f033a43aaa 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE // Also change the comment behind the number to describe the latest change. This has the added // benefit that if another patch changes the version too, it will result in a merge conflict, and // not get removed silently. -#define QV4_DATA_STRUCTURE_VERSION 0x3E // Add Translator pragma +#define QV4_DATA_STRUCTURE_VERSION 0x3F // Refactor compilation units class QIODevice; class QQmlTypeNameCache; @@ -1421,48 +1421,7 @@ using DependentTypesHasher = std::function<QByteArray()>; // This is how this hooks into the existing structures: -struct CompilationUnitBase -{ - Q_DISABLE_COPY(CompilationUnitBase) - - CompilationUnitBase() = default; - ~CompilationUnitBase() = default; - - CompilationUnitBase(CompilationUnitBase &&other) noexcept { *this = std::move(other); } - - CompilationUnitBase &operator=(CompilationUnitBase &&other) noexcept - { - if (this != &other) { - runtimeStrings = other.runtimeStrings; - other.runtimeStrings = nullptr; - constants = other.constants; - other.constants = nullptr; - runtimeRegularExpressions = other.runtimeRegularExpressions; - other.runtimeRegularExpressions = nullptr; - runtimeClasses = other.runtimeClasses; - other.runtimeClasses = nullptr; - imports = other.imports; - other.imports = nullptr; - } - return *this; - } - - // pointers either to data->constants() or little-endian memory copy. - Heap::String **runtimeStrings = nullptr; // Array - const StaticValue* constants = nullptr; - QV4::StaticValue *runtimeRegularExpressions = nullptr; - Heap::InternalClass **runtimeClasses = nullptr; - const StaticValue** imports = nullptr; -}; - -Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value); -Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0); -Q_STATIC_ASSERT(offsetof(CompilationUnitBase, constants) == sizeof(QV4::Heap::String **)); -Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offsetof(CompilationUnitBase, constants) + sizeof(const StaticValue *)); -Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeClasses) == offsetof(CompilationUnitBase, runtimeRegularExpressions) + sizeof(const StaticValue *)); -Q_STATIC_ASSERT(offsetof(CompilationUnitBase, imports) == offsetof(CompilationUnitBase, runtimeClasses) + sizeof(const StaticValue *)); - -struct CompilationUnit : public CompilationUnitBase +struct CompilationUnit { Q_DISABLE_COPY(CompilationUnit) @@ -1470,6 +1429,9 @@ struct CompilationUnit : public CompilationUnitBase const QmlUnit *qmlData = nullptr; QStringList dynamicStrings; const QQmlPrivate::AOTCompiledFunction *aotCompiledFunctions = nullptr; + + // pointers either to data->constants() or little-endian memory copy. + const StaticValue *constants = nullptr; public: using CompiledObject = CompiledData::Object; @@ -1501,9 +1463,6 @@ public: delete [] constants; constants = nullptr; #endif - - delete [] imports; - imports = nullptr; } CompilationUnit(CompilationUnit &&other) noexcept @@ -1519,15 +1478,15 @@ public: qmlData = other.qmlData; other.qmlData = nullptr; dynamicStrings = std::move(other.dynamicStrings); - aotCompiledFunctions = other.aotCompiledFunctions; other.dynamicStrings.clear(); + aotCompiledFunctions = other.aotCompiledFunctions; + other.aotCompiledFunctions = nullptr; + constants = other.constants; + other.constants = nullptr; m_fileName = std::move(other.m_fileName); other.m_fileName.clear(); m_finalUrlString = std::move(other.m_finalUrlString); other.m_finalUrlString.clear(); - m_module = other.m_module; - other.m_module = nullptr; - CompilationUnitBase::operator=(std::move(other)); } return *this; } @@ -1577,9 +1536,6 @@ public: QString fileName() const { return m_fileName; } QString finalUrlString() const { return m_finalUrlString; } - Heap::Module *module() const { return m_module; } - void setModule(Heap::Module *module) { m_module = module; } - QString bindingValueAsString(const CompiledData::Binding *binding) const { using namespace CompiledData; @@ -1621,8 +1577,6 @@ public: private: QString m_fileName; // initialized from data->sourceFileIndex QString m_finalUrlString; // initialized from data->finalUrlIndex - - Heap::Module *m_module = nullptr; }; class SaveableUnitPointer diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index 6840dab340..e83608ae23 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -562,7 +562,7 @@ public: Address loadConstAddress(int constIndex, RegisterID baseReg = ScratchRegister) { Address addr = loadCompilationUnitPtr(baseReg); - addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, constants); + addr.offset = offsetof(QV4::CompilationUnitRuntimeData, constants); loadPtr(addr, baseReg); addr.offset = constIndex * int(sizeof(QV4::Value)); return addr; @@ -571,7 +571,7 @@ public: Address loadStringAddress(int stringId) { Address addr = loadCompilationUnitPtr(ScratchRegister); - addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, runtimeStrings); + addr.offset = offsetof(QV4::CompilationUnitRuntimeData, runtimeStrings); loadPtr(addr, ScratchRegister); return Address(ScratchRegister, stringId * PointerSize); } diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp index 156266a234..496624c752 100644 --- a/src/qml/jit/qv4baselineassembler.cpp +++ b/src/qml/jit/qv4baselineassembler.cpp @@ -903,7 +903,7 @@ void BaselineAssembler::storeHeapObject(int reg) void BaselineAssembler::loadImport(int index) { Address addr = pasm()->loadCompilationUnitPtr(PlatformAssembler::ScratchRegister); - addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, imports); + addr.offset = offsetof(QV4::CompilationUnitRuntimeData, imports); pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister); addr.offset = index * int(sizeof(QV4::Value*)); pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister); diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index c0c5f341e5..2ab38b70d9 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -57,10 +57,13 @@ ExecutableCompilationUnit::ExecutableCompilationUnit() = default; ExecutableCompilationUnit::ExecutableCompilationUnit( CompiledData::CompilationUnit &&compilationUnit) : CompiledData::CompilationUnit(std::move(compilationUnit)) -{} +{ + CompilationUnitRuntimeData::constants = CompiledData::CompilationUnit::constants; +} ExecutableCompilationUnit::~ExecutableCompilationUnit() { + delete [] imports; unlink(); } @@ -219,7 +222,7 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE"); if (showCode) { qDebug() << "=== Constant table"; - dumpConstantTable(constants, data->constantTableSize); + dumpConstantTable(CompiledData::CompilationUnit::constants, data->constantTableSize); qDebug() << "=== String table"; for (uint i = 0, end = totalStringCount(); i < end; ++i) qDebug() << " " << i << ":" << runtimeStrings[i]->toQString(); @@ -887,6 +890,7 @@ bool ExecutableCompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &s dataPtrRevert.dismiss(); free(const_cast<CompiledData::Unit*>(oldDataPtr)); backingFile = std::move(cacheFile); + CompilationUnitRuntimeData::constants = CompiledData::CompilationUnit::constants; return true; } diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 4cd1ce204e..6b29760d35 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -65,8 +65,34 @@ struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*> bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const; }; +struct CompilationUnitRuntimeData +{ + Heap::String **runtimeStrings = nullptr; // Array + + // pointers either to data->constants() or little-endian memory copy. + // We keep this member twice so that the JIT can access it via standard layout. + const StaticValue *constants = nullptr; + + QV4::StaticValue *runtimeRegularExpressions = nullptr; + Heap::InternalClass **runtimeClasses = nullptr; + const StaticValue **imports = nullptr; + + QV4::Lookup *runtimeLookups = nullptr; + QVector<QV4::Function *> runtimeFunctions; + QVector<QV4::Heap::InternalClass *> runtimeBlocks; + mutable QVector<QV4::Heap::Object *> templateObjects; +}; + +static_assert(std::is_standard_layout_v<CompilationUnitRuntimeData>); +static_assert(offsetof(CompilationUnitRuntimeData, runtimeStrings) == 0); +static_assert(offsetof(CompilationUnitRuntimeData, constants) == sizeof(QV4::Heap::String **)); +static_assert(offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) == offsetof(CompilationUnitRuntimeData, constants) + sizeof(const StaticValue *)); +static_assert(offsetof(CompilationUnitRuntimeData, runtimeClasses) == offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) + sizeof(const StaticValue *)); +static_assert(offsetof(CompilationUnitRuntimeData, imports) == offsetof(CompilationUnitRuntimeData, runtimeClasses) + sizeof(const StaticValue *)); + class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final : public CompiledData::CompilationUnit, + public CompilationUnitRuntimeData, public QQmlRefCounted<ExecutableCompilationUnit> { Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit) @@ -113,10 +139,6 @@ public: return m_finalUrl; } - QV4::Lookup *runtimeLookups = nullptr; - QVector<QV4::Function *> runtimeFunctions; - QVector<QV4::Heap::InternalClass *> runtimeBlocks; - mutable QVector<QV4::Heap::Object *> templateObjects; mutable QQmlNullableValue<QUrl> m_url; mutable QQmlNullableValue<QUrl> m_finalUrl; @@ -322,11 +344,17 @@ public: static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp, QString *errorString); + + Heap::Module *module() const { return m_module; } + void setModule(Heap::Module *module) { m_module = module; } + protected: quint32 totalStringCount() const { return data->stringTableSize; } private: + Heap::Module *m_module = nullptr; + struct ResolveSetEntry { ResolveSetEntry() {} diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 57d0deb734..6cefae8fa8 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -30,8 +30,9 @@ struct QQmlSourceLocation; namespace QV4 { -struct Q_QML_EXPORT FunctionData { - CompiledData::CompilationUnitBase *compilationUnit; +struct Q_QML_EXPORT FunctionData +{ + CompilationUnitRuntimeData *compilationUnit; // Intentionally require an ExecutableCompilationUnit but save only a pointer to // CompilationUnitBase. This is so that we can take advantage of the standard layout diff --git a/src/qml/qml/qqmlbuiltinfunctions.cpp b/src/qml/qml/qqmlbuiltinfunctions.cpp index 24de6cc069..c23e8f8914 100644 --- a/src/qml/qml/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/qqmlbuiltinfunctions.cpp @@ -2173,8 +2173,7 @@ QString GlobalExtensions::currentTranslationContext(ExecutionEngine *engine) // The first non-empty source URL in the call stack determines the translation context. while (frame && context.isEmpty()) { - if (CompiledData::CompilationUnitBase *baseUnit = frame->v4Function->compilationUnit) { - const auto *unit = static_cast<const CompiledData::CompilationUnit *>(baseUnit); + if (ExecutableCompilationUnit *unit = frame->v4Function->executableCompilationUnit()) { auto translationContextIndex = unit->data->translationContextIndex(); if (translationContextIndex) context = unit->stringAt(*translationContextIndex); diff --git a/tests/auto/toolsupport/tst_toolsupport.cpp b/tests/auto/toolsupport/tst_toolsupport.cpp index bf7a06e305..486d760511 100644 --- a/tests/auto/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/toolsupport/tst_toolsupport.cpp @@ -9,6 +9,7 @@ #include <private/qobject_p.h> #include <private/qv4compileddata_p.h> +#include <private/qv4executablecompilationunit_p.h> #include <private/qv4string_p.h> #include <private/qqmlrefcount_p.h> #include <qobject.h> @@ -77,13 +78,13 @@ void tst_toolsupport::offsets_data() = QTest::newRow("CompiledData::CompilationUnit::data") << pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::data); - data << 20 << 40; + data << 0 << 0; } { QTestData &data - = QTest::newRow("CompiledData::CompilationUnit::runtimeStrings") - << pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::runtimeStrings); + = QTest::newRow("ExecutableCompilationUnit::runtimeStrings") + << pmm_to_offsetof(&QV4::ExecutableCompilationUnit::runtimeStrings); data << 0 << 0; } |