Bug 750570, part 4 - Switch most native CC classes to use the purple buffer. r=smaug

This patch actually converts over most of the existing native CC classes
to use the participant. This is done by converting them to use
the newly generalized nsCycleCollectingAutoRefCnt instead of their usual
ref count.

This is mostly a matter of defining new macros defining AddRef() and Release()
for native CC classes with the CC ref count.

nsTimeout is left as a legacy native CC class because it is a weird class,
but hopefully eventually it too can be converted over.  See bug 774874.
This commit is contained in:
Andrew McCreight 2012-08-24 09:50:06 -07:00
Родитель d0e1cf9ab3
Коммит c063a3e54c
15 изменённых файлов: 110 добавлений и 40 удалений

Просмотреть файл

@ -107,7 +107,7 @@ public:
/**
* Reference counting and cycle collection.
*/
NS_INLINE_DECL_REFCOUNTING(AccEvent)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
protected:

Просмотреть файл

@ -55,8 +55,8 @@ NotificationController::~NotificationController()
////////////////////////////////////////////////////////////////////////////////
// NotificationCollector: AddRef/Release and cycle collection
NS_IMPL_ADDREF(NotificationController)
NS_IMPL_RELEASE(NotificationController)
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(NotificationController)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(NotificationController)
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)

Просмотреть файл

@ -173,7 +173,7 @@ public:
#endif
protected:
nsAutoRefCnt mRefCnt;
nsCycleCollectingAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
/**
@ -272,7 +272,7 @@ private:
ContentInsertion(DocAccessible* aDocument, Accessible* aContainer);
virtual ~ContentInsertion() { mDocument = nullptr; }
NS_INLINE_DECL_REFCOUNTING(ContentInsertion)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ContentInsertion)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentInsertion)
bool InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode);

Просмотреть файл

@ -70,7 +70,7 @@ public:
nsEventListenerManager(nsISupports* aTarget);
virtual ~nsEventListenerManager();
NS_INLINE_DECL_REFCOUNTING(nsEventListenerManager)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsEventListenerManager)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsEventListenerManager)

Просмотреть файл

@ -45,7 +45,7 @@ public:
* which are queued to fire their constructors.
*/
NS_INLINE_DECL_REFCOUNTING(nsXBLBinding)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsXBLBinding)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding)

Просмотреть файл

@ -17,7 +17,7 @@ public:
nsXBLInsertionPoint(nsIContent* aParentElement, uint32_t aIndex, nsIContent* aDefContent);
~nsXBLInsertionPoint();
NS_INLINE_DECL_REFCOUNTING(nsXBLInsertionPoint)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsXBLInsertionPoint)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPoint)

Просмотреть файл

@ -204,7 +204,7 @@ public:
nsXBLInsertionPointEntry::ReleasePool();
}
NS_INLINE_DECL_REFCOUNTING(nsXBLInsertionPointEntry)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsXBLInsertionPointEntry)
protected:
nsCOMPtr<nsIContent> mInsertionParent;

Просмотреть файл

@ -7,8 +7,8 @@
#include "nsXULTemplateResultXML.h"
#include "nsXMLBinding.h"
NS_IMPL_ADDREF(nsXMLBindingSet)
NS_IMPL_RELEASE(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXMLBindingSet)

Просмотреть файл

@ -49,15 +49,15 @@ public:
// results hold a reference to a binding set in their
// nsXMLBindingValues fields
nsAutoRefCnt mRefCnt;
nsCycleCollectingAutoRefCnt mRefCnt;
// pointer to the first binding in a linked list
nsAutoPtr<nsXMLBinding> mFirst;
public:
NS_IMETHOD_(nsrefcnt) AddRef();
NS_IMETHOD_(nsrefcnt) Release();
NS_METHOD_(nsrefcnt) AddRef();
NS_METHOD_(nsrefcnt) Release();
NS_DECL_OWNINGTHREAD
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXMLBindingSet)

Просмотреть файл

@ -554,7 +554,7 @@ nsTimeout::~nsTimeout()
MOZ_COUNT_DTOR(nsTimeout);
}
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow,

Просмотреть файл

@ -138,7 +138,7 @@ struct nsTimeout : PRCList
nsTimeout();
~nsTimeout();
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout)
NS_DECL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(nsTimeout)
nsrefcnt Release();
nsrefcnt AddRef();

Просмотреть файл

@ -26,26 +26,8 @@ nsTransactionItem::~nsTransactionItem()
delete mUndoStack;
}
nsrefcnt
nsTransactionItem::AddRef()
{
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsTransactionItem",
sizeof(nsTransactionItem));
return mRefCnt;
}
nsrefcnt
nsTransactionItem::Release() {
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsTransactionItem");
if (mRefCnt == 0) {
mRefCnt = 1;
delete this;
return 0;
}
return mRefCnt;
}
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsTransactionItem)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsTransactionItem)
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsTransactionItem)

Просмотреть файл

@ -21,14 +21,13 @@ class nsTransactionItem
nsCOMPtr<nsITransaction> mTransaction;
nsTransactionStack *mUndoStack;
nsTransactionStack *mRedoStack;
nsAutoRefCnt mRefCnt;
public:
nsTransactionItem(nsITransaction *aTransaction);
virtual ~nsTransactionItem();
nsrefcnt AddRef();
nsrefcnt Release();
NS_METHOD_(nsrefcnt) AddRef();
NS_METHOD_(nsrefcnt) Release();
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTransactionItem)
@ -52,6 +51,10 @@ private:
virtual nsresult GetNumberOfUndoItems(int32_t *aNumItems);
virtual nsresult GetNumberOfRedoItems(int32_t *aNumItems);
protected:
nsCycleCollectingAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
#endif // nsTransactionItem_h__

Просмотреть файл

@ -852,16 +852,25 @@ struct Skippable
// Cycle collector participant implementations.
// A native class is non-nsISupports and uses nsCycleCollectingAutoRefCnt.
#define NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
::Type _class::NS_CYCLE_COLLECTION_INNERNAME = \
{ NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
// For native classes containing JS pointers.
#define NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class) \
const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
::Type _class::NS_CYCLE_COLLECTION_INNERNAME = \
{ NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
// A legacy native class is non-nsISupports, but does not use
// nsCycleCollectingAutoRefCnt. This should be avoided because it can
// cause leaks.
#define NS_IMPL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(_class) \
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(_class)
// For nsISupports classes.
#define NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
const CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
::Type _class::NS_CYCLE_COLLECTION_INNERNAME = \
@ -875,15 +884,26 @@ struct Skippable
static NS_METHOD RootImpl(void *n); \
static NS_METHOD UnlinkImpl(void *n); \
static NS_METHOD UnrootImpl(void *n); \
static NS_METHOD_(void) UnmarkIfPurpleImpl(void *n) {}; \
static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, \
void *n, nsCycleCollectionTraversalCallback &cb);
#define NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class) \
static NS_METHOD_(void) UnmarkIfPurpleImpl(void *p) \
{ \
_class *tmp = static_cast<_class *>(p); \
if (NS_LIKELY(tmp->mRefCnt.IsPurple())) \
tmp->mRefCnt.unmarkPurple(); \
}
#define NS_DECL_CYCLE_COLLECTION_STUB_UNMARK_IF_PURPLE(_class) \
static NS_METHOD_(void) UnmarkIfPurpleImpl(void *p) {}
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsCycleCollectionParticipant \
{ \
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class) \
}; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -892,11 +912,21 @@ struct Skippable
: public nsScriptObjectTracer \
{ \
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
NS_DECL_CYCLE_COLLECTION_NATIVE_UNMARK_IF_PURPLE(_class) \
static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, \
void *closure); \
}; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
#define NS_DECL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(_class) \
class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsCycleCollectionParticipant \
{ \
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
NS_DECL_CYCLE_COLLECTION_STUB_UNMARK_IF_PURPLE(_class) \
}; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
#define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \
NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootImpl(void *p) \

Просмотреть файл

@ -288,6 +288,61 @@ protected: \
public:
///////////////////////////////////////////////////////////////////////////////
/*
* Implementation of AddRef and Release for non-nsISupports (ie "native")
* cycle-collected classes that use the purple buffer to avoid leaks.
*/
#define NS_IMPL_CC_NATIVE_ADDREF_BODY(_class) \
NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
NS_ASSERT_OWNINGTHREAD_AND_NOT_CCTHREAD(_class); \
nsrefcnt count = mRefCnt.incr(this); \
NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \
return count;
#define NS_IMPL_CC_NATIVE_RELEASE_BODY(_class) \
NS_PRECONDITION(0 != mRefCnt, "dup release"); \
NS_ASSERT_OWNINGTHREAD_AND_NOT_CCTHREAD(_class); \
nsrefcnt count = \
mRefCnt.decr(static_cast<void*>(this), \
_class::NS_CYCLE_COLLECTION_INNERNAME.GetParticipant()); \
NS_LOG_RELEASE(this, count, #_class); \
if (count == 0) { \
NS_ASSERT_OWNINGTHREAD(_class); \
mRefCnt.stabilizeForDeletion(); \
delete this; \
return 0; \
} \
return count;
#define NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(_class) \
NS_METHOD_(nsrefcnt) _class::AddRef(void) \
{ \
NS_IMPL_CC_NATIVE_ADDREF_BODY(_class) \
}
#define NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(_class) \
NS_METHOD_(nsrefcnt) _class::Release(void) \
{ \
NS_IMPL_CC_NATIVE_RELEASE_BODY(_class) \
}
#define NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(_class) \
public: \
NS_METHOD_(nsrefcnt) AddRef(void) { \
NS_IMPL_CC_NATIVE_ADDREF_BODY(_class) \
} \
NS_METHOD_(nsrefcnt) Release(void) { \
NS_IMPL_CC_NATIVE_RELEASE_BODY(_class) \
} \
protected: \
nsCycleCollectingAutoRefCnt mRefCnt; \
NS_DECL_OWNINGTHREAD \
public:
///////////////////////////////////////////////////////////////////////////////
/**