summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qvector.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-10-22 21:09:24 +0200
committerThiago Macieira <thiago.macieira@nokia.com>2009-10-28 15:27:40 +0100
commite83bb2fdfc2dc899526c8157fd8b77a68cdde9da (patch)
tree50a23cf12df52705f254156072269ec4cce04a21 /src/corelib/tools/qvector.h
parent3f0b969772cf3056ed54349bfe6837d9de2995ea (diff)
Fix Qt containers to properly support types with strict alignments.
QContiguousCache is a new type, so there are no binary compatibility issues. QHash and QMap didn't have any public qMalloc / qFree, so the entire logic is contained in .cpp code. However, since old code will not inform us of the alignment requirements, we need to add a bit to the structure to indicate whether strict alignment is in use or not. QList doesn't require any changes. For small, movable types, they're all stored in the pointer array itself, so they're aligned. For larger types, we use new(), so types with stricter requirements should define their own operator new(). QLinkedList cannot be fixed. It uses new() on the QLinkedListNode, which contains a T type. Sorry. QVector did have public qMalloc / qFree. I've moved the calls to the inner function and made it keep the old calls if the alignment requirement is below a certain threshold. The idea is that, if it's above, no one was using QVector anyway. Reviewed-by: Bradley T. Hughes
Diffstat (limited to 'src/corelib/tools/qvector.h')
-rw-r--r--src/corelib/tools/qvector.h20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index b77b53a21d..cf7df1211b 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -79,6 +79,9 @@ struct Q_CORE_EXPORT QVectorData
// some debugges when the QVector is member of a class within an unnamed namespace.
// ### Qt 5: can be removed completely. (Ralf)
static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init);
+ 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, bool excessive);
};
@@ -87,6 +90,8 @@ struct QVectorTypedData : private QVectorData
{ // private inheritance as we must not access QVectorData member thought QVectorTypedData
// as this would break strict aliasing rules. (in the case of shared_null)
T array[1];
+
+ static inline void free(QVectorTypedData *x, int alignment) { QVectorData::free(x, alignment); }
};
class QRegion;
@@ -302,6 +307,14 @@ private:
// count the padding at the end
return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
}
+ inline int alignOfTypedData() const
+ {
+#ifdef Q_ALIGNOF
+ return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
+#else
+ return 0;
+#endif
+ }
};
template <typename T>
@@ -373,7 +386,7 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v)
template <typename T>
inline QVectorData *QVector<T>::malloc(int aalloc)
{
- QVectorData *vectordata = static_cast<QVectorData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+ QVectorData *vectordata = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
Q_CHECK_PTR(vectordata);
return vectordata;
}
@@ -420,7 +433,7 @@ void QVector<T>::free(Data *x)
while (i-- != b)
i->~T();
}
- qFree(x);
+ x->free(x, alignOfTypedData());
}
template <typename T>
@@ -459,7 +472,8 @@ void QVector<T>::realloc(int asize, int aalloc)
}
} else {
QT_TRY {
- QVectorData *mem = static_cast<QVectorData *>(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+ QVectorData *mem = QVectorData::reallocate(d, sizeOfTypedData() + (aalloc - 1) * sizeof(T),
+ sizeOfTypedData() + (d->alloc - 1) * sizeof(T), alignOfTypedData());
Q_CHECK_PTR(mem);
x.d = d = mem;
x.d->size = d->size;