From c5bf202f21a4f429d7d63b26be3650bfa0886edf Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 29 Feb 2024 14:48:01 +0100 Subject: [PATCH] QJniObject: use ctor delegation instead of construct+assign MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old code used unintialized construction followed by (move) assignment to construct a QJniObject that requires a LocalFrame object. That is two constructors and therefore one more than we need (and need to destroy in inline code again). Everything can be solved with another level of indirection.™ Since the LocalFrame needs to remain alive for the duration of argument evaluation, the usual comma operator trick won't work. But we can add a private helper ctor that takes the LocalFrame as an additional argument to inject the object with the correct lifetime into the ctor delegation chain. Put the new argument in the front, to avoid clashes with the primary contructor's trailing universal references, which might be a better match than the new overload had we added the argument at the end. The hope is that the compiler will avoid the ensuing register shuffling by inlining the outer two constructor calls. This brings the number of QJniObjects constructed down to one, as it should be. We might also be able to remove the Uninitialized ctor again. Found in API-review. Amends 62cb5589b3723fe8162e190cd54d9c78929b98d2. Change-Id: I326187e54fd0705a1bbedb2d51d94a46b108a3c8 Reviewed-by: Qt CI Bot Reviewed-by: Volker Hilsheimer (cherry picked from commit ddaf7642828c970a69c995a606c5cb16e003c26c) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qjniobject.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h index 178a4b7faac..ecce99433fb 100644 --- a/src/corelib/kernel/qjniobject.h +++ b/src/corelib/kernel/qjniobject.h @@ -69,12 +69,17 @@ public: #endif > explicit QJniObject(const char *className, Args &&...args) - : QJniObject(Qt::Uninitialized) + : QJniObject(LocalFrame{}, className, std::forward(args)...) { - LocalFrame localFrame; - *this = QJniObject(className, QtJniTypes::constructorSignature().data(), - localFrame.convertToJni(std::forward(args))...); } +private: + template + explicit QJniObject(LocalFrame localFrame, const char *className, Args &&...args) + : QJniObject(className, QtJniTypes::constructorSignature().data(), + localFrame.convertToJni(std::forward(args))...) + { + } +public: explicit QJniObject(jclass clazz); explicit QJniObject(jclass clazz, const char *signature, ...); template