diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-10-22 19:09:24 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-10-28 14:27:40 (GMT) |
commit | e83bb2fdfc2dc899526c8157fd8b77a68cdde9da (patch) | |
tree | 50a23cf12df52705f254156072269ec4cce04a21 /src/corelib/tools/qcontiguouscache.h | |
parent | 3f0b969772cf3056ed54349bfe6837d9de2995ea (diff) | |
download | Qt-e83bb2fdfc2dc899526c8157fd8b77a68cdde9da.zip Qt-e83bb2fdfc2dc899526c8157fd8b77a68cdde9da.tar.gz Qt-e83bb2fdfc2dc899526c8157fd8b77a68cdde9da.tar.bz2 |
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/qcontiguouscache.h')
-rw-r--r-- | src/corelib/tools/qcontiguouscache.h | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 862df61..b9d04b8 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -69,6 +69,9 @@ struct Q_CORE_EXPORT QContiguousCacheData // there will be an 8 byte gap here if T requires 16-byte alignment // (such as long double on 64-bit platforms, __int128, __float128) + static QContiguousCacheData *allocate(int size, int alignment); + static void free(QContiguousCacheData *data); + #ifdef QT_QCONTIGUOUSCACHE_DEBUG void dump() const; #endif @@ -161,6 +164,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); } + int alignOfTypedData() const + { +#ifdef Q_ALIGNOF + return qMax<int>(sizeof(void*), Q_ALIGNOF(Data)); +#else + return 0; +#endif + } }; template <typename T> @@ -262,7 +273,7 @@ void QContiguousCache<T>::clear() template <typename T> inline QContiguousCacheData *QContiguousCache<T>::malloc(int aalloc) { - return static_cast<QContiguousCacheData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + return QContiguousCacheData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData()); } template <typename T> @@ -317,7 +328,7 @@ void QContiguousCache<T>::free(Data *x) i = p->array; } } - qFree(x); + x->free(x); } template <typename T> void QContiguousCache<T>::append(const T &value) |