Reserve enough space in the QDeclarativePropertyCache hash
authorAaron Kennedy <aaron.kennedy@nokia.com>
Wed, 21 Dec 2011 18:44:26 +0000 (18:44 +0000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 22 Dec 2011 11:06:03 +0000 (12:06 +0100)
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 <martin.jones@nokia.com>
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativeengine.cpp
src/declarative/qml/qdeclarativepropertycache.cpp
src/declarative/qml/qdeclarativepropertycache_p.h

index 10e64b3..faaebc0 100644 (file)
@@ -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();
index 9f2f4a0..2b77fe5 100644 (file)
@@ -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;
     }
index bd3bc33..899bb1f 100644 (file)
@@ -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,
index 746c1fe..c3e9482 100644 (file)
@@ -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<v8::Object> newQObject(QObject *, QV8Engine *);