aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-01-17 12:16:07 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-20 11:49:42 +0100
commit65a02ef32f7131f5e0b87dd18b4f81486d507ae3 (patch)
tree07bcb66e6f18641991e5f8532a5e5503780bdfee /src/qml/compiler
parent3a9e7f056f487c9740621750067781d33a7c9f34 (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/compiler')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp10
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp80
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h8
3 files changed, 54 insertions, 44 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 22ae1228c7..46bb07f8bc 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1639,8 +1639,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
QString elementName = stringAt(obj->inheritedTypeNameIndex);
if (elementName.isEmpty())
continue;
- QQmlCompiledData::TypeReference &tr = unit->resolvedTypes[obj->inheritedTypeNameIndex];
- if (tr.type && tr.type->customParser())
+ QQmlCompiledData::TypeReference *tr = unit->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ if (tr && tr->type && tr->type->customParser())
continue;
QQmlPropertyCache *cache = unit->propertyCaches.value(objectIndex);
Q_ASSERT(cache);
@@ -1660,7 +1660,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
// Attached property?
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
QmlObject *attachedObj = parsedQML->objects[binding->value.objectIndex];
- QQmlType *type = unit->resolvedTypes.value(binding->propertyNameIndex).type;
+ QQmlCompiledData::TypeReference *typeRef = unit->resolvedTypes.value(binding->propertyNameIndex);
+ QQmlType *type = typeRef ? typeRef->type : 0;
const QMetaObject *attachedType = type ? type->attachedPropertiesType() : 0;
if (!attachedType)
COMPILE_EXCEPTION(binding->location, tr("Non-existent attached object"));
@@ -1703,7 +1704,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
- const QQmlType *type = unit->resolvedTypes.value(obj->inheritedTypeNameIndex).type;
+ QQmlCompiledData::TypeReference *typeRef = unit->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ const QQmlType *type = typeRef ? typeRef->type : 0;
if (type) {
COMPILE_EXCEPTION(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type->module()).arg(type->majorVersion()).arg(type->minorVersion()));
} else {
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 91f5535f9c..4fe3008003 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -80,16 +80,16 @@ bool QQmlTypeCompiler::compile()
const QHash<int, QQmlTypeData::TypeReference> &resolvedTypes = typeData->resolvedTypeRefs();
for (QHash<int, QQmlTypeData::TypeReference>::ConstIterator resolvedType = resolvedTypes.constBegin(), end = resolvedTypes.constEnd();
resolvedType != end; ++resolvedType) {
- QQmlCompiledData::TypeReference ref;
+ QQmlCompiledData::TypeReference *ref = new QQmlCompiledData::TypeReference;
if (resolvedType->typeData) {
- ref.component = resolvedType->typeData->compiledData();
- ref.component->addref();
+ ref->component = resolvedType->typeData->compiledData();
+ ref->component->addref();
} else {
- ref.type = resolvedType->type;
- Q_ASSERT(ref.type);
+ ref->type = resolvedType->type;
+ Q_ASSERT(ref->type);
}
- ref.majorVersion = resolvedType->majorVersion;
- ref.minorVersion = resolvedType->minorVersion;
+ ref->majorVersion = resolvedType->majorVersion;
+ ref->minorVersion = resolvedType->minorVersion;
compiledData->resolvedTypes.insert(resolvedType.key(), ref);
}
@@ -175,13 +175,14 @@ bool QQmlTypeCompiler::compile()
engine->registerInternalCompositeType(compiledData);
else {
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
- QQmlCompiledData::TypeReference typeRef = compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex);
- if (typeRef.component) {
- compiledData->metaTypeId = typeRef.component->metaTypeId;
- compiledData->listMetaTypeId = typeRef.component->listMetaTypeId;
+ QQmlCompiledData::TypeReference *typeRef = compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ if (typeRef->component) {
+ compiledData->metaTypeId = typeRef->component->metaTypeId;
+ compiledData->listMetaTypeId = typeRef->component->listMetaTypeId;
} else {
- compiledData->metaTypeId = typeRef.type->typeId();
- compiledData->listMetaTypeId = typeRef.type->qListTypeId();
+ compiledData->metaTypeId = typeRef->type->typeId();
+ compiledData->listMetaTypeId = typeRef->type->qListTypeId();
}
}
@@ -220,7 +221,7 @@ const QQmlImports *QQmlTypeCompiler::imports() const
return &typeData->imports();
}
-QHash<int, QQmlCompiledData::TypeReference> *QQmlTypeCompiler::resolvedTypes()
+QHash<int, QQmlCompiledData::TypeReference*> *QQmlTypeCompiler::resolvedTypes()
{
return &compiledData->resolvedTypes;
}
@@ -241,6 +242,7 @@ void QQmlTypeCompiler::setPropertyCaches(const QVector<QQmlPropertyCache *> &cac
compiledData->propertyCaches = caches;
Q_ASSERT(caches.count() >= parsedQML->indexOfRootObject);
compiledData->rootPropertyCache = caches.at(parsedQML->indexOfRootObject);
+ compiledData->rootPropertyCache->addref();
}
const QVector<QQmlPropertyCache *> &QQmlTypeCompiler::propertyCaches() const
@@ -369,8 +371,9 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r
QString typeName = stringAt(obj->inheritedTypeNameIndex);
if (!typeName.isEmpty()) {
- QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
- baseTypeCache = typeRef.createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
Q_ASSERT(baseTypeCache);
}
@@ -395,8 +398,9 @@ bool QQmlPropertyCacheCreator::ensureMetaObject(int objectIndex)
if (!vmeMetaObjects.at(objectIndex).isEmpty())
return true;
const QtQml::QmlObject *obj = qmlObjects.at(objectIndex);
- QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
- QQmlPropertyCache *baseTypeCache = typeRef.createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ QQmlPropertyCache *baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
return createMetaObject(objectIndex, obj, baseTypeCache);
}
@@ -407,7 +411,6 @@ bool QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QtQml::Qm
obj->functions->count + obj->properties->count + obj->qmlSignals->count,
obj->qmlSignals->count + obj->properties->count);
propertyCaches[objectIndex] = cache;
- cache->addref();
struct TypeData {
QV4::CompiledData::Property::Type dtype;
@@ -776,7 +779,9 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QtQm
continue;
const QtQml::QmlObject *targetObject = qmlObjects->at(binding->value.objectIndex);
- QQmlType *targetType = resolvedTypes->value(targetObject->inheritedTypeNameIndex).type;
+ QQmlCompiledData::TypeReference *tr = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
+ Q_ASSERT(tr);
+ QQmlType *targetType = tr->type;
if (targetType && targetType->metaObject() == &QQmlComponent::staticMetaObject)
continue;
@@ -813,10 +818,10 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QtQm
syntheticComponent->init(pool, compiler->registerString(QString::fromUtf8(componentType->typeName())), compiler->registerString(QString()));
if (!resolvedTypes->contains(syntheticComponent->inheritedTypeNameIndex)) {
- QQmlCompiledData::TypeReference typeRef;
- typeRef.type = componentType;
- typeRef.majorVersion = componentType->majorVersion();
- typeRef.minorVersion = componentType->minorVersion();
+ QQmlCompiledData::TypeReference *typeRef = new QQmlCompiledData::TypeReference;
+ typeRef->type = componentType;
+ typeRef->majorVersion = componentType->majorVersion();
+ typeRef->minorVersion = componentType->minorVersion();
resolvedTypes->insert(syntheticComponent->inheritedTypeNameIndex, typeRef);
}
@@ -847,10 +852,11 @@ bool QQmlComponentAndAliasResolver::resolve()
if (stringAt(obj->inheritedTypeNameIndex).isEmpty())
continue;
- QQmlCompiledData::TypeReference tref = resolvedTypes->value(obj->inheritedTypeNameIndex);
- if (!tref.type)
+ QQmlCompiledData::TypeReference *tref = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(tref);
+ if (!tref->type)
continue;
- if (tref.type->metaObject() != &QQmlComponent::staticMetaObject) {
+ if (tref->type->metaObject() != &QQmlComponent::staticMetaObject) {
findAndRegisterImplicitComponents(obj, i);
continue;
}
@@ -995,12 +1001,13 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
if (property.isEmpty()) {
const QtQml::QmlObject *targetObject = qmlObjects->at(targetObjectIndex);
- QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
- if (typeRef.type)
- type = typeRef.type->typeId();
+ if (typeRef->type)
+ type = typeRef->type->typeId();
else
- type = typeRef.component->metaTypeId;
+ type = typeRef->component->metaTypeId;
flags |= QML_ALIAS_FLAG_PTR;
propertyFlags |= QQmlPropertyData::IsQObjectDerived;
@@ -1125,9 +1132,10 @@ bool QQmlPropertyValidator::validateObject(int objectIndex)
Q_ASSERT(propertyCache);
QQmlCustomParser *customParser = 0;
- QQmlCompiledData::TypeReference objectType = resolvedTypes.value(obj->inheritedTypeNameIndex);
- if (objectType.type)
- customParser = objectType.type->customParser();
+ QQmlCompiledData::TypeReference *objectType = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(objectType);
+ if (objectType->type)
+ customParser = objectType->type->customParser();
QList<const QV4::CompiledData::Binding*> customBindings;
PropertyResolver propertyResolver(propertyCache);
@@ -1162,8 +1170,8 @@ bool QQmlPropertyValidator::validateObject(int objectIndex)
if (notInRevision) {
QString typeName = stringAt(obj->inheritedTypeNameIndex);
- if (objectType.type) {
- COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType.type->module()).arg(objectType.majorVersion).arg(objectType.minorVersion));
+ if (objectType->type) {
+ COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type->module()).arg(objectType->majorVersion).arg(objectType->minorVersion));
} else {
COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name));
}
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index 4fde8f58c2..e6a34fa376 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -81,7 +81,7 @@ struct QQmlTypeCompiler
QQmlEnginePrivate *enginePrivate() const { return engine; }
const QQmlImports *imports() const;
- QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes();
+ QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes();
QList<QtQml::QmlObject*> *qmlObjects();
int rootObjectIndex() const;
void setPropertyCaches(const QVector<QQmlPropertyCache *> &caches);
@@ -130,7 +130,7 @@ protected:
QQmlEnginePrivate *enginePrivate;
const QList<QtQml::QmlObject*> &qmlObjects;
const QQmlImports *imports;
- QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes;
+ QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes;
QVector<QByteArray> vmeMetaObjects;
QVector<QQmlPropertyCache*> propertyCaches;
};
@@ -165,7 +165,7 @@ protected:
QHash<int, int> *_objectIndexToIdInScope;
QList<int> _objectsWithAliases;
- QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes;
+ QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes;
const QVector<QQmlPropertyCache *> propertyCaches;
QVector<QByteArray> *vmeMetaObjectData;
QHash<int, int> *objectIndexToIdForRoot;
@@ -190,7 +190,7 @@ private:
bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
const QV4::CompiledData::QmlUnit *qmlUnit;
- const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes;
+ const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes;
const QVector<QQmlPropertyCache *> &propertyCaches;
const QHash<int, QHash<int, int> > objectIndexToIdPerComponent;
QHash<int, QByteArray> *customParserData;