Loading include/utils/RefBase.h +56 −39 Original line number 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: virtual size_t getReferenceTypeSize() const = 0; virtual void* getReferenceBase(void const*) const = 0; inline virtual ~ReferenceConverterBase() { } virtual void operator()(size_t i) const = 0; }; // --------------------------------------------------------------------------- Loading Loading @@ -143,11 +147,6 @@ protected: virtual bool onIncStrongAttempted(uint32_t flags, 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: friend class weakref_type; class weakref_impl; Loading @@ -155,6 +154,17 @@ private: RefBase(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; }; Loading Loading @@ -185,8 +195,9 @@ protected: private: friend class ReferenceMover; inline static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster) { } inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } inline static void renameRefId(T* ref, const void* old_id, const void* new_id) { } private: 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 // private. class ReferenceMover { // StrongReferenceCast and WeakReferenceCast do the impedance matching // between the generic (void*) implementation in Refbase and the strongly typed // template specializations below. public: // it would be nice if we could make sure no extra code is generated // 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> struct StrongReferenceCast : public ReferenceConverterBase { 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> static inline void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { template <typename TYPE> struct WeakReferenceCast : public ReferenceConverterBase { virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } virtual void* getReferenceBase(void const* p) const { wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); class Renamer : public ReferenceRenamer { sp<TYPE>* d; sp<TYPE> const* s; virtual void operator()(size_t i) const { // The id are known to be the sp<>'s this pointer 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>)); StrongReferenceCast<TYPE> caster; TYPE::moveReferences(d, s, n, caster); TYPE::renameRefs(n, Renamer(d, s)); } template<typename TYPE> static inline 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>)); WeakReferenceCast<TYPE> caster; TYPE::moveReferences(d, s, n, caster); TYPE::renameRefs(n, Renamer(d, s)); } }; Loading libs/utils/RefBase.cpp +15 −9 Original line number 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, const ReferenceConverterBase& caster) { void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { #if DEBUG_REFS const size_t itemSize = caster.getReferenceTypeSize(); for (size_t i=0 ; i<n ; i++) { void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); 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); renamer(i); } #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) Loading Loading
include/utils/RefBase.h +56 −39 Original line number 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: virtual size_t getReferenceTypeSize() const = 0; virtual void* getReferenceBase(void const*) const = 0; inline virtual ~ReferenceConverterBase() { } virtual void operator()(size_t i) const = 0; }; // --------------------------------------------------------------------------- Loading Loading @@ -143,11 +147,6 @@ protected: virtual bool onIncStrongAttempted(uint32_t flags, 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: friend class weakref_type; class weakref_impl; Loading @@ -155,6 +154,17 @@ private: RefBase(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; }; Loading Loading @@ -185,8 +195,9 @@ protected: private: friend class ReferenceMover; inline static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster) { } inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } inline static void renameRefId(T* ref, const void* old_id, const void* new_id) { } private: 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 // private. class ReferenceMover { // StrongReferenceCast and WeakReferenceCast do the impedance matching // between the generic (void*) implementation in Refbase and the strongly typed // template specializations below. public: // it would be nice if we could make sure no extra code is generated // 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> struct StrongReferenceCast : public ReferenceConverterBase { 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> static inline void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { template <typename TYPE> struct WeakReferenceCast : public ReferenceConverterBase { virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } virtual void* getReferenceBase(void const* p) const { wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); class Renamer : public ReferenceRenamer { sp<TYPE>* d; sp<TYPE> const* s; virtual void operator()(size_t i) const { // The id are known to be the sp<>'s this pointer 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>)); StrongReferenceCast<TYPE> caster; TYPE::moveReferences(d, s, n, caster); TYPE::renameRefs(n, Renamer(d, s)); } template<typename TYPE> static inline 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>)); WeakReferenceCast<TYPE> caster; TYPE::moveReferences(d, s, n, caster); TYPE::renameRefs(n, Renamer(d, s)); } }; Loading
libs/utils/RefBase.cpp +15 −9 Original line number 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, const ReferenceConverterBase& caster) { void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { #if DEBUG_REFS const size_t itemSize = caster.getReferenceTypeSize(); for (size_t i=0 ; i<n ; i++) { void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); 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); renamer(i); } #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) Loading