diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2022-05-05 12:17:11 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-06-24 15:21:04 +0200 |
commit | 8ca617a178c316124e4c50f79dded853e889f140 (patch) | |
tree | b4005d7304d2e637180aea62b9b504ae22aef1c7 | |
parent | eb2257e8443777adbd455dc54ce507a10f832618 (diff) |
QML: Port QV4::CompiledData::Object to new special integer bitfield
Task-number: QTBUG-99545
Change-Id: Ia57a16313e883a8d4dab15c971181440ed1d2214
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
(cherry picked from commit 745cce4391a8b6255605cb304d8bc14b11168423)
-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 | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 12 | ||||
-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, 35 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 1b137a0826..f818e45d11 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -872,7 +872,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 @@ -880,17 +885,15 @@ struct Object IsInlineComponentRoot = 0x8, InPartOfInlineComponent = 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; @@ -919,6 +922,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 15b333584e..bc4b537a6f 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1672,10 +1672,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 665c90215d..7cf6492471 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -394,6 +394,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 b00d6b96cc..aba15709c2 100644 --- a/src/qml/inlinecomponentutils_p.h +++ b/src/qml/inlinecomponentutils_p.h @@ -121,8 +121,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::InPartOfInlineComponent); + bool stillInIC + = !potentiallyReferencedInICObject->hasFlag( + QV4::CompiledData::Object::IsInlineComponentRoot) + && potentiallyReferencedInICObject->hasFlag( + QV4::CompiledData::Object::InPartOfInlineComponent); if (!stillInIC) break; createEdgeFromTypeRef(objectContainer->resolvedType(potentiallyReferencedInICObject->inheritedTypeNameIndex)); diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index b6c6138da5..5cf496255f 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -368,7 +368,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()); } return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache); } @@ -425,9 +425,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::InPartOfInlineComponent); + bool leftCurrentInlineComponent + = (i != lastICRoot + && obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) + || !obj->hasFlag(QV4::CompiledData::Object::InPartOfInlineComponent); if (leftCurrentInlineComponent) break; inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings; @@ -457,9 +458,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::InPartOfInlineComponent) { + if (obj->hasFlag(QV4::CompiledData::Object::InPartOfInlineComponent)) continue; - } + bindingCount += obj->nBindings; if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) { if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1) diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp index 7805f014f8..3c82ffd146 100644 --- a/src/qml/qml/qqmlirloader.cpp +++ b/src/qml/qml/qqmlirloader.cpp @@ -94,10 +94,11 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali object->init(pool, serializedObject->inheritedTypeNameIndex, serializedObject->idNameIndex); object->indexOfDefaultPropertyOrAlias = serializedObject->indexOfDefaultPropertyOrAlias; - object->defaultPropertyIsAlias = serializedObject->defaultPropertyIsAlias; - object->isInlineComponent = serializedObject->flags & QV4::CompiledData::Object::IsInlineComponentRoot; - object->flags = serializedObject->flags; - object->id = serializedObject->id; + object->defaultPropertyIsAlias = serializedObject->hasAliasAsDefaultProperty(); + object->isInlineComponent = serializedObject->hasFlag( + QV4::CompiledData::Object::IsInlineComponentRoot); + object->flags = serializedObject->flags(); + object->id = serializedObject->objectId(); object->location = serializedObject->location; object->locationOfIdProperty = serializedObject->locationOfIdProperty; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0d6fbe6f36..3b875d5253 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1155,8 +1155,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->setIdProperty(object->id, instance); + if (object->objectId() >= 0) + context->setIdProperty(object->objectId(), instance); } void QQmlObjectCreator::createQmlContext() @@ -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; QQmlComponent *component = new QQmlComponent(engine, compilationUnit.data(), index, parent); typeName = QStringLiteral("<component>"); @@ -1279,7 +1279,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo ddata->setImplicitDestructible(); // inline components are root objects, but their index is != 0, so we need // an additional check - const bool isInlineComponent = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot; + const bool isInlineComponent = obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot); if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation || isInlineComponent) { if (ddata->context) { Q_ASSERT(ddata->context != context); @@ -1312,7 +1312,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (isContextObject) context->contextObject = 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(); @@ -1517,7 +1517,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * qSwap(_propertyCache, cache); qSwap(_vmeMetaObject, vmeMetaObject); - if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) + if (_compiledObject->hasFlag(QV4::CompiledData::Object::HasDeferredBindings)) _ddata->deferData(_compiledObjectIndex, compilationUnit, context); QSet<QString> postHocRequired; diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 8ebbe07e37..ebee50cc79 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -226,7 +226,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); @@ -618,7 +618,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int propertyFlags.setIsWritable(true); 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, propertTypeMinorVersion, effectiveSignalIndex); @@ -704,7 +704,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(); @@ -774,7 +774,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(); @@ -941,7 +941,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++, @@ -957,7 +957,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 8bb95045a4..f3947a73d4 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -104,7 +104,8 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( validateObject(it->objectIndex, /* instantiatingBinding*/ nullptr); } - 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 40f957ae0d..6f168989c0 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -309,7 +309,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( |