diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-08-22 14:28:39 -0700 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2023-12-11 18:41:56 +0000 |
commit | 4d7864f0517679ebe70a2a96afdae5dc4f5a2d62 (patch) | |
tree | 457dba7e4e93b6a6c7cbf6a1d3cbcacebdcfccb8 /src/corelib/tools/qarraydata.h | |
parent | 7a829eaf51853e0852db28b8b8223e1a62a3db0c (diff) |
QArrayData: add allocate1 and allocate2 for 1- and 2-byte types
This makes the two most-often used QTypedArrayData::allocate() -- the
ones for char (for QByteArray) and char16_t (for QString) -- go to
specialized versions, which have much simpler code. After all,
multiplications by 1 are quite trivial.
I didn't check whether an LTO compiler was const-propagating the sizes
in inlined calls from qstring.cpp and qbytearray.cpp. But not everyone
uses LTO, so this benefits everyone, in a very hot path, for minimal
cost.
Pick-to: 6.7
Change-Id: Ifa1111900d6945ea8e05fffd177dd1ce659b3fd5
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydata.h')
-rw-r--r-- | src/corelib/tools/qarraydata.h | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index adc53fe39d..2369a27e84 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -11,6 +11,12 @@ QT_BEGIN_NAMESPACE +#if __has_cpp_attribute(gnu::malloc) +# define Q_DECL_MALLOCLIKE [[nodiscard, gnu::malloc]] +#else +# define Q_DECL_MALLOCLIKE [[nodiscard]] +#endif + template <class T> struct QTypedArrayData; struct QArrayData @@ -78,12 +84,16 @@ struct QArrayData return newSize; } - [[nodiscard]] -#if defined(Q_CC_GNU) - __attribute__((__malloc__)) -#endif + Q_DECL_MALLOCLIKE static Q_CORE_EXPORT void *allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment, qsizetype capacity, AllocationOption option = QArrayData::KeepSize) noexcept; + Q_DECL_MALLOCLIKE + static Q_CORE_EXPORT void *allocate1(QArrayData **pdata, qsizetype capacity, + AllocationOption option = QArrayData::KeepSize) noexcept; + Q_DECL_MALLOCLIKE + static Q_CORE_EXPORT void *allocate2(QArrayData **pdata, qsizetype capacity, + AllocationOption option = QArrayData::KeepSize) noexcept; + [[nodiscard]] static Q_CORE_EXPORT QPair<QArrayData *, void *> reallocateUnaligned(QArrayData *data, void *dataPointer, qsizetype objectSize, qsizetype newCapacity, AllocationOption option) noexcept; static Q_CORE_EXPORT void deallocate(QArrayData *data, qsizetype objectSize, @@ -102,8 +112,18 @@ struct QTypedArrayData { static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData)); QArrayData *d; - void *result = QArrayData::allocate(&d, sizeof(T), alignof(AlignmentDummy), capacity, option); + void *result; + if constexpr (sizeof(T) == 1) { + // necessarily, alignof(T) == 1 + result = allocate1(&d, capacity, option); + } else if constexpr (sizeof(T) == 2) { + // alignof(T) may be 1, but that makes no difference + result = allocate2(&d, capacity, option); + } else { + result = QArrayData::allocate(&d, sizeof(T), alignof(AlignmentDummy), capacity, option); + } #if __has_builtin(__builtin_assume_aligned) + // and yet we do offer results that have stricter alignment result = __builtin_assume_aligned(result, Q_ALIGNOF(AlignmentDummy)); #endif return qMakePair(static_cast<QTypedArrayData *>(d), static_cast<T *>(result)); @@ -172,6 +192,8 @@ struct Q_CORE_EXPORT QContainerImplHelper }; } +#undef Q_DECL_MALLOCLIKE + QT_END_NAMESPACE #endif // include guard |