summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/text/qstring.cpp2
-rw-r--r--src/corelib/text/qstringliteral.h2
-rw-r--r--src/corelib/tools/qarraydata.cpp13
-rw-r--r--src/corelib/tools/qarraydata.h27
-rw-r--r--src/corelib/tools/qarraydataops.h4
-rw-r--r--src/corelib/tools/qvector.h2
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)