From 15b5b28425f52fcbb2b85c94ec485af841adb4b5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 15 Aug 2012 16:42:06 +0200 Subject: [PATCH] QSlotObjectBase: re-enable tail-call optimisation in impl() Two of the three operations in impl() return void, among them the most common one, call(). Having impl() return bool prevents tail- call optimisations for these. Fix by passing the bool return value for Compare as an out-parameter. Results in a nice decrease in text size (GCC 4.8-pre -O2 -std=c++11, stripped): text data bss dec hex filename 507343 13984 48 521375 7f49f tst_qobject (old) 505551 13984 48 519583 7ed9f tst_qobject (new) Reported-by: Thiago Macieira Change-Id: I7538c5b3f0992970c089e44f07244e6b62794a1d Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart --- src/corelib/kernel/qobject_impl.h | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index eeb64db0dd..f5187c803a 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -113,13 +113,13 @@ namespace QtPrivate { NumOperations }; - typedef bool (*ImplFn)(int which, QSlotObjectBase* this_, QObject *receiver, void **args); + typedef void (*ImplFn)(int which, QSlotObjectBase* this_, QObject *receiver, void **args, bool *ret); const ImplFn impl; explicit QSlotObjectBase(ImplFn fn) : ref(1), impl(fn) {} // ### make constexpr once QAtomicInt's ctor is, too - inline void destroy() { impl(Destroy, this, 0, 0); } - inline bool compare(void **a) { return impl(Compare, this, 0, a); } - inline void call(QObject *r, void **a) { impl(Call, this, r, a); } + inline void destroy() { impl(Destroy, this, 0, 0, 0); } + inline bool compare(void **a) { bool ret; impl(Compare, this, 0, a, &ret); return ret; } + inline void call(QObject *r, void **a) { impl(Call, this, r, a, 0); } protected: ~QSlotObjectBase() {} }; @@ -129,20 +129,20 @@ namespace QtPrivate { { typedef QtPrivate::FunctionPointer FuncType; Func function; - static bool impl(int which, QSlotObjectBase *this_, QObject *r, void **a) + static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) { switch (which) { case Destroy: delete static_cast(this_); - return true; + break; case Call: FuncType::template call(static_cast(this_)->function, static_cast(r), a); - return true; + break; case Compare: - return *reinterpret_cast(a) == static_cast(this_)->function; + *ret = *reinterpret_cast(a) == static_cast(this_)->function; + break; case NumOperations: ; } - return false; } public: explicit QSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {} @@ -153,20 +153,20 @@ namespace QtPrivate { { typedef QtPrivate::FunctionPointer FuncType; Func function; - static bool impl(int which, QSlotObjectBase *this_, QObject *r, void **a) + static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) { switch (which) { case Destroy: delete static_cast(this_); - return true; + break; case Call: FuncType::template call(static_cast(this_)->function, r, a); - return true; + break; case Compare: - return false; // not implemented + *ret = false; // not implemented + break; case NumOperations: ; } - return false; } public: explicit QStaticSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {} @@ -178,20 +178,20 @@ namespace QtPrivate { { typedef QtPrivate::Functor FuncType; Func function; - static bool impl(int which, QSlotObjectBase *this_, QObject *r, void **a) + static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) { switch (which) { case Destroy: delete static_cast(this_); - return true; + break; case Call: FuncType::template call(static_cast(this_)->function, r, a); - return true; + break; case Compare: - return false; // not implemented + *ret = false; // not implemented + break; case NumOperations: ; } - return false; } public: explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}