diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-05-20 08:32:11 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-05-20 15:46:21 +0200 |
commit | f65493489e3ca0a86a5e014d3ea2803368d77cd3 (patch) | |
tree | 4554cbcfd5246964dff15c7f07e9949cd1674d89 | |
parent | afb081115d05c010aa4c80c985f69f8f333264c7 (diff) |
QQmlObjectCreator: Avoid atomic operations
Atomic ref-counting has a notable performance overhead in the object
creator in creation heavy benchmarks. Considering that allCreatedObjects
and sharedState are only managed by a single thread, we can avoid this.
To that end, we do two datatype replacements:
1. Replace QSharedData/QExplicitlySharedDataPointer with
QQmlRefCount/QQmlRef for sharedData.
2. Replace QPointer with QQmlGuard for allCreatedObjects. Note that
shortly before pushing the object to the (finite) stack of QPointer,
we created its DeclarativeData. Thus, using QQmlGuard has no overhead
here; it probably even reduces it, as we no longer unconditionally
allocate the sharedRefCount of the QObject.
Task-number: QTBUG-88672
Change-Id: I76bf0ca2f2c479fd9c389ec7843c882abe3cda80
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlvme.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlvme_p.h | 2 |
4 files changed, 9 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 51a6b37f51..c0cc917499 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -80,7 +80,7 @@ QQmlObjectCreator::QQmlObjectCreator( : phase(Startup) , compilationUnit(compilationUnit) , propertyCaches(&compilationUnit->propertyCaches) - , sharedState(new QQmlObjectCreatorSharedState) + , sharedState(new QQmlObjectCreatorSharedState, QQmlRefPointer<QQmlObjectCreatorSharedState>::Adopt) , topLevelCreator(true) , incubator(incubator) { diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 0059c6da7b..1881b3eb23 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -89,13 +89,13 @@ struct RequiredPropertyInfo class RequiredProperties : public QHash<QQmlPropertyData*, RequiredPropertyInfo> {}; -struct QQmlObjectCreatorSharedState : public QSharedData +struct QQmlObjectCreatorSharedState : QQmlRefCount { QQmlRefPointer<QQmlContextData> rootContext; QQmlRefPointer<QQmlContextData> creationContext; QFiniteStack<QQmlAbstractBinding::Ptr> allCreatedBindings; QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks; - QFiniteStack<QPointer<QObject> > allCreatedObjects; + QFiniteStack<QQmlGuard<QObject> > allCreatedObjects; QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase. QQmlComponentAttached *componentAttached; QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks; @@ -141,7 +141,7 @@ public: { return parentContext.contextData(); } - QFiniteStack<QPointer<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; } + QFiniteStack<QQmlGuard<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; } RequiredProperties &requiredProperties() {return sharedState->requiredProperties;} bool componentHadRequiredProperties() const {return sharedState->hadRequiredProperties;} @@ -195,7 +195,7 @@ private: QQmlGuardedContextData parentContext; QQmlRefPointer<QQmlContextData> context; const QQmlPropertyCacheVector *propertyCaches; - QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState; + QQmlRefPointer<QQmlObjectCreatorSharedState> sharedState; bool topLevelCreator; QQmlIncubatorPrivate *incubator; @@ -225,7 +225,7 @@ struct QQmlObjectCreatorRecursionWatcher bool hasRecursed() const { return watcher.hasRecursed(); } private: - QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState; + QQmlRefPointer<QQmlObjectCreatorSharedState> sharedState; QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher; }; diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index cf073dc768..d120f34d1a 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -107,9 +107,9 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator) { clear(); - QFiniteStack<QPointer<QObject> > &objects = creator->allCreatedObjects(); + QFiniteStack<QQmlGuard<QObject> > &objects = creator->allCreatedObjects(); m_objectCount = objects.count(); - m_objects = new QPointer<QObject>[m_objectCount]; + m_objects = new QQmlGuard<QObject>[m_objectCount]; for (int ii = 0; ii < m_objectCount; ++ii) m_objects[ii] = objects[ii]; diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h index 78631ecdf8..9b4bb63d25 100644 --- a/src/qml/qml/qqmlvme_p.h +++ b/src/qml/qml/qqmlvme_p.h @@ -116,7 +116,7 @@ public: private: int m_objectCount; - QPointer<QObject> *m_objects; + QQmlGuard<QObject> *m_objects; int m_contextCount; QQmlGuardedContextData *m_contexts; }; |