From 520cfa6b6cf4b53a02cc08f01323da036d5b9bea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 17:25:16 +0200 Subject: Performance improvements by avoiding creation of temporary QSharedPointers with d=value=0 --- src/corelib/tools/qsharedpointer_impl.h | 68 ++++++++++++--------------------- 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 1fed024..421db34 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -94,7 +94,6 @@ namespace QtSharedPointer { template class InternalRefCount; template class ExternalRefCount; - template QSharedPointer strongRefFromWeakHelper(const QWeakPointer &, X*); template QSharedPointer copyAndSetPointer(X * ptr, const QSharedPointer &src); // used in debug mode to verify the reuse of pointers @@ -131,21 +130,10 @@ namespace QtSharedPointer { inline T *operator->() const { return data(); } protected: - inline Basic() : value(0) { } + inline Basic(T *ptr = 0) : value(ptr) { } + inline Basic(Qt::Initialization) { } // ~Basic(); - inline void verifyReconstruction(const T *ptr) - { - Q_ASSERT_X(!ptr || value != ptr, "QSharedPointer", - "QSharedPointer violation: you cannot create two QSharedPointer objects " - "from the same pointer"); - - // make use of the "ptr" variable in the no-op statement below - // since this function is in a public header, we don't - // want warnings on "unused variables" to show up everywhere - ptr = 0; - } - inline void internalConstruct(T *ptr) { value = ptr; @@ -312,9 +300,10 @@ namespace QtSharedPointer { #ifdef QT_SHAREDPOINTER_TRACK_POINTERS internalConstruct(ptr, normalDeleter); #else - Q_ASSERT(!d); if (ptr) d = new Data; + else + d = 0; internalFinishConstruction(ptr); #endif } @@ -322,9 +311,10 @@ namespace QtSharedPointer { template inline void internalConstruct(T *ptr, Deleter deleter) { - Q_ASSERT(!d); if (ptr) d = ExternalRefCountWithCustomDeleter::create(ptr, deleter); + else + d = 0; internalFinishConstruction(ptr); } @@ -344,9 +334,13 @@ namespace QtSharedPointer { } inline ExternalRefCount() : d(0) { } - inline ~ExternalRefCount() { if (d && !deref()) delete d; } + inline ExternalRefCount(Qt::Initialization i) : Basic(i) { } inline ExternalRefCount(const ExternalRefCount &other) : Basic(other), d(other.d) { if (d) ref(); } + template + inline ExternalRefCount(const ExternalRefCount &other) : Basic(other.value), d(other.d) + { if (d) ref(); } + inline ~ExternalRefCount() { if (d && !deref()) delete d; } template inline void internalCopy(const ExternalRefCount &other) @@ -360,23 +354,19 @@ namespace QtSharedPointer { delete this->value; } - private: #if defined(Q_NO_TEMPLATE_FRIENDS) public: #else template friend class ExternalRefCount; template friend class QWeakPointer; template friend QSharedPointer copyAndSetPointer(X * ptr, const QSharedPointer &src); - template friend QSharedPointer QtSharedPointer::strongRefFromWeakHelper(const QWeakPointer &src, X *); #endif inline void internalSet(Data *o, T *actual) { - if (d == o) return; if (o) { - verifyReconstruction(actual); - // increase the strongref, but never up from zero + // or less (-1 is used by QWeakPointer on untracked QObject) register int tmp = o->strongref; while (tmp > 0) { // try to increment from "tmp" to "tmp + 1" @@ -411,7 +401,8 @@ public: inline QSharedPointer() { } // inline ~QSharedPointer() { } - inline explicit QSharedPointer(T *ptr) { internalConstruct(ptr); } + inline explicit QSharedPointer(T *ptr) : BaseClass(Qt::Uninitialized) + { internalConstruct(ptr); } template inline QSharedPointer(T *ptr, Deleter d) { internalConstruct(ptr, d); } @@ -423,13 +414,9 @@ public: return *this; } - inline QSharedPointer(const QWeakPointer &other) - { *this = QtSharedPointer::strongRefFromWeakHelper(other, static_cast(0)); } - inline QSharedPointer &operator=(const QWeakPointer &other) - { *this = QtSharedPointer::strongRefFromWeakHelper(other, static_cast(0)); return *this; } - template - inline QSharedPointer(const QSharedPointer &other) { *this = other; } + inline QSharedPointer(const QSharedPointer &other) : BaseClass(other) + { } template inline QSharedPointer &operator=(const QSharedPointer &other) @@ -440,12 +427,12 @@ public: } template - inline QSharedPointer(const QWeakPointer &other) - { *this = QtSharedPointer::strongRefFromWeakHelper(other, static_cast(0)); } + inline QSharedPointer(const QWeakPointer &other) : BaseClass(Qt::Uninitialized) + { this->d = 0; *this = other; } template inline QSharedPointer &operator=(const QWeakPointer &other) - { *this = strongRefFromWeakHelper(other, static_cast(0)); return *this; } + { internalSet(other.d, other.value); return *this; } template QSharedPointer staticCast() const @@ -477,10 +464,13 @@ public: QWeakPointer toWeakRef() const; +protected: + inline QSharedPointer(Qt::Initialization i) : BaseClass(i) {} + public: static inline QSharedPointer create() { - QSharedPointer result; + QSharedPointer result(Qt::Uninitialized); result.internalCreate(); // now initialize the data @@ -564,7 +554,7 @@ public: template inline bool operator==(const QSharedPointer &o) const - { return d == o.d && value == static_cast(o.data()); } + { return d == o.d; } template inline bool operator!=(const QSharedPointer &o) const @@ -579,7 +569,7 @@ private: #if defined(Q_NO_TEMPLATE_FRIENDS) public: #else - template friend QSharedPointer QtSharedPointer::strongRefFromWeakHelper(const QWeakPointer &src, X *); + template friend class QSharedPointer; #endif inline void internalSet(Data *o, T *actual) @@ -656,14 +646,6 @@ namespace QtSharedPointer { result.internalSet(src.d, ptr); return result; } - template - Q_INLINE_TEMPLATE QSharedPointer strongRefFromWeakHelper - (const QT_PREPEND_NAMESPACE(QWeakPointer) &src, X *) - { - QSharedPointer result; - result.internalSet(src.d, src.value); - return result; - } } // cast operators -- cgit v0.12