diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-02-03 22:13:15 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-02-05 07:40:35 +0100 |
commit | 0a86e7fb6d83559905146fc8ba43eaba8da780ed (patch) | |
tree | 7b14c88e5926a1260a88453b6a5cf134c971ed16 /src/corelib/kernel | |
parent | a1e9817cec5e0dccf26040d0b0d24e974841d5b8 (diff) |
QMetaType: avoid id() calls in compare
We can avoid the overhead of the out-of-line function calls if the id is
already set.
As a drive-by, use relaxed loads in QMetaType::id (was: acquire).
Change-Id: I1d53dbf7e58eae80776ff36334ebf0642ba7842f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 88 |
2 files changed, 51 insertions, 41 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 06dbdbde18..71fcc6d407 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -490,8 +490,8 @@ bool QMetaType::isRegistered() const int QMetaType::id() const { if (d_ptr) { - if (d_ptr->typeId) - return d_ptr->typeId; + if (int id = d_ptr->typeId.loadRelaxed()) + return id; auto reg = customTypeRegistry(); if (reg) { return reg->registerCustomType(d_ptr); diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 67bcacd751..3d282ba8c9 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -258,7 +258,42 @@ struct QMetaObject; namespace QtPrivate { -class QMetaTypeInterface; +class QMetaTypeInterface +{ +public: + ushort revision; // 0 in Qt 6.0. Can increase if new field are added + ushort alignment; + uint size; + uint flags; + mutable QBasicAtomicInt typeId; + + using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *); + const MetaObjectFn metaObjectFn; + + const char *name; + + using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *); + DefaultCtrFn defaultCtr; + using CopyCtrFn = void (*)(const QMetaTypeInterface *, void *, const void *); + CopyCtrFn copyCtr; + using MoveCtrFn = void (*)(const QMetaTypeInterface *, void *, void *); + MoveCtrFn moveCtr; + using DtorFn = void (*)(const QMetaTypeInterface *, void *); + DtorFn dtor; + using EqualsFn = bool (*)(const QMetaTypeInterface *, const void *, const void *); + EqualsFn equals; + using LessThanFn = bool (*)(const QMetaTypeInterface *, const void *, const void *); + LessThanFn lessThan; + using DebugStreamFn = void (*)(const QMetaTypeInterface *, QDebug &, const void *); + DebugStreamFn debugStream; + using DataStreamOutFn = void (*)(const QMetaTypeInterface *, QDataStream &, const void *); + DataStreamOutFn dataStreamOut; + using DataStreamInFn = void (*)(const QMetaTypeInterface *, QDataStream &, void *); + DataStreamInFn dataStreamIn; + + using LegacyRegisterOp = void (*)(); + LegacyRegisterOp legacyRegisterOp; +}; /*! This template is used for implicit conversion from type From to type To. @@ -444,7 +479,19 @@ public: constexpr static QMetaType fromType(); static QMetaType fromName(QByteArrayView name); - friend bool operator==(QMetaType a, QMetaType b) { return a.d_ptr == b.d_ptr || a.id() == b.id(); } + friend bool operator==(QMetaType a, QMetaType b) + { + if (a.d_ptr == b.d_ptr) + return true; + if (!a.d_ptr || !b.d_ptr) + return false; // one type is undefined, the other is defined + // avoid id call if we already have the id + const int ai = a.d_ptr->typeId.loadRelaxed(); // avoid reading the atomic twice + const int aId = ai ? ai : a.id(); + const int bi = b.d_ptr->typeId.loadRelaxed(); + const int bId = bi ? bi : b.id(); + return aId == bId; + } friend bool operator!=(QMetaType a, QMetaType b) { return !(a == b); } public: @@ -1603,43 +1650,6 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T } }; -class QMetaTypeInterface -{ -public: - ushort revision; // 0 in Qt 6.0. Can increase if new field are added - ushort alignment; - uint size; - uint flags; - mutable QBasicAtomicInt typeId; - - using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *); - const MetaObjectFn metaObjectFn; - - const char *name; - - using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *); - DefaultCtrFn defaultCtr; - using CopyCtrFn = void (*)(const QMetaTypeInterface *, void *, const void *); - CopyCtrFn copyCtr; - using MoveCtrFn = void (*)(const QMetaTypeInterface *, void *, void *); - MoveCtrFn moveCtr; - using DtorFn = void (*)(const QMetaTypeInterface *, void *); - DtorFn dtor; - using EqualsFn = bool (*)(const QMetaTypeInterface *, const void *, const void *); - EqualsFn equals; - using LessThanFn = bool (*)(const QMetaTypeInterface *, const void *, const void *); - LessThanFn lessThan; - using DebugStreamFn = void (*)(const QMetaTypeInterface *, QDebug &, const void *); - DebugStreamFn debugStream; - using DataStreamOutFn = void (*)(const QMetaTypeInterface *, QDataStream &, const void *); - DataStreamOutFn dataStreamOut; - using DataStreamInFn = void (*)(const QMetaTypeInterface *, QDataStream &, void *); - DataStreamInFn dataStreamIn; - - using LegacyRegisterOp = void (*)(); - LegacyRegisterOp legacyRegisterOp; -}; - struct QTypeNormalizer { char *output; |