aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-12-20 15:47:43 +0100
committerUlf Hermann <ulf.hermann@qt.io>2024-01-08 22:30:11 +0100
commit933f80f345cb04df6ecafe9c76f262553a5a198c (patch)
tree336ab12536d67c5e6f38b7428cc9d940a75eca0d
parent796dd2ab8c7b0e85f2469df9b79f65ca62719c8b (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.h64
-rw-r--r--src/qml/jit/qv4assemblercommon_p.h4
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp2
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp8
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h36
-rw-r--r--src/qml/jsruntime/qv4function_p.h5
-rw-r--r--src/qml/qml/qqmlbuiltinfunctions.cpp3
-rw-r--r--tests/auto/toolsupport/tst_toolsupport.cpp7
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;
}