aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-07-04 14:43:10 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2019-07-05 16:31:45 +0200
commite203418096e66f2173d05788e5cb18e79141e772 (patch)
treea686a081985b9c120d83f6399af8b65fc7669aaa /src
parent2024df6604dbb78f5eee6f61e73fb0d2fc3bb008 (diff)
Reduce the size of Property fields in type compilation data
We can shave off 4 bytes of each property declaration by sharing the bits for the custom type name index or the builtin type enum. Change-Id: I77071cbef66c5a83b3e7e281dba3a435d3c68b39 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp25
-rw-r--r--src/qml/compiler/qv4compileddata_p.h31
-rw-r--r--src/qml/qml/qqmlpropertycachecreator.cpp3
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h40
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp51
5 files changed, 81 insertions, 69 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 8bdbab3b5a..6c61473418 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -872,13 +872,15 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
} else {
const QStringRef &name = node->name;
+ Property *property = New<Property>();
+ property->isReadOnly = node->isReadonlyMember;
+
bool typeFound = false;
- QV4::CompiledData::Property::Type type = QV4::CompiledData::Property::Var;
for (int ii = 0; !typeFound && ii < propTypeNameToTypesCount; ++ii) {
const TypeNameToType *t = propTypeNameToTypes + ii;
if (memberType == QLatin1String(t->name, static_cast<int>(t->nameLength))) {
- type = t->type;
+ property->setBuiltinType(t->type);
typeFound = true;
}
}
@@ -886,11 +888,10 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
if (!typeFound && memberType.at(0).isUpper()) {
const QStringRef &typeModifier = node->typeModifier;
- if (typeModifier.isEmpty()) {
- type = QV4::CompiledData::Property::Custom;
- } else if (typeModifier == QLatin1String("list")) {
- type = QV4::CompiledData::Property::CustomList;
- } else {
+ property->setCustomType(registerString(memberType));
+ if (typeModifier == QLatin1String("list")) {
+ property->isList = true;
+ } else if (!typeModifier.isEmpty()) {
recordError(node->typeModifierToken, QCoreApplication::translate("QQmlParser","Invalid property type modifier"));
return false;
}
@@ -905,14 +906,6 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
return false;
}
- Property *property = New<Property>();
- property->isReadOnly = node->isReadonlyMember;
- property->type = type;
- if (type >= QV4::CompiledData::Property::Custom)
- property->customTypeNameIndex = registerString(memberType);
- else
- property->customTypeNameIndex = emptyStringIndex;
-
const QString propName = name.toString();
property->nameIndex = registerString(propName);
@@ -1530,7 +1523,7 @@ bool IRBuilder::isStatementNodeScript(QQmlJS::AST::Statement *statement)
bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement)
{
- if (property->type != QV4::CompiledData::Property::Custom)
+ if (property->isBuiltinType || property->isList)
return false;
QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(statement);
if (!exprStmt)
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 9123f9f0ec..639595509a 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -642,18 +642,35 @@ struct Property
{
enum Type : unsigned int { Var = 0, Variant, Int, Bool, Real, String, Url, Color,
Font, Time, Date, DateTime, Rect, Point, Size,
- Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion,
- Custom, CustomList };
+ Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion, InvalidBuiltin };
quint32_le nameIndex;
union {
- quint32_le_bitfield<0, 31> type;
+ quint32_le_bitfield<0, 29> builtinTypeOrTypeNameIndex;
+ quint32_le_bitfield<29, 1> isBuiltinType;
+ quint32_le_bitfield<30, 1> isList;
quint32_le_bitfield<31, 1> isReadOnly;
};
- quint32_le customTypeNameIndex; // If type >= Custom
+
Location location;
+
+ void setBuiltinType(Type t)
+ {
+ builtinTypeOrTypeNameIndex = t;
+ isBuiltinType = true;
+ }
+ Type builtinType() const {
+ if (isBuiltinType)
+ return static_cast<Type>(quint32(builtinTypeOrTypeNameIndex));
+ return InvalidBuiltin;
+ }
+ void setCustomType(int nameIndex)
+ {
+ builtinTypeOrTypeNameIndex = nameIndex;
+ isBuiltinType = false;
+ }
};
-static_assert(sizeof(Property) == 16, "Property 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(Property) == 12, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Alias {
enum Flags : unsigned int {
@@ -1044,8 +1061,8 @@ struct TypeReferenceMap : QHash<int, TypeReference>
auto prop = obj->propertiesBegin();
auto propEnd = obj->propertiesEnd();
for ( ; prop != propEnd; ++prop) {
- if (prop->type >= QV4::CompiledData::Property::Custom) {
- TypeReference &r = this->add(prop->customTypeNameIndex, prop->location);
+ if (!prop->isBuiltinType) {
+ TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex, prop->location);
r.errorWhenNotFound = true;
}
}
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index 822241d58c..6e492f7a80 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -69,8 +69,7 @@ int QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(QV4::CompiledData::Pro
case QV4::CompiledData::Property::Vector4D: return QMetaType::QVector4D;
case QV4::CompiledData::Property::Matrix4x4: return QMetaType::QMatrix4x4;
case QV4::CompiledData::Property::Quaternion: return QMetaType::QQuaternion;
- case QV4::CompiledData::Property::Custom: break;
- case QV4::CompiledData::Property::CustomList: break;
+ case QV4::CompiledData::Property::InvalidBuiltin: break;
};
return QMetaType::UnknownType;
}
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index e227301175..5421e2c61b 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -304,7 +304,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
auto p = obj->propertiesBegin();
auto pend = obj->propertiesEnd();
for ( ; p != pend; ++p) {
- if (p->type == QV4::CompiledData::Property::Var)
+ if (p->builtinType() == QV4::CompiledData::Property::Var)
varPropCount++;
bool notInRevision = false;
@@ -477,20 +477,22 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
int propertTypeMinorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- if (p->type == QV4::CompiledData::Property::Var) {
- propertyType = QMetaType::QVariant;
+ const QV4::CompiledData::Property::Type type = p->builtinType();
+
+ if (type == QV4::CompiledData::Property::Var)
propertyFlags.type = QQmlPropertyData::Flags::VarPropertyType;
- } else if (p->type < QV4::CompiledData::Property::Custom) {
- propertyType = metaTypeForPropertyType(static_cast<QV4::CompiledData::Property::Type>(quint32(p->type)));
- if (p->type == QV4::CompiledData::Property::Variant)
+
+ if (type != QV4::CompiledData::Property::InvalidBuiltin) {
+ propertyType = metaTypeForPropertyType(type);
+
+ if (type == QV4::CompiledData::Property::Variant)
propertyFlags.type = QQmlPropertyData::Flags::QVariantType;
} else {
- Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList ||
- p->type == QV4::CompiledData::Property::Custom);
+ Q_ASSERT(!p->isBuiltinType);
QQmlType qmltype;
- if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, nullptr, nullptr, nullptr)) {
+ if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr)) {
return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
}
@@ -502,27 +504,27 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea
auto compilationUnit = tdata->compilationUnit();
- if (p->type == QV4::CompiledData::Property::Custom) {
- propertyType = compilationUnit->metaTypeId;
- } else {
+ if (p->isList) {
propertyType = compilationUnit->listMetaTypeId;
+ } else {
+ propertyType = compilationUnit->metaTypeId;
}
} else {
- if (p->type == QV4::CompiledData::Property::Custom) {
+ if (p->isList) {
+ propertyType = qmltype.qListTypeId();
+ } else {
propertyType = qmltype.typeId();
propertTypeMinorVersion = qmltype.minorVersion();
- } else {
- propertyType = qmltype.qListTypeId();
}
}
- if (p->type == QV4::CompiledData::Property::Custom)
- propertyFlags.type = QQmlPropertyData::Flags::QObjectDerivedType;
- else
+ if (p->isList)
propertyFlags.type = QQmlPropertyData::Flags::QListType;
+ else
+ propertyFlags.type = QQmlPropertyData::Flags::QObjectDerivedType;
}
- if (!p->isReadOnly && p->type != QV4::CompiledData::Property::CustomList)
+ if (!p->isReadOnly && !p->isList)
propertyFlags.isWritable = true;
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index e26dc4d9aa..d210b049df 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -639,7 +639,8 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
id -= propOffset();
if (id < propertyCount) {
- const QV4::CompiledData::Property::Type t = static_cast<QV4::CompiledData::Property::Type>(qint32(compiledObject->propertyTable()[id].type));
+ const QV4::CompiledData::Property &property = compiledObject->propertyTable()[id];
+ const QV4::CompiledData::Property::Type t = property.builtinType();
// the context can be null if accessing var properties from cpp after re-parenting an item.
QQmlEnginePrivate *ep = (ctxt == nullptr || ctxt->engine == nullptr) ? nullptr : QQmlEnginePrivate::get(ctxt->engine);
@@ -678,22 +679,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
case QV4::CompiledData::Property::Point:
*reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
break;
- case QV4::CompiledData::Property::Custom:
- *reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
- break;
case QV4::CompiledData::Property::Variant:
*reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
break;
- case QV4::CompiledData::Property::CustomList: {
- QList<QObject *> *list = readPropertyAsList(id);
- QQmlListProperty<QObject> *p = static_cast<QQmlListProperty<QObject> *>(a[0]);
- *p = QQmlListProperty<QObject>(object, list,
- list_append, list_count, list_at,
- list_clear);
- p->dummy1 = this;
- p->dummy2 = reinterpret_cast<void *>(quintptr(methodOffset() + id));
- break;
- }
case QV4::CompiledData::Property::Font:
case QV4::CompiledData::Property::Time:
case QV4::CompiledData::Property::Color:
@@ -718,6 +706,18 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
*reinterpret_cast<QVariant *>(a[0]) = QVariant();
}
break;
+ case QV4::CompiledData::Property::InvalidBuiltin:
+ if (property.isList) {
+ QList<QObject *> *list = readPropertyAsList(id);
+ QQmlListProperty<QObject> *p = static_cast<QQmlListProperty<QObject> *>(a[0]);
+ *p = QQmlListProperty<QObject>(object, list,
+ list_append, list_count, list_at,
+ list_clear);
+ p->dummy1 = this;
+ p->dummy2 = reinterpret_cast<void *>(quintptr(methodOffset() + id));
+ } else {
+ *reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
+ }
}
} else if (c == QMetaObject::WriteProperty) {
@@ -763,17 +763,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
needActivate = *reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
writeProperty(id, *reinterpret_cast<QPointF *>(a[0]));
break;
- case QV4::CompiledData::Property::Custom:
- needActivate = *reinterpret_cast<QObject **>(a[0]) != readPropertyAsQObject(id);
- writeProperty(id, *reinterpret_cast<QObject **>(a[0]));
- break;
case QV4::CompiledData::Property::Variant:
writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
break;
- case QV4::CompiledData::Property::CustomList:
- // Writing such a property is not supported. Content is added through the list property
- // methods.
- break;
case QV4::CompiledData::Property::Font:
case QV4::CompiledData::Property::Time:
case QV4::CompiledData::Property::Color:
@@ -798,6 +790,15 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if (ep)
writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
break;
+ case QV4::CompiledData::Property::InvalidBuiltin:
+ if (property.isList) {
+ // Writing such a property is not supported. Content is added through the list property
+ // methods.
+ } else {
+ needActivate = *reinterpret_cast<QObject **>(a[0]) != readPropertyAsQObject(id);
+ writeProperty(id, *reinterpret_cast<QObject **>(a[0]));
+ }
+
}
if (needActivate)
@@ -965,7 +966,7 @@ QV4::ReturnedValue QQmlVMEMetaObject::method(int index) const
QV4::ReturnedValue QQmlVMEMetaObject::readVarProperty(int id) const
{
- Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].type == QV4::CompiledData::Property::Var);
+ Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].builtinType() == QV4::CompiledData::Property::Var);
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
@@ -990,7 +991,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) const
void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
{
- Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].type == QV4::CompiledData::Property::Var);
+ Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].builtinType() == QV4::CompiledData::Property::Var);
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
@@ -1030,7 +1031,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
{
- if (compiledObject && compiledObject->propertyTable()[id].type == QV4::CompiledData::Property::Var) {
+ if (compiledObject && compiledObject->propertyTable()[id].builtinType() == QV4::CompiledData::Property::Var) {
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
return;