summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2012-02-17 11:23:41 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-20 17:52:27 +0100
commitebeebe212624b0d6fb87266629dce20ee75391bd (patch)
tree0fba86eea8512979658576ed2a6186a3cca477d2 /src/corelib
parentec5eb45cd3e6d60744afd9e4b16e36fbba3eaf05 (diff)
Have QVectorData::grow, take size of header w/ padding
This includes padding necessary to align the data array, but excludes the first element as was done before. Size of header is the interesting piece of information, anyway. This simplifies calculations in a couple of places, harmonizes code with the QRawVector fork and paves the way for further changes in QVector, namely the memory layout. When Q_ALIGNOF is not available, default to pointer-size alignment. This should be honoured by malloc and won't trigger use of more expensive aligned allocation. Change-Id: I504022ac7595f69089cafd96e47a91b874d5771e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qvector.cpp4
-rw-r--r--src/corelib/tools/qvector.h31
2 files changed, 18 insertions, 17 deletions
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 254dd34771..b70436f907 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -76,9 +76,9 @@ void QVectorData::free(QVectorData *x, int alignment)
::free(x);
}
-int QVectorData::grow(int sizeofTypedData, int size, int sizeofT)
+int QVectorData::grow(int sizeOfHeader, int size, int sizeOfT)
{
- return qAllocMore(size * sizeofT, sizeofTypedData - sizeofT) / sizeofT;
+ return qAllocMore(size * sizeOfT, sizeOfHeader) / sizeOfT;
}
/*!
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 4f9e1839ec..b47dddab14 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -80,7 +80,7 @@ struct Q_CORE_EXPORT QVectorData
static QVectorData *allocate(int size, int alignment);
static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment);
static void free(QVectorData *data, int alignment);
- static int grow(int sizeofTypedData, int size, int sizeofT);
+ static int grow(int sizeOfHeader, int size, int sizeOfT);
};
template <typename T>
@@ -331,17 +331,18 @@ private:
QVectorData *malloc(int alloc);
void realloc(int size, int alloc);
void free(Data *d);
- int sizeOfTypedData() {
- // this is more or less the same as sizeof(Data), except that it doesn't
- // count the padding at the end
- return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
+
+ static Q_DECL_CONSTEXPR int offsetOfTypedData()
+ {
+ // (non-POD)-safe offsetof(Data, array)
+ return (sizeof(QVectorData) + (alignOfTypedData() - 1)) & ~(alignOfTypedData() - 1);
}
- inline int alignOfTypedData() const
+ static Q_DECL_CONSTEXPR int alignOfTypedData()
{
#ifdef Q_ALIGNOF
- return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
+ return Q_ALIGNOF(Data);
#else
- return 0;
+ return sizeof(void *);
#endif
}
};
@@ -355,7 +356,7 @@ void QVector<T>::reserve(int asize)
template <typename T>
void QVector<T>::resize(int asize)
{ realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ?
- QVectorData::grow(sizeOfTypedData(), asize, sizeof(T))
+ QVectorData::grow(offsetOfTypedData(), asize, sizeof(T))
: d->alloc); }
template <typename T>
inline void QVector<T>::clear()
@@ -413,7 +414,7 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v)
template <typename T>
inline QVectorData *QVector<T>::malloc(int aalloc)
{
- QVectorData *vectordata = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
+ QVectorData *vectordata = QVectorData::allocate(offsetOfTypedData() + aalloc * sizeof(T), alignOfTypedData());
Q_CHECK_PTR(vectordata);
return vectordata;
}
@@ -508,13 +509,13 @@ void QVector<T>::realloc(int asize, int aalloc)
if (QTypeInfo<T>::isComplex) {
x.d->size = 0;
} else {
- ::memcpy(x.p, p, sizeOfTypedData() + (qMin(aalloc, d->alloc) - 1) * sizeof(T));
+ ::memcpy(x.p, p, offsetOfTypedData() + qMin(aalloc, d->alloc) * sizeof(T));
x.d->size = d->size;
}
} else {
QT_TRY {
- QVectorData *mem = QVectorData::reallocate(d, sizeOfTypedData() + (aalloc - 1) * sizeof(T),
- sizeOfTypedData() + (d->alloc - 1) * sizeof(T), alignOfTypedData());
+ QVectorData *mem = QVectorData::reallocate(d, offsetOfTypedData() + aalloc * sizeof(T),
+ offsetOfTypedData() + d->alloc * sizeof(T), alignOfTypedData());
Q_CHECK_PTR(mem);
x.d = d = mem;
x.d->size = d->size;
@@ -582,7 +583,7 @@ void QVector<T>::append(const T &t)
if (!isDetached() || d->size + 1 > d->alloc) {
const T copy(t);
realloc(d->size, (d->size + 1 > d->alloc) ?
- QVectorData::grow(sizeOfTypedData(), d->size + 1, sizeof(T))
+ QVectorData::grow(offsetOfTypedData(), d->size + 1, sizeof(T))
: d->alloc);
if (QTypeInfo<T>::isComplex)
new (p->array + d->size) T(copy);
@@ -604,7 +605,7 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
if (n != 0) {
const T copy(t);
if (!isDetached() || d->size + n > d->alloc)
- realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + n, sizeof(T)));
+ realloc(d->size, QVectorData::grow(offsetOfTypedData(), d->size + n, sizeof(T)));
if (QTypeInfo<T>::isStatic) {
T *b = p->array + d->size;
T *i = p->array + d->size + n;