Update allocation interface of QArrayDataPointer

Added overload to allocGrow that figures the capacity to allocate from
the newSize argument passed. This is useful in QList (and likely in other
places)

Fixed QArrayPodOps::reallocate as a drive by: don't call memmove when
it is not needed

Task-number: QTBUG-84320
Change-Id: I67efe55a60efaf3ab6057b0249d6a446e04a09e3
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Andrei Golubev 2020-08-26 09:11:18 +02:00
parent 15553c39f4
commit f48dba0665
3 changed files with 11 additions and 8 deletions

View File

@ -460,8 +460,7 @@ public:
const bool grows = options & (Data::GrowsForward | Data::GrowsBackwards);
// ### optimize me: there may be cases when moving is not obligatory
if (this->d && !grows) {
const auto gap = this->freeSpaceAtBegin();
if (const auto gap = this->freeSpaceAtBegin(); this->d && !grows && gap) {
auto oldBegin = this->begin();
this->ptr -= gap;
::memmove(static_cast<void *>(this->begin()), static_cast<void *>(oldBegin),

View File

@ -209,6 +209,12 @@ public:
return d->constAllocatedCapacity() - freeSpaceAtBegin() - this->size;
}
static QArrayDataPointer allocateGrow(const QArrayDataPointer &from,
qsizetype newSize, QArrayData::ArrayOptions options)
{
return allocateGrow(from, from.detachCapacity(newSize), newSize, options);
}
static QArrayDataPointer allocateGrow(const QArrayDataPointer &from, qsizetype capacity,
qsizetype newSize, QArrayData::ArrayOptions options)
{

View File

@ -564,7 +564,7 @@ inline void QList<T>::append(const_iterator i1, const_iterator i2)
const size_t newSize = size() + distance;
const bool shouldGrow = d->shouldGrowBeforeInsert(d.end(), qsizetype(distance));
if (d->needsDetach() || newSize > d->allocatedCapacity() || shouldGrow) {
DataPointer detached(DataPointer::allocateGrow(d, d->detachCapacity(newSize), newSize,
DataPointer detached(DataPointer::allocateGrow(d, newSize,
d->detachFlags() | Data::GrowsForward));
detached->copyAppend(constBegin(), constEnd());
detached->copyAppend(i1, i2);
@ -586,7 +586,7 @@ inline void QList<T>::append(QList<T> &&other)
const size_t newSize = size() + other.size();
const bool shouldGrow = d->shouldGrowBeforeInsert(d.end(), other.size());
if (d->needsDetach() || newSize > d->allocatedCapacity() || shouldGrow) {
DataPointer detached(DataPointer::allocateGrow(d, d->detachCapacity(newSize), newSize,
DataPointer detached(DataPointer::allocateGrow(d, newSize,
d->detachFlags() | Data::GrowsForward));
if (!d->needsDetach())
@ -619,8 +619,7 @@ QList<T>::insert(qsizetype i, qsizetype n, parameter_type t)
if (size_t(i) <= newSize / 4)
flags |= Data::GrowsBackwards;
DataPointer detached(DataPointer::allocateGrow(d, d->detachCapacity(newSize), newSize,
flags));
DataPointer detached(DataPointer::allocateGrow(d, newSize, flags));
const_iterator where = constBegin() + i;
detached->copyAppend(constBegin(), where);
detached->copyAppend(n, t);
@ -652,8 +651,7 @@ QList<T>::emplace(qsizetype i, Args&&... args)
if (size_t(i) <= newSize / 4)
flags |= Data::GrowsBackwards;
DataPointer detached(DataPointer::allocateGrow(d, d->detachCapacity(newSize), newSize,
flags));
DataPointer detached(DataPointer::allocateGrow(d, newSize, flags));
const_iterator where = constBegin() + i;
// Create an element here to handle cases when a user moves the element
// from a container to the same container. This is a critical step for