summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject_p.h
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2012-08-10 16:12:58 +0200
committerQt by Nokia <qt-info@nokia.com>2012-08-15 23:40:57 +0200
commit04c286ceb60311d4d7e1ae589b99d1ed7120c9cf (patch)
treec8e2efa83cf8a286dc9717eea54c1f9a25ab8cfc /src/corelib/kernel/qobject_p.h
parent3ef51efbe75bfb9f1dfbe7df073e9eb745a72ad8 (diff)
QSlotObjectBase: combat virtual function "bloat"
In C++, the compiler creates extra functions and data for classes with virtual functions. This can lead to "virtual function bloat": http://www.boost.org/doc/libs/1_47_0/doc/html/function/misc.html#id1382504 This is especially true when the number of instances is of the same order of magnitute as the number of derived classes, such as is common with type erasure techniques. One such case is the QSlotObjectBase hierarchy, which this patch tackles. The mechanics of this optimisation are simple: re-implement the virtual function call mechanism by hand, with function pointers. But we go one step further and collapse the vtable into a single pointer to a function that implements all three currently-defined operations, swtching on an 'int which' argument. This even allows us to extend this in a BC way, should that become necessary later, by adding a new Operation and using the void** argument to transport arguments, if any. This approach was inspired by: Ulrich Drepper: How To Write Shared Libraries, Section 2.4.4 http://www.akkadia.org/drepper/dsohowto.pdf Also move the QSlotObjectBase hierarchy out of QObject so as not to export all the derived classes. This was pointed out in review by Thiago. Results (Linux amd64, GCC 4.8-pre -O2 -std=c++11, stripped): size tst_qobject* text data bss dec hex filename 523275 21192 48 544515 84f03 tst_qobject (old) 507343 13984 48 521375 7f49f tst_qobject (new) relinfo.pl tst_qobject* (old) tst_qobject: 473 relocations, 0 relative (0%), 240 PLT entries, 240 for local syms (100%), 0 users (new) tst_qobject: 323 relocations, 0 relative (0%), 238 PLT entries, 238 for local syms (100%), 0 users Change-Id: I40ad4744dde8c5c29ef62ed2d82d4b1ede178510 Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel/qobject_p.h')
-rw-r--r--src/corelib/kernel/qobject_p.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 02580caf41..d47426b14c 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -120,7 +120,7 @@ public:
QObject *receiver;
union {
StaticMetaCallFunction callFunction;
- QObject::QSlotObjectBase *slotObj;
+ QtPrivate::QSlotObjectBase *slotObj;
};
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
@@ -280,7 +280,7 @@ public:
/*! \internal
\a signalId is in the signal index range (see QObjectPrivate::signalIndex()).
*/
- QMetaCallEvent(QObject::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
+ QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
~QMetaCallEvent();
@@ -293,7 +293,7 @@ public:
virtual void placeMetaCall(QObject *object);
private:
- QObject::QSlotObjectBase *slotObj_;
+ QtPrivate::QSlotObjectBase *slotObj_;
const QObject *sender_;
int signalId_;
int nargs_;