Bug 386025 - Expose cycle-collection symbols, r=graydon

This commit is contained in:
benjamin@smedbergs.us 2007-08-06 07:34:02 -07:00
parent c7a065333e
commit 5fb457dd7e
16 changed files with 104 additions and 58 deletions

View File

@ -49,7 +49,7 @@ class nsNodeInfoManager;
class nsIVariant;
class nsIDOMUserDataHandler;
template<class E> class nsCOMArray;
struct nsCycleCollectionTraversalCallback;
class nsCycleCollectionTraversalCallback;
struct CharacterDataChangeInfo;
class nsNodeUtils

View File

@ -51,7 +51,7 @@
class nsIScriptContext;
struct JSRuntime;
class nsIJSRuntimeService;
struct nsCycleCollectionTraversalCallback;
class nsCycleCollectionTraversalCallback;
struct nsXBLTextWithLineNumber
{

View File

@ -150,7 +150,7 @@ interface nsIXPCSecurityManager;
interface nsIPrincipal;
%{C++
struct nsCycleCollectionTraversalCallback;
class nsCycleCollectionTraversalCallback;
%}
/***************************************************************************/

View File

@ -65,7 +65,6 @@ CPPSRCS = \
nsUUIDGenerator.cpp \
nsSystemInfo.cpp \
nsCycleCollector.cpp \
nsCycleCollectionParticipant.cpp \
$(NULL)
ifdef GC_LEAK_DETECTOR
@ -118,7 +117,6 @@ SDK_HEADERS = \
nsISupportsBase.h \
nscore.h \
nsCycleCollector.h \
nsCycleCollectionParticipant.h
XPIDLSRCS = \
nsIConsoleListener.idl \

View File

@ -1110,14 +1110,14 @@ public:
private:
// nsCycleCollectionTraversalCallback methods.
#ifdef DEBUG_CC
void DescribeNode(size_t refCount, size_t objSz, const char *objName);
NS_METHOD_(void) DescribeNode(nsrefcnt refCount, size_t objSz, const char *objName);
#else
void DescribeNode(size_t refCount);
NS_METHOD_(void) DescribeNode(nsrefcnt refCount);
#endif
void NoteXPCOMChild(nsISupports *child);
void NoteNativeChild(void *child,
nsCycleCollectionParticipant *participant);
void NoteScriptChild(PRUint32 langID, void *child);
NS_METHOD_(void) NoteXPCOMChild(nsISupports *child);
NS_METHOD_(void) NoteNativeChild(void *child,
nsCycleCollectionParticipant *participant);
NS_METHOD_(void) NoteScriptChild(PRUint32 langID, void *child);
};
GCGraphBuilder::GCGraphBuilder(GCGraph &aGraph,
@ -1182,9 +1182,9 @@ GCGraphBuilder::Traverse(PtrInfo* aPtrInfo)
void
#ifdef DEBUG_CC
GCGraphBuilder::DescribeNode(size_t refCount, size_t objSz, const char *objName)
GCGraphBuilder::DescribeNode(nsrefcnt refCount, size_t objSz, const char *objName)
#else
GCGraphBuilder::DescribeNode(size_t refCount)
GCGraphBuilder::DescribeNode(nsrefcnt refCount)
#endif
{
#ifdef DEBUG_CC
@ -1846,7 +1846,7 @@ public:
return mSuppressThisNode;
}
void DescribeNode(size_t refCount, size_t objSz, const char *objName)
void DescribeNode(nsrefcnt refCount, size_t objSz, const char *objName)
{
mSuppressThisNode = (PL_strstr(sSuppressionList, objName) != nsnull);
}
@ -2519,7 +2519,7 @@ nsCycleCollector_forgetRuntime(PRUint32 langID)
PRBool
nsCycleCollector_suspect(nsISupports *n)
NS_CycleCollectorSuspect(nsISupports *n)
{
if (sCollector)
return sCollector->Suspect(n);
@ -2539,7 +2539,7 @@ nsCycleCollector_suspectCurrent(nsISupports *n)
PRBool
nsCycleCollector_forget(nsISupports *n)
NS_CycleCollectorForget(nsISupports *n)
{
if (sCollector)
return sCollector->Forget(n);

View File

@ -51,9 +51,9 @@ struct nsCycleCollectionLanguageRuntime
virtual nsCycleCollectionParticipant *ToParticipant(void *p) = 0;
};
NS_COM PRBool nsCycleCollector_suspect(nsISupports *n);
// PRBool nsCycleCollector_suspect(nsISupports *n);
NS_COM void nsCycleCollector_suspectCurrent(nsISupports *n);
NS_COM PRBool nsCycleCollector_forget(nsISupports *n);
// NS_COM PRBool nsCycleCollector_forget(nsISupports *n);
nsresult nsCycleCollector_startup();
NS_COM void nsCycleCollector_collect();
void nsCycleCollector_shutdown();

View File

@ -64,6 +64,8 @@
# define NS_LogDtor NS_LogDtor_P
# define NS_LogCOMPtrAddRef NS_LogCOMPtrAddRef_P
# define NS_LogCOMPtrRelease NS_LogCOMPtrRelease_P
# define NS_CycleCollectorSuspect NS_CycleCollectorSuspect_P
# define NS_CycleCollectorForget NS_CycleCollectorForget_P
#endif
#include "nscore.h"
@ -453,6 +455,17 @@ NS_LogCOMPtrAddRef(void *aCOMPtr, nsISupports *aObject);
XPCOM_API(void)
NS_LogCOMPtrRelease(void *aCOMPtr, nsISupports *aObject);
/**
* The XPCOM cycle collector analyzes and breaks reference cycles between
* participating XPCOM objects. All objects in the cycle must implement
* nsCycleCollectionParticipant to break cycles correctly.
*/
XPCOM_API(PRBool)
NS_CycleCollectorSuspect(nsISupports *n);
XPCOM_API(PRBool)
NS_CycleCollectorForget(nsISupports *n);
/**
* Categories (in the category manager service) used by XPCOM:
*/

View File

@ -114,6 +114,7 @@ typedef void (* LogCOMPtrFunc)(void*, nsISupports*);
typedef nsresult (* GetXPTCallStubFunc)(REFNSIID, nsIXPTCProxy*, nsISomeInterface**);
typedef void (* DestroyXPTCallStubFunc)(nsISomeInterface*);
typedef nsresult (* InvokeByIndexFunc)(nsISupports*, PRUint32, PRUint32, nsXPTCVariant*);
typedef PRBool (* CycleCollectorFunc)(nsISupports*);
// PRIVATE AND DEPRECATED
typedef NS_CALLBACK(XPCOMExitRoutine)(void);
@ -182,6 +183,8 @@ typedef struct XPCOMFunctions{
GetXPTCallStubFunc getXPTCallStubFunc;
DestroyXPTCallStubFunc destroyXPTCallStubFunc;
InvokeByIndexFunc invokeByIndexFunc;
CycleCollectorFunc cycleSuspectFunc;
CycleCollectorFunc cycleForgetFunc;
} XPCOMFunctions;

View File

@ -43,7 +43,7 @@
#include "nsStringFwd.h"
#include "xpt_struct.h"
struct nsCycleCollectionTraversalCallback;
class nsCycleCollectionTraversalCallback;
/**
* Map the nsAUTF8String, nsUTF8String classes to the nsACString and

View File

@ -111,6 +111,7 @@ SDK_HEADERS = \
nsVersionComparator.h \
nsIClassInfoImpl.h \
nsTObserverArray.h \
nsCycleCollectionParticipant.h \
$(NULL)
EXPORTS = \

View File

@ -38,7 +38,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h"
NS_IMETHODIMP
nsresult
nsXPCOMCycleCollectionParticipant::Root(void *p)
{
nsISupports *s = static_cast<nsISupports*>(p);
@ -46,13 +46,13 @@ nsXPCOMCycleCollectionParticipant::Root(void *p)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsXPCOMCycleCollectionParticipant::Unlink(void *p)
{
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsXPCOMCycleCollectionParticipant::Unroot(void *p)
{
nsISupports *s = static_cast<nsISupports*>(p);
@ -60,19 +60,18 @@ nsXPCOMCycleCollectionParticipant::Unroot(void *p)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsXPCOMCycleCollectionParticipant::Traverse
(void *p, nsCycleCollectionTraversalCallback &cb)
{
return NS_OK;
}
NS_IMETHODIMP_(void)
void
nsXPCOMCycleCollectionParticipant::UnmarkPurple(nsISupports *n)
{
}
#ifdef DEBUG
PRBool
nsXPCOMCycleCollectionParticipant::CheckForRightISupports(nsISupports *s)
{
@ -81,4 +80,3 @@ nsXPCOMCycleCollectionParticipant::CheckForRightISupports(nsISupports *s)
getter_AddRefs(foo));
return s == foo;
}
#endif

View File

@ -42,10 +42,10 @@
#define NS_CYCLECOLLECTIONPARTICIPANT_IID \
{ \
0x8057ad9e, \
0x3ecc, \
0x4e89, \
{ 0x89, 0xac, 0x0a, 0x71, 0xf3, 0x8b, 0x14, 0xc2 } \
0x9674489b, \
0x1f6f, \
0x4550, \
{ 0xa7, 0x30, 0xcc, 0xae, 0xdd, 0x10, 0x4c, 0xf9 } \
}
/**
@ -66,7 +66,7 @@
/**
* Just holds the IID so NS_GET_IID works.
*/
class NS_COM nsCycleCollectionISupports
class nsCycleCollectionISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONISUPPORTS_IID)
@ -75,31 +75,31 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports,
NS_CYCLECOLLECTIONISUPPORTS_IID)
#undef IMETHOD_VISIBILITY
#define IMETHOD_VISIBILITY NS_VISIBILITY_DEFAULT
class nsCycleCollectionParticipant;
struct nsCycleCollectionTraversalCallback
class NS_NO_VTABLE nsCycleCollectionTraversalCallback
{
public:
// You must call DescribeNode() with an accurate refcount,
// otherwise cycle collection will fail, and probably crash.
#ifdef DEBUG_CC
virtual void DescribeNode(size_t refcount,
size_t objsz,
const char *objname) = 0;
NS_IMETHOD_(void) DescribeNode(nsrefcnt refcount,
size_t objsz,
const char *objname) = 0;
#else
virtual void DescribeNode(size_t refcount) = 0;
NS_IMETHOD_(void) DescribeNode(nsrefcnt refcount) = 0;
#endif
virtual void NoteScriptChild(PRUint32 langID, void *child) = 0;
virtual void NoteXPCOMChild(nsISupports *child) = 0;
virtual void NoteNativeChild(void *child,
nsCycleCollectionParticipant *helper) = 0;
NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void *child) = 0;
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child) = 0;
NS_IMETHOD_(void) NoteNativeChild(void *child,
nsCycleCollectionParticipant *helper) = 0;
};
class NS_NO_VTABLE nsCycleCollectionParticipant
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
NS_IMETHOD Root(void *p) = 0;
@ -107,12 +107,16 @@ public:
NS_IMETHOD Unroot(void *p) = 0;
};
class NS_COM nsXPCOMCycleCollectionParticipant
NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant,
NS_CYCLECOLLECTIONPARTICIPANT_IID)
#undef IMETHOD_VISIBILITY
#define IMETHOD_VISIBILITY NS_COM_GLUE
class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
: public nsCycleCollectionParticipant
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
NS_IMETHOD Root(void *p);
@ -121,18 +125,12 @@ public:
NS_IMETHOD_(void) UnmarkPurple(nsISupports *p);
#ifdef DEBUG
NS_EXTERNAL_VIS_(PRBool) CheckForRightISupports(nsISupports *s);
#endif
PRBool CheckForRightISupports(nsISupports *s);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCOMCycleCollectionParticipant,
NS_CYCLECOLLECTIONPARTICIPANT_IID)
#undef IMETHOD_VISIBILITY
#undef IMETHOD_VISIBILITY
#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
///////////////////////////////////////////////////////////////////////////////
// Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant
///////////////////////////////////////////////////////////////////////////////

View File

@ -134,7 +134,7 @@ public:
if (NS_UNLIKELY(purple)) {
NS_ASSERTION(tmp != 0, "purple ISupports pointer with zero refcnt");
if (!nsCycleCollector_forget(owner))
if (!NS_CycleCollectorForget(owner))
tmp |= NS_PURPLE_BIT;
}
@ -159,10 +159,10 @@ public:
PRBool shouldBePurple = tmp > 1;
if (NS_UNLIKELY(shouldBePurple && !purple)) {
if (!nsCycleCollector_suspect(owner))
if (!NS_CycleCollectorSuspect(owner))
shouldBePurple = PR_FALSE;
} else if (NS_UNLIKELY(tmp == 1 && purple)) {
if (!nsCycleCollector_forget(owner)) {
if (!NS_CycleCollectorForget(owner)) {
NS_NOTREACHED("forget should not fail when reference count hits 0");
}
}

View File

@ -63,6 +63,7 @@ XPCOM_GLUE_SRC_LCPPSRCS = \
nsTArray.cpp \
nsThreadUtils.cpp \
nsTObserverArray.cpp \
nsCycleCollectionParticipant.cpp \
$(NULL)
XPCOM_GLUE_SRC_CPPSRCS = $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCPPSRCS))

View File

@ -517,3 +517,21 @@ NS_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
return xpcomFunctions.invokeByIndexFunc(that, methodIndex,
paramCount, params);
}
XPCOM_API(PRBool)
NS_CycleCollectorSuspect(nsISupports* obj)
{
if (!xpcomFunctions.cycleSuspectFunc)
return PR_FALSE;
return xpcomFunctions.cycleSuspectFunc(obj);
}
XPCOM_API(PRBool)
NS_CycleCollectorForget(nsISupports* obj)
{
if (!xpcomFunctions.cycleForgetFunc)
return PR_FALSE;
return xpcomFunctions.cycleForgetFunc(obj);
}

View File

@ -114,7 +114,9 @@ static const XPCOMFunctions kFrozenFunctions = {
&NS_LogCOMPtrRelease_P,
&NS_GetXPTCallStub_P,
&NS_DestroyXPTCallStub_P,
&NS_InvokeByIndex_P
&NS_InvokeByIndex_P,
&NS_CycleCollectorSuspect_P,
&NS_CycleCollectorForget_P
};
EXPORT_XPCOM_API(nsresult)
@ -505,3 +507,17 @@ NS_UTF16ToCString(const nsAString &aSrc, nsCStringEncoding aDestEncoding, nsACSt
{
return NS_UTF16ToCString_P(aSrc, aDestEncoding, aDest);
}
#undef NS_CycleCollectorSuspect
EXPORT_XPCOM_API(PRBool)
NS_CycleCollectorSuspect(nsISupports* obj)
{
return NS_CycleCollectorSuspect_P(obj);
}
#undef NS_CycleCollectorForget
EXPORT_XPCOM_API(PRBool)
NS_CycleCollectorForget(nsISupports* obj)
{
return NS_CycleCollectorForget_P(obj);
}