diff options
author | Ulf Hermann <[email protected]> | 2022-05-05 12:17:11 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2022-05-11 12:56:21 +0200 |
commit | 745cce4391a8b6255605cb304d8bc14b11168423 (patch) | |
tree | b4b73c3530109442070eb9cb8eeaaedbe6406042 | |
parent | 2642058df8429cd593d0c7adf45a818a42fc0d88 (diff) |
QML: Port QV4::CompiledData::Object to new special integer bitfield
Pick-to: 5.15 6.2 6.3
Task-number: QTBUG-99545
Change-Id: Ia57a16313e883a8d4dab15c971181440ed1d2214
Reviewed-by: Fabian Kosmale <[email protected]>
Reviewed-by: Sami Shalayel <[email protected]>
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 57 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 4 | ||||
-rw-r--r-- | src/qml/inlinecomponentutils_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlirloader.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 16 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator_p.h | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertyvalidator.cpp | 3 | ||||
-rw-r--r-- | src/qmltest/quicktest.cpp | 2 |
10 files changed, 90 insertions, 36 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 0d2c171e5d..1c3732fd00 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -764,7 +764,12 @@ static_assert(sizeof(Alias) == 20, "Alias structure needs to have the expected s struct Object { - enum Flags : unsigned int { +private: + using FlagsField = quint32_le_bitfield_member<0, 15>; + using DefaultPropertyIsAliasField = quint32_le_bitfield_member<15, 1>; + using IdField = quint32_le_bitfield_member<16, 16, qint32>; +public: + enum Flag : unsigned int { NoFlag = 0x0, IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary HasDeferredBindings = 0x2, // any of the bindings are deferred @@ -772,17 +777,15 @@ struct Object IsInlineComponentRoot = 0x8, IsPartOfInlineComponent = 0x10 }; + Q_DECLARE_FLAGS(Flags, Flag); // Depending on the use, this may be the type name to instantiate before instantiating this // object. For grouped properties the type name will be empty and for attached properties // it will be the name of the attached type. quint32_le inheritedTypeNameIndex; quint32_le idNameIndex; - union { - quint32_le_bitfield<0, 15> flags; - quint32_le_bitfield<15, 1> defaultPropertyIsAlias; - qint32_le_bitfield<16, 16> id; - }; + quint32_le_bitfield_union<FlagsField, DefaultPropertyIsAliasField, IdField> + flagsAndDefaultPropertyIsAliasAndId; qint32_le indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object quint16_le nFunctions; quint16_le nProperties; @@ -811,6 +814,48 @@ struct Object // InlineComponent[] // RequiredPropertyExtraData[] + Flags flags() const + { + return Flags(flagsAndDefaultPropertyIsAliasAndId.get<FlagsField>()); + } + + bool hasFlag(Flag flag) const + { + return flagsAndDefaultPropertyIsAliasAndId.get<FlagsField>() & flag; + } + + void setFlag(Flag flag) + { + flagsAndDefaultPropertyIsAliasAndId.set<FlagsField>( + flagsAndDefaultPropertyIsAliasAndId.get<FlagsField>() | flag); + } + + void setFlags(Flags flags) + { + flagsAndDefaultPropertyIsAliasAndId.set<FlagsField>(flags); + } + + bool hasAliasAsDefaultProperty() const + { + return flagsAndDefaultPropertyIsAliasAndId.get<DefaultPropertyIsAliasField>(); + } + + void setHasAliasAsDefaultProperty(bool defaultAlias) + { + flagsAndDefaultPropertyIsAliasAndId.set<DefaultPropertyIsAliasField>(defaultAlias); + } + + qint32 objectId() const + { + return flagsAndDefaultPropertyIsAliasAndId.get<IdField>(); + } + + void setObjectId(qint32 id) + { + flagsAndDefaultPropertyIsAliasAndId.set<IdField>(id); + } + + static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent, int nInlineComponents, int nRequiredPropertyExtraData) { return ( sizeof(Object) diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 8a61a58486..1b0ecacdf3 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1638,10 +1638,10 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen QV4::CompiledData::Object *objectToWrite = reinterpret_cast<QV4::CompiledData::Object*>(objectPtr); objectToWrite->inheritedTypeNameIndex = o->inheritedTypeNameIndex; objectToWrite->indexOfDefaultPropertyOrAlias = o->indexOfDefaultPropertyOrAlias; - objectToWrite->defaultPropertyIsAlias = o->defaultPropertyIsAlias; - objectToWrite->flags = o->flags; + objectToWrite->setHasAliasAsDefaultProperty(o->defaultPropertyIsAlias); + objectToWrite->setFlags(QV4::CompiledData::Object::Flags(o->flags)); objectToWrite->idNameIndex = o->idNameIndex; - objectToWrite->id = o->id; + objectToWrite->setObjectId(o->id); objectToWrite->location = o->location; objectToWrite->locationOfIdProperty = o->locationOfIdProperty; diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 80376a2834..7acc3b14b2 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -393,6 +393,10 @@ public: int namedObjectsInComponentCount() const { return namedObjectsInComponent.size(); } const quint32 *namedObjectsInComponentTable() const { return namedObjectsInComponent.begin(); } + bool hasFlag(QV4::CompiledData::Object::Flag flag) const { return flags & flag; } + qint32 objectId() const { return id; } + bool hasAliasAsDefaultProperty() const { return defaultPropertyIsAlias; } + private: friend struct ::QQmlIRLoader; diff --git a/src/qml/inlinecomponentutils_p.h b/src/qml/inlinecomponentutils_p.h index ea6b24de26..742d6405ae 100644 --- a/src/qml/inlinecomponentutils_p.h +++ b/src/qml/inlinecomponentutils_p.h @@ -113,8 +113,11 @@ void fillAdjacencyListForInlineComponents(ObjectContainer *objectContainer, Adja auto referencedInICObjectIndex = ic.objectIndex + 1; while (int(referencedInICObjectIndex) < objectContainer->objectCount()) { auto potentiallyReferencedInICObject = objectContainer->objectAt(referencedInICObjectIndex); - bool stillInIC = !(potentiallyReferencedInICObject-> flags & QV4::CompiledData::Object::IsInlineComponentRoot) - && (potentiallyReferencedInICObject-> flags & QV4::CompiledData::Object::IsPartOfInlineComponent); + bool stillInIC + = !potentiallyReferencedInICObject->hasFlag( + QV4::CompiledData::Object::IsInlineComponentRoot) + && potentiallyReferencedInICObject->hasFlag( + QV4::CompiledData::Object::IsPartOfInlineComponent); if (!stillInIC) break; createEdgeFromTypeRef(objectContainer->resolvedType(potentiallyReferencedInICObject->inheritedTypeNameIndex)); diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index 1c26d7aa6b..934d7f1fb0 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -388,7 +388,7 @@ IdentifierHash ExecutableCompilationUnit::createNamedObjectsPerComponent(int com const quint32_le *namedObjectIndexPtr = component->namedObjectsInComponentTable(); for (quint32 i = 0; i < component->nNamedObjectsInComponent; ++i, ++namedObjectIndexPtr) { const CompiledData::Object *namedObject = objectAt(*namedObjectIndexPtr); - namedObjectCache.add(runtimeStrings[namedObject->idNameIndex], namedObject->id); + namedObjectCache.add(runtimeStrings[namedObject->idNameIndex], namedObject->objectId()); } Q_ASSERT(!namedObjectCache.isEmpty()); return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache); @@ -444,9 +444,10 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi int lastICRoot = ic.objectIndex; for (int i = ic.objectIndex; i<objectCount(); ++i) { const QV4::CompiledData::Object *obj = objectAt(i); - bool leftCurrentInlineComponent = - (i != lastICRoot && obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot) - || !(obj->flags & QV4::CompiledData::Object::IsPartOfInlineComponent); + bool leftCurrentInlineComponent + = (i != lastICRoot + && obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) + || !obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent); if (leftCurrentInlineComponent) break; inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings; @@ -476,9 +477,9 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi int objectCount = 0; for (quint32 i = 0, count = this->objectCount(); i < count; ++i) { const QV4::CompiledData::Object *obj = objectAt(i); - if (obj->flags & QV4::CompiledData::Object::IsPartOfInlineComponent) { + if (obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent)) continue; - } + bindingCount += obj->nBindings; if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) { const auto type = typeRef->type(); diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp index 6b8be0bb74..21bc2038c4 100644 --- a/src/qml/qml/qqmlirloader.cpp +++ b/src/qml/qml/qqmlirloader.cpp @@ -107,9 +107,9 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali serializedObject->location); object->indexOfDefaultPropertyOrAlias = serializedObject->indexOfDefaultPropertyOrAlias; - object->defaultPropertyIsAlias = serializedObject->defaultPropertyIsAlias; - object->flags = serializedObject->flags; - object->id = serializedObject->id; + object->defaultPropertyIsAlias = serializedObject->hasAliasAsDefaultProperty(); + object->flags = serializedObject->flags(); + object->id = serializedObject->objectId(); object->locationOfIdProperty = serializedObject->locationOfIdProperty; QVector<int> functionIndices; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 05eddcce29..49e05fdae0 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -811,7 +811,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper for (int i = 0, end = compilationUnit->objectCount(); i != end; ++i) { const QV4::CompiledData::Object *external = compilationUnit->objectAt(i); if (external->idNameIndex == binding->propertyNameIndex) { - bindingTarget = groupObject = context->idValue(external->id); + bindingTarget = groupObject = context->idValue(external->objectId()); break; } } @@ -1160,8 +1160,8 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location, void QQmlObjectCreator::registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const { - if (object->id >= 0) - context->setIdValue(object->id, instance); + if (object->objectId() >= 0) + context->setIdValue(object->objectId(), instance); } QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) @@ -1181,7 +1181,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo QQmlParserStatus *parserStatus = nullptr; bool installPropertyCache = true; - if (obj->flags & QV4::CompiledData::Object::IsComponent) { + if (obj->hasFlag(QV4::CompiledData::Object::IsComponent)) { isComponent = true; instance = createComponent(engine, compilationUnit.data(), index, parent, context); typeName = QStringLiteral("<component>"); @@ -1283,7 +1283,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo // an additional check const bool documentRoot = static_cast<quint32>(index) == /*root object*/ 0 || ddata->rootObjectInCreation - || (obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot); + || obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot); context->installContext( ddata, documentRoot ? QQmlContextData::DocumentRoot : QQmlContextData::OrdinaryObject); @@ -1301,7 +1301,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (isContextObject) context->setContextObject(instance); - if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) { + if (customParser && obj->hasFlag(QV4::CompiledData::Object::HasCustomParserBindings)) { customParser->engine = QQmlEnginePrivate::get(engine); customParser->imports = compilationUnit->typeNameCache.data(); @@ -1533,7 +1533,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * qSwap(_vmeMetaObject, vmeMetaObject); _ddata->compilationUnit = compilationUnit; - if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) + if (_compiledObject->hasFlag(QV4::CompiledData::Object::HasDeferredBindings)) _ddata->deferData(_compiledObjectIndex, compilationUnit, context); const qsizetype oldRequiredPropertiesCount = sharedState->requiredProperties.size(); @@ -1583,7 +1583,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * Q_ASSERT(binding->isGroupProperty()); return { 0, _propertyCache->propertyOffset() + 1 }; // 4. } - Q_ASSERT(!(_compiledObject->flags & QV4::CompiledData::Object::IsComponent)); + Q_ASSERT(!_compiledObject->hasFlag(QV4::CompiledData::Object::IsComponent)); QQmlType type = typeRef->type(); if (type.isValid() && !type.isInlineComponentType()) { return { 0, _propertyCache->propertyCount() }; // 1. diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 892b08c614..84c78a1973 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -293,7 +293,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecur const CompiledObject *obj = objectContainer->objectAt(objectIndex); bool needVMEMetaObject = isVMERequired == VMEMetaObjectIsRequired::Always || obj->propertyCount() != 0 || obj->aliasCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0 || obj->enumCount() != 0 - || (((obj->flags & QV4::CompiledData::Object::IsComponent) + || ((obj->hasFlag(QV4::CompiledData::Object::IsComponent) || (objectIndex == 0 && isAddressable(objectContainer->url()))) && !objectContainer->resolvedType(obj->inheritedTypeNameIndex)->isFullyDynamicType()); @@ -727,7 +727,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject( QString propertyName = stringAt(p->nameIndex); - if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias) + if (!obj->hasAliasAsDefaultProperty() && propertyIdx == obj->indexOfDefaultPropertyOrAlias) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, propertyType, propertyTypeVersion, effectiveSignalIndex); @@ -813,7 +813,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie // from a binding. for (int i = 1; i < objectContainer->objectCount(); ++i) { const CompiledObject &component = *objectContainer->objectAt(i); - if (!(component.flags & QV4::CompiledData::Object::IsComponent)) + if (!component.hasFlag(QV4::CompiledData::Object::IsComponent)) continue; const auto rootBinding = component.bindingsBegin(); @@ -884,7 +884,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl objectsWithAliases->append(objectIndex); // Stop at Component boundary - if (object.flags & QV4::CompiledData::Object::IsComponent && objectIndex != /*root object*/0) + if (object.hasFlag(QV4::CompiledData::Object::IsComponent) && objectIndex != /*root object*/0) return; auto binding = object.bindingsBegin(); @@ -1054,7 +1054,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo const QString propertyName = objectContainer->stringAt(alias->nameIndex); - if (object.defaultPropertyIsAlias && aliasIndex == object.indexOfDefaultPropertyOrAlias) + if (object.hasAliasAsDefaultProperty() && aliasIndex == object.indexOfDefaultPropertyOrAlias) propertyCache->_defaultPropertyName = propertyName; propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, @@ -1070,7 +1070,7 @@ inline int QQmlPropertyCacheAliasCreator<ObjectContainer>::objectForId(const Com for (quint32 i = 0, count = component.namedObjectsInComponentCount(); i < count; ++i) { const int candidateIndex = component.namedObjectsInComponentTable()[i]; const CompiledObject &candidate = *objectContainer->objectAt(candidateIndex); - if (candidate.id == id) + if (candidate.objectId() == id) return candidateIndex; } return -1; diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 06a6acc229..fb4d4875d6 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -109,7 +109,8 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( return errors; } - if (obj->flags & QV4::CompiledData::Object::IsComponent && !(obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot)) { + if (obj->hasFlag(QV4::CompiledData::Object::IsComponent) + && !obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) { Q_ASSERT(obj->nBindings == 1); const QV4::CompiledData::Binding *componentBinding = obj->bindingTable(); Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index da631cb5ec..d8689124c2 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -302,7 +302,7 @@ private: if (!object) // Start at root of compilation unit if not enumerating a specific child object = compilationUnit->objectAt(0); - if (object->flags & Object::IsInlineComponentRoot) + if (object->hasFlag(Object::IsInlineComponentRoot)) return result; if (const auto superTypeUnit = compilationUnit->resolvedTypes.value( |