diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-04-10 14:22:58 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-04-16 13:40:22 +0000 |
commit | 379342c64db71745edb2bf9a9a100fd1798dbf69 (patch) | |
tree | 70e319f5d341be5cb3e21c0b5f32cf339b5af858 /src/qml | |
parent | b220a20552838fbafbbf126b9e50d148ae76518d (diff) |
Speed up copying of value types in bindings
When a binding results in a value type reference and the destination property
is of the same time, then we can avoid a heap allocation and just allocate
the value type memory on the stack, construct, copy and destruct.
Change-Id: If71ef82b0ced85c1b962c5e44147d6c07edd1440
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 25 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper_p.h | 1 |
3 files changed, 32 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 931adb9a13..ae452b727e 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -53,6 +53,7 @@ #include <QStringList> #include <private/qmetaobject_p.h> +#include <private/qqmlvaluetypewrapper_p.h> #include <QtCore/qdebug.h> Q_DECLARE_METATYPE(QList<int>) @@ -1519,6 +1520,11 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, QUICK_STORE(QString, result.toQStringNoThrow()) break; default: + if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) { + if (vtw->d()->valueType->typeId == core.propType) { + return vtw->write(object, core.coreIndex); + } + } break; } } diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 90ffe0d525..397068f5d9 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -264,6 +264,31 @@ int QQmlValueTypeWrapper::typeId() const return d()->valueType->typeId; } +bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const +{ + bool destructGadgetOnExit = false; + if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) { + if (!d()->gadgetPtr) { + d()->gadgetPtr = alloca(d()->valueType->metaType.sizeOf()); + d()->valueType->metaType.construct(d()->gadgetPtr, 0); + destructGadgetOnExit = true; + } + if (!ref->readReferenceValue()) + return false; + } + + int flags = 0; + int status = -1; + void *a[] = { d()->gadgetPtr, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, propertyIndex, a); + + if (destructGadgetOnExit) { + d()->valueType->metaType.destruct(d()->gadgetPtr); + d()->gadgetPtr = 0; + } + return true; +} + ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) { Object *o = ctx->thisObject().asObject(); diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index 6118511852..cad48e661c 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -87,6 +87,7 @@ public: bool toGadget(void *data) const; bool isEqual(const QVariant& value); int typeId() const; + bool write(QObject *target, int propertyIndex) const; static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); |