From 5c22d958fb7cd5e9729518a6fdd0a9a18a9a7481 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 21 Dec 2011 18:44:26 +0000 Subject: Reserve enough space in the QDeclarativePropertyCache hash It was too easy for callers of copy() to pass the wrong reserve size, so a new copyAndAppend() method has been added to reduce error. Change-Id: If2f13e2e0733e5d87c527934dc5a6c8d0c8df572 Reviewed-by: Martin Jones --- src/declarative/qml/qdeclarativecompiler.cpp | 11 ++++--- src/declarative/qml/qdeclarativeengine.cpp | 5 +-- src/declarative/qml/qdeclarativepropertycache.cpp | 37 ++++++++++++++++++++++- src/declarative/qml/qdeclarativepropertycache_p.h | 14 ++++++++- 4 files changed, 56 insertions(+), 11 deletions(-) (limited to 'src/declarative/qml') diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 10e64b34df..faaebc0f82 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -3121,11 +3121,12 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, Dyn } if (obj->type != -1) { - QDeclarativePropertyCache *cache = output->types[obj->type].createPropertyCache(engine)->copy(); - cache->append(engine, &obj->extObject, - QDeclarativePropertyData::NoFlags, - QDeclarativePropertyData::IsVMEFunction, - QDeclarativePropertyData::IsVMESignal); + QDeclarativePropertyCache *superCache = output->types[obj->type].createPropertyCache(engine); + QDeclarativePropertyCache *cache = + superCache->copyAndAppend(engine, &obj->extObject, + QDeclarativePropertyData::NoFlags, + QDeclarativePropertyData::IsVMEFunction, + QDeclarativePropertyData::IsVMESignal); // now we modify the flags appropriately for var properties. int propertyOffset = obj->extObject.propertyOffset(); diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 9f2f4a0a09..2b77fe536d 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1575,10 +1575,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObj return rv; } else { QDeclarativePropertyCache *super = cache(mo->superClass()); - QDeclarativePropertyCache *rv = super->copy(mo->propertyCount() + mo->methodCount() - - mo->superClass()->propertyCount() - - mo->superClass()->methodCount()); - rv->append(q, mo); + QDeclarativePropertyCache *rv = super->copyAndAppend(q, mo); propertyCache.insert(mo, rv); return rv; } diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index bd3bc338ce..899bb1fce3 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -280,7 +280,7 @@ void QDeclarativePropertyCache::clear() engine = 0; } -QDeclarativePropertyCache *QDeclarativePropertyCache::copy(int reserve) +QDeclarativePropertyCache *QDeclarativePropertyCache::copy(int reserve) { QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine); cache->parent = this; @@ -297,6 +297,41 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy(int reserve) return cache; } +QDeclarativePropertyCache *QDeclarativePropertyCache::copy() +{ + return copy(0); +} + +QDeclarativePropertyCache * +QDeclarativePropertyCache::copyAndAppend(QDeclarativeEngine *engine, const QMetaObject *metaObject, + QDeclarativePropertyData::Flag propertyFlags, + QDeclarativePropertyData::Flag methodFlags, + QDeclarativePropertyData::Flag signalFlags) +{ + return copyAndAppend(engine, metaObject, -1, propertyFlags, methodFlags, signalFlags); +} + +QDeclarativePropertyCache * +QDeclarativePropertyCache::copyAndAppend(QDeclarativeEngine *engine, const QMetaObject *metaObject, + int revision, + QDeclarativePropertyData::Flag propertyFlags, + QDeclarativePropertyData::Flag methodFlags, + QDeclarativePropertyData::Flag signalFlags) +{ + Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4); + + // Reserve enough space in the name hash for all the methods (including signals), all the + // signal handlers and all the properties. This assumes no name clashes, but this is the + // common case. + QDeclarativePropertyCache *rv = copy(QMetaObjectPrivate::get(metaObject)->methodCount + + QMetaObjectPrivate::get(metaObject)->signalCount + + QMetaObjectPrivate::get(metaObject)->propertyCount); + + rv->append(engine, metaObject, revision, propertyFlags, methodFlags, signalFlags); + + return rv; +} + void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaObject *metaObject, QDeclarativePropertyData::Flag propertyFlags, QDeclarativePropertyData::Flag methodFlags, diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 746c1fe8e8..c3e9482baa 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -219,7 +219,17 @@ public: void update(QDeclarativeEngine *, const QMetaObject *); - QDeclarativePropertyCache *copy(int reserve = 0); + QDeclarativePropertyCache *copy(); + + QDeclarativePropertyCache *copyAndAppend(QDeclarativeEngine *, const QMetaObject *, + QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags, + QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags, + QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags); + QDeclarativePropertyCache *copyAndAppend(QDeclarativeEngine *, const QMetaObject *, int revision, + QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags, + QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags, + QDeclarativePropertyData::Flag signalFlags = QDeclarativePropertyData::NoFlags); + void append(QDeclarativeEngine *, const QMetaObject *, QDeclarativePropertyData::Flag propertyFlags = QDeclarativePropertyData::NoFlags, QDeclarativePropertyData::Flag methodFlags = QDeclarativePropertyData::NoFlags, @@ -257,6 +267,8 @@ private: friend class QDeclarativeEnginePrivate; friend class QV8QObjectWrapper; + inline QDeclarativePropertyCache *copy(int reserve); + // Implemented in v8/qv8qobjectwrapper.cpp v8::Local newQObject(QObject *, QV8Engine *); -- cgit v1.2.3