aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-03-24 18:01:16 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-03-29 09:04:13 +0100
commitb82ae347397595241dcd4a5848ad0c6bfae4574b (patch)
tree045bea2be5ac6c88ccf498537913e200a4e627d6 /src
parentbd294e78239a198c9c7458a490681d170823a97f (diff)
Avoid needless construction and destruction of return values
In most cases the AOT compiled function will successfully placement-new the return value. Therefore, we can provide uninitialized space. Only do the construct/destruct dance in the cases when it's already slow. Change-Id: Ia339774fde03e459f290f167ddadd1c47a644b8e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h12
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp12
-rw-r--r--src/qml/qml/qqmlbinding.cpp1
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp4
4 files changed, 15 insertions, 14 deletions
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h
index de4acca8a3..3f0c8ee06d 100644
--- a/src/qml/jsruntime/qv4jscall_p.h
+++ b/src/qml/jsruntime/qv4jscall_p.h
@@ -184,7 +184,6 @@ ReturnedValue convertAndCall(
types[0] = aotFunction->returnType;
if (const qsizetype returnSize = types[0].sizeOf()) {
Q_ALLOCA_ASSIGN(void, returnValue, returnSize);
- types[0].construct(returnValue);
values[0] = returnValue;
} else {
values[0] = nullptr;
@@ -227,15 +226,16 @@ void convertAndCall(ExecutionEngine *engine, const Value *thisObject,
const QMetaType resultType = types[0];
if (scope.hasException()) {
// Clear the return value
- resultType.destruct(result);
- resultType.construct(result, nullptr);
+ resultType.construct(result);
} else {
// When the return type is QVariant, JS objects are to be returned as
// QJSValue wrapped in QVariant. metaTypeFromJS unwraps them, unfortunately.
- if (resultType == QMetaType::fromType<QVariant>())
- *static_cast<QVariant *>(result) = scope.engine->toVariant(jsResult, QMetaType {});
- else
+ if (resultType == QMetaType::fromType<QVariant>()) {
+ new (result) QVariant(scope.engine->toVariant(jsResult, QMetaType {}));
+ } else {
+ resultType.construct(result);
scope.engine->metaTypeFromJS(jsResult, resultType, result);
+ }
}
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index eb18ea933b..9077529277 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -468,13 +468,9 @@ void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine)
const QMetaType returnType = function->aotFunction->returnType;
Q_ALLOCA_DECLARE(void, transformedResult);
- if (frame->returnValue()) {
- if (returnType == frame->returnType()) {
- returnType.destruct(frame->returnValue());
- } else {
- Q_ASSERT(returnType.sizeOf() > 0);
- Q_ALLOCA_ASSIGN(void, transformedResult, returnType.sizeOf());
- }
+ if (frame->returnValue() && returnType != frame->returnType()) {
+ Q_ASSERT(returnType.sizeOf() > 0);
+ Q_ALLOCA_ASSIGN(void, transformedResult, returnType.sizeOf());
}
QQmlPrivate::AOTCompiledContext aotContext;
@@ -491,6 +487,8 @@ void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine)
transformedArguments ? transformedArguments : frame->argv());
if (transformedResult) {
+ // Convert needs a pre-constructed target.
+ frame->returnType().construct(frame->returnValue());
QMetaType::convert(returnType, transformedResult,
frame->returnType(), frame->returnValue());
returnType.destruct(transformedResult);
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index b9d783736c..650482b3f0 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -255,7 +255,6 @@ protected:
const auto size = returnType.sizeOf();
if (Q_LIKELY(size > 0)) {
Q_ALLOCA_VAR(void, result, size);
- returnType.construct(result);
const bool isUndefined = !evaluate(result, returnType);
if (canWrite())
error = !write(result, returnType, isUndefined, flags);
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 7580d45104..7e6e4b1ef3 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -1002,10 +1002,14 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if (arguments && arguments->names) {
const auto parameterCount = arguments->names->count();
Q_ASSERT(parameterCount == function->formalParameterCount());
+ if (void *result = a[0])
+ arguments->types[0].destruct(result);
function->call(v4->globalObject, a, arguments->types, parameterCount);
} else {
Q_ASSERT(function->formalParameterCount() == 0);
const QMetaType returnType = methodData->propType();
+ if (void *result = a[0])
+ returnType.destruct(result);
function->call(v4->globalObject, a, &returnType, 0);
}