aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-06-26 14:52:22 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2017-08-02 16:33:05 +0000
commit48c09a85ce397979c7e706e3694c879ffe456e09 (patch)
treecc2c437bb35f05cc68ef384ba00b833cfde11033 /src
parent4d393779e7a6ec09267f40420f39f8dc28ed7aef (diff)
Remove unused types on engine destruction
The QML engine destructor as well as trimComponentCache() do now clean out unused composite types that the engine registered internally. This helps avoid 'static' leaks, when more and more types would get registered by the engine. Task-number: QTBUG-61536 Change-Id: I5b32af4b88fbf626de8c0bfbaedb2285b09e3679 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsapi/qjsengine.cpp2
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlimport.cpp4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp251
-rw-r--r--src/qml/qml/qqmlmetatype_p.h39
-rw-r--r--src/qml/qml/qqmltypeloader.cpp3
6 files changed, 202 insertions, 99 deletions
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 35b4929c3a..d5b8b295a7 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -730,7 +730,7 @@ QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e)
QJSEnginePrivate::~QJSEnginePrivate()
{
- // ### FIXME: sweep unused QQmlType instances
+ QQmlMetaType::freeUnusedTypesAndCaches();
}
void QJSEnginePrivate::addToDebugServer(QJSEngine *q)
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 6f5dcc0746..3003d18efc 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -694,6 +694,8 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
if (incubationController) incubationController->d = 0;
incubationController = 0;
+ QQmlMetaType::freeUnusedTypesAndCaches();
+
for (auto iter = m_compositeTypes.cbegin(), end = m_compositeTypes.cend(); iter != end; ++iter) {
iter.value()->isRegisteredWithEngine = false;
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 89c7fd3214..e197efe72b 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -183,7 +183,7 @@ QQmlType fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRe
minorVersion,
buf.constData()
};
- ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, &reg));
+ ret = QQmlMetaType::registerCompositeSingletonType(reg);
} else {
QQmlPrivate::RegisterCompositeType reg = {
url,
@@ -192,7 +192,7 @@ QQmlType fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRe
minorVersion,
buf.constData()
};
- ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &reg));
+ ret = QQmlMetaType::registerCompositeType(reg);
}
// This means that the type couldn't be found by URL, but could not be
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 59ed86f31a..efe6e1c3be 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -69,7 +69,9 @@ struct QQmlMetaTypeData
{
QQmlMetaTypeData();
~QQmlMetaTypeData();
+ void registerType(QQmlTypePrivate *priv);
QList<QQmlType> types;
+ QSet<QQmlType> undeletableTypes;
typedef QHash<int, QQmlTypePrivate *> Ids;
Ids idToType;
typedef QHash<QHashedStringRef, QQmlTypePrivate *> Names;
@@ -131,8 +133,10 @@ public:
bool locked;
void add(QQmlTypePrivate *);
+ void remove(const QQmlTypePrivate *type);
- QStringHash<QList<QQmlTypePrivate *> > typeHash;
+ typedef QStringHash<QList<QQmlTypePrivate *> > TypeHash;
+ TypeHash typeHash;
};
Q_GLOBAL_STATIC(QQmlMetaTypeData, metaTypeData)
@@ -226,7 +230,7 @@ public:
struct PropertyCacheByMinorVersion
{
- PropertyCacheByMinorVersion() : cache(nullptr), minorVersion(-1) {}
+ PropertyCacheByMinorVersion() : cache(Q_NULLPTR), minorVersion(-1) {}
explicit PropertyCacheByMinorVersion(QQmlPropertyCache *pc, int ver) : cache(pc), minorVersion(ver) {}
QQmlPropertyCachePtr cache;
int minorVersion;
@@ -236,6 +240,19 @@ public:
void setPropertyCacheForMinorVersion(int minorVersion, QQmlPropertyCache *cache);
};
+void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
+{
+ for (int i = 0; i < types.count(); ++i) {
+ if (!types.at(i).isValid()) {
+ types[i] = QQmlType(priv);
+ priv->index = i;
+ return;
+ }
+ }
+ types.append(QQmlType(priv));
+ priv->index = types.count() - 1;
+}
+
void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(e->handle());
@@ -347,21 +364,23 @@ QQmlTypePrivate::~QQmlTypePrivate()
}
}
-QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &interface)
: d(new QQmlTypePrivate(InterfaceType))
{
d->iid = interface.iid;
d->typeId = interface.typeId;
d->listId = interface.listId;
- d->index = index;
d->isSetup = true;
d->version_maj = 0;
d->version_min = 0;
+ data->registerType(d);
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
: d(new QQmlTypePrivate(SingletonType))
{
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
@@ -377,8 +396,6 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
d->revision = type.revision;
}
- d->index = index;
-
d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
@@ -387,25 +404,27 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
= (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
: d(new QQmlTypePrivate(CompositeSingletonType))
{
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
d->version_maj = type.versionMajor;
d->version_min = type.versionMinor;
- d->index = index;
-
d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->url = type.url;
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterType &type)
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterType &type)
: d(new QQmlTypePrivate(CppType))
{
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
@@ -424,7 +443,7 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
if (d->extraData.cd->attachedPropertiesType) {
QHash<const QMetaObject *, int>::Iterator iter = d->attachedPropertyIds.find(d->baseMetaObject);
if (iter == d->attachedPropertyIds.end())
- iter = d->attachedPropertyIds.insert(d->baseMetaObject, index);
+ iter = d->attachedPropertyIds.insert(d->baseMetaObject, d->index);
d->extraData.cd->attachedPropertiesId = *iter;
} else {
d->extraData.cd->attachedPropertiesId = -1;
@@ -434,16 +453,16 @@ QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::Reg
d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast;
d->extraData.cd->extFunc = type.extensionObjectCreate;
d->extraData.cd->customParser = type.customParser;
- d->index = index;
if (type.extensionMetaObject)
d->extraData.cd->extMetaObject = type.extensionMetaObject;
}
-QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
+QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
: d(new QQmlTypePrivate(CompositeType))
{
- d->index = index;
+ data->registerType(d);
+
d->elementName = elementName;
d->module = QString::fromUtf8(type.uri);
@@ -772,7 +791,7 @@ QQmlPropertyCache *QQmlTypePrivate::propertyCacheForMinorVersion(int minorVersio
for (int i = 0; i < propertyCaches.count(); ++i)
if (propertyCaches.at(i).minorVersion == minorVersion)
return propertyCaches.at(i).cache;
- return nullptr;
+ return Q_NULLPTR;
}
void QQmlTypePrivate::setPropertyCacheForMinorVersion(int minorVersion, QQmlPropertyCache *cache)
@@ -1123,6 +1142,27 @@ void QQmlType::derefHandle(QQmlTypePrivate *priv)
delete priv;
}
+namespace {
+template <typename QQmlTypeContainer>
+void removeQQmlTypePrivate(QQmlTypeContainer &container, const QQmlTypePrivate *reference)
+{
+ for (typename QQmlTypeContainer::iterator it = container.begin(); it != container.end();) {
+ if (*it == reference)
+ it = container.erase(it);
+ else
+ ++it;
+ }
+}
+
+struct IsQQmlTypePrivate
+{
+ const QQmlTypePrivate *reference;
+ explicit IsQQmlTypePrivate(const QQmlTypePrivate *ref) : reference(ref) {}
+
+ bool operator()(const QQmlTypePrivate *priv) const { return reference == priv; }
+};
+}
+
QQmlTypeModule::QQmlTypeModule()
: d(new QQmlTypeModulePrivate)
{
@@ -1170,6 +1210,24 @@ void QQmlTypeModulePrivate::add(QQmlTypePrivate *type)
list.append(type);
}
+void QQmlTypeModulePrivate::remove(const QQmlTypePrivate *type)
+{
+ for (TypeHash::ConstIterator elementIt = typeHash.begin(); elementIt != typeHash.end();) {
+ QList<QQmlTypePrivate *> &list = typeHash[elementIt.key()];
+
+ removeQQmlTypePrivate(list, type);
+
+#if 0
+ if (list.isEmpty())
+ elementIt = typeHash.erase(elementIt);
+ else
+ ++elementIt;
+#else
+ ++elementIt;
+#endif
+ }
+}
+
QQmlType QQmlTypeModule::type(const QHashedStringRef &name, int minor) const
{
QMutexLocker lock(metaTypeDataLock());
@@ -1269,7 +1327,7 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
#endif
}
-int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
+static int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
@@ -1279,7 +1337,7 @@ int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
return data->parentFunctions.count() - 1;
}
-int registerInterface(const QQmlPrivate::RegisterInterface &interface)
+QQmlType registerInterface(const QQmlPrivate::RegisterInterface &interface)
{
if (interface.version > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
@@ -1287,13 +1345,10 @@ int registerInterface(const QQmlPrivate::RegisterInterface &interface)
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- int index = data->types.count();
-
- QQmlType type(index, interface);
+ QQmlType type(data, interface);
QQmlTypePrivate *priv = type.priv();
Q_ASSERT(priv);
- data->types.append(type);
data->idToType.insert(priv->typeId, priv);
data->idToType.insert(priv->listId, priv);
// XXX No insertMulti, so no multi-version interfaces?
@@ -1307,7 +1362,7 @@ int registerInterface(const QQmlPrivate::RegisterInterface &interface)
data->interfaces.setBit(interface.typeId, true);
data->lists.setBit(interface.listId, true);
- return index;
+ return type;
}
QString registrationTypeString(QQmlType::RegistrationType typeType)
@@ -1422,45 +1477,39 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
}
}
-int registerType(const QQmlPrivate::RegisterType &type)
+QQmlType registerType(const QQmlPrivate::RegisterType &type)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString elementName = QString::fromUtf8(type.elementName);
if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType dtype(index, elementName, type);
+ QQmlType dtype(data, elementName, type);
- data->types.append(dtype);
addTypeToData(dtype.priv(), data);
if (!type.typeId)
data->idToType.insert(dtype.typeId(), dtype.priv());
- return index;
+ return dtype;
}
-int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
+QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString typeName = QString::fromUtf8(type.typeName);
if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType dtype(index, typeName, type);
+ QQmlType dtype(data, typeName, type);
- data->types.append(dtype);
addTypeToData(dtype.priv(), data);
- return index;
+ return dtype;
}
-int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
+QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
QMutexLocker lock(metaTypeDataLock());
@@ -1470,22 +1519,19 @@ int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingleton
if (*(type.uri) == '\0')
fileImport = true;
if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? 0 : type.uri, typeName))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType dtype(index, typeName, type);
+ QQmlType dtype(data, typeName, type);
- data->types.append(dtype);
addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
files->insertMulti(type.url, dtype.priv());
- return index;
+ return dtype;
}
-int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
+QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
{
// Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
QMutexLocker lock(metaTypeDataLock());
@@ -1495,18 +1541,15 @@ int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
if (*(type.uri) == '\0')
fileImport = true;
if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName, type.versionMajor))
- return -1;
-
- int index = data->types.count();
+ return QQmlType();
- QQmlType dtype(index, typeName, type);
- data->types.append(dtype);
+ QQmlType dtype(data, typeName, type);
addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
files->insertMulti(type.url, dtype.priv());
- return index;
+ return dtype;
}
int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration)
@@ -1525,22 +1568,30 @@ the future without adding exported symbols.
*/
int QQmlPrivate::qmlregister(RegistrationType type, void *data)
{
- if (type == TypeRegistration) {
- return registerType(*reinterpret_cast<RegisterType *>(data));
- } else if (type == InterfaceRegistration) {
- return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
- } else if (type == AutoParentRegistration) {
+ if (type == AutoParentRegistration)
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
- } else if (type == SingletonRegistration) {
- return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
- } else if (type == CompositeRegistration) {
- return registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
- } else if (type == CompositeSingletonRegistration) {
- return registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
- } else if (type == QmlUnitCacheHookRegistration) {
+ else if (type == QmlUnitCacheHookRegistration)
return registerQmlUnitCacheHook(*reinterpret_cast<RegisterQmlUnitCacheHook *>(data));
- }
- return -1;
+
+ QQmlType dtype;
+ if (type == TypeRegistration)
+ dtype = registerType(*reinterpret_cast<RegisterType *>(data));
+ else if (type == InterfaceRegistration)
+ dtype = registerInterface(*reinterpret_cast<RegisterInterface *>(data));
+ else if (type == SingletonRegistration)
+ dtype = registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
+ else if (type == CompositeRegistration)
+ dtype = QQmlMetaType::registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
+ else if (type == CompositeSingletonRegistration)
+ dtype = QQmlMetaType::registerCompositeSingletonType(*reinterpret_cast<RegisterCompositeSingletonType *>(data));
+ else
+ return -1;
+
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *typeData = metaTypeData();
+ typeData->undeletableTypes.insert(dtype);
+
+ return dtype.index();
}
//From qqml.h
@@ -1982,21 +2033,6 @@ QQmlType QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* =
return QQmlType();
}
-/*!
- Returns the type (if any) with the given \a index in the global type store.
- This is for use when you just got the index back from a qmlRegister function.
- Returns null if the index is out of bounds.
-*/
-QQmlType QQmlMetaType::qmlTypeFromIndex(int idx)
-{
- QMutexLocker lock(metaTypeDataLock());
- QQmlMetaTypeData *data = metaTypeData();
-
- if (idx < 0 || idx >= data->types.count())
- return QQmlType();
- return data->types.at(idx);
-}
-
QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QMetaObject *metaObject)
{
if (QQmlPropertyCache *rv = propertyCaches.value(metaObject))
@@ -2132,6 +2168,61 @@ QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVe
return data->propertyCache(type, minorVersion);
}
+void QQmlMetaType::freeUnusedTypesAndCaches()
+{
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ {
+ bool deletedAtLeastOneType;
+ do {
+ deletedAtLeastOneType = false;
+ QList<QQmlType>::Iterator it = data->types.begin();
+ while (it != data->types.end()) {
+ const QQmlTypePrivate *d = (*it).priv();
+ if (d && d->refCount == 1) {
+ deletedAtLeastOneType = true;
+
+ removeQQmlTypePrivate(data->idToType, d);
+ removeQQmlTypePrivate(data->nameToType, d);
+ removeQQmlTypePrivate(data->urlToType, d);
+ removeQQmlTypePrivate(data->urlToNonFileImportType, d);
+ removeQQmlTypePrivate(data->metaObjectToType, d);
+
+ for (QQmlMetaTypeData::TypeModules::Iterator module = data->uriToModule.begin(); module != data->uriToModule.end(); ++module) {
+ QQmlTypeModulePrivate *modulePrivate = (*module)->priv();
+ modulePrivate->remove(d);
+ }
+
+ *it = QQmlType();
+ } else {
+ ++it;
+ }
+ }
+ } while (deletedAtLeastOneType);
+ }
+
+ {
+ bool deletedAtLeastOneCache;
+ do {
+ deletedAtLeastOneCache = false;
+ QHash<const QMetaObject *, QQmlPropertyCache *>::Iterator it = data->propertyCaches.begin();
+ while (it != data->propertyCaches.end()) {
+
+ if ((*it)->count() == 1) {
+ QQmlPropertyCache *pc = Q_NULLPTR;
+ qSwap(pc, *it);
+ it = data->propertyCaches.erase(it);
+ pc->release();
+ deletedAtLeastOneCache = true;
+ } else {
+ ++it;
+ }
+ }
+ } while (deletedAtLeastOneCache);
+ }
+}
+
/*!
Returns the list of registered QML type names.
*/
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 0077306a64..c0fbdd5060 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -77,6 +77,9 @@ namespace QV4 { struct String; }
class Q_QML_PRIVATE_EXPORT QQmlMetaType
{
public:
+ static QQmlType registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &type);
+ static QQmlType registerCompositeType(const QQmlPrivate::RegisterCompositeType &type);
+
static QList<QString> qmlTypeNames();
static QList<QQmlType> qmlTypes();
static QList<QQmlType> qmlSingletonTypes();
@@ -88,11 +91,12 @@ public:
static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
static QQmlType qmlType(int);
static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false);
- static QQmlType qmlTypeFromIndex(int);
static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject);
static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
+ static void freeUnusedTypesAndCaches();
+
static QMetaProperty defaultProperty(const QMetaObject *);
static QMetaProperty defaultProperty(QObject *);
static QMetaMethod defaultMethod(const QMetaObject *);
@@ -237,11 +241,6 @@ public:
QQmlTypePrivate *priv() const { return d; }
static void refHandle(QQmlTypePrivate *priv);
static void derefHandle(QQmlTypePrivate *priv);
-private:
- QQmlType superType() const;
- QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const;
- int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const;
- friend class QQmlTypePrivate;
enum RegistrationType {
CppType = 0,
@@ -250,21 +249,28 @@ private:
CompositeType = 3,
CompositeSingletonType = 4
};
+
+private:
+ QQmlType superType() const;
+ QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const;
+ int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const;
+ friend class QQmlTypePrivate;
+
friend QString registrationTypeString(RegistrationType);
friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &, int);
- friend int registerType(const QQmlPrivate::RegisterType &);
- friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
- friend int registerInterface(const QQmlPrivate::RegisterInterface &);
- friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &);
- friend int registerCompositeSingletonType(const QQmlPrivate::RegisterCompositeSingletonType &);
+ friend QQmlType registerType(const QQmlPrivate::RegisterType &);
+ friend QQmlType registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
+ friend QQmlType registerInterface(const QQmlPrivate::RegisterInterface &);
friend int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &);
friend uint qHash(const QQmlType &t, uint seed);
friend Q_QML_EXPORT void qmlClearTypeRegistrations();
- QQmlType(int, const QQmlPrivate::RegisterInterface &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterType &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeType &);
- QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &);
+ friend class QQmlMetaType;
+
+ QQmlType(QQmlMetaTypeData *data, const QQmlPrivate::RegisterInterface &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterSingletonType &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterType &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeType &);
+ QQmlType(QQmlMetaTypeData *data, const QString &, const QQmlPrivate::RegisterCompositeSingletonType &);
QQmlTypePrivate *d;
};
@@ -288,6 +294,7 @@ public:
QQmlType type(const QHashedStringRef &, int) const;
QQmlType type(const QV4::String *, int) const;
+ QQmlTypeModulePrivate *priv() { return d; }
private:
//Used by register functions and creates the QQmlTypeModule for them
friend QQmlTypeModule *getTypeModule(const QHashedString &uri, int majorVersion, QQmlMetaTypeData *data);
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index fbb04af165..2825e0d698 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1947,6 +1947,7 @@ void QQmlTypeLoader::clearCache()
m_qmldirCache.clear();
m_importDirCache.clear();
m_importQmlDirCache.clear();
+ QQmlMetaType::freeUnusedTypesAndCaches();
}
void QQmlTypeLoader::updateTypeCacheTrimThreshold()
@@ -1988,6 +1989,8 @@ void QQmlTypeLoader::trimCache()
updateTypeCacheTrimThreshold();
+ QQmlMetaType::freeUnusedTypesAndCaches();
+
// TODO: release any scripts which are no longer referenced by any types
}