QDataStream: Move trasactionDepth to the main class

The q_status member has too much space dedicated to it: 32 bits. So we
can shrink it to a mere 8 bits and move it up to the 1-byte padding hole
and repurpose the space it used to use. This only works because the
q_status member was not accessed by any inline function before Qt 6.8
(see commit fc23fa459c5924bf1cc4564c7bce1fd59d7c972b).

After this, pahole says:
  class QScopedPointer<QDataStreamPrivate> d;      /*     0     8 */
  class QIODevice *          dev;                  /*     8     8 */
  bool                       owndev;               /*    16     1 */
  bool                       noswap;               /*    17     1 */
  quint8                     fpPrecision;          /*    18     1 */
  quint8                     q_status;             /*    19     1 */
  enum ByteOrder             byteorder;            /*    20     4 */
  int                        ver;                  /*    24     4 */
  quint16                    transactionDepth;     /*    28     2 */
  /* size: 32, cachelines: 1, members: 10 */

That leaves 16 bits of tail padding unused, so reduces the maximum
number of nested transactions to 65536. That is to support a Qt 7 layout
in an upcoming commit.

Change-Id: I50e2158aeade4256ad1dfffd17b29d75fd13f472
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2024-02-10 13:25:38 -08:00
parent 4aa0eab263
commit 9b2835e464
3 changed files with 9 additions and 11 deletions

View File

@ -258,7 +258,7 @@ constexpr quint32 QDataStream::ExtendedSize;
return retVal;
#define CHECK_STREAM_TRANSACTION_PRECOND(retVal) \
if (!d || d->transactionDepth == 0) { \
if (transactionDepth == 0) { \
qWarning("QDataStream: No transaction in progress"); \
return retVal; \
}
@ -623,10 +623,7 @@ void QDataStream::startTransaction()
{
CHECK_STREAM_PRECOND(Q_VOID)
if (!d)
d.reset(new QDataStreamPrivate());
if (++d->transactionDepth == 1) {
if (++transactionDepth == 1) {
dev->startTransaction();
resetStatus();
}
@ -655,7 +652,7 @@ void QDataStream::startTransaction()
bool QDataStream::commitTransaction()
{
CHECK_STREAM_TRANSACTION_PRECOND(false)
if (--d->transactionDepth == 0) {
if (--transactionDepth == 0) {
CHECK_STREAM_PRECOND(false)
if (q_status == ReadPastEnd) {
@ -695,7 +692,7 @@ void QDataStream::rollbackTransaction()
setStatus(ReadPastEnd);
CHECK_STREAM_TRANSACTION_PRECOND(Q_VOID)
if (--d->transactionDepth != 0)
if (--transactionDepth != 0)
return;
CHECK_STREAM_PRECOND(Q_VOID)
@ -731,7 +728,7 @@ void QDataStream::abortTransaction()
q_status = ReadCorruptData;
CHECK_STREAM_TRANSACTION_PRECOND(Q_VOID)
if (--d->transactionDepth != 0)
if (--transactionDepth != 0)
return;
CHECK_STREAM_PRECOND(Q_VOID)

View File

@ -220,9 +220,11 @@ private:
bool owndev;
bool noswap;
quint8 fpPrecision = QDataStream::DoublePrecision;
quint8 q_status;
ByteOrder byteorder;
int ver;
Status q_status;
quint16 transactionDepth = 0;
#if QT_CORE_REMOVED_SINCE(6, 7)
int readBlock(char *data, int len);
#endif
@ -426,7 +428,7 @@ inline QIODevice *QDataStream::device() const
#if QT_CORE_INLINE_IMPL_SINCE(6, 8)
QDataStream::Status QDataStream::status() const
{
return q_status;
return Status(q_status);
}
QDataStream::FloatingPointPrecision QDataStream::floatingPointPrecision() const

View File

@ -24,7 +24,6 @@ QT_BEGIN_NAMESPACE
class QDataStreamPrivate
{
public:
int transactionDepth = 0;
};
#endif