From 7b1a8fa821ef5bac4ecad91be7f0e62809e80a12 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 16 Oct 2013 14:50:57 +0200 Subject: Fix performance regression when doing property lookups for non-existant properties Commit 84627464eb11ca1149d46946b12e3c82eb54a8bf introduced a performance regression of falling back to reading the QMetaObject, when the lookup for a property in QML failed, after we've tried in the property cache. This is very very expensive to do and was only due to QQmlPropertyMap not correctly invalidating the property cache. Instead remove the property cache from the property map's QObject and on the lookup side rely on the property cache being correct in the result (positive or negative). Change-Id: I8a013483203f2007d48b71feafa10b3ea02c53fd Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 2 +- src/qml/qml/qqmlopenmetaobject.cpp | 15 ++++++++++++--- src/qml/qml/qqmlpropertycache.cpp | 3 +-- 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 03d839316b..c4566fe2a3 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -263,7 +263,7 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont QQmlPropertyData *result = 0; if (ddata && ddata->propertyCache) result = ddata->propertyCache->property(name, m_object, qmlContext); - if (!result) + else result = QQmlPropertyCache::property(engine->v8Engine->engine(), m_object, name, qmlContext, *local); return result; } diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp index 278287e697..5745f35498 100644 --- a/src/qml/qml/qqmlopenmetaobject.cpp +++ b/src/qml/qml/qqmlopenmetaobject.cpp @@ -357,9 +357,18 @@ void QQmlOpenMetaObject::setCached(bool c) int QQmlOpenMetaObject::createProperty(const char *name, const char *) { - if (d->autoCreate) - return d->type->createProperty(name); - else + if (d->autoCreate) { + int result = d->type->createProperty(name); + + if (QQmlData *ddata = QQmlData::get(d->object, /*create*/false)) { + if (ddata->propertyCache) { + ddata->propertyCache->release(); + ddata->propertyCache = 0; + } + } + + return result; + } else return -1; } diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index e498ca5dee..2cb944d824 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -1419,8 +1419,7 @@ qQmlPropertyCacheProperty(QQmlEngine *engine, QObject *obj, T name, if (cache) { rv = cache->property(name, obj, context); - } - if (!rv) { + } else { local = qQmlPropertyCacheCreate(obj->metaObject(), qQmlPropertyCacheToString(name)); if (local.isValid()) rv = &local; -- cgit v1.2.3