diff options
-rw-r--r-- | src/corelib/text/qbytearray.cpp | 6 | ||||
-rw-r--r-- | src/corelib/text/qstring.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qarraydata.cpp | 18 | ||||
-rw-r--r-- | src/corelib/tools/qarraydata.h | 12 | ||||
-rw-r--r-- | src/corelib/tools/qarraydataops.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 3 |
6 files changed, 26 insertions, 21 deletions
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index 945a2a26fd..1a1b2d86b0 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -671,7 +671,7 @@ QByteArray qUncompress(const uchar* data, qsizetype nbytes) return invalidCompressedData(); } else { // grow the block - d->reallocate(d->allocatedCapacity()*2); + d->reallocate(d->allocatedCapacity()*2, QArrayData::Grow); if (Q_UNLIKELY(d.data() == nullptr)) return invalidCompressedData(); } @@ -1719,7 +1719,7 @@ void QByteArray::reallocData(qsizetype alloc, Data::ArrayOptions options) dd.data()[dd.size] = 0; d = dd; } 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; d = dd; } else { - d->reallocate(d.constAllocatedCapacity() + n); + d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow); } } diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 3e6188a38d..ebdb571041 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2516,7 +2516,7 @@ void QString::reallocData(qsizetype alloc, Data::ArrayOptions allocOptions) dd.data()[dd.size] = 0; d = dd; } 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; d = dd; } else { - d->reallocate(d.constAllocatedCapacity() + n); + d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow); } } diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index ab4a0f8af6..4feb52a710 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -159,12 +159,12 @@ static inline qsizetype reserveExtraBytes(qsizetype 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 // allocSize = objectSize * capacity + headerSize, but checked for overflow // plus padded to grow in size - if (options & (QArrayData::GrowsForward | QArrayData::GrowsBackwards)) { + if (option == QArrayData::Grow) { auto r = qCalculateGrowingBlockSize(capacity, objectSize, headerSize); capacity = r.elementCount; 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))); if (header) { header->ref_.storeRelaxed(1); - header->flags = options; + header->flags = 0; header->alloc = 0; } return header; @@ -208,18 +208,19 @@ void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype al } 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); if (Q_UNLIKELY(allocSize < 0)) { // handle overflow. cannot allocate reliably *dptr = nullptr; return nullptr; } - QArrayData *header = allocateData(allocSize, options); + QArrayData *header = allocateData(allocSize); void *data = nullptr; if (header) { // find where offset should point to so that data() is aligned to alignment bytes data = QTypedArrayData<void>::dataStart(header, alignment); + header->flags = options & CapacityReserved; header->alloc = qsizetype(capacity); } @@ -229,12 +230,12 @@ void *QArrayData::allocate(QArrayData **dptr, qsizetype objectSize, qsizetype al QPair<QArrayData *, void *> 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()); 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; allocSize = reserveExtraBytes(allocSize); @@ -243,7 +244,6 @@ QArrayData::reallocateUnaligned(QArrayData *data, void *dataPointer, QArrayData *header = static_cast<QArrayData *>(::realloc(data, size_t(allocSize))); if (header) { - header->flags = options; header->alloc = uint(capacity); dataPointer = reinterpret_cast<char *>(header) + offset; } diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index 4cb0f7a45c..76f2c33043 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -51,6 +51,11 @@ template <class T> struct QTypedArrayData; struct Q_CORE_EXPORT QArrayData { + enum AllocationOption { + Grow, + KeepSize + }; + enum ArrayOption { /// this option is used by the allocate() function DefaultAllocationFlags = 0, @@ -122,7 +127,7 @@ struct Q_CORE_EXPORT QArrayData static void *allocate(QArrayData **pdata, qsizetype objectSize, qsizetype alignment, qsizetype capacity, ArrayOptions options = DefaultAllocationFlags) noexcept; [[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, qsizetype alignment) noexcept; }; @@ -221,12 +226,11 @@ struct QTypedArrayData } static QPair<QTypedArrayData *, T *> - reallocateUnaligned(QTypedArrayData *data, T *dataPointer, qsizetype capacity, - ArrayOptions options = DefaultAllocationFlags) + reallocateUnaligned(QTypedArrayData *data, T *dataPointer, qsizetype capacity, AllocationOption option) { static_assert(sizeof(QTypedArrayData) == sizeof(QArrayData)); 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)); } diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 140d79b2e3..a904341eff 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -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->ptr = pair.second; } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 5910a29b43..f8d85a37e7 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -547,7 +547,8 @@ void tst_QArrayData::reallocate() // now try to reallocate int newCapacity = 40; auto pair = QArrayData::reallocateUnaligned(data, dataPointer, objectSize, newCapacity, - QArrayData::ArrayOptions(allocateOptions)); + (allocateOptions & (QArrayData::GrowsBackwards|QArrayData::GrowsForward)) ? + QArrayData::Grow : QArrayData::KeepSize); data = pair.first; dataPointer = pair.second; QVERIFY(data); |