Cleanup QArrayDataOps::reallocate() and related
Don't use QArrayData::GrowsForward/Backward anymore and replace it with a simple 'bool grow'. Change-Id: Ifddfef3ae860b11dda4c40854c71ef2aeb29df34 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
32a703e277
commit
419eaa0679
@ -671,7 +671,7 @@ QByteArray qUncompress(const uchar* data, qsizetype nbytes)
|
|||||||
return invalidCompressedData();
|
return invalidCompressedData();
|
||||||
} else {
|
} else {
|
||||||
// grow the block
|
// grow the block
|
||||||
d->reallocate(d->allocatedCapacity()*2);
|
d->reallocate(d->allocatedCapacity()*2, QArrayData::Grow);
|
||||||
if (Q_UNLIKELY(d.data() == nullptr))
|
if (Q_UNLIKELY(d.data() == nullptr))
|
||||||
return invalidCompressedData();
|
return invalidCompressedData();
|
||||||
}
|
}
|
||||||
@ -1719,7 +1719,7 @@ void QByteArray::reallocData(qsizetype alloc, Data::ArrayOptions options)
|
|||||||
dd.data()[dd.size] = 0;
|
dd.data()[dd.size] = 0;
|
||||||
d = dd;
|
d = dd;
|
||||||
} else {
|
} else {
|
||||||
d->reallocate(alloc);
|
d->reallocate(alloc, options & (QArrayData::GrowsBackwards|QArrayData::GrowsForward) ? QArrayData::Grow : QArrayData::KeepSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1734,7 +1734,7 @@ void QByteArray::reallocGrowData(qsizetype n)
|
|||||||
dd.data()[dd.size] = 0;
|
dd.data()[dd.size] = 0;
|
||||||
d = dd;
|
d = dd;
|
||||||
} else {
|
} else {
|
||||||
d->reallocate(d.constAllocatedCapacity() + n);
|
d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2516,7 +2516,7 @@ void QString::reallocData(qsizetype alloc, Data::ArrayOptions allocOptions)
|
|||||||
dd.data()[dd.size] = 0;
|
dd.data()[dd.size] = 0;
|
||||||
d = dd;
|
d = dd;
|
||||||
} else {
|
} else {
|
||||||
d->reallocate(alloc);
|
d->reallocate(alloc, allocOptions & (QArrayData::GrowsBackwards|QArrayData::GrowsForward) ? QArrayData::Grow : QArrayData::KeepSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2531,7 +2531,7 @@ void QString::reallocGrowData(qsizetype n)
|
|||||||
dd.data()[dd.size] = 0;
|
dd.data()[dd.size] = 0;
|
||||||
d = dd;
|
d = dd;
|
||||||
} else {
|
} else {
|
||||||
d->reallocate(d.constAllocatedCapacity() + n);
|
d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,12 +159,12 @@ static inline qsizetype reserveExtraBytes(qsizetype allocSize)
|
|||||||
return allocSize;
|
return allocSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline qsizetype calculateBlockSize(qsizetype &capacity, qsizetype objectSize, qsizetype headerSize, uint options)
|
static inline qsizetype calculateBlockSize(qsizetype &capacity, qsizetype objectSize, qsizetype headerSize, QArrayData::AllocationOption option)
|
||||||
{
|
{
|
||||||
// Calculate the byte size
|
// Calculate the byte size
|
||||||
// allocSize = objectSize * capacity + headerSize, but checked for overflow
|
// allocSize = objectSize * capacity + headerSize, but checked for overflow
|
||||||
// plus padded to grow in size
|
// plus padded to grow in size
|
||||||
if (options & (QArrayData::GrowsForward | QArrayData::GrowsBackwards)) {
|
if (option == QArrayData::Grow) {
|
||||||
auto r = qCalculateGrowingBlockSize(capacity, objectSize, headerSize);
|
auto r = qCalculateGrowingBlockSize(capacity, objectSize, headerSize);
|
||||||
capacity = r.elementCount;
|
capacity = r.elementCount;
|
||||||
return r.size;
|
return r.size;
|
||||||
@ -173,12 +173,12 @@ static inline qsizetype calculateBlockSize(qsizetype &capacity, qsizetype object
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QArrayData *allocateData(qsizetype allocSize, uint options)
|
static QArrayData *allocateData(qsizetype allocSize)
|
||||||
{
|
{
|
||||||
QArrayData *header = static_cast<QArrayData *>(::malloc(size_t(allocSize)));
|
QArrayData *header = static_cast<QArrayData *>(::malloc(size_t(allocSize)));
|
||||||
if (header) {
|
if (header) {
|
||||||
header->ref_.storeRelaxed(1);
|
header->ref_.storeRelaxed(1);
|
||||||
header->flags = options;
|
header->flags = 0;
|
||||||
header->alloc = 0;
|
header->alloc = 0;
|
||||||
}
|
}
|
||||||
return header;
|
return header;
|
||||||
@ -208,18 +208,19 @@ void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype al
|
|||||||
}
|
}
|
||||||
Q_ASSERT(headerSize > 0);
|
Q_ASSERT(headerSize > 0);
|
||||||
|
|
||||||
qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
|
qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, (options & (GrowsForward|GrowsBackwards)) ? QArrayData::Grow : QArrayData::KeepSize);
|
||||||
allocSize = reserveExtraBytes(allocSize);
|
allocSize = reserveExtraBytes(allocSize);
|
||||||
if (Q_UNLIKELY(allocSize < 0)) { // handle overflow. cannot allocate reliably
|
if (Q_UNLIKELY(allocSize < 0)) { // handle overflow. cannot allocate reliably
|
||||||
*dptr = nullptr;
|
*dptr = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QArrayData *header = allocateData(allocSize, options);
|
QArrayData *header = allocateData(allocSize);
|
||||||
void *data = nullptr;
|
void *data = nullptr;
|
||||||
if (header) {
|
if (header) {
|
||||||
// find where offset should point to so that data() is aligned to alignment bytes
|
// find where offset should point to so that data() is aligned to alignment bytes
|
||||||
data = QTypedArrayData<void>::dataStart(header, alignment);
|
data = QTypedArrayData<void>::dataStart(header, alignment);
|
||||||
|
header->flags = options & CapacityReserved;
|
||||||
header->alloc = qsizetype(capacity);
|
header->alloc = qsizetype(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,12 +230,12 @@ void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype al
|
|||||||
|
|
||||||
QPair<QArrayData *, void *>
|
QPair<QArrayData *, void *>
|
||||||
QArrayData::reallocateUnaligned(QArrayData *data, void *dataPointer,
|
QArrayData::reallocateUnaligned(QArrayData *data, void *dataPointer,
|
||||||
qsizetype objectSize, qsizetype capacity, ArrayOptions options) noexcept
|
qsizetype objectSize, qsizetype capacity, AllocationOption option) noexcept
|
||||||
{
|
{
|
||||||
Q_ASSERT(!data || !data->isShared());
|
Q_ASSERT(!data || !data->isShared());
|
||||||
|
|
||||||
qsizetype headerSize = sizeof(QArrayData);
|
qsizetype headerSize = sizeof(QArrayData);
|
||||||
qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
|
qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, option);
|
||||||
qptrdiff offset = dataPointer ? reinterpret_cast<char *>(dataPointer) - reinterpret_cast<char *>(data) : headerSize;
|
qptrdiff offset = dataPointer ? reinterpret_cast<char *>(dataPointer) - reinterpret_cast<char *>(data) : headerSize;
|
||||||
|
|
||||||
allocSize = reserveExtraBytes(allocSize);
|
allocSize = reserveExtraBytes(allocSize);
|
||||||
@ -243,7 +244,6 @@ QArrayData::reallocateUnaligned(QArrayData *data, void *dataPointer,
|
|||||||
|
|
||||||
QArrayData *header = static_cast<QArrayData *>(::realloc(data, size_t(allocSize)));
|
QArrayData *header = static_cast<QArrayData *>(::realloc(data, size_t(allocSize)));
|
||||||
if (header) {
|
if (header) {
|
||||||
header->flags = options;
|
|
||||||
header->alloc = uint(capacity);
|
header->alloc = uint(capacity);
|
||||||
dataPointer = reinterpret_cast<char *>(header) + offset;
|
dataPointer = reinterpret_cast<char *>(header) + offset;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,11 @@ template <class T> struct QTypedArrayData;
|
|||||||
|
|
||||||
struct Q_CORE_EXPORT QArrayData
|
struct Q_CORE_EXPORT QArrayData
|
||||||
{
|
{
|
||||||
|
enum AllocationOption {
|
||||||
|
Grow,
|
||||||
|
KeepSize
|
||||||
|
};
|
||||||
|
|
||||||
enum ArrayOption {
|
enum ArrayOption {
|
||||||
/// this option is used by the allocate() function
|
/// this option is used by the allocate() function
|
||||||
DefaultAllocationFlags = 0,
|
DefaultAllocationFlags = 0,
|
||||||
@ -122,7 +127,7 @@ struct Q_CORE_EXPORT QArrayData
|
|||||||
static void *allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment,
|
static void *allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment,
|
||||||
qsizetype capacity, ArrayOptions options = DefaultAllocationFlags) noexcept;
|
qsizetype capacity, ArrayOptions options = DefaultAllocationFlags) noexcept;
|
||||||
[[nodiscard]] static QPair<QArrayData *, void *> reallocateUnaligned(QArrayData *data, void *dataPointer,
|
[[nodiscard]] static QPair<QArrayData *, void *> reallocateUnaligned(QArrayData *data, void *dataPointer,
|
||||||
qsizetype objectSize, qsizetype newCapacity, ArrayOptions newOptions = DefaultAllocationFlags) noexcept;
|
qsizetype objectSize, qsizetype newCapacity, AllocationOption option) noexcept;
|
||||||
static void deallocate(QArrayData *data, qsizetype objectSize,
|
static void deallocate(QArrayData *data, qsizetype objectSize,
|
||||||
qsizetype alignment) noexcept;
|
qsizetype alignment) noexcept;
|
||||||
};
|
};
|
||||||
@ -221,12 +226,11 @@ struct QTypedArrayData
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QPair<QTypedArrayData *, T *>
|
static QPair<QTypedArrayData *, T *>
|
||||||
reallocateUnaligned(QTypedArrayData *data, T *dataPointer, qsizetype capacity,
|
reallocateUnaligned(QTypedArrayData *data, T *dataPointer, qsizetype capacity, AllocationOption option)
|
||||||
ArrayOptions options = DefaultAllocationFlags)
|
|
||||||
{
|
{
|
||||||
static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
|
static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData));
|
||||||
QPair<QArrayData *, void *> pair =
|
QPair<QArrayData *, void *> pair =
|
||||||
QArrayData::reallocateUnaligned(data, dataPointer, sizeof(T), capacity, options);
|
QArrayData::reallocateUnaligned(data, dataPointer, sizeof(T), capacity, option);
|
||||||
return qMakePair(static_cast<QTypedArrayData *>(pair.first), static_cast<T *>(pair.second));
|
return qMakePair(static_cast<QTypedArrayData *>(pair.first), static_cast<T *>(pair.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,9 +457,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reallocate(qsizetype alloc)
|
void reallocate(qsizetype alloc, QArrayData::AllocationOption option)
|
||||||
{
|
{
|
||||||
auto pair = Data::reallocateUnaligned(this->d, this->ptr, alloc, QArrayData::GrowsBackwards);
|
auto pair = Data::reallocateUnaligned(this->d, this->ptr, alloc, option);
|
||||||
this->d = pair.first;
|
this->d = pair.first;
|
||||||
this->ptr = pair.second;
|
this->ptr = pair.second;
|
||||||
}
|
}
|
||||||
|
@ -547,7 +547,8 @@ void tst_QArrayData::reallocate()
|
|||||||
// now try to reallocate
|
// now try to reallocate
|
||||||
int newCapacity = 40;
|
int newCapacity = 40;
|
||||||
auto pair = QArrayData::reallocateUnaligned(data, dataPointer, objectSize, newCapacity,
|
auto pair = QArrayData::reallocateUnaligned(data, dataPointer, objectSize, newCapacity,
|
||||||
QArrayData::ArrayOptions(allocateOptions));
|
(allocateOptions & (QArrayData::GrowsBackwards|QArrayData::GrowsForward)) ?
|
||||||
|
QArrayData::Grow : QArrayData::KeepSize);
|
||||||
data = pair.first;
|
data = pair.first;
|
||||||
dataPointer = pair.second;
|
dataPointer = pair.second;
|
||||||
QVERIFY(data);
|
QVERIFY(data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user