From 8e45a7b2b66d998c941c1c66bdabc240decd5474 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 3 Dec 2009 16:09:31 +1000 Subject: Optimization --- src/declarative/graphicsitems/qmlgraphicsitem.cpp | 12 +- src/declarative/qml/qmlcompiler.cpp | 28 ++-- src/declarative/qml/qmlcompiler_p.h | 3 + src/declarative/qml/qmlmetaproperty.cpp | 168 ++++++++++------------ src/declarative/qml/qmlmetaproperty_p.h | 23 +-- src/declarative/qml/qmlpropertycache.cpp | 33 ++++- src/declarative/qml/qmlpropertycache_p.h | 23 ++- src/declarative/qml/qmlvme.cpp | 13 +- 8 files changed, 166 insertions(+), 137 deletions(-) diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index d02ab1c..cb34c1f 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -1442,13 +1442,23 @@ QmlGraphicsKeysAttached *QmlGraphicsKeysAttached::qmlAttachedProperties(QObject \internal */ -static inline void qfxitem_registerAnchorLine() { +static int qfxitem_registerAnchorLine() { + /* static bool registered = false; if (!registered) { qRegisterMetaType("QmlGraphicsAnchorLine"); registered = true; } + */ } +// ### Must fix +struct RegisterAnchorLineAtStartup { + RegisterAnchorLineAtStartup() { + qRegisterMetaType("QmlGraphicsAnchorLine"); + } +}; +static RegisterAnchorLineAtStartup registerAnchorLineAtStartup; + /*! \fn QmlGraphicsItem::QmlGraphicsItem(QmlGraphicsItem *parent) diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 7a31673..c8e9fa3 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1577,11 +1577,10 @@ void QmlCompiler::genPropertyAssignment(QmlParser::Property *prop, store.type = QmlInstruction::StoreValueSource; store.line = v->object->location.start.line; if (valueTypeProperty) { - store.assignValueSource.property = QmlMetaPropertyPrivate::saveValueType(valueTypeProperty->index, prop->index); + store.assignValueSource.property = genValueTypeData(prop, valueTypeProperty); store.assignValueSource.owner = 1; } else { - store.assignValueSource.property = - QmlMetaPropertyPrivate::saveProperty(prop->index); + store.assignValueSource.property = genPropertyData(prop); store.assignValueSource.owner = 0; } QmlType *valueType = QmlMetaType::qmlType(v->object->metatype); @@ -1595,11 +1594,10 @@ void QmlCompiler::genPropertyAssignment(QmlParser::Property *prop, store.type = QmlInstruction::StoreValueInterceptor; store.line = v->object->location.start.line; if (valueTypeProperty) { - store.assignValueInterceptor.property = QmlMetaPropertyPrivate::saveValueType(valueTypeProperty->index, prop->index); + store.assignValueInterceptor.property = genValueTypeData(prop, valueTypeProperty); store.assignValueInterceptor.owner = 1; } else { - store.assignValueInterceptor.property = - QmlMetaPropertyPrivate::saveProperty(prop->index); + store.assignValueInterceptor.property = genPropertyData(prop); store.assignValueInterceptor.owner = 0; } QmlType *valueType = QmlMetaType::qmlType(v->object->metatype); @@ -2467,12 +2465,9 @@ void QmlCompiler::genBindingAssignment(QmlParser::Value *binding, Q_ASSERT(ref.bindingContext.owner == 0 || (ref.bindingContext.owner != 0 && valueTypeProperty)); if (ref.bindingContext.owner) { - store.assignBinding.property = - QmlMetaPropertyPrivate::saveValueType(valueTypeProperty->index, - prop->index); + store.assignBinding.property = genValueTypeData(prop, valueTypeProperty); } else { - store.assignBinding.property = - QmlMetaPropertyPrivate::saveProperty(prop->index); + store.assignBinding.property = genPropertyData(prop); } output->bytecode << store; @@ -2494,6 +2489,17 @@ int QmlCompiler::genContextCache() return output->contextCaches.count() - 1; } +int QmlCompiler::genValueTypeData(QmlParser::Property *valueTypeProp, + QmlParser::Property *prop) +{ + return output->indexForByteArray(QmlMetaPropertyPrivate::saveValueType(prop->parent->metaObject(), prop->index, valueTypeProp->index, valueTypeProp->type)); +} + +int QmlCompiler::genPropertyData(QmlParser::Property *prop) +{ + return output->indexForByteArray(QmlMetaPropertyPrivate::saveProperty(prop->parent->metaObject(), prop->index)); +} + bool QmlCompiler::completeComponentBuild() { componentStat.ids = compileState.ids.count(); diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 542fb48..f7f72e7 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -246,6 +246,9 @@ private: QmlParser::Property *valueTypeProperty = 0); int genContextCache(); + int genValueTypeData(QmlParser::Property *prop, QmlParser::Property *valueTypeProp); + int genPropertyData(QmlParser::Property *prop); + int componentTypeRef(); static int findSignalByName(const QMetaObject *, const QByteArray &name); diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 5a1c327..44fa3d6 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -293,7 +293,7 @@ const char *QmlMetaProperty::propertyTypeName() const else valueType = QmlValueTypeFactory::valueType(d->core.propType); Q_ASSERT(valueType); - const char *rv = valueType->metaObject()->property(d->valueTypeCoreIdx).typeName(); + const char *rv = valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).typeName(); if (!ep) delete valueType; @@ -315,8 +315,7 @@ bool QmlMetaProperty::operator==(const QmlMetaProperty &other) const // from the other members return d->object == other.d->object && d->core == other.d->core && - d->valueTypeCoreIdx == other.d->valueTypeCoreIdx && - d->valueTypePropType == other.d->valueTypePropType && + d->valueType == other.d->valueType && d->attachedFunc == other.d->attachedFunc; } @@ -333,7 +332,7 @@ int QmlMetaPropertyPrivate::propertyType() const { uint type = q->type(); if (type & QmlMetaProperty::ValueTypeProperty) { - return valueTypePropType; + return valueType.valueTypePropType; } else if (type & QmlMetaProperty::Attached) { return qMetaTypeId(); } else if (type & QmlMetaProperty::Property) { @@ -355,7 +354,7 @@ QmlMetaProperty::Type QmlMetaProperty::type() const return SignalProperty; else if (d->attachedFunc != -1) return Attached; - else if (d->valueTypeCoreIdx != -1) + else if (d->valueType.valueTypeCoreIdx != -1) return (Type)(Property | ValueTypeProperty); else if (d->core.isValid()) return (Type)(Property | ((d->isDefaultProperty)?Default:0)); @@ -398,8 +397,7 @@ QmlMetaProperty &QmlMetaProperty::operator=(const QmlMetaProperty &other) d->isDefaultProperty = other.d->isDefaultProperty; d->core = other.d->core; - d->valueTypeCoreIdx = other.d->valueTypeCoreIdx; - d->valueTypePropType = other.d->valueTypePropType; + d->valueType = other.d->valueType; d->attachedFunc = other.d->attachedFunc; return *this; @@ -449,29 +447,34 @@ bool QmlMetaProperty::isValid() const */ QString QmlMetaProperty::name() const { - if (type() & ValueTypeProperty) { - QString rv = d->core.name + QLatin1String("."); + if (!d->isNameCached) { + // ### + if (!d->object) { + } else if (type() & ValueTypeProperty) { + QString rv = d->core.name(d->object) + QLatin1String("."); - QmlEnginePrivate *ep = d->context?QmlEnginePrivate::get(d->context->engine()):0; - QmlValueType *valueType = 0; - if (ep) valueType = ep->valueTypes[d->core.propType]; - else valueType = QmlValueTypeFactory::valueType(d->core.propType); - Q_ASSERT(valueType); + QmlEnginePrivate *ep = d->context?QmlEnginePrivate::get(d->context->engine()):0; + QmlValueType *valueType = 0; + if (ep) valueType = ep->valueTypes[d->core.propType]; + else valueType = QmlValueTypeFactory::valueType(d->core.propType); + Q_ASSERT(valueType); - rv += QString::fromUtf8(valueType->metaObject()->property(d->valueTypeCoreIdx).name()); + rv += QString::fromUtf8(valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).name()); - if (!ep) delete valueType; + if (!ep) delete valueType; - return rv; - } else { - if (type() & SignalProperty) { - QString name = QLatin1String("on") + d->core.name; + d->nameCache = rv; + } else if (type() & SignalProperty) { + QString name = QLatin1String("on") + d->core.name(d->object); name[2] = name.at(2).toUpper(); - return name; + d->nameCache = name; } else { - return d->core.name; + d->nameCache = d->core.name(d->object); } + d->isNameCached = true; } + + return d->nameCache; } /*! @@ -694,7 +697,7 @@ QVariant QmlMetaPropertyPrivate::readValueProperty() valueType->read(object, core.coreIndex); QVariant rv = - valueType->metaObject()->property(valueTypeCoreIdx).read(valueType); + valueType->metaObject()->property(this->valueType.valueTypeCoreIdx).read(valueType); if (!ep) delete valueType; return rv; @@ -769,8 +772,8 @@ bool QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value, writeBack->read(object, core.coreIndex); QmlPropertyCache::Data data = core; - data.coreIndex = valueTypeCoreIdx; - data.propType = valueTypePropType; + data.coreIndex = valueType.valueTypeCoreIdx; + data.propType = valueType.valueTypePropType; rv = write(writeBack, data, value, context, flags); writeBack->write(object, core.coreIndex, flags); @@ -1048,92 +1051,65 @@ int QmlMetaProperty::coreIndex() const /*! \internal */ int QmlMetaProperty::valueTypeCoreIndex() const { - return d->valueTypeCoreIdx; + return d->valueType.valueTypeCoreIdx; } Q_GLOBAL_STATIC(QmlValueTypeFactory, qmlValueTypes); -/*! - Returns the property information serialized into a single integer. - QmlMetaProperty uses the bottom 24 bits only. -*/ -quint32 QmlMetaPropertyPrivate::saveValueType(int core, int valueType) + +struct SerializedData { + QmlMetaProperty::Type type; + QmlPropertyCache::Data core; +}; + +struct ValueTypeSerializedData : public SerializedData { + QmlPropertyCache::ValueTypeData valueType; +}; + +QByteArray QmlMetaPropertyPrivate::saveValueType(const QMetaObject *metaObject, int index, + int subIndex, int subType) { - Q_ASSERT(core <= 0x7FF); - Q_ASSERT(valueType <= 0x7F); - quint32 rv = 0; - rv = (QmlMetaProperty::ValueTypeProperty | QmlMetaProperty::Property) << 18; - rv |= core; - rv |= valueType << 11; + ValueTypeSerializedData sd; + sd.type = QmlMetaProperty::ValueTypeProperty; + sd.core.load(metaObject->property(index)); + sd.valueType.valueTypeCoreIdx = subIndex; + sd.valueType.valueTypePropType = subType; + + QByteArray rv((const char *)&sd, sizeof(sd)); return rv; } -quint32 QmlMetaPropertyPrivate::saveProperty(int core) +QByteArray QmlMetaPropertyPrivate::saveProperty(const QMetaObject *metaObject, int index) { - Q_ASSERT(core <= 0x7FF); - quint32 rv = 0; - rv = (QmlMetaProperty::Property) << 18; - rv |= core; + SerializedData sd; + sd.type = QmlMetaProperty::Property; + sd.core.load(metaObject->property(index)); + + QByteArray rv((const char *)&sd, sizeof(sd)); return rv; } -/*! - Restore a QmlMetaProperty from a previously saved \a id. - \a obj must be the same object as used in the previous call - to QmlMetaProperty::save(). Only the bottom 24-bits are - used, the high bits can be set to any value. -*/ -void QmlMetaPropertyPrivate::restore(QmlMetaProperty &prop, quint32 id, - QObject *obj, QmlContext *ctxt) +QmlMetaProperty +QmlMetaPropertyPrivate::restore(const QByteArray &data, QObject *object, QmlContext *ctxt) { - QmlMetaPropertyPrivate *d = prop.d; + QmlMetaProperty prop; - QmlEnginePrivate *enginePrivate = 0; - if (ctxt && ctxt->engine()) - enginePrivate = QmlEnginePrivate::get(ctxt->engine()); - - d->object = obj; - d->context = ctxt; - - id &= 0xFFFFFF; - uint type = id >> 18; - id &= 0xFFFF; - - if (type & QmlMetaProperty::Attached) { - d->attachedFunc = id; - } else if (type & QmlMetaProperty::ValueTypeProperty) { - int coreIdx = id & 0x7FF; - int valueTypeIdx = id >> 11; - - QMetaProperty p(obj->metaObject()->property(coreIdx)); - Q_ASSERT(p.type() < QVariant::UserType); - - QmlValueType *valueType = qmlValueTypes()->valueTypes[p.type()]; - - QMetaProperty p2(valueType->metaObject()->property(valueTypeIdx)); - - d->core.load(p); - d->valueTypeCoreIdx = valueTypeIdx; - d->valueTypePropType = p2.userType(); - } else if (type & QmlMetaProperty::Property) { - - QmlPropertyCache *cache = enginePrivate?enginePrivate->cache(obj):0; - - if (cache) { - QmlPropertyCache::Data *data = cache->property(id); - if (data) d->core = *data; - } else { - QMetaProperty p(obj->metaObject()->property(id)); - d->core.load(p); - } + if (data.isEmpty()) + return prop; - } else if (type & QmlMetaProperty::SignalProperty) { + prop.d->object = object; + prop.d->context = ctxt; - QMetaMethod method = obj->metaObject()->method(id); - d->core.load(method); - } else { - prop = QmlMetaProperty(); + const SerializedData *sd = (const SerializedData *)data.constData(); + if (sd->type == QmlMetaProperty::Property) { + prop.d->core = sd->core; + } else if(sd->type == QmlMetaProperty::ValueTypeProperty) { + const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd; + prop.d->core = vt->core; + prop.d->valueType = vt->valueType; } + + return prop; } /*! @@ -1166,8 +1142,8 @@ QmlMetaProperty QmlMetaProperty::createProperty(QObject *obj, QMetaProperty vtProp = typeObject->metaObject()->property(idx); QmlMetaProperty p = prop; - p.d->valueTypeCoreIdx = idx; - p.d->valueTypePropType = vtProp.userType(); + p.d->valueType.valueTypeCoreIdx = idx; + p.d->valueType.valueTypePropType = vtProp.userType(); return p; } diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h index d225afa..4315c71 100644 --- a/src/declarative/qml/qmlmetaproperty_p.h +++ b/src/declarative/qml/qmlmetaproperty_p.h @@ -64,25 +64,26 @@ class QmlMetaPropertyPrivate { public: QmlMetaPropertyPrivate() - : q(0), context(0), object(0), isDefaultProperty(false), valueTypeCoreIdx(-1), - valueTypePropType(0), attachedFunc(-1) {} + : q(0), context(0), object(0), isDefaultProperty(false), isNameCached(false), + attachedFunc(-1) {} QmlMetaPropertyPrivate(const QmlMetaPropertyPrivate &other) : q(0), context(other.context), object(other.object), - isDefaultProperty(other.isDefaultProperty), core(other.core), - valueTypeCoreIdx(other.valueTypeCoreIdx), - valueTypePropType(other.valueTypePropType), attachedFunc(other.attachedFunc) {} + isDefaultProperty(other.isDefaultProperty), isNameCached(other.isNameCached), + core(other.core), nameCache(other.nameCache), + valueType(other.valueType), attachedFunc(other.attachedFunc) {} QmlMetaProperty *q; QmlContext *context; QGuard object; - bool isDefaultProperty; + bool isDefaultProperty:1; + bool isNameCached:1; QmlPropertyCache::Data core; + QString nameCache; // Describes the "virtual" value-type sub-property. - int valueTypeCoreIdx; // The prop index of the access property on the value type wrapper - int valueTypePropType; // The QVariant::Type of access property on the value type wrapper + QmlPropertyCache::ValueTypeData valueType; // The attached property accessor int attachedFunc; @@ -104,9 +105,9 @@ public: static QmlAbstractBinding *setBinding(QObject *, const QmlPropertyCache::Data &, QmlAbstractBinding *, QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding); - static void Q_AUTOTEST_EXPORT restore(QmlMetaProperty &prop, quint32, QObject *, QmlContext * = 0); - static quint32 Q_AUTOTEST_EXPORT saveValueType(int, int); - static quint32 Q_AUTOTEST_EXPORT saveProperty(int); + static QByteArray saveValueType(const QMetaObject *, int, int, int); + static QByteArray saveProperty(const QMetaObject *, int); + static QmlMetaProperty restore(const QByteArray &, QObject *, QmlContext * = 0); static bool equal(const QMetaObject *, const QMetaObject *); static bool canConvert(const QMetaObject *from, const QMetaObject *to); diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp index 89d66b1..7efeb82 100644 --- a/src/declarative/qml/qmlpropertycache.cpp +++ b/src/declarative/qml/qmlpropertycache.cpp @@ -54,7 +54,6 @@ void QmlPropertyCache::Data::load(const QMetaProperty &p) propType = qMetaTypeId(); coreIndex = p.propertyIndex(); notifyIndex = p.notifySignalIndex(); - name = QString::fromUtf8(p.name()); if (p.isConstant()) flags |= Data::IsConstant; @@ -80,11 +79,6 @@ void QmlPropertyCache::Data::load(const QMetaProperty &p) void QmlPropertyCache::Data::load(const QMetaMethod &m) { - name = QString::fromUtf8(m.signature()); - int parenIdx = name.indexOf(QLatin1Char('(')); - Q_ASSERT(parenIdx != -1); - name = name.left(parenIdx); - coreIndex = m.methodIndex(); flags |= Data::IsFunction; } @@ -224,4 +218,31 @@ QmlPropertyCache::property(const QString &str) const return stringCache.value(str); } +QString QmlPropertyCache::Data::name(QObject *object) +{ + if (!object) + return QString(); + + return name(object->metaObject()); +} + +QString QmlPropertyCache::Data::name(const QMetaObject *metaObject) +{ + if (!metaObject || coreIndex == -1) + return QString(); + + if (flags & IsFunction) { + QMetaMethod m = metaObject->method(coreIndex); + + QString name = QString::fromUtf8(m.signature()); + int parenIdx = name.indexOf(QLatin1Char('(')); + if (parenIdx != -1) + name = name.left(parenIdx); + return name; + } else { + QMetaProperty p = metaObject->property(coreIndex); + return QString::fromUtf8(p.name()); + } +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h index 8f19a8b..e4efc04 100644 --- a/src/declarative/qml/qmlpropertycache_p.h +++ b/src/declarative/qml/qmlpropertycache_p.h @@ -78,7 +78,7 @@ public: IsWritable = 0x00000002, // These are mutually exclusive - IsFunction = 0x00000004, + IsFunction = 0x00000004, IsQObjectDerived = 0x00000008, IsEnumType = 0x00000010, IsQmlList = 0x00000020, @@ -94,18 +94,19 @@ public: int propType; int coreIndex; int notifyIndex; - QString name; void load(const QMetaProperty &); void load(const QMetaMethod &); + QString name(QObject *); + QString name(const QMetaObject *); }; -#if 0 struct ValueTypeData { + inline ValueTypeData(); + inline bool operator==(const ValueTypeData &); int valueTypeCoreIdx; // The prop index of the access property on the value type wrapper int valueTypePropType; // The QVariant::Type of access property on the value type wrapper }; -#endif static QmlPropertyCache *create(QmlEngine *, const QMetaObject *); static Data create(const QMetaObject *, const QString &); @@ -142,8 +143,7 @@ bool QmlPropertyCache::Data::operator==(const QmlPropertyCache::Data &other) return flags == other.flags && propType == other.propType && coreIndex == other.coreIndex && - notifyIndex == other.notifyIndex && - name == other.name; + notifyIndex == other.notifyIndex; } QmlPropertyCache::Data * @@ -152,6 +152,17 @@ QmlPropertyCache::property(const QScriptDeclarativeClass::Identifier &id) const return identifierCache.value(id); } +QmlPropertyCache::ValueTypeData::ValueTypeData() +: valueTypeCoreIdx(-1), valueTypePropType(0) +{ +} + +bool QmlPropertyCache::ValueTypeData::operator==(const ValueTypeData &o) +{ + return valueTypeCoreIdx == o.valueTypeCoreIdx && + valueTypePropType == o.valueTypePropType; +} + QT_END_NAMESPACE #endif // QMLPROPERTYCACHE_P_H diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 3968d8d..d3ffce2 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -589,8 +589,8 @@ QObject *QmlVME::run(QmlVMEStack &stack, QmlContext *ctxt, QObject *context = stack.at(stack.count() - 1 - instr.assignBinding.context); - QmlMetaProperty mp; - QmlMetaPropertyPrivate::restore(mp, instr.assignBinding.property, target, ctxt); + QmlMetaProperty mp = + QmlMetaPropertyPrivate::restore(datas.at(instr.assignBinding.property), target, ctxt); int coreIndex = mp.coreIndex(); @@ -646,8 +646,9 @@ QObject *QmlVME::run(QmlVMEStack &stack, QmlContext *ctxt, QObject *obj = stack.pop(); QmlPropertyValueSource *vs = reinterpret_cast(reinterpret_cast(obj) + instr.assignValueSource.castValue); QObject *target = stack.at(stack.count() - 1 - instr.assignValueSource.owner); - QmlMetaProperty prop; - QmlMetaPropertyPrivate::restore(prop, instr.assignValueSource.property, target, ctxt); + + QmlMetaProperty prop = + QmlMetaPropertyPrivate::restore(datas.at(instr.assignValueSource.property), target, ctxt); obj->setParent(target); vs->setTarget(prop); } @@ -658,8 +659,8 @@ QObject *QmlVME::run(QmlVMEStack &stack, QmlContext *ctxt, QObject *obj = stack.pop(); QmlPropertyValueInterceptor *vi = reinterpret_cast(reinterpret_cast(obj) + instr.assignValueInterceptor.castValue); QObject *target = stack.at(stack.count() - 1 - instr.assignValueInterceptor.owner); - QmlMetaProperty prop; - QmlMetaPropertyPrivate::restore(prop, instr.assignValueInterceptor.property, target, ctxt); + QmlMetaProperty prop = + QmlMetaPropertyPrivate::restore(datas.at(instr.assignValueInterceptor.property), target, ctxt); obj->setParent(target); vi->setTarget(prop); QmlVMEMetaObject *mo = static_cast((QMetaObject*)target->metaObject()); -- cgit v0.12