From cb0cdf6c0835c7cdff341c285cd0708aa2f4cb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 31 Oct 2011 15:30:20 +0100 Subject: Use RefCount::setSharable feature in QVector Note: This constitutes a break in Binary Compatibility. Change-Id: I050587901725b701f20dd46475ae48aec28aa54d Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qvector.cpp | 2 +- src/corelib/tools/qvector.h | 60 +++++++++++++--------- .../benchmarks/corelib/tools/qvector/qrawvector.h | 1 - 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 95ae76eb1e..d4c7fd79f7 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -52,7 +52,7 @@ static inline int alignmentThreshold() return 2 * sizeof(void*); } -const QVectorData QVectorData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, true, false, 0 }; +const QVectorData QVectorData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, false, 0 }; QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init) { diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index f408f6571f..f9db421fdb 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -70,13 +70,11 @@ struct Q_CORE_EXPORT QVectorData int size; #if defined(QT_ARCH_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED) // workaround for bug in gcc 3.4.2 - uint sharable; uint capacity; uint reserved; #else - uint sharable : 1; uint capacity : 1; - uint reserved : 30; + uint reserved : 31; #endif static const QVectorData shared_null; @@ -120,7 +118,19 @@ public: inline QVector() : d(const_cast(&QVectorData::shared_null)) { } explicit QVector(int size); QVector(int size, const T &t); - inline QVector(const QVector &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); } + inline QVector(const QVector &v) + { + if (v.d->ref.ref()) { + d = v.d; + } else { + d = const_cast(&QVectorData::shared_null); + realloc(0, v.d->alloc); + qCopy(v.p->array, v.p->array + v.d->size, p->array); + d->size = v.d->size; + d->capacity = v.d->capacity; + } + } + inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(p); } QVector &operator=(const QVector &v); #ifdef Q_COMPILER_RVALUE_REFS @@ -144,9 +154,18 @@ public: void reserve(int size); inline void squeeze() { realloc(d->size, d->size); d->capacity = 0; } - inline void detach() { if (d->ref != 1) detach_helper(); } - inline bool isDetached() const { return d->ref == 1; } - inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QVectorData::shared_null) d->sharable = sharable; } + inline void detach() { if (!isDetached()) detach_helper(); } + inline bool isDetached() const { return !d->ref.isShared(); } + inline void setSharable(bool sharable) + { + if (sharable == d->ref.isSharable()) + return; + if (!sharable) + detach(); + if (d != &QVectorData::shared_null) + d->ref.setSharable(sharable); + } + inline bool isSharedWith(const QVector &other) const { return d == other.d; } inline T *data() { detach(); return p->array; } @@ -337,7 +356,7 @@ void QVector::detach_helper() { realloc(d->size, d->alloc); } template void QVector::reserve(int asize) -{ if (asize > d->alloc) realloc(d->size, asize); if (d->ref == 1) d->capacity = 1; } +{ if (asize > d->alloc) realloc(d->size, asize); if (isDetached()) d->capacity = 1; } template void QVector::resize(int asize) { realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ? @@ -389,13 +408,10 @@ inline void QVector::replace(int i, const T &t) template QVector &QVector::operator=(const QVector &v) { - QVectorData *o = v.d; - o->ref.ref(); - if (!d->ref.deref()) - free(p); - d = o; - if (!d->sharable) - detach_helper(); + if (v.d != d) { + QVector tmp(v); + tmp.swap(*this); + } return *this; } @@ -413,7 +429,6 @@ QVector::QVector(int asize) d = malloc(asize); d->ref.initializeOwned(); d->alloc = d->size = asize; - d->sharable = true; d->capacity = false; if (QTypeInfo::isComplex) { T* b = p->array; @@ -431,7 +446,6 @@ QVector::QVector(int asize, const T &t) d = malloc(asize); d->ref.initializeOwned(); d->alloc = d->size = asize; - d->sharable = true; d->capacity = false; T* i = p->array + d->size; while (i != p->array) @@ -445,7 +459,6 @@ QVector::QVector(std::initializer_list args) d = malloc(int(args.size())); d->ref.initializeOwned(); d->alloc = d->size = int(args.size()); - d->sharable = true; d->capacity = false; T* i = p->array + d->size; auto it = args.end(); @@ -477,7 +490,7 @@ void QVector::realloc(int asize, int aalloc) union { QVectorData *d; Data *p; } x; x.d = d; - if (QTypeInfo::isComplex && asize < d->size && d->ref == 1 ) { + if (QTypeInfo::isComplex && asize < d->size && isDetached()) { // call the destructor on all objects that need to be // destroyed when shrinking pOld = p->array + d->size; @@ -488,13 +501,13 @@ void QVector::realloc(int asize, int aalloc) } } - if (aalloc != d->alloc || d->ref != 1) { + if (aalloc != d->alloc || !isDetached()) { // (re)allocate memory if (QTypeInfo::isStatic) { x.d = malloc(aalloc); Q_CHECK_PTR(x.p); x.d->size = 0; - } else if (d->ref != 1) { + } else if (!isDetached()) { x.d = malloc(aalloc); Q_CHECK_PTR(x.p); if (QTypeInfo::isComplex) { @@ -517,7 +530,6 @@ void QVector::realloc(int asize, int aalloc) } x.d->ref.initializeOwned(); x.d->alloc = aalloc; - x.d->sharable = true; x.d->capacity = d->capacity; x.d->reserved = 0; } @@ -572,7 +584,7 @@ Q_OUTOFLINE_TEMPLATE T QVector::value(int i, const T &defaultValue) const template void QVector::append(const T &t) { - if (d->ref != 1 || d->size + 1 > d->alloc) { + if (!isDetached() || d->size + 1 > d->alloc) { const T copy(t); realloc(d->size, (d->size + 1 > d->alloc) ? QVectorData::grow(sizeOfTypedData(), d->size + 1, sizeof(T), QTypeInfo::isStatic) @@ -596,7 +608,7 @@ Q_TYPENAME QVector::iterator QVector::insert(iterator before, size_type n, int offset = int(before - p->array); if (n != 0) { const T copy(t); - if (d->ref != 1 || d->size + n > d->alloc) + if (!isDetached() || d->size + n > d->alloc) realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + n, sizeof(T), QTypeInfo::isStatic)); if (QTypeInfo::isStatic) { diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index f786d83a53..2cdabb30c5 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -292,7 +292,6 @@ public: d->ref.initializeOwned(); d->alloc = m_alloc; d->size = m_size; - d->sharable = 0; d->capacity = 0; QVector v; -- cgit v1.2.3