summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-02-03 22:13:15 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2021-02-05 07:40:35 +0100
commit0a86e7fb6d83559905146fc8ba43eaba8da780ed (patch)
tree7b14c88e5926a1260a88453b6a5cf134c971ed16 /src/corelib/kernel
parenta1e9817cec5e0dccf26040d0b0d24e974841d5b8 (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.cpp4
-rw-r--r--src/corelib/kernel/qmetatype.h88
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;