diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/text/qstring.cpp | 2 | ||||
-rw-r--r-- | src/corelib/text/qstringliteral.h | 2 | ||||
-rw-r--r-- | src/corelib/tools/qarraydata.cpp | 13 | ||||
-rw-r--r-- | src/corelib/tools/qarraydata.h | 27 | ||||
-rw-r--r-- | src/corelib/tools/qarraydataops.h | 4 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 2 |
6 files changed, 29 insertions, 21 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 3e9deba29a..4d3f2016ac 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2677,7 +2677,7 @@ QString &QString::append(const QString &str) QString &QString::append(const QChar *str, int len) { if (str && len > 0) { - if (d->isShared() || uint(d->size + len) + 1u > d->allocatedCapacity()) + if (d->needsDetach() || uint(d->size + len) + 1u > d->allocatedCapacity()) reallocData(uint(d->size + len) + 1u, true); memcpy(d->data() + d->size, str, len * sizeof(QChar)); d->size += len; diff --git a/src/corelib/text/qstringliteral.h b/src/corelib/text/qstringliteral.h index 7b4d2d04f5..a0d4ddc30b 100644 --- a/src/corelib/text/qstringliteral.h +++ b/src/corelib/text/qstringliteral.h @@ -75,7 +75,7 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2, /**/ #define Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \ - { Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::StaticDataFlags, size, 0, offset } \ + { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, size, 0, offset } \ /**/ #define Q_STATIC_STRING_DATA_HEADER_INITIALIZER(size) \ diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index fdd441c7de..aa7fac15ef 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -153,11 +153,11 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") const QArrayData QArrayData::shared_null[2] = { - { Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::StaticDataFlags, 0, 0, sizeof(QArrayData) }, // shared null + { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0, 0, sizeof(QArrayData) }, // shared null /* zero initialized terminator */}; static const QArrayData emptyNotNullShared[2] = { - { Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::StaticDataFlags, 0, 0, sizeof(QArrayData) }, // shared empty + { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0, 0, sizeof(QArrayData) }, // shared empty /* zero initialized terminator */}; QT_WARNING_POP @@ -183,7 +183,7 @@ static QArrayData *allocateData(size_t allocSize, uint options) { QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize)); if (header) { - header->ref_.atomic.storeRelaxed(1); + header->ref_.storeRelaxed(1); header->flags = options; header->size = 0; } @@ -222,7 +222,8 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, return nullptr; size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options); - options |= AllocatedDataType | Mutable; + options |= AllocatedDataType | MutableData; + options &= ~ImmutableHeader; QArrayData *header = allocateData(allocSize, options); if (header) { quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1) @@ -249,10 +250,10 @@ QArrayData *QArrayData::reallocateUnaligned(QArrayData *data, size_t objectSize, Q_ASSERT(data->isMutable()); Q_ASSERT(!data->isShared()); - options |= ArrayOption(AllocatedDataType); size_t headerSize = sizeof(QArrayData); size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options); - options |= AllocatedDataType | Mutable; + options |= AllocatedDataType | MutableData; + options &= ~ImmutableHeader; QArrayData *header = reallocateData(data, allocSize, options); if (header) header->alloc = capacity; diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index 183cf9f002..56d61340f0 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -56,18 +56,19 @@ struct Q_CORE_EXPORT QArrayData CapacityReserved = 0x0010, //!< the capacity was reserved by the user, try to keep it GrowsForward = 0x0020, //!< allocate with eyes towards growing through append() GrowsBackwards = 0x0040, //!< allocate with eyes towards growing through prepend() - Mutable = 0x0080, //!< the data can be changed; doesn't say anything about the header + MutableData = 0x0080, //!< the data can be changed; doesn't say anything about the header + ImmutableHeader = 0x0100, //!< the header is static, it can't be changed /// this option is used by the Q_ARRAY_LITERAL and similar macros - StaticDataFlags = RawDataType, + StaticDataFlags = RawDataType | ImmutableHeader, /// this option is used by the allocate() function - DefaultAllocationFlags = 0, + DefaultAllocationFlags = MutableData, /// this option is used by the prepareRawData() function DefaultRawFlags = 0 }; Q_DECLARE_FLAGS(ArrayOptions, ArrayOption) - QtPrivate::RefCount ref_; + QBasicAtomicInt ref_; uint flags; int size; uint alloc; @@ -84,13 +85,19 @@ struct Q_CORE_EXPORT QArrayData return alloc; } + /// Returns true if sharing took place bool ref() { - return ref_.ref(); + if (!isStatic()) + ref_.ref(); + return true; } + /// Returns false if deallocation is necessary bool deref() { + if (isStatic()) + return true; return ref_.deref(); } @@ -113,17 +120,17 @@ struct Q_CORE_EXPORT QArrayData // follow COW principles. bool isMutable() const { - return flags & Mutable; + return flags & MutableData; } bool isStatic() const { - return ref_.isStatic(); + return flags & ImmutableHeader; } bool isShared() const { - return ref_.isShared(); + return ref_.loadRelaxed() != 1; } // Returns true if a detach is necessary before modifying the data @@ -131,7 +138,7 @@ struct Q_CORE_EXPORT QArrayData // detaching is necessary, you should be in a non-const function already bool needsDetach() { - // ### optimize me -- this currently requires 3 conditionals! + // requires two conditionals return !isMutable() || isShared(); } @@ -354,7 +361,7 @@ struct QArrayDataPointerRef }; #define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \ - { Q_REFCOUNT_INITIALIZE_STATIC, QArrayData::StaticDataFlags, size, 0, offset } \ + { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, size, 0, offset } \ /**/ #define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(type, size) \ diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 777f0d839f..11494a5f6f 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -106,7 +106,7 @@ struct QPodArrayOps void destroyAll() // Call from destructors, ONLY! { Q_ASSERT(this->isMutable()); - Q_ASSERT(this->ref_.atomic.loadRelaxed() == 0); + Q_ASSERT(this->ref_.loadRelaxed() == 0); // As this is to be called only from destructor, it doesn't need to be // exception safe; size not updated. @@ -204,7 +204,7 @@ struct QGenericArrayOps // As this is to be called only from destructor, it doesn't need to be // exception safe; size not updated. - Q_ASSERT(this->ref_.atomic.loadRelaxed() == 0); + Q_ASSERT(this->ref_.loadRelaxed() == 0); const T *const b = this->begin(); const T *i = this->end(); diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index d9512ee90e..bf422e72d4 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -701,7 +701,7 @@ void QVector<T>::removeLast() Q_ASSERT(!isEmpty()); Q_ASSERT(d->allocatedCapacity()); - if (d->isShared()) + if (d->needsDetach()) detach(); --d->size; if (QTypeInfo<T>::isComplex) |