diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 90069b112d..559ba193d1 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -69,24 +69,25 @@ int qFindByteArray( int qAllocMore(int alloc, int extra) { - if (alloc == 0 && extra == 0) - return 0; - const int page = 1 << 12; - int nalloc; - alloc += extra; - if (alloc < 1<<6) { - nalloc = (1<<3) + ((alloc >>3) << 3); - } else { - // don't do anything if the loop will overflow signed int. - if (alloc >= INT_MAX/2) - return INT_MAX; - nalloc = (alloc < page) ? 1 << 3 : page; - while (nalloc < alloc) { - if (nalloc <= 0) - return INT_MAX; - nalloc *= 2; - } - } + Q_ASSERT(alloc >= 0 && extra >= 0); + Q_ASSERT(alloc < (1 << 30) - extra); + + unsigned nalloc = alloc + extra; + + // Round up to next power of 2 + + // Assuming container is growing, always overshoot + //--nalloc; + + nalloc |= nalloc >> 1; + nalloc |= nalloc >> 2; + nalloc |= nalloc >> 4; + nalloc |= nalloc >> 8; + nalloc |= nalloc >> 16; + ++nalloc; + + Q_ASSERT(nalloc > unsigned(alloc + extra)); + return nalloc - extra; } diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 585d6afa44..4fb74a2af5 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1075,18 +1075,25 @@ void tst_QByteArray::toULongLong() // global function defined in qbytearray.cpp void tst_QByteArray::qAllocMore() { - static const int t[] = { - INT_MIN, INT_MIN + 1, -1234567, -66000, -1025, - -3, -1, 0, +1, +3, +1025, +66000, +1234567, INT_MAX - 1, INT_MAX, - INT_MAX/3 - }; - static const int N = sizeof(t)/sizeof(t[0]); + using QT_PREPEND_NAMESPACE(qAllocMore); - // make sure qAllocMore() doesn't loop infinitely on any input - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) { - ::qAllocMore(t[i], t[j]); - } + // Not very important, but please behave :-) + QVERIFY(qAllocMore(0, 0) >= 0); + + for (int i = 1; i < 1 << 8; i <<= 1) + QVERIFY(qAllocMore(i, 0) >= i); + + for (int i = 1 << 8; i < 1 << 30; i <<= 1) { + const int alloc = qAllocMore(i, 0); + + QVERIFY(alloc >= i); + QCOMPARE(qAllocMore(i - 8, 8), alloc - 8); + QCOMPARE(qAllocMore(i - 16, 16), alloc - 16); + QCOMPARE(qAllocMore(i - 24, 24), alloc - 24); + QCOMPARE(qAllocMore(i - 32, 32), alloc - 32); + + QVERIFY(qAllocMore(i - 1, 0) >= i - 1); + QVERIFY(qAllocMore(i + 1, 0) >= i + 1); } }