aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlboundsignal.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-03-31 15:29:48 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-04-01 10:14:16 +0200
commite99bcbd8bfe97f7b5b38f489de499cc15fbb9d19 (patch)
treeebbb9bce518b2e5048c334e8b7266ac02766cb35 /src/qml/qml/qqmlboundsignal.cpp
parente7e4eba6875c0f375c4fd03af9b3ed9ea44d0ba1 (diff)
Optimize invocation of signal handlers
We don't have to do any argument conversion if there are no arguments. Furthermore, we don't need to do the metatype-to-JS conversion if the handler to be invoked is AOT-compiled. Change-Id: I03d8fd7ad07d311d64c39adfd39febbe94396d2f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlboundsignal.cpp')
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index ee8fbe94e0..e624dc6e34 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -187,16 +187,32 @@ void QQmlBoundSignalExpression::evaluate(void **a)
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
- QQmlMetaObject::ArgTypeStorage storage;
- //TODO: lookup via signal index rather than method index as an optimization
- int methodIndex = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).methodIndex();
- bool ok = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, nullptr);
- const int argCount = ok ? storage.size() : 0;
-
- QV4::JSCallArguments jsCall(scope, argCount);
- populateJSCallArguments(v4, jsCall, argCount, a, storage.constData());
+ if (a) {
+ //TODO: lookup via signal index rather than method index as an optimization
+ const QMetaObject *targetMeta = m_target->metaObject();
+ const QMetaMethod metaMethod = targetMeta->method(
+ QMetaObjectPrivate::signal(targetMeta, m_index).methodIndex());
+
+ int argCount = metaMethod.parameterCount();
+ QQmlMetaObject::ArgTypeStorage storage;
+ storage.reserve(argCount + 1);
+ storage.append(QMetaType()); // We're not interested in the return value
+ for (int i = 0; i < argCount; ++i) {
+ const QMetaType type = metaMethod.parameterMetaType(i);
+ if (!type.isValid())
+ argCount = 0;
+ else if (type.flags().testFlag(QMetaType::IsEnumeration))
+ storage.append(QMetaType::fromType<int>());
+ else
+ storage.append(type);
+ }
- QQmlJavaScriptExpression::evaluate(jsCall.callData(scope), nullptr);
+ QQmlJavaScriptExpression::evaluate(a, storage.constData(), argCount);
+ } else {
+ void *ignoredResult = nullptr;
+ QMetaType invalidType;
+ QQmlJavaScriptExpression::evaluate(&ignoredResult, &invalidType, 0);
+ }
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}