summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlist.h
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2021-03-24 16:47:33 +0100
committerAndrei Golubev <andrei.golubev@qt.io>2021-04-27 14:12:34 +0200
commit1f2d0cd983d08f1b8d791cb3674b0965d5e89f1a (patch)
tree40dbbc2cf53bc154c3758a2fb60f492d8b20d41d /src/corelib/tools/qlist.h
parent4b518d878aadb132256e8cea48fd6249667f59bb (diff)
Resurrect data moves in QList
Use the data moves to readjust the free space in the QList, which ultimately fixes the out-of-memory issues caused by cases like: forever { list.prepend(list.back()); list.removeLast(); } Task-number: QTBUG-91801 Task-number: QTBUG-91360 Task-number: QTBUG-93019 Change-Id: Iacff69cbf36b8b5b176bb2663df635ec972c875c Reviewed-by: Lars Knoll <lars.knoll@qt.io> (cherry picked from commit a0253f5f0249024580050e4ec22d50cb139ef8d9)
Diffstat (limited to 'src/corelib/tools/qlist.h')
-rw-r--r--src/corelib/tools/qlist.h21
1 files changed, 10 insertions, 11 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 6aafb86c01..ddce07bbb7 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -676,9 +676,10 @@ inline void QList<T>::resize_internal(qsizetype newSize)
Q_ASSERT(newSize >= 0);
if (d->needsDetach() || newSize > capacity() - d.freeSpaceAtBegin()) {
- d.reallocateAndGrow(QArrayData::GrowsAtEnd, newSize - d.size);
- } else if (newSize < size())
+ d.detachAndGrow(QArrayData::GrowsAtEnd, newSize - d.size, nullptr, nullptr);
+ } else if (newSize < size()) {
d->truncate(newSize);
+ }
}
template <typename T>
@@ -761,12 +762,7 @@ inline T QList<T>::value(qsizetype i, parameter_type defaultValue) const
template <typename T>
inline void QList<T>::append(const_iterator i1, const_iterator i2)
{
- if (i1 == i2)
- return;
- const auto distance = std::distance(i1, i2);
- DataPointer oldData;
- d.detachAndGrow(QArrayData::GrowsAtEnd, distance, &oldData);
- d->copyAppend(i1, i2);
+ d->growAppend(i1, i2);
}
template <typename T>
@@ -778,7 +774,9 @@ inline void QList<T>::append(QList<T> &&other)
if (other.d->needsDetach() || !std::is_nothrow_move_constructible_v<T>)
return append(other);
- d.detachAndGrow(QArrayData::GrowsAtEnd, other.size());
+ // due to precondition &other != this, we can unconditionally modify 'this'
+ d.detachAndGrow(QArrayData::GrowsAtEnd, other.size(), nullptr, nullptr);
+ Q_ASSERT(d.freeSpaceAtEnd() >= other.size());
d->moveAppend(other.begin(), other.end());
}
@@ -796,8 +794,9 @@ inline typename QList<T>::iterator
QList<T>::insert(qsizetype i, qsizetype n, parameter_type t)
{
Q_ASSERT_X(size_t(i) <= size_t(d->size), "QList<T>::insert", "index out of range");
-
- d->insert(i, n, t);
+ Q_ASSERT_X(n >= 0, "QList::insert", "invalid count");
+ if (Q_LIKELY(n))
+ d->insert(i, n, t);
return d.begin() + i;
}