From e5d10b2a3be77244d8db3a4dac86168ee9b91e6f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 4 Apr 2012 13:50:21 +0200 Subject: [PATCH] Move growth computation to re-allocation function Callers of QByteArray/QString::realloc() are still responsible for the heuristics and decide whether to provide the "grow" hint, but computation is centralized there. With this change we also ensure growth takes into account the terminating null. Previously, calls to qAllocMore took into account header and string size, for left out the null, meaning we ended up allocating ("nice-size" + Null). Change-Id: Iad1536e7706cd2d446daee96859db9b01c5f9680 Reviewed-by: Marius Storm-Olsen Reviewed-by: Thiago Macieira --- src/corelib/tools/qbytearray.cpp | 19 +++++++++++-------- src/corelib/tools/qbytearray.h | 2 +- src/corelib/tools/qstring.cpp | 18 ++++++++---------- src/corelib/tools/qstring.h | 5 ++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 5961d68..731a1b1 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1432,7 +1432,7 @@ void QByteArray::resize(int size) } else { if (d->ref.isShared() || size > int(d->alloc) || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1)) - realloc(qAllocMore(size, sizeof(Data))); + realloc(size, true); if (int(d->alloc) >= size) { d->size = size; d->data()[size] = '\0'; @@ -1459,8 +1459,11 @@ QByteArray &QByteArray::fill(char ch, int size) return *this; } -void QByteArray::realloc(int alloc) +void QByteArray::realloc(int alloc, bool grow) { + if (grow) + alloc = qAllocMore(alloc + 1, sizeof(Data)) - 1; + if (d->ref.isShared() || IS_RAW_DATA(d)) { Data *x = static_cast(malloc(sizeof(Data) + alloc + 1)); Q_CHECK_PTR(x); @@ -1563,7 +1566,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) { if (str) { if (d->ref.isShared() || d->size + len > int(d->alloc)) - realloc(qAllocMore(d->size + len, sizeof(Data))); + realloc(d->size + len, true); memmove(d->data()+len, d->data(), d->size); memcpy(d->data(), str, len); d->size += len; @@ -1581,7 +1584,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) QByteArray &QByteArray::prepend(char ch) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - realloc(qAllocMore(d->size + 1, sizeof(Data))); + realloc(d->size + 1, true); memmove(d->data()+1, d->data(), d->size); d->data()[0] = ch; ++d->size; @@ -1619,7 +1622,7 @@ QByteArray &QByteArray::append(const QByteArray &ba) *this = ba; } else if (ba.d != &shared_null.ba) { if (d->ref.isShared() || d->size + ba.d->size > int(d->alloc)) - realloc(qAllocMore(d->size + ba.d->size, sizeof(Data))); + realloc(d->size + ba.d->size, true); memcpy(d->data() + d->size, ba.d->data(), ba.d->size); d->size += ba.d->size; d->data()[d->size] = '\0'; @@ -1653,7 +1656,7 @@ QByteArray& QByteArray::append(const char *str) if (str) { int len = strlen(str); if (d->ref.isShared() || d->size + len > int(d->alloc)) - realloc(qAllocMore(d->size + len, sizeof(Data))); + realloc(d->size + len, true); memcpy(d->data() + d->size, str, len + 1); // include null terminator d->size += len; } @@ -1678,7 +1681,7 @@ QByteArray &QByteArray::append(const char *str, int len) len = qstrlen(str); if (str && len) { if (d->ref.isShared() || d->size + len > int(d->alloc)) - realloc(qAllocMore(d->size + len, sizeof(Data))); + realloc(d->size + len, true); memcpy(d->data() + d->size, str, len); // include null terminator d->size += len; d->data()[d->size] = '\0'; @@ -1695,7 +1698,7 @@ QByteArray &QByteArray::append(const char *str, int len) QByteArray& QByteArray::append(char ch) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - realloc(qAllocMore(d->size + 1, sizeof(Data))); + realloc(d->size + 1, true); d->data()[d->size++] = ch; d->data()[d->size] = '\0'; return *this; diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 93e2419..62273c5 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -406,7 +406,7 @@ private: static const QStaticByteArrayData<1> shared_null; static const QStaticByteArrayData<1> shared_empty; Data *d; - void realloc(int alloc); + void realloc(int alloc, bool grow = false); void expand(int i); QByteArray nulTerminated() const; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c5c4367..123d332 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -799,11 +799,6 @@ const QString::Null QString::null = { }; const QStaticStringData<1> QString::shared_null = { Q_STATIC_STRING_DATA_HEADER_INITIALIZER(0), { 0 } }; const QStaticStringData<1> QString::shared_empty = { Q_STATIC_STRING_DATA_HEADER_INITIALIZER(0), { 0 } }; -int QString::grow(int size) -{ - return qAllocMore(size * sizeof(QChar), sizeof(Data)) / sizeof(QChar); -} - /*! \typedef QString::ConstIterator Qt-style synonym for QString::const_iterator. @@ -1247,7 +1242,7 @@ void QString::resize(int size) } else { if (d->ref.isShared() || size > int(d->alloc) || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1)) - realloc(grow(size)); + realloc(size, true); if (int(d->alloc) >= size) { d->size = size; d->data()[size] = '\0'; @@ -1306,8 +1301,11 @@ void QString::resize(int size) */ // ### Qt 5: rename reallocData() to avoid confusion. 197625 -void QString::realloc(int alloc) +void QString::realloc(int alloc, bool grow) { + if (grow) + alloc = qAllocMore((alloc+1) * sizeof(QChar), sizeof(Data)) / sizeof(QChar) - 1; + if (d->ref.isShared() || IS_RAW_DATA(d)) { Data *x = static_cast(::malloc(sizeof(Data) + (alloc+1) * sizeof(QChar))); Q_CHECK_PTR(x); @@ -1534,7 +1532,7 @@ QString &QString::append(const QString &str) operator=(str); } else { if (d->ref.isShared() || d->size + str.d->size > int(d->alloc)) - realloc(grow(d->size + str.d->size)); + realloc(d->size + str.d->size, true); memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar)); d->size += str.d->size; d->data()[d->size] = '\0'; @@ -1554,7 +1552,7 @@ QString &QString::append(const QLatin1String &str) if (s) { int len = str.size(); if (d->ref.isShared() || d->size + len > int(d->alloc)) - realloc(grow(d->size + len)); + realloc(d->size + len, true); ushort *i = d->data() + d->size; while ((*i++ = *s++)) ; @@ -1597,7 +1595,7 @@ QString &QString::append(const QLatin1String &str) QString &QString::append(QChar ch) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - realloc(grow(d->size + 1)); + realloc(d->size + 1, true); d->data()[d->size++] = ch.unicode(); d->data()[d->size] = '\0'; return *this; diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index fd22eb7..36acf32 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -372,7 +372,7 @@ public: inline QString &operator+=(QChar c) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - realloc(grow(d->size + 1)); + realloc(d->size + 1, true); d->data()[d->size++] = c.unicode(); d->data()[d->size] = '\0'; return *this; @@ -649,9 +649,8 @@ private: static const QStaticStringData<1> shared_empty; Data *d; - static int grow(int); static void free(Data *); - void realloc(int alloc); + void realloc(int alloc, bool grow = false); void expand(int i); void updateProperties() const; QString multiArg(int numArgs, const QString **args) const; -- 2.7.4