зеркало из https://github.com/mozilla/gecko-dev.git
Bug 663532 - Run GC from cycle collector in main thread, not CC thread. r=bent
This commit is contained in:
Родитель
38d068a45d
Коммит
81ec3bd93a
|
@ -1047,12 +1047,12 @@ struct nsCycleCollector
|
||||||
nsICycleCollectorListener *aListener);
|
nsICycleCollectorListener *aListener);
|
||||||
|
|
||||||
// Prepare for and cleanup after one or more collection(s).
|
// Prepare for and cleanup after one or more collection(s).
|
||||||
PRBool PrepareForCollection(nsTPtrArray<PtrInfo> *aWhiteNodes);
|
PRBool PrepareForCollection(nsTPtrArray<PtrInfo> *aWhiteNodes,
|
||||||
|
PRBool aForceGC);
|
||||||
void CleanupAfterCollection();
|
void CleanupAfterCollection();
|
||||||
|
|
||||||
// Start and finish an individual collection.
|
// Start and finish an individual collection.
|
||||||
PRBool BeginCollection(PRBool aForceGC,
|
PRBool BeginCollection(nsICycleCollectorListener *aListener);
|
||||||
nsICycleCollectorListener *aListener);
|
|
||||||
PRBool FinishCollection();
|
PRBool FinishCollection();
|
||||||
|
|
||||||
PRUint32 SuspectedCount();
|
PRUint32 SuspectedCount();
|
||||||
|
@ -2499,8 +2499,12 @@ nsCycleCollector::Freed(void *n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsCycleCollector::PrepareForCollection(nsTPtrArray<PtrInfo> *aWhiteNodes)
|
nsCycleCollector::PrepareForCollection(nsTPtrArray<PtrInfo> *aWhiteNodes,
|
||||||
|
PRBool aForceGC)
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(),
|
||||||
|
"PrepareForCollection must be called on the main thread.");
|
||||||
|
|
||||||
#if defined(DEBUG_CC) && !defined(__MINGW32__)
|
#if defined(DEBUG_CC) && !defined(__MINGW32__)
|
||||||
if (!mParams.mDoNothing && mParams.mHookMalloc)
|
if (!mParams.mDoNothing && mParams.mHookMalloc)
|
||||||
InitMemHook();
|
InitMemHook();
|
||||||
|
@ -2529,6 +2533,29 @@ nsCycleCollector::PrepareForCollection(nsTPtrArray<PtrInfo> *aWhiteNodes)
|
||||||
|
|
||||||
mWhiteNodes = aWhiteNodes;
|
mWhiteNodes = aWhiteNodes;
|
||||||
|
|
||||||
|
// The cycle collector uses the mark bitmap to discover what JS objects
|
||||||
|
// were reachable only from XPConnect roots that might participate in
|
||||||
|
// cycles. We ask the JS runtime whether we need to force a GC before
|
||||||
|
// this CC. It returns true on startup (before the mark bits have been set),
|
||||||
|
// and also when UnmarkGray has run out of stack.
|
||||||
|
if (mRuntimes[nsIProgrammingLanguage::JAVASCRIPT]) {
|
||||||
|
nsCycleCollectionJSRuntime* rt =
|
||||||
|
static_cast<nsCycleCollectionJSRuntime*>
|
||||||
|
(mRuntimes[nsIProgrammingLanguage::JAVASCRIPT]);
|
||||||
|
if (rt->NeedCollect() || aForceGC) {
|
||||||
|
#ifdef COLLECT_TIME_DEBUG
|
||||||
|
PRTime start = PR_Now();
|
||||||
|
#endif
|
||||||
|
// rt->Collect() must be called from the main thread,
|
||||||
|
// because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN)
|
||||||
|
// which returns false if not in the main thread.
|
||||||
|
rt->Collect();
|
||||||
|
#ifdef COLLECT_TIME_DEBUG
|
||||||
|
printf("cc: GC() took %lldms\n", (PR_Now() - start) / PR_USEC_PER_MSEC);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2563,13 +2590,13 @@ nsCycleCollector::Collect(PRUint32 aTryCollections,
|
||||||
{
|
{
|
||||||
nsAutoTPtrArray<PtrInfo, 4000> whiteNodes;
|
nsAutoTPtrArray<PtrInfo, 4000> whiteNodes;
|
||||||
|
|
||||||
if (!PrepareForCollection(&whiteNodes))
|
if (!PrepareForCollection(&whiteNodes, PR_TRUE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
PRUint32 totalCollections = 0;
|
PRUint32 totalCollections = 0;
|
||||||
while (aTryCollections > totalCollections) {
|
while (aTryCollections > totalCollections) {
|
||||||
// Synchronous cycle collection. Always force a JS GC as well.
|
// Synchronous cycle collection. Always force a JS GC as well.
|
||||||
if (!(BeginCollection(PR_TRUE, aListener) && FinishCollection()))
|
if (!(BeginCollection(aListener) && FinishCollection()))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
++totalCollections;
|
++totalCollections;
|
||||||
|
@ -2581,32 +2608,11 @@ nsCycleCollector::Collect(PRUint32 aTryCollections,
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsCycleCollector::BeginCollection(PRBool aForceGC,
|
nsCycleCollector::BeginCollection(nsICycleCollectorListener *aListener)
|
||||||
nsICycleCollectorListener *aListener)
|
|
||||||
{
|
{
|
||||||
if (mParams.mDoNothing)
|
if (mParams.mDoNothing)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
||||||
// The cycle collector uses the mark bitmap to discover what JS objects
|
|
||||||
// were reachable only from XPConnect roots that might participate in
|
|
||||||
// cycles. We ask the JS runtime whether we need to force a GC before
|
|
||||||
// this CC. It returns true on startup (before the mark bits have been set),
|
|
||||||
// and also when UnmarkGray has run out of stack.
|
|
||||||
if (mRuntimes[nsIProgrammingLanguage::JAVASCRIPT]) {
|
|
||||||
nsCycleCollectionJSRuntime* rt =
|
|
||||||
static_cast<nsCycleCollectionJSRuntime*>
|
|
||||||
(mRuntimes[nsIProgrammingLanguage::JAVASCRIPT]);
|
|
||||||
if (rt->NeedCollect() || aForceGC) {
|
|
||||||
#ifdef COLLECT_TIME_DEBUG
|
|
||||||
PRTime start = PR_Now();
|
|
||||||
#endif
|
|
||||||
rt->Collect();
|
|
||||||
#ifdef COLLECT_TIME_DEBUG
|
|
||||||
printf("cc: GC() took %lldms\n", (PR_Now() - start) / PR_USEC_PER_MSEC);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aListener && NS_FAILED(aListener->Begin())) {
|
if (aListener && NS_FAILED(aListener->Begin())) {
|
||||||
aListener = nsnull;
|
aListener = nsnull;
|
||||||
}
|
}
|
||||||
|
@ -3358,7 +3364,7 @@ public:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCollected = mCollector->BeginCollection(PR_FALSE, mListener);
|
mCollected = mCollector->BeginCollection(mListener);
|
||||||
|
|
||||||
mReply.Notify();
|
mReply.Notify();
|
||||||
}
|
}
|
||||||
|
@ -3389,7 +3395,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nsAutoTPtrArray<PtrInfo, 4000> whiteNodes;
|
nsAutoTPtrArray<PtrInfo, 4000> whiteNodes;
|
||||||
if (!mCollector->PrepareForCollection(&whiteNodes))
|
if (!mCollector->PrepareForCollection(&whiteNodes, PR_FALSE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
NS_ASSERTION(!mListener, "Should have cleared this already!");
|
NS_ASSERTION(!mListener, "Should have cleared this already!");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче