зеркало из https://github.com/mozilla/pjs.git
Bug 497808. Enable dumping of cycle-collector graphs in any debug build. r=peterv,a=blocking
This commit is contained in:
Родитель
24dd7c5e33
Коммит
e7bf0a8c07
|
@ -521,7 +521,7 @@ nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GarbageCollect()
|
||||
nsDOMWindowUtils::GarbageCollect(PRBool aDrawGraphs)
|
||||
{
|
||||
// Always permit this in debug builds.
|
||||
#ifndef DEBUG
|
||||
|
@ -530,7 +530,7 @@ nsDOMWindowUtils::GarbageCollect()
|
|||
}
|
||||
#endif
|
||||
|
||||
nsJSContext::CC();
|
||||
nsJSContext::CC(aDrawGraphs);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -307,7 +307,7 @@ NS_IMETHODIMP
|
|||
nsCCMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
nsJSContext::CC();
|
||||
nsJSContext::CC(PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -973,7 +973,7 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
|
|||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory) {
|
||||
// try to clean up:
|
||||
nsJSContext::CC();
|
||||
nsJSContext::CC(PR_FALSE);
|
||||
|
||||
// never prevent system scripts from running
|
||||
if (!::JS_IsSystemObject(cx, ::JS_GetGlobalObject(cx))) {
|
||||
|
@ -3616,7 +3616,7 @@ nsJSContext::ScriptExecuted()
|
|||
|
||||
//static
|
||||
void
|
||||
nsJSContext::CC()
|
||||
nsJSContext::CC(PRBool aDrawGraph)
|
||||
{
|
||||
NS_TIME_FUNCTION_MIN(1.0);
|
||||
|
||||
|
@ -3631,7 +3631,7 @@ nsJSContext::CC()
|
|||
// nsCycleCollector_collect() no longer forces a JS garbage collection,
|
||||
// so we have to do it ourselves here.
|
||||
nsContentUtils::XPConnect()->GarbageCollect();
|
||||
sCollectedObjectsCounts = nsCycleCollector_collect();
|
||||
sCollectedObjectsCounts = nsCycleCollector_collect(aDrawGraph);
|
||||
sCCSuspectedCount = nsCycleCollector_suspectedCount();
|
||||
sSavedGCCount = JS_GetGCParameter(nsJSRuntime::sRuntime, JSGC_NUMBER);
|
||||
#ifdef DEBUG_smaug
|
||||
|
@ -3719,7 +3719,7 @@ nsJSContext::IntervalCC()
|
|||
{
|
||||
if ((PR_Now() - sPreviousCCTime) >=
|
||||
PRTime(NS_MIN_CC_INTERVAL * PR_USEC_PER_MSEC)) {
|
||||
nsJSContext::CC();
|
||||
nsJSContext::CC(PR_FALSE);
|
||||
return PR_TRUE;
|
||||
}
|
||||
#ifdef DEBUG_smaug
|
||||
|
|
|
@ -188,7 +188,7 @@ public:
|
|||
|
||||
// CC does always call cycle collector and it also updates the counters
|
||||
// that MaybeCC uses.
|
||||
static void CC();
|
||||
static void CC(PRBool aDrawGraph);
|
||||
|
||||
// MaybeCC calls cycle collector if certain conditions are fulfilled.
|
||||
// The conditions are:
|
||||
|
|
|
@ -53,7 +53,7 @@ interface nsIDOMEvent;
|
|||
interface nsITransferable;
|
||||
interface nsIQueryContentEventResult;
|
||||
|
||||
[scriptable, uuid(1e042706-0343-4cba-a549-6a83eefb1835)]
|
||||
[scriptable, uuid(bf4df3a0-4567-47ec-be6d-9ec60eaed63c)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -258,8 +258,12 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
*
|
||||
* Will throw a DOM security error if called without UniversalXPConnect
|
||||
* privileges in non-debug builds. Available to all callers in debug builds.
|
||||
*
|
||||
* @param aDrawGraph when true, a cycle collection graph will be
|
||||
* dumped to a file named cycle-graph-*.dot in the current working
|
||||
* directory
|
||||
*/
|
||||
void garbageCollect();
|
||||
void garbageCollect([optional] in boolean aDrawGraph);
|
||||
|
||||
/**
|
||||
* Force processing of any queued paints
|
||||
|
|
|
@ -177,10 +177,10 @@
|
|||
struct nsCycleCollectorParams
|
||||
{
|
||||
PRBool mDoNothing;
|
||||
PRBool mDrawGraphs;
|
||||
#ifdef DEBUG_CC
|
||||
PRBool mReportStats;
|
||||
PRBool mHookMalloc;
|
||||
PRBool mDrawGraphs;
|
||||
PRBool mFaultIsFatal;
|
||||
PRBool mLogPointers;
|
||||
|
||||
|
@ -198,7 +198,8 @@ struct nsCycleCollectorParams
|
|||
|
||||
mShutdownCollections(DEFAULT_SHUTDOWN_COLLECTIONS)
|
||||
#else
|
||||
mDoNothing (PR_FALSE)
|
||||
mDoNothing (PR_FALSE),
|
||||
mDrawGraphs (PR_FALSE)
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
|
@ -445,10 +446,11 @@ struct PtrInfo
|
|||
PRUint32 mRefCount;
|
||||
EdgePool::Iterator mFirstChild; // first
|
||||
EdgePool::Iterator mLastChild; // one after last
|
||||
char *mName;
|
||||
nsTArray<nsCString> mEdgeNames;
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
size_t mBytes;
|
||||
char *mName;
|
||||
PRUint32 mLangID;
|
||||
|
||||
// For finding roots in ExplainLiveExpectedGarbage (when there are
|
||||
|
@ -460,8 +462,6 @@ struct PtrInfo
|
|||
ReversedEdge* mReversedEdges; // linked list
|
||||
PtrInfo* mShortestPathToExpectedGarbage;
|
||||
nsCString* mShortestPathToExpectedGarbageEdgeName;
|
||||
|
||||
nsTArray<nsCString> mEdgeNames;
|
||||
#endif
|
||||
|
||||
PtrInfo(void *aPointer, nsCycleCollectionParticipant *aParticipant
|
||||
|
@ -473,10 +473,10 @@ struct PtrInfo
|
|||
mInternalRefs(0),
|
||||
mRefCount(0),
|
||||
mFirstChild(),
|
||||
mLastChild()
|
||||
mLastChild(),
|
||||
mName(nsnull)
|
||||
#ifdef DEBUG_CC
|
||||
, mBytes(0),
|
||||
mName(nsnull),
|
||||
mLangID(aLangID),
|
||||
mSCCIndex(0),
|
||||
mReversedEdges(nsnull),
|
||||
|
@ -486,12 +486,10 @@ struct PtrInfo
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
void Destroy() {
|
||||
PL_strfree(mName);
|
||||
mEdgeNames.~nsTArray<nsCString>();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allow NodePool::Block's constructor to compile.
|
||||
PtrInfo() {
|
||||
|
@ -531,16 +529,15 @@ public:
|
|||
NS_ASSERTION(!mBlocks, "Didn't call Clear()?");
|
||||
}
|
||||
|
||||
void Clear()
|
||||
void Clear(PRBool aClearNames)
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
{
|
||||
if (aClearNames) {
|
||||
Enumerator queue(*this);
|
||||
while (!queue.IsDone()) {
|
||||
queue.GetNext()->Destroy();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Block *b = mBlocks;
|
||||
while (b) {
|
||||
Block *n = b->mNext;
|
||||
|
@ -651,10 +648,8 @@ struct GCGraph
|
|||
// Add/Remove/Has rather than PutEntry/RemoveEntry/GetEntry.
|
||||
typedef nsTHashtable<nsVoidPtrHashKey> PointerSet;
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
static void
|
||||
WriteGraph(FILE *stream, GCGraph &graph, const void *redPtr);
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
ToParticipant(nsISupports *s, nsXPCOMCycleCollectionParticipant **cp);
|
||||
|
@ -995,7 +990,7 @@ struct nsCycleCollector
|
|||
nsPurpleBufferEntry* Suspect2(nsISupports *n);
|
||||
PRBool Forget2(nsPurpleBufferEntry *e);
|
||||
|
||||
PRUint32 Collect(PRUint32 aTryCollections = 1);
|
||||
PRUint32 Collect(PRUint32 aTryCollections, PRBool aDrawGraph);
|
||||
PRBool BeginCollection();
|
||||
PRBool FinishCollection();
|
||||
PRUint32 SuspectedCount();
|
||||
|
@ -1003,17 +998,18 @@ struct nsCycleCollector
|
|||
|
||||
void ClearGraph()
|
||||
{
|
||||
mGraph.mNodes.Clear();
|
||||
mGraph.mNodes.Clear(mParams.mDrawGraphs);
|
||||
mGraph.mEdges.Clear();
|
||||
mGraph.mRootCount = 0;
|
||||
}
|
||||
|
||||
void MaybeDrawGraphs();
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
nsCycleCollectorStats mStats;
|
||||
|
||||
FILE *mPtrLog;
|
||||
|
||||
void MaybeDrawGraphs();
|
||||
void Allocated(void *n, size_t sz);
|
||||
void Freed(void *n);
|
||||
|
||||
|
@ -1301,13 +1297,12 @@ private:
|
|||
PLDHashTable mPtrToNodeMap;
|
||||
PtrInfo *mCurrPi;
|
||||
nsCycleCollectionLanguageRuntime **mRuntimes; // weak, from nsCycleCollector
|
||||
#ifdef DEBUG_CC
|
||||
nsCString mNextEdgeName;
|
||||
#endif
|
||||
|
||||
public:
|
||||
GCGraphBuilder(GCGraph &aGraph,
|
||||
nsCycleCollectionLanguageRuntime **aRuntimes);
|
||||
nsCycleCollectionLanguageRuntime **aRuntimes,
|
||||
PRBool aDrawGraph);
|
||||
~GCGraphBuilder();
|
||||
bool Initialized();
|
||||
|
||||
|
@ -1342,7 +1337,8 @@ private:
|
|||
};
|
||||
|
||||
GCGraphBuilder::GCGraphBuilder(GCGraph &aGraph,
|
||||
nsCycleCollectionLanguageRuntime **aRuntimes)
|
||||
nsCycleCollectionLanguageRuntime **aRuntimes,
|
||||
PRBool aDrawGraph)
|
||||
: mNodeBuilder(aGraph.mNodes),
|
||||
mEdgeBuilder(aGraph.mEdges),
|
||||
mRuntimes(aRuntimes)
|
||||
|
@ -1350,11 +1346,13 @@ GCGraphBuilder::GCGraphBuilder(GCGraph &aGraph,
|
|||
if (!PL_DHashTableInit(&mPtrToNodeMap, &PtrNodeOps, nsnull,
|
||||
sizeof(PtrToNodeEntry), 32768))
|
||||
mPtrToNodeMap.ops = nsnull;
|
||||
#ifdef DEBUG_CC
|
||||
// Do we need to set these all the time?
|
||||
mFlags |= nsCycleCollectionTraversalCallback::WANT_DEBUG_INFO |
|
||||
nsCycleCollectionTraversalCallback::WANT_ALL_TRACES;
|
||||
#ifndef DEBUG_CC
|
||||
if (aDrawGraph)
|
||||
#endif
|
||||
{
|
||||
mFlags |= nsCycleCollectionTraversalCallback::WANT_DEBUG_INFO |
|
||||
nsCycleCollectionTraversalCallback::WANT_ALL_TRACES;
|
||||
}
|
||||
}
|
||||
|
||||
GCGraphBuilder::~GCGraphBuilder()
|
||||
|
@ -1458,8 +1456,10 @@ GCGraphBuilder::DescribeNode(CCNodeType type, nsrefcnt refCount,
|
|||
{
|
||||
#ifdef DEBUG_CC
|
||||
mCurrPi->mBytes = objSz;
|
||||
mCurrPi->mName = PL_strdup(objName);
|
||||
#endif
|
||||
if (WantDebugInfo()) {
|
||||
mCurrPi->mName = PL_strdup(objName);
|
||||
}
|
||||
|
||||
if (type == RefCounted) {
|
||||
if (refCount == 0 || refCount == PR_UINT32_MAX)
|
||||
|
@ -1478,10 +1478,11 @@ GCGraphBuilder::DescribeNode(CCNodeType type, nsrefcnt refCount,
|
|||
NS_IMETHODIMP_(void)
|
||||
GCGraphBuilder::NoteXPCOMChild(nsISupports *child)
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
nsCString edgeName(mNextEdgeName);
|
||||
mNextEdgeName.Truncate();
|
||||
#endif
|
||||
nsCString edgeName;
|
||||
if (WantDebugInfo()) {
|
||||
edgeName.Assign(mNextEdgeName);
|
||||
mNextEdgeName.Truncate();
|
||||
}
|
||||
if (!child || !(child = canonicalize(child)))
|
||||
return;
|
||||
|
||||
|
@ -1497,9 +1498,9 @@ GCGraphBuilder::NoteXPCOMChild(nsISupports *child)
|
|||
if (!childPi)
|
||||
return;
|
||||
mEdgeBuilder.Add(childPi);
|
||||
#ifdef DEBUG_CC
|
||||
mCurrPi->mEdgeNames.AppendElement(edgeName);
|
||||
#endif
|
||||
if (WantDebugInfo()) {
|
||||
mCurrPi->mEdgeNames.AppendElement(edgeName);
|
||||
}
|
||||
++childPi->mInternalRefs;
|
||||
}
|
||||
}
|
||||
|
@ -1508,10 +1509,11 @@ NS_IMETHODIMP_(void)
|
|||
GCGraphBuilder::NoteNativeChild(void *child,
|
||||
nsCycleCollectionParticipant *participant)
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
nsCString edgeName(mNextEdgeName);
|
||||
mNextEdgeName.Truncate();
|
||||
#endif
|
||||
nsCString edgeName;
|
||||
if (WantDebugInfo()) {
|
||||
edgeName.Assign(mNextEdgeName);
|
||||
mNextEdgeName.Truncate();
|
||||
}
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
|
@ -1521,19 +1523,17 @@ GCGraphBuilder::NoteNativeChild(void *child,
|
|||
if (!childPi)
|
||||
return;
|
||||
mEdgeBuilder.Add(childPi);
|
||||
#ifdef DEBUG_CC
|
||||
mCurrPi->mEdgeNames.AppendElement(edgeName);
|
||||
#endif
|
||||
if (WantDebugInfo()) {
|
||||
mCurrPi->mEdgeNames.AppendElement(edgeName);
|
||||
}
|
||||
++childPi->mInternalRefs;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
GCGraphBuilder::NoteScriptChild(PRUint32 langID, void *child)
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
nsCString edgeName(mNextEdgeName);
|
||||
mNextEdgeName.Truncate();
|
||||
#endif
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
|
@ -1556,18 +1556,18 @@ GCGraphBuilder::NoteScriptChild(PRUint32 langID, void *child)
|
|||
if (!childPi)
|
||||
return;
|
||||
mEdgeBuilder.Add(childPi);
|
||||
#ifdef DEBUG_CC
|
||||
mCurrPi->mEdgeNames.AppendElement(edgeName);
|
||||
#endif
|
||||
if (WantDebugInfo()) {
|
||||
mCurrPi->mEdgeNames.AppendElement(edgeName);
|
||||
}
|
||||
++childPi->mInternalRefs;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
GCGraphBuilder::NoteNextEdgeName(const char* name)
|
||||
{
|
||||
#ifdef DEBUG_CC
|
||||
mNextEdgeName = name;
|
||||
#endif
|
||||
if (WantDebugInfo()) {
|
||||
mNextEdgeName = name;
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool
|
||||
|
@ -2079,8 +2079,6 @@ nsCycleCollector::ForgetRuntime(PRUint32 langID)
|
|||
mRuntimes[langID] = nsnull;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
static void
|
||||
WriteGraph(FILE *stream, GCGraph &graph, const void *redPtr)
|
||||
{
|
||||
|
@ -2108,63 +2106,36 @@ WriteGraph(FILE *stream, GCGraph &graph, const void *redPtr)
|
|||
"\", fillcolor=%s, fontcolor=%s]\n",
|
||||
(redPtr && redPtr == p ? "red" : (pi->mColor == black ? "black" : "white")),
|
||||
(pi->mColor == black ? "white" : "black"));
|
||||
PRInt32 i = 0;
|
||||
for (EdgePool::Iterator child = pi->mFirstChild,
|
||||
child_end = pi->mLastChild;
|
||||
child != child_end; ++child) {
|
||||
fprintf(stream, "n%p -> n%p\n", p, (*child)->mPointer);
|
||||
fprintf(stream, "n%p -> n%p [label=\"%s\"]\n", p,
|
||||
(*child)->mPointer, pi->mEdgeNames[i].get());
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stream, "\n}\n");
|
||||
}
|
||||
|
||||
static PRUint32 gCounter;
|
||||
|
||||
void
|
||||
nsCycleCollector::MaybeDrawGraphs()
|
||||
{
|
||||
if (mParams.mDrawGraphs) {
|
||||
// We draw graphs only if there were any white nodes.
|
||||
PRBool anyWhites = PR_FALSE;
|
||||
NodePool::Enumerator fwetor(mGraph.mNodes);
|
||||
while (!fwetor.IsDone())
|
||||
{
|
||||
PtrInfo *pinfo = fwetor.GetNext();
|
||||
if (pinfo->mColor == white) {
|
||||
anyWhites = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyWhites) {
|
||||
// We can't just use _popen here because graphviz-for-windows
|
||||
// doesn't set up its stdin stream properly, sigh.
|
||||
FILE *stream;
|
||||
#ifdef WIN32
|
||||
stream = fopen("c:\\cycle-graph.dot", "w+");
|
||||
#else
|
||||
stream = popen("dotty -", "w");
|
||||
#endif
|
||||
WriteGraph(stream, mGraph, nsnull);
|
||||
#ifdef WIN32
|
||||
fclose(stream);
|
||||
// Even dotty doesn't work terribly well on windows, since
|
||||
// they execute lefty asynchronously. So we'll just run
|
||||
// lefty ourselves.
|
||||
_spawnlp(_P_WAIT,
|
||||
"lefty",
|
||||
"lefty",
|
||||
"-e",
|
||||
"\"load('dotty.lefty');"
|
||||
"dotty.simple('c:\\cycle-graph.dot');\"",
|
||||
NULL);
|
||||
unlink("c:\\cycle-graph.dot");
|
||||
#else
|
||||
pclose(stream);
|
||||
#endif
|
||||
}
|
||||
FILE *stream;
|
||||
char name[255];
|
||||
sprintf(name, "cycle-graph-%d.dot", ++gCounter);
|
||||
stream = fopen(name, "w");
|
||||
WriteGraph(stream, mGraph, nsnull);
|
||||
fclose(stream);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
|
||||
class Suppressor :
|
||||
public nsCycleCollectionTraversalCallback
|
||||
{
|
||||
|
@ -2416,7 +2387,7 @@ nsCycleCollector::Freed(void *n)
|
|||
#endif
|
||||
|
||||
PRUint32
|
||||
nsCycleCollector::Collect(PRUint32 aTryCollections)
|
||||
nsCycleCollector::Collect(PRUint32 aTryCollections, PRBool aDrawGraph)
|
||||
{
|
||||
#if defined(DEBUG_CC) && !defined(__MINGW32__)
|
||||
if (!mParams.mDoNothing && mParams.mHookMalloc)
|
||||
|
@ -2434,6 +2405,9 @@ nsCycleCollector::Collect(PRUint32 aTryCollections)
|
|||
PRTime start = PR_Now();
|
||||
#endif
|
||||
|
||||
PRBool drawGraphs = mParams.mDrawGraphs;
|
||||
mParams.mDrawGraphs |= aDrawGraph;
|
||||
|
||||
mCollectionInProgress = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs =
|
||||
|
@ -2503,6 +2477,8 @@ nsCycleCollector::Collect(PRUint32 aTryCollections)
|
|||
|
||||
mCollectionInProgress = PR_FALSE;
|
||||
|
||||
mParams.mDrawGraphs = drawGraphs;
|
||||
|
||||
#ifdef XP_OS2
|
||||
// Now that the cycle collector has freed some memory, we can try to
|
||||
// force the C library to give back as much memory to the system as
|
||||
|
@ -2526,7 +2502,7 @@ nsCycleCollector::BeginCollection()
|
|||
if (mParams.mDoNothing)
|
||||
return PR_FALSE;
|
||||
|
||||
GCGraphBuilder builder(mGraph, mRuntimes);
|
||||
GCGraphBuilder builder(mGraph, mRuntimes, mParams.mDrawGraphs);
|
||||
if (!builder.Initialized())
|
||||
return PR_FALSE;
|
||||
|
||||
|
@ -2604,9 +2580,7 @@ nsCycleCollector::BeginCollection()
|
|||
(PR_Now() - now) / PR_USEC_PER_MSEC);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
MaybeDrawGraphs();
|
||||
#endif
|
||||
|
||||
mScanInProgress = PR_FALSE;
|
||||
|
||||
|
@ -2692,7 +2666,7 @@ nsCycleCollector::Shutdown()
|
|||
mRuntimes[i]->CommenceShutdown();
|
||||
}
|
||||
|
||||
Collect(SHUTDOWN_COLLECTIONS(mParams));
|
||||
Collect(SHUTDOWN_COLLECTIONS(mParams), PR_FALSE);
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
GCGraphBuilder builder(mGraph, mRuntimes);
|
||||
|
@ -3163,9 +3137,9 @@ NS_CycleCollectorForget2(nsPurpleBufferEntry *e)
|
|||
|
||||
|
||||
PRUint32
|
||||
nsCycleCollector_collect()
|
||||
nsCycleCollector_collect(PRBool aDrawGraph)
|
||||
{
|
||||
return sCollector ? sCollector->Collect() : 0;
|
||||
return sCollector ? sCollector->Collect(1, aDrawGraph) : 0;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
|
|
@ -63,7 +63,7 @@ struct nsCycleCollectionLanguageRuntime
|
|||
|
||||
nsresult nsCycleCollector_startup();
|
||||
// Returns the number of collected nodes.
|
||||
NS_COM PRUint32 nsCycleCollector_collect();
|
||||
NS_COM PRUint32 nsCycleCollector_collect(PRBool aDrawGraph);
|
||||
NS_COM PRUint32 nsCycleCollector_suspectedCount();
|
||||
void nsCycleCollector_shutdown();
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ void XXXNeverCalled()
|
|||
}
|
||||
|
||||
nsXPCOMCycleCollectionParticipant();
|
||||
nsCycleCollector_collect();
|
||||
nsCycleCollector_collect(PR_FALSE);
|
||||
#ifdef XP_WIN
|
||||
sXPCOMHasLoadedNewDLLs = !sXPCOMHasLoadedNewDLLs;
|
||||
NS_SetHasLoadedNewDLLs();
|
||||
|
|
Загрузка…
Ссылка в новой задаче