summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-10 18:06:26 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-12 22:38:25 +0100
commitd5ae51e0f5fb55f0a9f1c57d967bfa1ca67a75e4 (patch)
treee6585bcfabc897befd51ace2652d6d7385378ffa /src/corelib/kernel
parent090efe6b0e9f95988903136d94bf8a866852a406 (diff)
Clean up and pack data members of QEvent classes
Make sure all bits reported by sizeof for the most important public event classes are used optimally. QEvent is 24bytes large due to default alignment in C++, so we might just as well use bool instead of bitfields for the most important data members. This generates less (and thus smaller and faster) code, and we still have plenty of bits available for future needs. Default the copy constructor and assignment operator, the assert and tracing seem to be relics from the Qt 3/4 days. Note: QEvent's d-pointer is currently unused, with the exception of a hack in QGraphicsView. Removing that would save another 8 bytes through the entire event hierarchy. For the new classes in the QInputEvent hierarchy, apply the same principle. Allocate bits in QInputEvent and QSinglePointEvent to fill the 8-byte aligned space. Using some of those bits for QMouseEvent and QWheelEvent makes sure we don't increase the size for those in spite of additionally reserved bits. As a result of this, several QInputEvent and subclasses become 8 bytes smaller on clang and gcc (with the exception of QNativeGestureEvent) while at the same we have more space for future extensions. The sizeof's for the various classes on different compilers produce these before and after result: clang +/- gcc +/- msvc +/- QEvent 24 0 24 0 24 0 QInputEvent 56 -8 56 -8 48 0 QPointerEvent 80 -8 80 -8 72 0 QSinglePointEvent 96 -8 96 -8 88 0 QMouseEvent 96 -8 96 -8 88 0 QTabletEvent 112 -8 112 -8 96 -16 QKeyEvent 104 -8 104 -8 96 0 QNativeGestureEvent 120 0 120 0 120 0 QWheelEvent 112 -8 112 -8 112 -8 So, with this change we save 8 bytes on gcc and clang for many event types, esp on Linux systems. As a drive-by: replace ulong with quint64, make QTabletEvent data floating point, and rename some variables for clarity. Change-Id: I4cf81c8283262cbf59ee3fb7064a59837332ced7 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcoreevent.cpp32
-rw-r--r--src/corelib/kernel/qcoreevent.h29
2 files changed, 23 insertions, 38 deletions
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 847f3227ea..86d43d2d96 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -295,9 +295,8 @@ QT_BEGIN_NAMESPACE
Contructs an event object of type \a type.
*/
QEvent::QEvent(Type type)
- : d(nullptr), t(type), m_posted(false), m_spont(false), m_accept(true),
- m_inputEvent(false), m_pointerEvent(false), m_singlePointEvent(false),
- m_reserved(0)
+ : t(type), m_reserved(0),
+ m_inputEvent(false), m_pointerEvent(false), m_singlePointEvent(false)
{
Q_TRACE(QEvent_ctor, this, t);
}
@@ -306,17 +305,7 @@ QEvent::QEvent(Type type)
\internal
Copies the \a other event.
*/
-QEvent::QEvent(const QEvent &other)
- : d(other.d), t(other.t), m_posted(other.m_posted), m_spont(other.m_spont),
- m_accept(other.m_accept), m_inputEvent(other.m_inputEvent),
- m_pointerEvent(other.m_pointerEvent), m_singlePointEvent(other.m_singlePointEvent),
- m_reserved(other.m_reserved)
-{
- Q_TRACE(QEvent_ctor, this, t);
- // if QEventPrivate becomes available, make sure to implement a
- // virtual QEventPrivate *clone() const; function so we can copy here
- Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
-}
+QEvent::QEvent(const QEvent &other) = default;
/*!
\internal
@@ -351,18 +340,7 @@ QEvent::QEvent(const QEvent &other)
Copying events is a bad idea, yet some Qt 4 code does it (notably,
QApplication and the state machine).
*/
-QEvent &QEvent::operator=(const QEvent &other)
-{
- // if QEventPrivate becomes available, make sure to implement a
- // virtual QEventPrivate *clone() const; function so we can copy here
- Q_ASSERT_X(!other.d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
-
- t = other.t;
- m_posted = other.m_posted;
- m_spont = other.m_spont;
- m_accept = other.m_accept;
- return *this;
-}
+QEvent &QEvent::operator=(const QEvent &other) = default;
/*!
Destroys the event. If it was \l{QCoreApplication::postEvent()}{posted},
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index dbca4adaab..cfaa959dec 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -320,27 +320,34 @@ protected:
QEvent(Type type, PointerEventTag) : QEvent(type, InputEventTag{}) { m_pointerEvent = true; }
struct SinglePointEventTag { explicit SinglePointEventTag() = default; };
QEvent(Type type, SinglePointEventTag) : QEvent(type, PointerEventTag{}) { m_singlePointEvent = true; }
- QEventPrivate *d;
+ QEventPrivate *d = nullptr;
quint16 t;
private:
- quint16 m_posted : 1;
- quint16 m_spont : 1;
- quint16 m_accept : 1;
+ /*
+ We can assume that C++ types are 8-byte aligned, and we can't assume that compilers
+ coalesce data members from subclasses. Use bitfields to fill up to next 8-byte
+ aligned size, which is 24 bytes. That way we don't waste memory, and have plenty of room
+ for future flags.
+ Don't use bitfields for the most important flags, as that would generate more code, and
+ access is always inline. Bytes used are:
+ 8 vptr + 8 d-pointer + 2 type + 3 bool flags => 3 bytes left, so 24 bits. However,
+ compiler will add padding after the booleans, so add another unused bool, which leaves
+ us with 16 bits.
+ */
+ bool m_posted = false;
+ bool m_spont = false;
+ bool m_accept = true;
+ bool m_unused = false;
+ quint16 m_reserved : 13;
quint16 m_inputEvent : 1;
quint16 m_pointerEvent : 1;
quint16 m_singlePointEvent : 1;
- quint16 m_reserved : 10;
friend class QCoreApplication;
friend class QCoreApplicationPrivate;
friend class QThreadData;
friend class QApplication;
-#if QT_CONFIG(shortcut)
- friend class QShortcutMap;
-#endif
- friend class QGraphicsView;
- friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
// from QtTest:
friend class QSpontaneKeyEvent;