diff options
author | João Abecasis <joao.abecasis@nokia.com> | 2011-11-29 18:12:05 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-09 22:49:08 +0100 |
commit | 0806bc2d1b518b53681b3d8023def95ba8122630 (patch) | |
tree | 988c0b5574dfbae892d1764432399ea16a98297a /src | |
parent | 4714f86c54eb358ec431fb94d6b135b4cad2a7c7 (diff) |
Allocate/free support in QArrayData
Centralizing QArrayData memory management decisions in one place will
allow us to be smarter in how we allocate header and data.
At the moment, these are allocated as a single block. In the future we
may decide to allocate them separately for "large" data or specific
alignment requirements.
For users of QArrayData this remains transparent and not part of the
ABI. The offset field in QArrayDataHeader enables this.
This also hard-wires allocation of empty arrays to return shared_empty.
Allocating detached headers (e.g., to support fromRawData) will thus
require explicit support.
Change-Id: Icac5a1f51ee7e468c76b4493d29debc18780e5dc
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qarraydata.cpp | 44 | ||||
-rw-r--r-- | src/corelib/tools/qarraydata.h | 5 |
2 files changed, 49 insertions, 0 deletions
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 3b15c0e246..168249c074 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -46,4 +46,48 @@ QT_BEGIN_NAMESPACE const QArrayData QArrayData::shared_null = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 }; const QArrayData QArrayData::shared_empty = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, 0 }; +QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, + size_t capacity, bool reserve) +{ + // Alignment is a power of two + Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData) + && !(alignment & (alignment - 1))); + + // Don't allocate empty headers + if (!capacity) + return const_cast<QArrayData *>(&shared_empty); + + // Allocate extra (alignment - Q_ALIGNOF(QArrayData)) padding bytes so we + // can properly align the data array. This assumes malloc is able to + // provide appropriate alignment for the header -- as it should! + size_t allocSize = sizeof(QArrayData) + objectSize * capacity + + (alignment - Q_ALIGNOF(QArrayData)); + + QArrayData *header = static_cast<QArrayData *>(qMalloc(allocSize)); + Q_CHECK_PTR(header); + if (header) { + quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1) + & ~(alignment - 1); + + header->ref = 1; + header->size = 0; + header->alloc = capacity; + header->capacityReserved = reserve; + header->offset = data - quintptr(header); + } + + return header; +} + +void QArrayData::deallocate(QArrayData *data, size_t objectSize, + size_t alignment) +{ + // Alignment is a power of two + Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData) + && !(alignment & (alignment - 1))); + Q_UNUSED(objectSize) Q_UNUSED(alignment) + + qFree(data); +} + QT_END_NAMESPACE diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index 0b6949fe48..684f00870d 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -73,6 +73,11 @@ struct Q_CORE_EXPORT QArrayData return reinterpret_cast<const char *>(this) + offset; } + static QArrayData *allocate(size_t objectSize, size_t alignment, + size_t capacity, bool reserve) Q_REQUIRED_RESULT; + static void deallocate(QArrayData *data, size_t objectSize, + size_t alignment); + static const QArrayData shared_null; static const QArrayData shared_empty; }; |