diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-01-17 12:16:07 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-20 11:49:42 +0100 |
commit | 65a02ef32f7131f5e0b87dd18b4f81486d507ae3 (patch) | |
tree | 07bcb66e6f18641991e5f8532a5e5503780bdfee /src/qml/qml | |
parent | 3a9e7f056f487c9740621750067781d33a7c9f34 (diff) |
[new compiler] Fix refcounting leaks with property caches
The TypeReference is not copy-safe, as it holds refcounted property cache
pointers. For the new compiler code path, don't copy them but keep pointers to
TypeReference objects around. Also make sure to ref the root property cache
correctly and avoid the unnecessary addref for the property cache when creating
new vme meta objects (initial refcount is 1).
Change-Id: I0c4b952c8300c2167d926d9c35b8579fd505d596
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlcompileddata.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlcompiler_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 15 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 |
4 files changed, 18 insertions, 13 deletions
diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp index 76bf24fe6b..cc8fcdb6ba 100644 --- a/src/qml/qml/qqmlcompileddata.cpp +++ b/src/qml/qml/qqmlcompileddata.cpp @@ -117,13 +117,15 @@ QQmlCompiledData::~QQmlCompiledData() types.at(ii).typePropertyCache->release(); } - for (QHash<int, TypeReference>::Iterator resolvedType = resolvedTypes.begin(), end = resolvedTypes.end(); + for (QHash<int, TypeReference*>::Iterator resolvedType = resolvedTypes.begin(), end = resolvedTypes.end(); resolvedType != end; ++resolvedType) { - if (resolvedType->component) - resolvedType->component->release(); - if (resolvedType->typePropertyCache) - resolvedType->typePropertyCache->release(); + if ((*resolvedType)->component) + (*resolvedType)->component->release(); + if ((*resolvedType)->typePropertyCache) + (*resolvedType)->typePropertyCache->release(); } + qDeleteAll(resolvedTypes); + resolvedTypes.clear(); for (int ii = 0; ii < propertyCaches.count(); ++ii) if (propertyCaches.at(ii)) diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index 788def0288..58943b206a 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -129,7 +129,7 @@ public: QList<TypeReference> types; // --- new compiler: // map from name index - QHash<int, TypeReference> resolvedTypes; + QHash<int, TypeReference*> resolvedTypes; // --- struct V8Program { diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 963b8272f4..b1f4a8e1bf 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -642,7 +642,9 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI { if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { Q_ASSERT(stringAt(qmlUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty()); - QQmlType *attachedType = resolvedTypes.value(binding->propertyNameIndex).type; + QQmlCompiledData::TypeReference *tr = resolvedTypes.value(binding->propertyNameIndex); + Q_ASSERT(tr); + QQmlType *attachedType = tr->type; const int id = attachedType->attachedPropertiesId(); QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject); QQmlRefPointer<QQmlPropertyCache> cache = QQmlEnginePrivate::get(engine)->cache(qmlObject); @@ -931,8 +933,9 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent) } else { const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); - QQmlCompiledData::TypeReference typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex); - QQmlType *type = typeRef.type; + QQmlCompiledData::TypeReference *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex); + Q_ASSERT(typeRef); + QQmlType *type = typeRef->type; if (type) { instance = type->create(); if (!instance) { @@ -950,13 +953,13 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent) customParser = type->customParser(); } else { - Q_ASSERT(typeRef.component); - if (typeRef.component->qmlUnit->isSingleton()) + Q_ASSERT(typeRef->component); + if (typeRef->component->qmlUnit->isSingleton()) { recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex))); return 0; } - QmlObjectCreator subCreator(context, typeRef.component); + QmlObjectCreator subCreator(context, typeRef->component); instance = subCreator.create(); if (!instance) { errors += subCreator.errors; diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index a198396467..951c3a2eed 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -86,7 +86,7 @@ private: const QV4::CompiledData::CompilationUnit *jsUnit; QQmlContextData *parentContext; QQmlContextData *context; - const QHash<int, QQmlCompiledData::TypeReference> resolvedTypes; + const QHash<int, QQmlCompiledData::TypeReference*> resolvedTypes; const QVector<QQmlPropertyCache *> propertyCaches; const QVector<QByteArray> vmeMetaObjectData; QHash<int, int> objectIndexToId; |