aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-12-19 13:10:06 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-20 05:40:33 +0100
commit901bdf833cff3db5ef152c3539096b4a7f1de95b (patch)
tree5ef79bb716f786e2b55761420997504cec022bba /src/declarative
parentf217b776c8a41ea93e3b25a4009573bb94344ac2 (diff)
Fix QDeclarativePropertyCache crash.
Reserve enough space in the signalHandlerIndexCache so that it will not reallocated while the property cache is being built as this will invalidate the pointers stored in the stringCache. Also ensure signals for all cached meta-objects are included in signalHandlerIndexCache, and don't over allocate propertyIndexCache and methodIndexCache. Change-Id: Ic285d832d4b86106176bfe723ff10bdd65143910 Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp46
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h1
2 files changed, 34 insertions, 13 deletions
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index 239b7942da..67d0cea086 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -117,6 +117,14 @@ static QDeclarativePropertyData::Flags flagsForPropertyType(int propType, QDecla
return flags;
}
+static int metaObjectSignalCount(const QMetaObject *metaObject)
+{
+ int signalCount = 0;
+ for (const QMetaObject *obj = metaObject; obj; obj = obj->superClass())
+ signalCount += QMetaObjectPrivate::get(obj)->signalCount;
+ return signalCount;
+}
+
QDeclarativePropertyData::Flags
QDeclarativePropertyData::flagsForProperty(const QMetaProperty &p, QDeclarativeEngine *engine)
{
@@ -220,8 +228,8 @@ void QDeclarativePropertyData::lazyLoad(const QMetaMethod &m)
Creates a new empty QDeclarativePropertyCache.
*/
QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e)
-: engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0), metaObject(0),
- argumentsCache(0)
+: engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
+ signalHanderIndexCacheStart(0), metaObject(0), argumentsCache(0)
{
Q_ASSERT(engine);
}
@@ -230,8 +238,8 @@ QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e)
Creates a new QDeclarativePropertyCache of \a metaObject.
*/
QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e, const QMetaObject *metaObject)
-: engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0), metaObject(0),
- argumentsCache(0)
+: engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
+ signalHanderIndexCacheStart(0), metaObject(0), argumentsCache(0)
{
Q_ASSERT(engine);
Q_ASSERT(metaObject);
@@ -279,6 +287,7 @@ QDeclarativePropertyCache *QDeclarativePropertyCache::copy(int reserve)
cache->parent->addref();
cache->propertyIndexCacheStart = propertyIndexCache.count() + propertyIndexCacheStart;
cache->methodIndexCacheStart = methodIndexCache.count() + methodIndexCacheStart;
+ cache->signalHanderIndexCacheStart = signalHandlerIndexCache.count() + signalHanderIndexCacheStart;
cache->stringCache.copyAndReserve(stringCache, reserve);
cache->allowedRevisionCache = allowedRevisionCache;
cache->metaObject = metaObject;
@@ -313,7 +322,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
int methodCount = metaObject->methodCount();
Q_ASSERT(QMetaObjectPrivate::get(metaObject)->revision >= 4);
- int signalCount = QMetaObjectPrivate::get(metaObject)->signalCount;
+ int signalCount = metaObjectSignalCount(metaObject);
int classInfoCount = QMetaObjectPrivate::get(metaObject)->classInfoCount;
QDeclarativeAccessorProperties::Properties accessorProperties;
@@ -350,10 +359,13 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
// 3 to block the destroyed signal and the deleteLater() slot
int methodOffset = qMax(3, metaObject->methodOffset());
+ int signalOffset = signalCount - QMetaObjectPrivate::get(metaObject)->signalCount;
+ // update() should have reserved enough space in the vector that this doesn't cause a realloc
+ // and invalidate the stringCache.
methodIndexCache.resize(methodCount - methodIndexCacheStart);
- signalHandlerIndexCache.resize(signalCount);
- int signalHandlerIndex = 0;
+ signalHandlerIndexCache.resize(signalCount - signalHanderIndexCacheStart);
+ int signalHandlerIndex = signalOffset;
for (int ii = methodOffset; ii < methodCount; ++ii) {
QMetaMethod m = metaObject->method(ii);
if (m.access() == QMetaMethod::Private)
@@ -386,7 +398,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
data->metaObjectOffset = allowedRevisionCache.count() - 1;
if (data->isSignal()) {
- sigdata = &signalHandlerIndexCache[signalHandlerIndex];
+ sigdata = &signalHandlerIndexCache[signalHandlerIndex - signalHanderIndexCacheStart];
*sigdata = *data;
sigdata->flags |= QDeclarativePropertyData::IsSignalHandler;
}
@@ -439,6 +451,8 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
int propCount = metaObject->propertyCount();
int propOffset = metaObject->propertyOffset();
+ // update() should have reserved enough space in the vector that this doesn't cause a realloc
+ // and invalidate the stringCache.
propertyIndexCache.resize(propCount - propertyIndexCacheStart);
for (int ii = propOffset; ii < propCount; ++ii) {
QMetaProperty p = metaObject->property(ii);
@@ -524,13 +538,19 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
Q_ASSERT(metaObject);
Q_ASSERT(stringCache.isEmpty());
- // Optimization to prevent unnecessary reallocation of lists
+ // Preallocate enough space in the index caches for all the properties/methods/signals that
+ // are not cached in a parent cache so that the caches never need to be reallocated as this
+ // would invalidate pointers stored in the stringCache.
int pc = metaObject->propertyCount();
int mc = metaObject->methodCount();
- propertyIndexCache.reserve(pc);
- methodIndexCache.reserve(mc);
-
- stringCache.reserve(pc + mc);
+ int sc = metaObjectSignalCount(metaObject);
+ propertyIndexCache.reserve(pc - propertyIndexCacheStart);
+ methodIndexCache.reserve(mc - methodIndexCacheStart);
+ signalHandlerIndexCache.reserve(sc - signalHanderIndexCacheStart);
+
+ // Reserve enough space in the stringCache for all properties/methods/signals including those
+ // cached in a parent cache.
+ stringCache.reserve(pc + mc + sc);
updateRecur(engine,metaObject);
}
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index 3deafdf9c5..746c1fe8e8 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -272,6 +272,7 @@ private:
QDeclarativePropertyCache *parent;
int propertyIndexCacheStart;
int methodIndexCacheStart;
+ int signalHanderIndexCacheStart;
IndexCache propertyIndexCache;
IndexCache methodIndexCache;