aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlengine.cpp
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-05-04 08:32:45 +1000
committerQt by Nokia <qt-info@nokia.com>2012-05-17 08:58:45 +0200
commit43a6cc75886c662e63db440dd191cefa1fe956f3 (patch)
treecd3247453a0c2a59e0c5d3af11434d18761c2de4 /src/qml/qml/qqmlengine.cpp
parent9af1a7d0aee4f9ed48b2519779388830a8dd03e9 (diff)
Add QQmlEngine::trimComponentCache()
Allow unused data in the engine's component cache to be safely discarded so that the memory can be freed for other purposes. Unloading of scripts that are no longer required after trimming unused components is not yet supported. Task-number: QTBUG-25653 Change-Id: I37bc9d5592eeb5edceeb34d010a555dcffd11cea Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlengine.cpp')
-rw-r--r--src/qml/qml/qqmlengine.cpp97
1 files changed, 78 insertions, 19 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 788d5edb51..d3ca1b343c 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -429,8 +429,6 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
delete rootContext;
rootContext = 0;
- for(QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
- (*iter)->release();
for(QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
(*iter)->release();
for(QHash<QPair<QQmlType *, int>, QQmlPropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
@@ -716,11 +714,31 @@ QQmlEngine::~QQmlEngine()
Once the component cache has been cleared, components must be loaded before
any new objects can be created.
+
+ \sa trimComponentCache()
*/
void QQmlEngine::clearComponentCache()
{
Q_D(QQmlEngine);
- d->typeLoader.clearCache();
+ d->clearCache();
+}
+
+/*!
+ Trims the engine's internal component cache.
+
+ This function causes the property metadata of any loaded components which are
+ not currently in use to be destroyed.
+
+ A component is considered to be in use if there are any extant instances of
+ the component itself, any instances of other components that use the component,
+ or any objects instantiated by any of those components.
+
+ \sa clearComponentCache()
+ */
+void QQmlEngine::trimComponentCache()
+{
+ Q_D(QQmlEngine);
+ d->trimCache();
}
/*!
@@ -1074,7 +1092,7 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
{
QQmlData *data = QQmlData::get(object);
- if (data && data->deferredComponent) {
+ if (data && data->compiledData && data->deferredIdx) {
QQmlObjectCreatingProfiler prof;
if (prof.enabled) {
QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
@@ -1088,8 +1106,9 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
QQmlComponentPrivate::ConstructionState state;
QQmlComponentPrivate::beginDeferred(ep, object, &state);
- data->deferredComponent->release();
- data->deferredComponent = 0;
+ // Release the reference for the deferral action (we still have one from construction)
+ data->compiledData->release();
+ data->compiledData = 0;
QQmlComponentPrivate::complete(ep, &state);
}
@@ -1267,9 +1286,6 @@ QHash<int, QObject *> *QQmlData::attachedProperties() const
void QQmlData::destroyed(QObject *object)
{
- if (deferredComponent)
- deferredComponent->release();
-
if (nextContextObject)
nextContextObject->prevContextObject = prevContextObject;
if (prevContextObject)
@@ -1284,6 +1300,11 @@ void QQmlData::destroyed(QObject *object)
binding = next;
}
+ if (compiledData) {
+ compiledData->release();
+ compiledData = 0;
+ }
+
QQmlAbstractBoundSignal *signalHandler = signalHandlers;
while (signalHandler) {
QQmlAbstractBoundSignal *next = signalHandler->m_nextSignal;
@@ -1835,9 +1856,9 @@ int QQmlEnginePrivate::listType(int t) const
const QMetaObject *QQmlEnginePrivate::rawMetaObjectForType(int t) const
{
Locker locker(this);
- QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
+ QHash<int, const QMetaObject *>::ConstIterator iter = m_compositeTypes.find(t);
if (iter != m_compositeTypes.end()) {
- return (*iter)->root;
+ return *iter;
} else {
QQmlType *type = QQmlMetaType::qmlType(t);
return type?type->baseMetaObject():0;
@@ -1847,18 +1868,18 @@ const QMetaObject *QQmlEnginePrivate::rawMetaObjectForType(int t) const
const QMetaObject *QQmlEnginePrivate::metaObjectForType(int t) const
{
Locker locker(this);
- QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
+ QHash<int, const QMetaObject *>::ConstIterator iter = m_compositeTypes.find(t);
if (iter != m_compositeTypes.end()) {
- return (*iter)->root;
+ return *iter;
} else {
QQmlType *type = QQmlMetaType::qmlType(t);
return type?type->metaObject():0;
}
}
-void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data)
+void QQmlEnginePrivate::registerCompositeType(const QMetaObject *mo)
{
- QByteArray name = data->root->className();
+ QByteArray name = mo->className();
QByteArray ptr = name + '*';
QByteArray lst = "QQmlListProperty<" + name + '>';
@@ -1870,7 +1891,7 @@ void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data)
qMetaTypeConstructHelper<QObject*>,
sizeof(QObject*),
static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags),
- data->root);
+ mo);
int lst_type = QMetaType::registerNormalizedType(lst,
qMetaTypeDeleteHelper<QQmlListProperty<QObject> >,
qMetaTypeCreateHelper<QQmlListProperty<QObject> >,
@@ -1880,11 +1901,49 @@ void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data)
static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
static_cast<QMetaObject*>(0));
- data->addref();
-
Locker locker(this);
m_qmlLists.insert(lst_type, ptr_type);
- m_compositeTypes.insert(ptr_type, data);
+ m_compositeTypes.insert(ptr_type, mo);
+}
+
+void QQmlEnginePrivate::unregisterCompositeType(const QMetaObject *mo)
+{
+ QByteArray name = mo->className();
+
+ QByteArray ptr = name + '*';
+ QByteArray lst = "QQmlListProperty<" + name + '>';
+
+ int ptr_type = QMetaType::type(ptr.constData());
+ int lst_type = QMetaType::type(lst.constData());
+
+ Locker locker(this);
+ m_qmlLists.remove(lst_type);
+ m_compositeTypes.remove(ptr_type);
+}
+
+void QQmlEnginePrivate::clearCache()
+{
+ typeLoader.clearCache(this, &QQmlEnginePrivate::typeUnloaded);
+}
+
+void QQmlEnginePrivate::trimCache()
+{
+ typeLoader.trimCache(this, &QQmlEnginePrivate::typeUnloaded);
+}
+
+void QQmlEnginePrivate::typeUnloaded(QQmlTypeData *typeData)
+{
+ unregisterCompositeType(typeData->compiledData()->root);
+}
+
+bool QQmlEnginePrivate::isTypeLoaded(const QUrl &url) const
+{
+ return typeLoader.isTypeLoaded(url);
+}
+
+bool QQmlEnginePrivate::isScriptLoaded(const QUrl &url) const
+{
+ return typeLoader.isScriptLoaded(url);
}
bool QQml_isFileCaseCorrect(const QString &fileName)