Replace QArrayData::capacityReserved with a full flags field
Instead of stealing one bit from the alloc field, let's use a full 32-bit for the flags. The first flag to be in the field is the CapacityReserved (even though the allocate() function will store some others there, not relevant for now). This is done in preparation for the need for more flags necessary anyway. Change-Id: I4c997d14743495e0d4558a6fb0a6042eb3d4975d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>bb10
parent
bf0b4f332a
commit
64db4861bf
|
|
@ -160,7 +160,6 @@ static inline const QByteArray stringData(const QMetaObject *mo, int index)
|
|||
const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
|
||||
Q_ASSERT(data.ptr->ref.isStatic());
|
||||
Q_ASSERT(data.ptr->alloc == 0);
|
||||
Q_ASSERT(data.ptr->capacityReserved == 0);
|
||||
Q_ASSERT(data.ptr->size >= 0);
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,9 +509,7 @@ inline void QByteArray::reserve(int asize)
|
|||
if (d->ref.isShared() || uint(asize) + 1u > d->alloc) {
|
||||
reallocData(qMax(uint(size()), uint(asize)) + 1u, d->detachFlags() | Data::CapacityReserved);
|
||||
} else {
|
||||
// cannot set unconditionally, since d could be the shared_null or
|
||||
// otherwise static
|
||||
d->capacityReserved = true;
|
||||
d->flags |= Data::CapacityReserved;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -520,9 +518,7 @@ inline void QByteArray::squeeze()
|
|||
if (d->ref.isShared() || uint(d->size) + 1u < d->alloc) {
|
||||
reallocData(uint(d->size) + 1u, d->detachFlags() & ~Data::CapacityReserved);
|
||||
} else {
|
||||
// cannot set unconditionally, since d could be shared_null or
|
||||
// otherwise static.
|
||||
d->capacityReserved = false;
|
||||
d->flags &= ~Data::CapacityReserved;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1266,10 +1266,8 @@ inline void QString::reserve(int asize)
|
|||
if (d->ref.isShared() || uint(asize) >= d->alloc)
|
||||
reallocData(qMax(asize, d->size) + 1u);
|
||||
|
||||
if (!d->capacityReserved) {
|
||||
// cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
|
||||
d->capacityReserved = true;
|
||||
}
|
||||
// we're not shared anymore, for sure
|
||||
d->flags |= Data::CapacityReserved;
|
||||
}
|
||||
|
||||
inline void QString::squeeze()
|
||||
|
|
@ -1277,11 +1275,8 @@ inline void QString::squeeze()
|
|||
if (d->ref.isShared() || uint(d->size) + 1u < d->alloc)
|
||||
reallocData(uint(d->size) + 1u);
|
||||
|
||||
if (d->capacityReserved) {
|
||||
// cannot set unconditionally, since d could be shared_null or
|
||||
// otherwise static.
|
||||
d->capacityReserved = false;
|
||||
}
|
||||
// we're not shared anymore, for sure
|
||||
d->flags &= ~Data::CapacityReserved;
|
||||
}
|
||||
|
||||
inline QString &QString::setUtf16(const ushort *autf16, int asize)
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
|
|||
/**/
|
||||
|
||||
#define Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
|
||||
{ Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, offset } \
|
||||
{ Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::DefaultAllocationFlags, size, 0, offset } \
|
||||
/**/
|
||||
|
||||
#define Q_STATIC_STRING_DATA_HEADER_INITIALIZER(size) \
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ static QArrayData *reallocateData(QArrayData *header, size_t allocSize, uint opt
|
|||
{
|
||||
header = static_cast<QArrayData *>(::realloc(header, allocSize));
|
||||
if (header)
|
||||
header->capacityReserved = bool(options & QArrayData::CapacityReserved);
|
||||
header->flags = options;
|
||||
return header;
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
|
|||
header->ref.atomic.storeRelaxed(1);
|
||||
header->size = 0;
|
||||
header->alloc = capacity;
|
||||
header->capacityReserved = bool(options & CapacityReserved);
|
||||
header->flags = options;
|
||||
header->offset = data - quintptr(header);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ QT_BEGIN_NAMESPACE
|
|||
struct Q_CORE_EXPORT QArrayData
|
||||
{
|
||||
QtPrivate::RefCount ref;
|
||||
uint flags;
|
||||
int size;
|
||||
uint alloc : 31;
|
||||
uint capacityReserved : 1;
|
||||
uint alloc;
|
||||
|
||||
qptrdiff offset; // in bytes from beginning of header
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ struct Q_CORE_EXPORT QArrayData
|
|||
|
||||
size_t detachCapacity(size_t newSize) const
|
||||
{
|
||||
if (capacityReserved && newSize < alloc)
|
||||
if (flags & CapacityReserved && newSize < alloc)
|
||||
return alloc;
|
||||
return newSize;
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ struct Q_CORE_EXPORT QArrayData
|
|||
ArrayOptions detachFlags() const
|
||||
{
|
||||
ArrayOptions result;
|
||||
if (capacityReserved)
|
||||
if (flags & CapacityReserved)
|
||||
result |= CapacityReserved;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ struct Q_CORE_EXPORT QArrayData
|
|||
ArrayOptions cloneFlags() const
|
||||
{
|
||||
ArrayOptions result;
|
||||
if (capacityReserved)
|
||||
if (flags & CapacityReserved)
|
||||
result |= CapacityReserved;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -304,7 +304,7 @@ struct QArrayDataPointerRef
|
|||
};
|
||||
|
||||
#define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
|
||||
{ Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, offset } \
|
||||
{ Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::DefaultAllocationFlags, size, 0, offset } \
|
||||
/**/
|
||||
|
||||
#define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(type, size) \
|
||||
|
|
|
|||
|
|
@ -119,12 +119,7 @@ public:
|
|||
*this = QVector<T>();
|
||||
return;
|
||||
}
|
||||
realloc(d->size);
|
||||
}
|
||||
if (d->capacityReserved) {
|
||||
// capacity reserved in a read only memory would be useless
|
||||
// this checks avoid writing to such memory.
|
||||
d->capacityReserved = 0;
|
||||
realloc(d->size, QArrayData::ArrayOptions(d->flags));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -376,10 +371,10 @@ inline QVector<T>::QVector(const QVector<T> &v)
|
|||
if (v.d->ref.ref()) {
|
||||
d = v.d;
|
||||
} else {
|
||||
if (v.d->capacityReserved) {
|
||||
if (v.d->flags & Data::CapacityReserved) {
|
||||
d = Data::allocate(v.d->alloc);
|
||||
Q_CHECK_PTR(d);
|
||||
d->capacityReserved = true;
|
||||
d->flags |= Data::CapacityReserved;
|
||||
} else {
|
||||
d = Data::allocate(v.d->size);
|
||||
Q_CHECK_PTR(d);
|
||||
|
|
@ -412,7 +407,7 @@ void QVector<T>::reserve(int asize)
|
|||
if (asize > int(d->alloc))
|
||||
realloc(asize);
|
||||
if (isDetached())
|
||||
d->capacityReserved = 1;
|
||||
d->flags |= Data::CapacityReserved;
|
||||
Q_ASSERT(capacity() >= asize);
|
||||
}
|
||||
|
||||
|
|
@ -644,7 +639,6 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Arra
|
|||
Data::deallocate(x);
|
||||
QT_RETHROW;
|
||||
}
|
||||
x->capacityReserved = d->capacityReserved;
|
||||
} else {
|
||||
Q_ASSERT(int(d->alloc) == aalloc); // resize, without changing allocation size
|
||||
Q_ASSERT(isDetached()); // can be done only on detached d
|
||||
|
|
@ -723,7 +717,6 @@ void QVector<T>::realloc(int aalloc, QArrayData::ArrayOptions options)
|
|||
Data::deallocate(x);
|
||||
QT_RETHROW;
|
||||
}
|
||||
x->capacityReserved = d->capacityReserved;
|
||||
|
||||
Q_ASSERT(d != x);
|
||||
if (!d->ref.deref()) {
|
||||
|
|
|
|||
|
|
@ -139,10 +139,10 @@ public:
|
|||
return;
|
||||
|
||||
if (n <= capacity()) {
|
||||
if (d->capacityReserved)
|
||||
if (d->flags & Data::CapacityReserved)
|
||||
return;
|
||||
if (!d->ref.isShared()) {
|
||||
d->capacityReserved = 1;
|
||||
d->flags |= Data::CapacityReserved;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,11 +155,9 @@ void tst_QArrayData::sharedNullEmpty()
|
|||
|
||||
QCOMPARE(null->size, 0);
|
||||
QCOMPARE(null->alloc, 0u);
|
||||
QCOMPARE(null->capacityReserved, 0u);
|
||||
|
||||
QCOMPARE(empty->size, 0);
|
||||
QCOMPARE(empty->alloc, 0u);
|
||||
QCOMPARE(empty->capacityReserved, 0u);
|
||||
}
|
||||
|
||||
void tst_QArrayData::staticData()
|
||||
|
|
@ -602,7 +600,7 @@ void tst_QArrayData::allocate()
|
|||
QVERIFY(data->alloc > uint(capacity));
|
||||
else
|
||||
QCOMPARE(data->alloc, uint(capacity));
|
||||
QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
|
||||
QCOMPARE(bool(data->flags & QArrayData::CapacityReserved), isCapacityReserved);
|
||||
|
||||
// Check that the allocated array can be used. Best tested with a
|
||||
// memory checker, such as valgrind, running.
|
||||
|
|
@ -647,7 +645,7 @@ void tst_QArrayData::reallocate()
|
|||
QVERIFY(data->alloc > uint(newCapacity));
|
||||
else
|
||||
QCOMPARE(data->alloc, uint(newCapacity));
|
||||
QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
|
||||
QCOMPARE(!(data->flags & QArrayData::CapacityReserved), !isCapacityReserved);
|
||||
|
||||
for (int i = 0; i < capacity; ++i)
|
||||
QCOMPARE(static_cast<char *>(data->data())[i], 'A');
|
||||
|
|
|
|||
Loading…
Reference in New Issue