From a166367bd877a55e552e3dfe5cf2ee7fa1561100 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 5 Oct 2016 12:18:20 +0200 Subject: QML: Move the ScarceResourceData from VariantObject onto the heap So now VariantObject is nearly a trivial struct. Change-Id: Ifc54c04d9686c03e12066c5287823dd3b1315d2a Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlvaluetypewrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/qml/qqmlvaluetypewrapper.cpp') diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 6b308374e6..2279b72cbe 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -230,7 +230,7 @@ bool QQmlValueTypeWrapper::isEqualTo(Managed *m, Managed *other) QV4::QQmlValueTypeWrapper *lv = static_cast(m); if (QV4::VariantObject *rv = other->as()) - return lv->isEqual(rv->d()->data); + return lv->isEqual(rv->d()->data()); if (QV4::QQmlValueTypeWrapper *v = other->as()) return lv->isEqual(v->toVariant()); -- cgit v1.2.3 From 3b14e2ffdd8eb4b7f7f4508768b75f2acc399370 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 9 Sep 2016 15:37:57 +0200 Subject: QML: Make Heap::Object and all subclasses trivial GCC6 might dead-store-eliminate out our secret write to Base::mmdata, because it expects all memory content to be "undefined" before constructor calls. Clang might take the same approach if the constructor of Heap::Object is removed. By making these structs trivial, it also makes them memcpy-able. Change-Id: I055b2ad28311b997fbe059849ebda4d5894eaa9b Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlvaluetypewrapper.cpp | 39 +++++++++++++++++------------------- 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'src/qml/qml/qqmlvaluetypewrapper.cpp') diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 2279b72cbe..11849d2c63 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -63,8 +63,11 @@ namespace Heap { struct QQmlValueTypeReference : QQmlValueTypeWrapper { - QQmlValueTypeReference() { object.init(); } - ~QQmlValueTypeReference() { object.destroy(); } + void init() { + QQmlValueTypeWrapper::init(); + object.init(); + } + void destroy() { object.destroy(); } QQmlQPointer object; int property; }; @@ -86,7 +89,7 @@ DEFINE_OBJECT_VTABLE(QV4::QQmlValueTypeReference); using namespace QV4; -Heap::QQmlValueTypeWrapper::~QQmlValueTypeWrapper() +void Heap::QQmlValueTypeWrapper::destroy() { if (gadgetPtr) { valueType->metaType.destruct(gadgetPtr); @@ -140,7 +143,7 @@ bool QQmlValueTypeReference::readReferenceValue() const ::operator delete(d()->gadgetPtr); } d()->gadgetPtr =0; - d()->propertyCache = cache; + d()->setPropertyCache(cache); d()->valueType = QQmlValueTypeFactory::valueType(variantReferenceType); if (!cache) return false; @@ -163,7 +166,7 @@ bool QQmlValueTypeReference::readReferenceValue() const void QQmlValueTypeWrapper::initProto(ExecutionEngine *v4) { - if (v4->valueTypeWrapperPrototype()->d()) + if (v4->valueTypeWrapperPrototype()->d_unchecked()) return; Scope scope(v4); @@ -180,7 +183,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj Scoped r(scope, engine->memoryManager->allocObject()); r->d()->object = object; r->d()->property = property; - r->d()->propertyCache = QJSEnginePrivate::get(engine)->cache(metaObject); + r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject)); r->d()->valueType = QQmlValueTypeFactory::valueType(typeId); r->d()->gadgetPtr = 0; return r->asReturnedValue(); @@ -192,7 +195,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria initProto(engine); Scoped r(scope, engine->memoryManager->allocObject()); - r->d()->propertyCache = QJSEnginePrivate::get(engine)->cache(metaObject); + r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject)); r->d()->valueType = QQmlValueTypeFactory::valueType(typeId); r->d()->gadgetPtr = 0; r->d()->setValue(value); @@ -218,12 +221,6 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const return true; } -void QQmlValueTypeWrapper::destroy(Heap::Base *that) -{ - Heap::QQmlValueTypeWrapper *w = static_cast(that); - w->Heap::QQmlValueTypeWrapper::~QQmlValueTypeWrapper(); -} - bool QQmlValueTypeWrapper::isEqualTo(Managed *m, Managed *other) { Q_ASSERT(m && m->as() && other); @@ -243,7 +240,7 @@ PropertyAttributes QQmlValueTypeWrapper::query(const Managed *m, String *name) Q_ASSERT(m->as()); const QQmlValueTypeWrapper *r = static_cast(m); - QQmlPropertyData *result = r->d()->propertyCache->property(name, 0, 0); + QQmlPropertyData *result = r->d()->propertyCache()->property(name, 0, 0); return result ? Attr_Data : Attr_Invalid; } @@ -259,8 +256,8 @@ void QQmlValueTypeWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value return; } - if (that->d()->propertyCache) { - const QMetaObject *mo = that->d()->propertyCache->createMetaObject(); + if (that->d()->propertyCache()) { + const QMetaObject *mo = that->d()->propertyCache()->createMetaObject(); const int propertyCount = mo->propertyCount(); if (it->arrayIndex < static_cast(propertyCount)) { Scope scope(that->engine()); @@ -335,7 +332,7 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) } else { result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId)) + QLatin1Char('('); - const QMetaObject *mo = w->d()->propertyCache->metaObject(); + const QMetaObject *mo = w->d()->propertyCache()->metaObject(); const int propCount = mo->propertyCount(); for (int i = 0; i < propCount; ++i) { if (mo->property(i).isDesignable()) { @@ -362,7 +359,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha return Primitive::undefinedValue().asReturnedValue(); } - QQmlPropertyData *result = r->d()->propertyCache->property(name, 0, 0); + QQmlPropertyData *result = r->d()->propertyCache()->property(name, 0, 0); if (!result) return Object::get(m, name, hasProperty); @@ -381,7 +378,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha return QV4::Encode(constructor(v)); \ } - const QMetaObject *metaObject = r->d()->propertyCache->metaObject(); + const QMetaObject *metaObject = r->d()->propertyCache()->metaObject(); int index = result->coreIndex(); QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(QMetaObject::ReadProperty, &metaObject, &index); @@ -429,8 +426,8 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) writeBackPropertyType = writebackProperty.userType(); } - const QMetaObject *metaObject = r->d()->propertyCache->metaObject(); - const QQmlPropertyData *pd = r->d()->propertyCache->property(name, 0, 0); + const QMetaObject *metaObject = r->d()->propertyCache()->metaObject(); + const QQmlPropertyData *pd = r->d()->propertyCache()->property(name, 0, 0); if (!pd) return; -- cgit v1.2.3 From 57c9d6969ac474177c77d5ea59768b39620a3b2f Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 9 Sep 2016 16:20:57 +0200 Subject: QML: Also check for correct destroy() chaining Check that the destroy() method of Heap::Base was called when a Managed object needs destruction. This checks if a call to the parent's destroy() method was accidentally omitted. Change-Id: Id025ecd6d4744bf3eab23503fbe317ed2a461138 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlvaluetypewrapper.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/qml/qml/qqmlvaluetypewrapper.cpp') diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 11849d2c63..b23bc033d1 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -67,7 +67,10 @@ struct QQmlValueTypeReference : QQmlValueTypeWrapper QQmlValueTypeWrapper::init(); object.init(); } - void destroy() { object.destroy(); } + void destroy() { + object.destroy(); + QQmlValueTypeWrapper::destroy(); + } QQmlQPointer object; int property; }; @@ -77,8 +80,7 @@ struct QQmlValueTypeReference : QQmlValueTypeWrapper struct QQmlValueTypeReference : public QQmlValueTypeWrapper { V4_OBJECT2(QQmlValueTypeReference, QQmlValueTypeWrapper) - - static void destroy(Heap::Base *that); + V4_NEEDS_DESTROY bool readReferenceValue() const; }; @@ -95,6 +97,7 @@ void Heap::QQmlValueTypeWrapper::destroy() valueType->metaType.destruct(gadgetPtr); ::operator delete(gadgetPtr); } + Object::destroy(); } void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const @@ -491,9 +494,4 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) } } -void QQmlValueTypeReference::destroy(Heap::Base *that) -{ - static_cast(that)->Heap::QQmlValueTypeReference::~QQmlValueTypeReference(); -} - QT_END_NAMESPACE -- cgit v1.2.3