diff options
-rw-r--r-- | src/corelib/tools/qvector.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 31 | ||||
-rw-r--r-- | tests/benchmarks/corelib/tools/qvector/qrawvector.h | 46 |
3 files changed, 38 insertions, 43 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; diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 4a4f03ee1b..1342513a7f 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -73,17 +73,11 @@ class QRawVector int m_alloc; public: - //static Data dummy; - //int headerOffset() { return (char*)&dummy.array - (char*)&dummy; } - inline int headerOffset() const { - // gcc complains about: return offsetof(Data, array); and also - // does not like '0' in the expression below. - return (char *)&(((Data *)(1))->array) - (char *)1; - } - inline Data *toBase(T *begin) const - { return (Data*)((char*)begin - headerOffset()); } - inline T *fromBase(void *d) const - { return (T*)((char*)d + headerOffset()); } + static Data *toBase(T *begin) + { return (Data*)((char*)begin - offsetOfTypedData()); } + static T *fromBase(void *d) + { return (T*)((char*)d + offsetOfTypedData()); } + inline QRawVector() { m_begin = fromBase(0); m_alloc = m_size = 0; realloc(m_size, m_alloc, true); } explicit QRawVector(int size); @@ -270,17 +264,18 @@ private: T *allocate(int alloc); void realloc(int size, int alloc, bool ref); void free(T *begin, int size); - 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); } - static inline int alignOfTypedData() + 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 } @@ -308,7 +303,7 @@ void QRawVector<T>::reserve(int asize) template <typename T> void QRawVector<T>::resize(int asize) { realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1))) - ? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T)) + ? QVectorData::grow(offsetOfTypedData(), asize, sizeof(T)) : m_alloc, false); } template <typename T> inline void QRawVector<T>::clear() @@ -369,7 +364,7 @@ QRawVector<T> &QRawVector<T>::operator=(const QRawVector<T> &v) template <typename T> inline T *QRawVector<T>::allocate(int aalloc) { - QVectorData *d = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData()); + QVectorData *d = QVectorData::allocate(offsetOfTypedData() + aalloc * sizeof(T), alignOfTypedData()); Q_CHECK_PTR(d); return fromBase(d); } @@ -445,10 +440,9 @@ void QRawVector<T>::realloc(int asize, int aalloc, bool ref) changed = true; } else { QT_TRY { - QVectorData *mem = QVectorData::reallocate( - toBase(m_begin), sizeOfTypedData() + (aalloc - 1) * sizeof(T), - sizeOfTypedData() -+ (xalloc - 1) * sizeof(T), alignOfTypedData()); + QVectorData *mem = QVectorData::reallocate(toBase(m_begin), + offsetOfTypedData() + aalloc * sizeof(T), + offsetOfTypedData() + xalloc * sizeof(T), alignOfTypedData()); Q_CHECK_PTR(mem); xbegin = fromBase(mem); xsize = m_size; @@ -510,7 +504,7 @@ void QRawVector<T>::append(const T &t) { if (m_size + 1 > m_alloc) { const T copy(t); - realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + 1, sizeof(T)), false); + realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + 1, sizeof(T)), false); if (QTypeInfo<T>::isComplex) new (m_begin + m_size) T(copy); else @@ -531,7 +525,7 @@ typename QRawVector<T>::iterator QRawVector<T>::insert(iterator before, size_typ if (n != 0) { const T copy(t); if (m_size + n > m_alloc) - realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + n, sizeof(T)), false); + realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + n, sizeof(T)), false); if (QTypeInfo<T>::isStatic) { T *b = m_begin + m_size; T *i = m_begin + m_size + n; |