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/jsruntime/qv4engine.cpp | 8 +++---- src/qml/jsruntime/qv4variantobject.cpp | 29 +++++++++++------------ src/qml/jsruntime/qv4variantobject_p.h | 15 ++++++++++-- src/qml/qml/qqmlbinding.cpp | 2 +- src/qml/qml/qqmlvaluetypewrapper.cpp | 2 +- src/qml/qml/qqmlvmemetaobject.cpp | 42 +++++++++++++++++----------------- 6 files changed, 55 insertions(+), 43 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index e81292f598..7b33cec1f1 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1079,7 +1079,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int QV4::Scope scope(e); if (const QV4::VariantObject *v = value.as()) - return v->d()->data; + return v->d()->data(); if (typeHint == QVariant::Bool) return QVariant(value.toBoolean()); @@ -1693,7 +1693,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data) return true; if (value->as() && name.endsWith('*')) { int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = value->as()->d()->data; + QVariant &var = value->as()->d()->data(); if (valueType == var.userType()) { // We have T t, T* is requested, so return &t. *reinterpret_cast(data) = var.data(); @@ -1705,7 +1705,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data) while (proto) { bool canCast = false; if (QV4::VariantObject *vo = proto->as()) { - const QVariant &v = vo->d()->data; + const QVariant &v = vo->d()->data(); canCast = (type == v.userType()) || (valueType && (valueType == v.userType())); } else if (proto->as()) { @@ -1760,7 +1760,7 @@ static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const Value &value) QV4::Scoped v(scope, value); if (v) { - QVariant variant = v->d()->data; + QVariant variant = v->d()->data(); int type = variant.userType(); if (type == QMetaType::QObjectStar) return *reinterpret_cast(variant.constData()); diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index 444c0a37e0..eff4db268c 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -52,18 +52,19 @@ DEFINE_OBJECT_VTABLE(VariantObject); Heap::VariantObject::VariantObject() { + scarceData = new ExecutionEngine::ScarceResourceData; } Heap::VariantObject::VariantObject(const QVariant &value) { - data = value; + scarceData = new ExecutionEngine::ScarceResourceData(value); if (isScarce()) - internalClass->engine->scarceResources.insert(this); + removeVmePropertyReference(); } bool VariantObject::Data::isScarce() const { - QVariant::Type t = data.type(); + QVariant::Type t = data().type(); return t == QVariant::Pixmap || t == QVariant::Image; } @@ -73,10 +74,10 @@ bool VariantObject::isEqualTo(Managed *m, Managed *other) QV4::VariantObject *lv = static_cast(m); if (QV4::VariantObject *rv = other->as()) - return lv->d()->data == rv->d()->data; + return lv->d()->data() == rv->d()->data(); if (QV4::QQmlValueTypeWrapper *v = other->as()) - return v->isEqual(lv->d()->data); + return v->isEqual(lv->d()->data()); return false; } @@ -87,7 +88,7 @@ void VariantObject::addVmePropertyReference() // remove from the ep->scarceResources list // since it is now no longer eligible to be // released automatically by the engine. - d()->node.remove(); + d()->addVmePropertyReference(); } } @@ -97,7 +98,7 @@ void VariantObject::removeVmePropertyReference() // and add to the ep->scarceResources list // since it is now eligible to be released // automatically by the engine. - internalClass()->engine->scarceResources.insert(d()); + d()->removeVmePropertyReference(); } } @@ -115,7 +116,7 @@ QV4::ReturnedValue VariantPrototype::method_preserve(CallContext *ctx) Scope scope(ctx); Scoped o(scope, ctx->thisObject().as()); if (o && o->d()->isScarce()) - o->d()->node.remove(); + o->d()->addVmePropertyReference(); return Encode::undefined(); } @@ -125,8 +126,8 @@ QV4::ReturnedValue VariantPrototype::method_destroy(CallContext *ctx) Scoped o(scope, ctx->thisObject().as()); if (o) { if (o->d()->isScarce()) - o->d()->node.remove(); - o->d()->data = QVariant(); + o->d()->addVmePropertyReference(); + o->d()->data() = QVariant(); } return Encode::undefined(); } @@ -137,9 +138,9 @@ QV4::ReturnedValue VariantPrototype::method_toString(CallContext *ctx) Scoped o(scope, ctx->thisObject().as()); if (!o) return Encode::undefined(); - QString result = o->d()->data.toString(); - if (result.isEmpty() && !o->d()->data.canConvert(QVariant::String)) - result = QStringLiteral("QVariant(%0)").arg(QString::fromLatin1(o->d()->data.typeName())); + QString result = o->d()->data().toString(); + if (result.isEmpty() && !o->d()->data().canConvert(QVariant::String)) + result = QStringLiteral("QVariant(%0)").arg(QString::fromLatin1(o->d()->data().typeName())); return Encode(ctx->d()->engine->newString(result)); } @@ -148,7 +149,7 @@ QV4::ReturnedValue VariantPrototype::method_valueOf(CallContext *ctx) Scope scope(ctx); Scoped o(scope, ctx->thisObject().as()); if (o) { - QVariant v = o->d()->data; + QVariant v = o->d()->data(); switch (v.type()) { case QVariant::Invalid: return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h index e50706ef94..9b744faf75 100644 --- a/src/qml/jsruntime/qv4variantobject_p.h +++ b/src/qml/jsruntime/qv4variantobject_p.h @@ -64,16 +64,27 @@ namespace QV4 { namespace Heap { -struct VariantObject : Object, public ExecutionEngine::ScarceResourceData +struct VariantObject : Object { VariantObject(); VariantObject(const QVariant &value); ~VariantObject() { + Q_ASSERT(scarceData); if (isScarce()) - node.remove(); + addVmePropertyReference(); + delete scarceData; } bool isScarce() const; int vmePropertyReferenceCount; + + const QVariant &data() const { return scarceData->data; } + QVariant &data() { return scarceData->data; } + + void addVmePropertyReference() { scarceData->node.remove(); } + void removeVmePropertyReference() { internalClass->engine->scarceResources.insert(scarceData); } + +private: + ExecutionEngine::ScarceResourceData *scarceData; }; } diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 90698c3b24..203bfec838 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -600,7 +600,7 @@ protected: resultMo = resultObject->metaObject(); } } else if (auto variant = result.as()) { - QVariant value = variant->d()->data; + QVariant value = variant->d()->data(); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()); resultMo = QQmlPropertyPrivate::rawMetaObjectForType(ep, value.userType()); if (resultMo.isNull()) 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()); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 4f13b44fc0..b08a0e5087 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -503,9 +503,9 @@ QUrl QQmlVMEMetaObject::readPropertyAsUrl(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as(); - if (!v || v->d()->data.type() != QVariant::Url) + if (!v || v->d()->data().type() != QVariant::Url) return QUrl(); - return v->d()->data.value(); + return v->d()->data().value(); } QDate QQmlVMEMetaObject::readPropertyAsDate(int id) @@ -517,9 +517,9 @@ QDate QQmlVMEMetaObject::readPropertyAsDate(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as(); - if (!v || v->d()->data.type() != QVariant::Date) + if (!v || v->d()->data().type() != QVariant::Date) return QDate(); - return v->d()->data.value(); + return v->d()->data().value(); } QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id) @@ -531,9 +531,9 @@ QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as(); - if (!v || v->d()->data.type() != QVariant::DateTime) + if (!v || v->d()->data().type() != QVariant::DateTime) return QDateTime(); - return v->d()->data.value(); + return v->d()->data().value(); } QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) @@ -545,9 +545,9 @@ QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as(); - if (!v || v->d()->data.type() != QVariant::SizeF) + if (!v || v->d()->data().type() != QVariant::SizeF) return QSizeF(); - return v->d()->data.value(); + return v->d()->data().value(); } QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) @@ -559,9 +559,9 @@ QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as(); - if (!v || v->d()->data.type() != QVariant::PointF) + if (!v || v->d()->data().type() != QVariant::PointF) return QPointF(); - return v->d()->data.value(); + return v->d()->data().value(); } QObject* QQmlVMEMetaObject::readPropertyAsQObject(int id) @@ -586,12 +586,12 @@ QList *QQmlVMEMetaObject::readPropertyAsList(int id) QV4::Scope scope(cache->engine); QV4::Scoped v(scope, *(md->data() + id)); - if (!v || (int)v->d()->data.userType() != qMetaTypeId >()) { + if (!v || (int)v->d()->data().userType() != qMetaTypeId >()) { QVariant variant(qVariantFromValue(QList())); v = cache->engine->newVariantObject(variant); *(md->data() + id) = v; } - return static_cast *>(v->d()->data.data()); + return static_cast *>(v->d()->data().data()); } QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) @@ -603,9 +603,9 @@ QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as(); - if (!v || v->d()->data.type() != QVariant::RectF) + if (!v || v->d()->data().type() != QVariant::RectF) return QRectF(); - return v->d()->data.value(); + return v->d()->data().value(); } #if defined(Q_OS_WINRT) && defined(_M_ARM) @@ -740,7 +740,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) { QVariant propertyAsVariant; if (QV4::VariantObject *v = (md->data() + id)->as()) - propertyAsVariant = v->d()->data; + propertyAsVariant = v->d()->data(); QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType); } break; @@ -816,10 +816,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (!v) { *(md->data() + id) = cache->engine->newVariantObject(QVariant()); v = (md->data() + id)->as(); - QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data); + QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data()); } - needActivate = !QQml_valueTypeProvider()->equalValueType(fallbackMetaType, a[0], v->d()->data); - QQml_valueTypeProvider()->writeValueType(fallbackMetaType, a[0], v->d()->data); + needActivate = !QQml_valueTypeProvider()->equalValueType(fallbackMetaType, a[0], v->d()->data()); + QQml_valueTypeProvider()->writeValueType(fallbackMetaType, a[0], v->d()->data()); } break; case QV4::CompiledData::Property::Var: @@ -1009,7 +1009,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) return QVariant::fromValue(wrapper->object()); const QV4::VariantObject *v = (md->data() + id)->as(); if (v) - return v->d()->data; + return v->d()->data(); return cache->engine->toVariant(*(md->data() + id), -1); } return QVariant(); @@ -1092,8 +1092,8 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) if (md) { QV4::VariantObject *v = (md->data() + id)->as(); needActivate = (!v || - v->d()->data.userType() != value.userType() || - v->d()->data != value); + v->d()->data().userType() != value.userType() || + v->d()->data() != value); if (v) v->removeVmePropertyReference(); *(md->data() + id) = cache->engine->newVariantObject(value); -- cgit v1.2.3