diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-03-24 18:01:16 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-03-29 09:04:13 +0100 |
commit | b82ae347397595241dcd4a5848ad0c6bfae4574b (patch) | |
tree | 045bea2be5ac6c88ccf498537913e200a4e627d6 /src | |
parent | bd294e78239a198c9c7458a490681d170823a97f (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.h | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 4 |
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); } |