aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-07-20 15:41:29 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-07-31 07:28:47 +0000
commit2ee5331d8ae73c0abde129eb26df4ca000470007 (patch)
tree748ef5bdf37fce8c5d8acdc448ddb7ac430f11dd /src/qml/compiler
parentfcf9b7efa5b2a0d8f49e59b2a977b8122632aff6 (diff)
Shrink CompiledData::Binding by 8 bytes
Move the translation data out into a separately indexed table, which allows to shrunk the value union down to 4 bytes, together with the previous commit. Saves ~4k with examples/quickcontrols/extras/flat/Content.qml and ~37K RAM with the gallery. Task-number: QTBUG-69588 Change-Id: Ia5016b072320ebb6b8fcfbb4dad128d53c901c74 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp8
-rw-r--r--src/qml/compiler/qv4compileddata.cpp16
-rw-r--r--src/qml/compiler/qv4compileddata_p.h23
-rw-r--r--src/qml/compiler/qv4compiler.cpp15
-rw-r--r--src/qml/compiler/qv4compiler_p.h3
5 files changed, 46 insertions, 19 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 1f6a702e4a..d5d7d6d6b0 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1120,6 +1120,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg
} else {
return; // first argument is not a string, stop
}
+ translationData.stringIndex = jsGenerator->registerString(translation.toString());
args = args->next;
@@ -1144,8 +1145,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg
return; // too many arguments, stop
binding->type = QV4::CompiledData::Binding::Type_Translation;
- binding->stringIndex = jsGenerator->registerString(translation.toString());
- binding->value.translationData = translationData;
+ binding->value.translationDataIndex = jsGenerator->registerTranslation(translationData);
} else if (base == QLatin1String("qsTrId")) {
QV4::CompiledData::TranslationData translationData;
translationData.number = -1;
@@ -1160,6 +1160,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg
} else {
return; // first argument is not a string, stop
}
+ translationData.stringIndex = jsGenerator->registerString(id.toString());
args = args->next;
@@ -1176,8 +1177,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg
return; // too many arguments, stop
binding->type = QV4::CompiledData::Binding::Type_TranslationById;
- binding->stringIndex = jsGenerator->registerString(id.toString());
- binding->value.translationData = translationData;
+ binding->value.translationDataIndex = jsGenerator->registerTranslation(translationData);
} else if (base == QLatin1String("QT_TR_NOOP") || base == QLatin1String("QT_TRID_NOOP")) {
if (!args || !args->expression)
return; // no arguments, stop
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 3e3859d9fb..357c6fc04a 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -604,23 +604,25 @@ QString Binding::valueAsString(const CompilationUnit *unit) const
#if !QT_CONFIG(translation)
case Type_TranslationById:
case Type_Translation:
- return unit->stringAt(stringIndex);
+ return unit->stringAt(unit->unitData->translations()[value.translationDataIndex].stringIndex);
#else
case Type_TranslationById: {
- QByteArray id = unit->stringAt(stringIndex).toUtf8();
- return qtTrId(id.constData(), value.translationData.number);
+ const TranslationData &translation = unit->unitData()->translations()[value.translationDataIndex];
+ QByteArray id = unit->stringAt(translation.stringIndex).toUtf8();
+ return qtTrId(id.constData(), translation.number);
}
case Type_Translation: {
+ const TranslationData &translation = unit->unitData()->translations()[value.translationDataIndex];
// This code must match that in the qsTr() implementation
- const QString &path = unit->stringAt(unit->data->sourceFileIndex);
+ const QString &path = unit->stringAt(unit->unitData()->sourceFileIndex);
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
QStringRef context = (lastSlash > -1) ? path.midRef(lastSlash + 1, path.length() - lastSlash - 5)
: QStringRef();
QByteArray contextUtf8 = context.toUtf8();
- QByteArray comment = unit->stringAt(value.translationData.commentIndex).toUtf8();
- QByteArray text = unit->stringAt(stringIndex).toUtf8();
+ QByteArray comment = unit->stringAt(translation.commentIndex).toUtf8();
+ QByteArray text = unit->stringAt(translation.stringIndex).toUtf8();
return QCoreApplication::translate(contextUtf8.constData(), text.constData(),
- comment.constData(), value.translationData.number);
+ comment.constData(), translation.number);
}
#endif
default:
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 7bbc4d2835..20e8db528e 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -362,11 +362,14 @@ static_assert(sizeof(Class) == 24, "Class structure needs to have the expected s
// Qml data structures
-struct Q_QML_EXPORT TranslationData {
+struct Q_QML_EXPORT TranslationData
+{
+ quint32_le stringIndex;
quint32_le commentIndex;
qint32_le number;
+ quint32_le padding;
};
-static_assert(sizeof(TranslationData) == 8, "TranslationData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(TranslationData) == 16, "TranslationData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Q_QML_PRIVATE_EXPORT Binding
{
@@ -407,15 +410,13 @@ struct Q_QML_PRIVATE_EXPORT Binding
quint32_le constantValueIndex;
quint32_le compiledScriptIndex; // used when Type_Script
quint32_le objectIndex;
- TranslationData translationData; // used when Type_Translation
+ quint32_le translationDataIndex; // used when Type_Translation
} value;
- quint32_le stringIndex; // Set for Type_String, Type_Translation and Type_Script (the latter because of script strings)
+ quint32_le stringIndex; // Set for Type_String and Type_Script (the latter because of script strings)
Location location;
Location valueLocation;
- quint32_le padding;
-
bool isValueBinding() const
{
if (type == Type_AttachedProperty
@@ -490,7 +491,7 @@ struct Q_QML_PRIVATE_EXPORT Binding
};
-static_assert(sizeof(Binding) == 32, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Binding) == 24, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct EnumValue
{
@@ -799,6 +800,8 @@ struct Unit
quint32_le offsetToConstantTable;
quint32_le jsClassTableSize;
quint32_le offsetToJSClassTable;
+ quint32_le translationTableSize;
+ quint32_le offsetToTranslationTable;
qint32_le indexOfRootFunction;
quint32_le sourceFileIndex;
quint32_le finalUrlIndex;
@@ -889,9 +892,13 @@ struct Unit
*nMembers = klass->nMembers;
return reinterpret_cast<const JSClassMember*>(ptr + sizeof(JSClass));
}
+
+ const TranslationData *translations() const {
+ return reinterpret_cast<const TranslationData *>(reinterpret_cast<const char *>(this) + offsetToTranslationTable);
+ }
};
-static_assert(sizeof(Unit) == 208, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Unit) == 216, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct TypeReference
{
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index a2afc7fefe..252056b2b6 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -208,6 +208,12 @@ int QV4::Compiler::JSUnitGenerator::registerJSClass(const QStringList &members)
return jsClassOffsets.size() - 1;
}
+int QV4::Compiler::JSUnitGenerator::registerTranslation(const QV4::CompiledData::TranslationData &translation)
+{
+ translations.append(translation);
+ return translations.size() - 1;
+}
+
QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorOption option)
{
registerString(module->fileName);
@@ -286,6 +292,8 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
jsClassOffsetTable[i] = jsClassDataOffset + jsClassOffsets.at(i);
}
+ memcpy(dataPtr + unit->offsetToTranslationTable, translations.constData(), translations.count() * sizeof(CompiledData::TranslationData));
+
// write strings and string table
if (option == GenerateWithStringTable)
stringTable.serialize(unit);
@@ -521,6 +529,12 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
nextOffset = (nextOffset + 7) & ~quint32(0x7);
+ unit.translationTableSize = translations.count();
+ unit.offsetToTranslationTable = nextOffset;
+ nextOffset += unit.translationTableSize * sizeof(CompiledData::TranslationData);
+
+ nextOffset = (nextOffset + 7) & ~quint32(0x7);
+
quint32 functionSize = 0;
for (int i = 0; i < module->functions.size(); ++i) {
@@ -575,6 +589,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
if (showStats) {
qDebug() << "Generated JS unit that is" << unit.unitSize << "bytes contains:";
qDebug() << " " << functionSize << "bytes for non-code function data for" << unit.functionTableSize << "functions";
+ qDebug() << " " << translations.count() * sizeof(CompiledData::TranslationData) << "bytes for" << translations.count() << "translations";
}
return unit;
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index 944c44b1ff..381b6fad21 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -120,6 +120,8 @@ struct Q_QML_PRIVATE_EXPORT JSUnitGenerator {
int registerJSClass(const QStringList &members);
+ int registerTranslation(const CompiledData::TranslationData &translation);
+
enum GeneratorOption {
GenerateWithStringTable,
GenerateWithoutStringTable
@@ -142,6 +144,7 @@ private:
QVector<ReturnedValue> constants;
QByteArray jsClassData;
QVector<int> jsClassOffsets;
+ QVector<CompiledData::TranslationData> translations;
};
}