QArrayData: move AlignedQArrayData to the public header
This allows us to use it in QTypedArrayData<T>::AlignmentDummy, which is used in __builtin_assume_aligned() as a hint to the compiler. This increases the value we were passing as the compiler hint from 4 to 8 on 32-bit platforms and from 8 to 16 on 64-bit platforms. We actually do align to a bit higher than even that, but that's not an ABI guarantee we're making. However, it looks like GCC on 32-bit platforms is buggy, so we work around it. Commit r240248 ("Make max_align_t respect _Float128.", 63012d9a57edc950c5f30242d1e19318b5708060 in Git) increased std::max_align_t to 16 bytes on all platforms, saying "Such an increase is of course an ABI change" and "I think glibc malloc alignment should also increase to 16-byte 32-bit x86", but such a change to glibc was never implemented. Moreover, there are systems that don't use glibc, such as when using GCC on other OSes. This is not a change in Qt behavior anywhere. i386 does not (usually) do alignment checks, so most code wouldn't notice this at all. Change-Id: I79e700614d034281bf55fffd178fa0aee2344307 Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 4d57b30194f31865132312c67abf796cb58a0f8f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5d534ee9a9
commit
9039b0cd25
@ -145,18 +145,13 @@ static QArrayData *allocateData(qsizetype allocSize)
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
// QArrayData with strictest alignment requirements supported by malloc()
|
||||
struct alignas(std::max_align_t) AlignedQArrayData : QArrayData
|
||||
{
|
||||
};
|
||||
|
||||
struct AllocationResult {
|
||||
void *data;
|
||||
QArrayData *header;
|
||||
};
|
||||
}
|
||||
using QtPrivate::AlignedQArrayData;
|
||||
|
||||
static inline AllocationResult
|
||||
allocateHelper(qsizetype objectSize, qsizetype alignment, qsizetype capacity,
|
||||
@ -172,6 +167,7 @@ allocateHelper(qsizetype objectSize, qsizetype alignment, qsizetype capacity,
|
||||
// Allocate extra (alignment - Q_ALIGNOF(AlignedQArrayData)) padding
|
||||
// bytes so we can properly align the data array. This assumes malloc is
|
||||
// able to provide appropriate alignment for the header -- as it should!
|
||||
// Effectively, we allocate one QTypedArrayData<T>::AlignmentDummy.
|
||||
headerSize += alignment - headerAlignment;
|
||||
}
|
||||
Q_ASSERT(headerSize > 0);
|
||||
|
@ -102,11 +102,27 @@ struct QArrayData
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QArrayData::ArrayOptions)
|
||||
|
||||
namespace QtPrivate {
|
||||
// QArrayData with strictest alignment requirements supported by malloc()
|
||||
#if defined(Q_PROCESSOR_X86_32) && defined(Q_CC_GNU)
|
||||
// GCC's definition is incorrect since GCC 8 (commit r240248 in SVN; commit
|
||||
// 63012d9a57edc950c5f30242d1e19318b5708060 in Git). This is applied to all
|
||||
// GCC-like compilers in case they decide to follow GCC's lead in being wrong.
|
||||
constexpr size_t MaxPrimitiveAlignment = 2 * sizeof(void *);
|
||||
#else
|
||||
constexpr size_t MaxPrimitiveAlignment = alignof(std::max_align_t);
|
||||
#endif
|
||||
|
||||
struct alignas(MaxPrimitiveAlignment) AlignedQArrayData : QArrayData
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct QTypedArrayData
|
||||
: QArrayData
|
||||
{
|
||||
struct AlignmentDummy { QArrayData header; T data; };
|
||||
struct AlignmentDummy { QtPrivate::AlignedQArrayData header; T data; };
|
||||
|
||||
[[nodiscard]] static QPair<QTypedArrayData *, T *> allocate(qsizetype capacity, AllocationOption option = QArrayData::KeepSize)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user