summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydata.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-06-04 22:31:26 +0200
committerLars Knoll <lars.knoll@qt.io>2019-12-07 14:18:19 +0100
commitf6a151024b03158bcf46dc86e346d4227f8ca9d4 (patch)
tree898bbc0be052034801a5269bdd291de09766bd95 /src/corelib/tools/qarraydata.cpp
parent8fb45ae5b8b8ad276aeb9bc9e40f351f47523087 (diff)
Introduce flags to indicate the QArrayData type
These flags allow us to determine what type of data QArrayData is carrying. There are currently only two supported types: - raw data type: constructed via fromRawData or static data - allocated data type: regular data done via heap allocation The QArrayData object is usually allocated on the heap, unless its own reference count is -1 (indicating static const QArrayData). Such object should have a type of RawDataType, since we can't call free(). Add GrowsBackward for completeness as well as the StaticDataFlags default for static data. Change-Id: Icc915a468a2acf2eae91a94e82451f852d382c92 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydata.cpp')
-rw-r--r--src/corelib/tools/qarraydata.cpp57
1 files changed, 37 insertions, 20 deletions
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index ce6f1384977..bc486193492 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -153,17 +153,17 @@ QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers")
const QArrayData QArrayData::shared_null[2] = {
- { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, sizeof(QArrayData) }, // shared null
+ { Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::StaticDataFlags, 0, 0, sizeof(QArrayData) }, // shared null
/* zero initialized terminator */};
-static const QArrayData qt_array[3] = {
- { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, sizeof(QArrayData) }, // shared empty
- { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, sizeof(QArrayData) }, // unsharable empty
+static const QArrayData emptyNotNullShared[2] = {
+ { Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::StaticDataFlags, 0, 0, sizeof(QArrayData) }, // shared empty
/* zero initialized terminator */};
QT_WARNING_POP
-static const QArrayData &qt_array_empty = qt_array[0];
+static const QArrayData &qt_array_empty = emptyNotNullShared[0];
+
static inline size_t calculateBlockSize(size_t &capacity, size_t objectSize, size_t headerSize,
uint options)
{
@@ -179,6 +179,17 @@ static inline size_t calculateBlockSize(size_t &capacity, size_t objectSize, siz
}
}
+static QArrayData *allocateData(size_t allocSize, uint options)
+{
+ QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
+ if (header) {
+ header->ref.atomic.storeRelaxed(1);
+ header->flags = options;
+ header->size = 0;
+ }
+ return header;
+}
+
static QArrayData *reallocateData(QArrayData *header, size_t allocSize, uint options)
{
header = static_cast<QArrayData *>(::realloc(header, allocSize));
@@ -194,38 +205,43 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
Q_ASSERT(alignment >= alignof(QArrayData)
&& !(alignment & (alignment - 1)));
- // Don't allocate empty headers
- if (!(options & RawData) && !capacity)
+ if (capacity == 0)
+ // optimization for empty headers
return const_cast<QArrayData *>(&qt_array_empty);
size_t headerSize = sizeof(QArrayData);
- // Allocate extra (alignment - 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!
- // Padding is skipped when allocating a header for RawData.
- if (!(options & RawData))
- headerSize += (alignment - alignof(QArrayData));
+ if (alignment > alignof(QArrayData)) {
+ // 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!
+ headerSize += alignment - alignof(QArrayData);
+ }
if (headerSize > size_t(MaxAllocSize))
return nullptr;
size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
- QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
+ options |= ArrayOption(AllocatedDataType);
+ QArrayData *header = allocateData(allocSize, options);
if (header) {
quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
& ~(alignment - 1);
-
- header->ref.atomic.storeRelaxed(1);
- header->size = 0;
- header->alloc = capacity;
- header->flags = options;
header->offset = data - quintptr(header);
+ header->alloc = capacity;
}
return header;
}
+QArrayData *QArrayData::prepareRawData(ArrayOptions options) Q_DECL_NOTHROW
+{
+ QArrayData *header = allocateData(sizeof(QArrayData), (options & ~DataTypeBits) | RawDataType);
+ if (header)
+ header->alloc = 0;
+ return header;
+}
+
QArrayData *QArrayData::reallocateUnaligned(QArrayData *data, size_t objectSize, size_t capacity,
ArrayOptions options) noexcept
{
@@ -233,9 +249,10 @@ QArrayData *QArrayData::reallocateUnaligned(QArrayData *data, size_t objectSize,
Q_ASSERT(data->isMutable());
Q_ASSERT(!data->ref.isShared());
+ options |= ArrayOption(AllocatedDataType);
size_t headerSize = sizeof(QArrayData);
size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
- QArrayData *header = static_cast<QArrayData *>(reallocateData(data, allocSize, options));
+ QArrayData *header = reallocateData(data, allocSize, options);
if (header)
header->alloc = capacity;
return header;