From d31054c31456bc840061089e37e956ad815215c6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 3 May 2024 11:24:09 +0200 Subject: [PATCH] QMetaType: make sequence, pair adapters SCARY Extract (non-template) Methods from template functions and pull them behind the ABI boundary to avoid re-compiling the same code multiple times ("SCARY"). In this particular case, the extracted code contains QMetaType::fromType() calls, which, taken together, were responsible for at least 91s of the ~8250s total time for a qt5.git-wide headersclean_check (1.1%): Says Clang -ftime-trace: $ grep fromType hc*.txt hc-00-baseline.txt: 32122 ms: QMetaType::fromType> (1240 times, avg 25 ms) hc-00-baseline.txt: 31717 ms: QMetaType::fromType> (1240 times, avg 25 ms) hc-00-baseline.txt: 23531 ms: QMetaType::fromType (1240 times, avg 18 ms) hc-00-baseline.txt: 91143 ms: QMetaType::fromType<$> (6440 times, avg 14 ms) # QIterable out-of-lined: hc-01-meta-seq.txt: 29869 ms: QMetaType::fromType> (1240 times, avg 24 ms) hc-01-meta-seq.txt: 21618 ms: QMetaType::fromType (1240 times, avg 17 ms) hc-01-meta-seq.txt: 55029 ms: QMetaType::fromType<$> (5025 times, avg 10 ms) # QIterable out-of-lined: hc-02-meta-ass.txt: 21689 ms: QMetaType::fromType (1240 times, avg 17 ms) hc-02-meta-ass.txt: 25224 ms: QMetaType::fromType<$> (3799 times, avg 6 ms) # QPairVariantInterfaceImpl out-of-lined: Amends 01fb843af88d949cd38b494a60bb64b730a045d2 (sequences), 87e27eb870d08ee8953cc9b350ed29c5b3e4f785 (associations), b88b09fb16754c5057b781d1b625855f75b22aee (pairs). Task-number: QTBUG-97601 Change-Id: If34cf94703a203bc231f1bac656d2f5278bbd8f8 Reviewed-by: Fabian Kosmale --- src/corelib/kernel/qmetatype.cpp | 50 ++++++++++++++++++++++++++++++++ src/corelib/kernel/qmetatype.h | 24 ++++++++------- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 9a57f46cbfa..1c2665e53c0 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -2659,6 +2659,36 @@ bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toT return customTypesConversionRegistry()->contains({fromType.id(), toType.id()}); } +/*! + \internal + Non-template helper ("SCARY") for IsMetaTypePair::registerConverter(). +*/ +bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m) +{ + const QMetaType to = QMetaType::fromType(); + return QMetaType::hasRegisteredConverterFunction(m, to); +} + +/*! + \internal + Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerConverter(). +*/ +bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m) +{ + const QMetaType to = QMetaType::fromType>(); + return QMetaType::hasRegisteredConverterFunction(m, to); +} + +/*! + \internal + Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerConverter(). +*/ +bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m) +{ + const QMetaType to = QMetaType::fromType>(); + return QMetaType::hasRegisteredConverterFunction(m, to); +} + /*! \fn template bool QMetaType::hasRegisteredMutableViewFunction() Returns \c true, if the meta type system has a registered mutable view on type From of type To. @@ -2676,6 +2706,26 @@ bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType t return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()}); } +/*! + \internal + Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerMutableView(). +*/ +bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m) +{ + const QMetaType to = QMetaType::fromType>(); + return QMetaType::hasRegisteredMutableViewFunction(m, to); +} + +/*! + \internal + Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerMutableView(). +*/ +bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m) +{ + const QMetaType to = QMetaType::fromType>(); + return QMetaType::hasRegisteredMutableViewFunction(m, to); +} + /*! \fn const char *QMetaType::typeName(int typeId) \deprecated diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 80d10f5c9ab..12a67aef584 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1750,11 +1750,19 @@ QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE) QT_BEGIN_NAMESPACE +namespace QtPrivate { +// out-of-line helpers to reduce template code bloat ("SCARY") and improve compile times: +Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m); +Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m); +} + template inline bool QtPrivate::IsMetaTypePair::registerConverter() { - const QMetaType to = QMetaType::fromType(); - if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType(), to)) { + if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType())) { QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor o; return QMetaType::registerConverter(o); } @@ -1786,8 +1794,7 @@ struct SequentialValueTypeIsMetaType { static bool registerConverter() { - const QMetaType to = QMetaType::fromType>(); - if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType(), to)) { + if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType())) { QSequentialIterableConvertFunctor o; return QMetaType::registerConverter>(o); } @@ -1796,8 +1803,7 @@ struct SequentialValueTypeIsMetaType static bool registerMutableView() { - const QMetaType to = QMetaType::fromType>(); - if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType(), to)) { + if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType())) { QSequentialIterableMutableViewFunctor o; return QMetaType::registerMutableView>(o); } @@ -1830,8 +1836,7 @@ struct AssociativeKeyTypeIsMetaType : AssociativeMappedTypeIsMetaType>(); - if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType(), to)) { + if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType())) { QAssociativeIterableConvertFunctor o; return QMetaType::registerConverter>(o); } @@ -1840,8 +1845,7 @@ struct AssociativeKeyTypeIsMetaType : AssociativeMappedTypeIsMetaType>(); - if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType(), to)) { + if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType())) { QAssociativeIterableMutableViewFunctor o; return QMetaType::registerMutableView>(o); }