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 <thiago.macieira@intel.com> Change-Id: I7538c5b3f0992970c089e44f07244e6b62794a1d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>bb10
parent
04c286ceb6
commit
15b5b28425
|
|
@ -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<Func> 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<QSlotObject*>(this_);
|
||||
return true;
|
||||
break;
|
||||
case Call:
|
||||
FuncType::template call<Args, R>(static_cast<QSlotObject*>(this_)->function, static_cast<typename FuncType::Object *>(r), a);
|
||||
return true;
|
||||
break;
|
||||
case Compare:
|
||||
return *reinterpret_cast<Func *>(a) == static_cast<QSlotObject*>(this_)->function;
|
||||
*ret = *reinterpret_cast<Func *>(a) == static_cast<QSlotObject*>(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<Func> 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<QStaticSlotObject*>(this_);
|
||||
return true;
|
||||
break;
|
||||
case Call:
|
||||
FuncType::template call<Args, R>(static_cast<QStaticSlotObject*>(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<Func, N> 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<QFunctorSlotObject*>(this_);
|
||||
return true;
|
||||
break;
|
||||
case Call:
|
||||
FuncType::template call<Args, R>(static_cast<QFunctorSlotObject*>(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) {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue