Loading include/utils/RefBase.h +56 −39 Original line number Original line Diff line number Diff line Loading @@ -52,12 +52,16 @@ inline bool operator _op_ (const U* o) const { \ } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- class ReferenceMover; class ReferenceConverterBase { class ReferenceRenamer { protected: // destructor is purposedly not virtual so we avoid code overhead from // subclasses; we have to make it protected to guarantee that it // cannot be called from this base class (and to make strict compilers // happy). ~ReferenceRenamer() { } public: public: virtual size_t getReferenceTypeSize() const = 0; virtual void operator()(size_t i) const = 0; virtual void* getReferenceBase(void const*) const = 0; inline virtual ~ReferenceConverterBase() { } }; }; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading Loading @@ -143,11 +147,6 @@ protected: virtual bool onIncStrongAttempted(uint32_t flags, const void* id); virtual bool onIncStrongAttempted(uint32_t flags, const void* id); virtual void onLastWeakRef(const void* id); virtual void onLastWeakRef(const void* id); private: friend class ReferenceMover; static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster); private: private: friend class weakref_type; friend class weakref_type; class weakref_impl; class weakref_impl; Loading @@ -155,6 +154,17 @@ private: RefBase(const RefBase& o); RefBase(const RefBase& o); RefBase& operator=(const RefBase& o); RefBase& operator=(const RefBase& o); private: friend class ReferenceMover; static void renameRefs(size_t n, const ReferenceRenamer& renamer); static void renameRefId(weakref_type* ref, const void* old_id, const void* new_id); static void renameRefId(RefBase* ref, const void* old_id, const void* new_id); weakref_impl* const mRefs; weakref_impl* const mRefs; }; }; Loading Loading @@ -185,8 +195,9 @@ protected: private: private: friend class ReferenceMover; friend class ReferenceMover; inline static void moveReferences(void* d, void const* s, size_t n, inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } const ReferenceConverterBase& caster) { } inline static void renameRefId(T* ref, const void* old_id, const void* new_id) { } private: private: mutable volatile int32_t mCount; mutable volatile int32_t mCount; Loading Loading @@ -455,42 +466,48 @@ inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) // this class just serves as a namespace so TYPE::moveReferences can stay // this class just serves as a namespace so TYPE::moveReferences can stay // private. // private. class ReferenceMover { class ReferenceMover { // StrongReferenceCast and WeakReferenceCast do the impedance matching public: // between the generic (void*) implementation in Refbase and the strongly typed // it would be nice if we could make sure no extra code is generated // template specializations below. // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: // Using a sp<RefBase> override doesn't work; it's a bit like we wanted // a template<typename TYPE inherits RefBase> template... template <typename TYPE> template<typename TYPE> static inline struct StrongReferenceCast : public ReferenceConverterBase { void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); } virtual void* getReferenceBase(void const* p) const { sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p)); return static_cast<typename TYPE::basetype *>(sptr->get()); } }; template <typename TYPE> class Renamer : public ReferenceRenamer { struct WeakReferenceCast : public ReferenceConverterBase { sp<TYPE>* d; virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } sp<TYPE> const* s; virtual void* getReferenceBase(void const* p) const { virtual void operator()(size_t i) const { wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); // The id are known to be the sp<>'s this pointer return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); TYPE::renameRefId(d[i].get(), &s[i], &d[i]); } } public: Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { } }; }; public: template<typename TYPE> static inline void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { memmove(d, s, n*sizeof(sp<TYPE>)); memmove(d, s, n*sizeof(sp<TYPE>)); StrongReferenceCast<TYPE> caster; TYPE::renameRefs(n, Renamer(d, s)); TYPE::moveReferences(d, s, n, caster); } } template<typename TYPE> static inline template<typename TYPE> static inline void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { class Renamer : public ReferenceRenamer { wp<TYPE>* d; wp<TYPE> const* s; virtual void operator()(size_t i) const { // The id are known to be the wp<>'s this pointer TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); } public: Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { } }; memmove(d, s, n*sizeof(wp<TYPE>)); memmove(d, s, n*sizeof(wp<TYPE>)); WeakReferenceCast<TYPE> caster; TYPE::renameRefs(n, Renamer(d, s)); TYPE::moveReferences(d, s, n, caster); } } }; }; Loading libs/utils/RefBase.cpp +15 −9 Original line number Original line Diff line number Diff line Loading @@ -631,21 +631,27 @@ void RefBase::onLastWeakRef(const void* /*id*/) // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- void RefBase::moveReferences(void* dst, void const* src, size_t n, void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { const ReferenceConverterBase& caster) { #if DEBUG_REFS #if DEBUG_REFS const size_t itemSize = caster.getReferenceTypeSize(); for (size_t i=0 ; i<n ; i++) { for (size_t i=0 ; i<n ; i++) { void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); renamer(i); void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize); RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d))); ref->mRefs->renameStrongRefId(s, d); ref->mRefs->renameWeakRefId(s, d); } } #endif #endif } } void RefBase::renameRefId(weakref_type* ref, const void* old_id, const void* new_id) { weakref_impl* const impl = static_cast<weakref_impl*>(ref); impl->renameStrongRefId(old_id, new_id); impl->renameWeakRefId(old_id, new_id); } void RefBase::renameRefId(RefBase* ref, const void* old_id, const void* new_id) { ref->mRefs->renameStrongRefId(old_id, new_id); ref->mRefs->renameWeakRefId(old_id, new_id); } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- TextOutput& printStrongPointer(TextOutput& to, const void* val) TextOutput& printStrongPointer(TextOutput& to, const void* val) Loading Loading
include/utils/RefBase.h +56 −39 Original line number Original line Diff line number Diff line Loading @@ -52,12 +52,16 @@ inline bool operator _op_ (const U* o) const { \ } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- class ReferenceMover; class ReferenceConverterBase { class ReferenceRenamer { protected: // destructor is purposedly not virtual so we avoid code overhead from // subclasses; we have to make it protected to guarantee that it // cannot be called from this base class (and to make strict compilers // happy). ~ReferenceRenamer() { } public: public: virtual size_t getReferenceTypeSize() const = 0; virtual void operator()(size_t i) const = 0; virtual void* getReferenceBase(void const*) const = 0; inline virtual ~ReferenceConverterBase() { } }; }; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading Loading @@ -143,11 +147,6 @@ protected: virtual bool onIncStrongAttempted(uint32_t flags, const void* id); virtual bool onIncStrongAttempted(uint32_t flags, const void* id); virtual void onLastWeakRef(const void* id); virtual void onLastWeakRef(const void* id); private: friend class ReferenceMover; static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster); private: private: friend class weakref_type; friend class weakref_type; class weakref_impl; class weakref_impl; Loading @@ -155,6 +154,17 @@ private: RefBase(const RefBase& o); RefBase(const RefBase& o); RefBase& operator=(const RefBase& o); RefBase& operator=(const RefBase& o); private: friend class ReferenceMover; static void renameRefs(size_t n, const ReferenceRenamer& renamer); static void renameRefId(weakref_type* ref, const void* old_id, const void* new_id); static void renameRefId(RefBase* ref, const void* old_id, const void* new_id); weakref_impl* const mRefs; weakref_impl* const mRefs; }; }; Loading Loading @@ -185,8 +195,9 @@ protected: private: private: friend class ReferenceMover; friend class ReferenceMover; inline static void moveReferences(void* d, void const* s, size_t n, inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } const ReferenceConverterBase& caster) { } inline static void renameRefId(T* ref, const void* old_id, const void* new_id) { } private: private: mutable volatile int32_t mCount; mutable volatile int32_t mCount; Loading Loading @@ -455,42 +466,48 @@ inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) // this class just serves as a namespace so TYPE::moveReferences can stay // this class just serves as a namespace so TYPE::moveReferences can stay // private. // private. class ReferenceMover { class ReferenceMover { // StrongReferenceCast and WeakReferenceCast do the impedance matching public: // between the generic (void*) implementation in Refbase and the strongly typed // it would be nice if we could make sure no extra code is generated // template specializations below. // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: // Using a sp<RefBase> override doesn't work; it's a bit like we wanted // a template<typename TYPE inherits RefBase> template... template <typename TYPE> template<typename TYPE> static inline struct StrongReferenceCast : public ReferenceConverterBase { void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); } virtual void* getReferenceBase(void const* p) const { sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p)); return static_cast<typename TYPE::basetype *>(sptr->get()); } }; template <typename TYPE> class Renamer : public ReferenceRenamer { struct WeakReferenceCast : public ReferenceConverterBase { sp<TYPE>* d; virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } sp<TYPE> const* s; virtual void* getReferenceBase(void const* p) const { virtual void operator()(size_t i) const { wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); // The id are known to be the sp<>'s this pointer return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); TYPE::renameRefId(d[i].get(), &s[i], &d[i]); } } public: Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { } }; }; public: template<typename TYPE> static inline void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { memmove(d, s, n*sizeof(sp<TYPE>)); memmove(d, s, n*sizeof(sp<TYPE>)); StrongReferenceCast<TYPE> caster; TYPE::renameRefs(n, Renamer(d, s)); TYPE::moveReferences(d, s, n, caster); } } template<typename TYPE> static inline template<typename TYPE> static inline void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { class Renamer : public ReferenceRenamer { wp<TYPE>* d; wp<TYPE> const* s; virtual void operator()(size_t i) const { // The id are known to be the wp<>'s this pointer TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); } public: Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { } }; memmove(d, s, n*sizeof(wp<TYPE>)); memmove(d, s, n*sizeof(wp<TYPE>)); WeakReferenceCast<TYPE> caster; TYPE::renameRefs(n, Renamer(d, s)); TYPE::moveReferences(d, s, n, caster); } } }; }; Loading
libs/utils/RefBase.cpp +15 −9 Original line number Original line Diff line number Diff line Loading @@ -631,21 +631,27 @@ void RefBase::onLastWeakRef(const void* /*id*/) // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- void RefBase::moveReferences(void* dst, void const* src, size_t n, void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { const ReferenceConverterBase& caster) { #if DEBUG_REFS #if DEBUG_REFS const size_t itemSize = caster.getReferenceTypeSize(); for (size_t i=0 ; i<n ; i++) { for (size_t i=0 ; i<n ; i++) { void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); renamer(i); void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize); RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d))); ref->mRefs->renameStrongRefId(s, d); ref->mRefs->renameWeakRefId(s, d); } } #endif #endif } } void RefBase::renameRefId(weakref_type* ref, const void* old_id, const void* new_id) { weakref_impl* const impl = static_cast<weakref_impl*>(ref); impl->renameStrongRefId(old_id, new_id); impl->renameWeakRefId(old_id, new_id); } void RefBase::renameRefId(RefBase* ref, const void* old_id, const void* new_id) { ref->mRefs->renameStrongRefId(old_id, new_id); ref->mRefs->renameWeakRefId(old_id, new_id); } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- TextOutput& printStrongPointer(TextOutput& to, const void* val) TextOutput& printStrongPointer(TextOutput& to, const void* val) Loading