QItemSelectionModel: avoid 24 relocations

Use qOffsetStringArray() instead of an array of pairs of pointers.

This unearthed a problem with SIGNAL and SLOT calling qFlagLocation()
(meaning in debug mode, the array was runtime-initialized, not just
relocated), which we work around by using the new QT_STRINGIFY_
{SIGNAL,SLOT} macros now.

Saves 24 relocations, but, interestingly, saves only 4b in text size
on GCC 11.2 Linux AMD64 -O2 C++20 builds (TEXT and DATA combined)
while saving 760b on the equivalent Clang 10 libc++ build (expected,
in both cases: 24 * (sizeof(void*) - sizeof(quint16))):

Clang:

  $ size qtbase/lib/libQt6Core.so.6.4.0
     text    data     bss     dec     hex filename
  5476156   90520   16185 5582861  55300d qtbase/lib/libQt6Core.so.6.4.0
  $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0
  qtbase/lib/libQt6Core.so.6.4.0: 6528 relocations, 3598 relative (55%), 2540 PLT entries, 2227 for local syms (87%), 0 users
  $ ninja libQt6Core.so
  [6/6] Creating library symlink qtbase/lib/libQt6Core.so.6 qtbase/lib/libQt6Core.so
  $ size qtbase/lib/libQt6Core.so.6.4.0
     text    data     bss     dec     hex filename
  5475604   90312   16185 5582101  552d15 qtbase/lib/libQt6Core.so.6.4.0
  $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0
  qtbase/lib/libQt6Core.so.6.4.0: 6504 relocations, 3574 relative (54%), 2540 PLT entries, 2227 for local syms (87%), 0 users

GCC:

  $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0
  qtbase/lib/libQt6Core.so.6.4.0: 6300 relocations, 5343 relative (84%), 318 PLT entries, 1 for local syms (0%), 0 users
  $ size qtbase/lib/libQt6Core.so.6.4.0
     text    data     bss     dec     hex filename
  6019871   75896   16952 6112719  5d45cf qtbase/lib/libQt6Core.so.6.4.0
  $ ninja libQt6Core.so
  [6/6] Creating library symlink qtbase/lib/libQt6Core.so.6 qtbase/lib/libQt6Core.so
  $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0
  qtbase/lib/libQt6Core.so.6.4.0: 6276 relocations, 5319 relative (84%), 318 PLT entries, 1 for local syms (0%), 0 users
  $ size qtbase/lib/libQt6Core.so.6.4.0
     text    data     bss     dec     hex filename
  6020091   75672   16952 6112715  5d45cb qtbase/lib/libQt6Core.so.6.4.0

Pick-to: 6.3
Change-Id: I60749953f1a63d23d696a5a547cd924ec259ead3
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Marc Mutz 2022-02-08 08:25:47 +01:00
parent efe411b8b7
commit fa0764bbd2
1 changed files with 31 additions and 35 deletions

View File

@ -43,6 +43,7 @@
#include <private/qitemselectionmodel_p.h>
#include <private/qabstractitemmodel_p.h>
#include <private/qduplicatetracker_p.h>
#include <private/qoffsetstringarray_p.h>
#include <qdebug.h>
#include <algorithm>
@ -585,45 +586,40 @@ void QItemSelection::split(const QItemSelectionRange &range,
void QItemSelectionModelPrivate::initModel(QAbstractItemModel *m)
{
struct Cx {
const char *signal;
const char *slot;
};
static const Cx connections[] = {
{ SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)) },
{ SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)) },
{ SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)) },
{ SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int)) },
{ SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
SLOT(_q_layoutAboutToBeChanged()) },
{ SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
SLOT(_q_layoutAboutToBeChanged()) },
{ SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
SLOT(_q_layoutChanged()) },
{ SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
SLOT(_q_layoutChanged()) },
{ SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
SLOT(_q_layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)) },
{ SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)) },
{ SIGNAL(modelReset()),
SLOT(reset()) },
{ SIGNAL(destroyed(QObject*)),
SLOT(_q_modelDestroyed()) },
{ nullptr, nullptr }
};
static constexpr auto connections = qOffsetStringArray(
QT_STRINGIFY_SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
QT_STRINGIFY_SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)),
QT_STRINGIFY_SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
QT_STRINGIFY_SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)),
QT_STRINGIFY_SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
QT_STRINGIFY_SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)),
QT_STRINGIFY_SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
QT_STRINGIFY_SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int)),
QT_STRINGIFY_SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
QT_STRINGIFY_SLOT(_q_layoutAboutToBeChanged()),
QT_STRINGIFY_SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
QT_STRINGIFY_SLOT(_q_layoutAboutToBeChanged()),
QT_STRINGIFY_SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
QT_STRINGIFY_SLOT(_q_layoutChanged()),
QT_STRINGIFY_SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
QT_STRINGIFY_SLOT(_q_layoutChanged()),
QT_STRINGIFY_SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
QT_STRINGIFY_SLOT(_q_layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
QT_STRINGIFY_SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
QT_STRINGIFY_SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
QT_STRINGIFY_SIGNAL(modelReset()),
QT_STRINGIFY_SLOT(reset()),
QT_STRINGIFY_SIGNAL(destroyed(QObject*)),
QT_STRINGIFY_SLOT(_q_modelDestroyed())
);
if (model == m)
return;
Q_Q(QItemSelectionModel);
if (model.value()) {
for (const Cx *cx = &connections[0]; cx->signal; cx++)
QObject::disconnect(model.value(), cx->signal, q, cx->slot);
for (int i = 0; i < connections.count(); i += 2)
QObject::disconnect(model.value(), connections.at(i), q, connections.at(i + 1));
q->reset();
}
@ -631,8 +627,8 @@ void QItemSelectionModelPrivate::initModel(QAbstractItemModel *m)
model.setValueBypassingBindings(m);
if (model.value()) {
for (const Cx *cx = &connections[0]; cx->signal; cx++)
QObject::connect(model.value(), cx->signal, q, cx->slot);
for (int i = 0; i < connections.count(); i += 2)
QObject::connect(model.value(), connections.at(i), q, connections.at(i + 1));
}
}