Move rarely used QObjectPrivate data to extraData
Move runningTimers, eventFilters and objectName data members to ExtraData. Saves 12 bytes per QObject for 95% of use cases (QObjectPrivate goes from 76B -> 64B). Change-Id: I5648c89f65a7be3ea51bd703ee8a9dcff6222c3c Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
parent
0b8021f5cb
commit
11fa02c5cd
@ -789,10 +789,10 @@ bool QCoreApplication::notify(QObject *receiver, QEvent *event)
|
||||
|
||||
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
|
||||
{
|
||||
if (receiver->d_func()->threadData == this->threadData) {
|
||||
if (receiver->d_func()->threadData == this->threadData && extraData) {
|
||||
// application event filters are only called for objects in the GUI thread
|
||||
for (int i = 0; i < eventFilters.size(); ++i) {
|
||||
register QObject *obj = eventFilters.at(i);
|
||||
for (int i = 0; i < extraData->eventFilters.size(); ++i) {
|
||||
register QObject *obj = extraData->eventFilters.at(i);
|
||||
if (!obj)
|
||||
continue;
|
||||
if (obj->d_func()->threadData != threadData) {
|
||||
@ -809,9 +809,9 @@ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiv
|
||||
bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
|
||||
{
|
||||
Q_Q(QCoreApplication);
|
||||
if (receiver != q) {
|
||||
for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
|
||||
register QObject *obj = receiver->d_func()->eventFilters.at(i);
|
||||
if (receiver != q && receiver->d_func()->extraData) {
|
||||
for (int i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
|
||||
register QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
|
||||
if (!obj)
|
||||
continue;
|
||||
if (obj->d_func()->threadData != receiver->d_func()->threadData) {
|
||||
|
@ -70,16 +70,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct QObjectPrivate::ExtraData
|
||||
{
|
||||
ExtraData() {}
|
||||
#ifndef QT_NO_USERDATA
|
||||
QVector<QObjectUserData *> userData;
|
||||
#endif
|
||||
QList<QByteArray> propertyNames;
|
||||
QList<QVariant> propertyValues;
|
||||
};
|
||||
|
||||
static int DIRECT_CONNECTION_ONLY = 0;
|
||||
|
||||
static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
|
||||
@ -217,14 +207,14 @@ QObjectPrivate::QObjectPrivate(int version)
|
||||
|
||||
QObjectPrivate::~QObjectPrivate()
|
||||
{
|
||||
if (!runningTimers.isEmpty()) {
|
||||
if (extraData && !extraData->runningTimers.isEmpty()) {
|
||||
// unregister pending timers
|
||||
if (threadData->eventDispatcher)
|
||||
threadData->eventDispatcher->unregisterTimers(q_ptr);
|
||||
|
||||
// release the timer ids back to the pool
|
||||
for (int i = 0; i < runningTimers.size(); ++i)
|
||||
QAbstractEventDispatcherPrivate::releaseTimerId(runningTimers.at(i));
|
||||
for (int i = 0; i < extraData->runningTimers.size(); ++i)
|
||||
QAbstractEventDispatcherPrivate::releaseTimerId(extraData->runningTimers.at(i));
|
||||
}
|
||||
|
||||
if (postedEvents)
|
||||
@ -237,8 +227,8 @@ QObjectPrivate::~QObjectPrivate()
|
||||
#ifndef QT_NO_USERDATA
|
||||
if (extraData)
|
||||
qDeleteAll(extraData->userData);
|
||||
delete extraData;
|
||||
#endif
|
||||
delete extraData;
|
||||
}
|
||||
|
||||
/*!\internal
|
||||
@ -983,7 +973,7 @@ QObjectPrivate::Connection::~Connection()
|
||||
QString QObject::objectName() const
|
||||
{
|
||||
Q_D(const QObject);
|
||||
return d->objectName;
|
||||
return d->extraData ? d->extraData->objectName : QString();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -992,9 +982,12 @@ QString QObject::objectName() const
|
||||
void QObject::setObjectName(const QString &name)
|
||||
{
|
||||
Q_D(QObject);
|
||||
if (d->objectName != name) {
|
||||
d->objectName = name;
|
||||
emit objectNameChanged(d->objectName);
|
||||
if (!d->extraData)
|
||||
d->extraData = new QObjectPrivate::ExtraData;
|
||||
|
||||
if (d->extraData->objectName != name) {
|
||||
d->extraData->objectName = name;
|
||||
emit objectNameChanged(d->extraData->objectName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1425,7 +1418,9 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
|
||||
return 0;
|
||||
}
|
||||
int timerId = d->threadData->eventDispatcher->registerTimer(interval, timerType, this);
|
||||
d->runningTimers.append(timerId);
|
||||
if (!d->extraData)
|
||||
d->extraData = new QObjectPrivate::ExtraData;
|
||||
d->extraData->runningTimers.append(timerId);
|
||||
return timerId;
|
||||
}
|
||||
|
||||
@ -1442,7 +1437,7 @@ void QObject::killTimer(int id)
|
||||
{
|
||||
Q_D(QObject);
|
||||
if (id) {
|
||||
int at = d->runningTimers.indexOf(id);
|
||||
int at = d->extraData ? d->extraData->runningTimers.indexOf(id) : -1;
|
||||
if (at == -1) {
|
||||
// timer isn't owned by this object
|
||||
qWarning("QObject::killTimer(): Error: timer id %d is not valid for object %p (%s), timer has not been killed",
|
||||
@ -1455,7 +1450,7 @@ void QObject::killTimer(int id)
|
||||
if (d->threadData->eventDispatcher)
|
||||
d->threadData->eventDispatcher->unregisterTimer(id);
|
||||
|
||||
d->runningTimers.remove(at);
|
||||
d->extraData->runningTimers.remove(at);
|
||||
QAbstractEventDispatcherPrivate::releaseTimerId(id);
|
||||
}
|
||||
}
|
||||
@ -1844,10 +1839,13 @@ void QObject::installEventFilter(QObject *obj)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->extraData)
|
||||
d->extraData = new QObjectPrivate::ExtraData;
|
||||
|
||||
// clean up unused items in the list
|
||||
d->eventFilters.removeAll((QObject*)0);
|
||||
d->eventFilters.removeAll(obj);
|
||||
d->eventFilters.prepend(obj);
|
||||
d->extraData->eventFilters.removeAll((QObject*)0);
|
||||
d->extraData->eventFilters.removeAll(obj);
|
||||
d->extraData->eventFilters.prepend(obj);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1866,9 +1864,11 @@ void QObject::installEventFilter(QObject *obj)
|
||||
void QObject::removeEventFilter(QObject *obj)
|
||||
{
|
||||
Q_D(QObject);
|
||||
for (int i = 0; i < d->eventFilters.count(); ++i) {
|
||||
if (d->eventFilters.at(i) == obj)
|
||||
d->eventFilters[i] = 0;
|
||||
if (d->extraData) {
|
||||
for (int i = 0; i < d->extraData->eventFilters.count(); ++i) {
|
||||
if (d->extraData->eventFilters.at(i) == obj)
|
||||
d->extraData->eventFilters[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "QtCore/qcoreevent.h"
|
||||
#include "QtCore/qlist.h"
|
||||
#include "QtCore/qvector.h"
|
||||
#include "QtCore/qvariant.h"
|
||||
#include "QtCore/qreadwritelock.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -97,8 +98,19 @@ class Q_CORE_EXPORT QObjectPrivate : public QObjectData
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QObject)
|
||||
|
||||
struct ExtraData;
|
||||
public:
|
||||
struct ExtraData
|
||||
{
|
||||
ExtraData() {}
|
||||
#ifndef QT_NO_USERDATA
|
||||
QVector<QObjectUserData *> userData;
|
||||
#endif
|
||||
QList<QByteArray> propertyNames;
|
||||
QList<QVariant> propertyValues;
|
||||
QVector<int> runningTimers;
|
||||
QList<QPointer<QObject> > eventFilters;
|
||||
QString objectName;
|
||||
};
|
||||
|
||||
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
|
||||
struct Connection
|
||||
@ -179,7 +191,6 @@ public:
|
||||
inline bool isSignalConnected(uint signalIdx) const;
|
||||
|
||||
public:
|
||||
QString objectName;
|
||||
ExtraData *extraData; // extra data set by the user
|
||||
QThreadData *threadData; // id of the thread that owns the object
|
||||
|
||||
@ -189,8 +200,6 @@ public:
|
||||
Sender *currentSender; // object currently activating the object
|
||||
mutable quint32 connectedSignals[2];
|
||||
|
||||
QVector<int> runningTimers;
|
||||
QList<QPointer<QObject> > eventFilters;
|
||||
union {
|
||||
QObject *currentChildBeingDeleted;
|
||||
QAbstractDeclarativeData *declarativeData; //extra data used by the declarative module
|
||||
|
@ -1599,7 +1599,7 @@ void QStateMachinePrivate::registerEventTransition(QEventTransition *transition)
|
||||
if (!object)
|
||||
return;
|
||||
QObjectPrivate *od = QObjectPrivate::get(object);
|
||||
if (!od->eventFilters.contains(q))
|
||||
if (!od->extraData || !od->extraData->eventFilters.contains(q))
|
||||
object->installEventFilter(q);
|
||||
++qobjectEvents[object][transition->eventType()];
|
||||
QEventTransitionPrivate::get(transition)->registered = true;
|
||||
|
@ -3164,8 +3164,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
|
||||
if (!w->hasMouseTracking()
|
||||
&& mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
|
||||
// but still send them through all application event filters (normally done by notify_helper)
|
||||
for (int i = 0; i < d->eventFilters.size(); ++i) {
|
||||
register QObject *obj = d->eventFilters.at(i);
|
||||
for (int i = 0; d->extraData && i < d->extraData->eventFilters.size(); ++i) {
|
||||
register QObject *obj = d->extraData->eventFilters.at(i);
|
||||
if (!obj)
|
||||
continue;
|
||||
if (obj->d_func()->threadData != w->d_func()->threadData) {
|
||||
|
Loading…
Reference in New Issue
Block a user