зеркало из https://github.com/mozilla/pjs.git
Only run CC after the GC has run at least once (bug 626768, r=gal). a=blocker
This commit is contained in:
Родитель
40a217d8b6
Коммит
3362ed55f8
|
@ -148,6 +148,8 @@ static PRLogModuleInfo* gJSDiagnostics;
|
|||
static nsITimer *sGCTimer;
|
||||
static nsITimer *sCCTimer;
|
||||
|
||||
static bool sGCHasRun;
|
||||
|
||||
// The number of currently pending document loads. This count isn't
|
||||
// guaranteed to always reflect reality and can't easily as we don't
|
||||
// have an easy place to know when a load ends or is interrupted in
|
||||
|
@ -3392,8 +3394,8 @@ nsJSContext::MaybePokeCC()
|
|||
void
|
||||
nsJSContext::PokeCC()
|
||||
{
|
||||
if (sCCTimer) {
|
||||
// There's already a timer for GC'ing, just return
|
||||
if (sCCTimer || !sGCHasRun) {
|
||||
// There's already a timer for GC'ing, or GC hasn't run yet, just return.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3477,6 +3479,7 @@ DOMGCCallback(JSContext *cx, JSGCStatus status)
|
|||
} else {
|
||||
// If this was a full GC, poke the CC to run soon.
|
||||
if (!cx->runtime->gcTriggerCompartment) {
|
||||
sGCHasRun = true;
|
||||
nsJSContext::PokeCC();
|
||||
}
|
||||
}
|
||||
|
@ -3589,6 +3592,7 @@ nsJSRuntime::Startup()
|
|||
{
|
||||
// initialize all our statics, so that we can restart XPCOM
|
||||
sGCTimer = sCCTimer = nsnull;
|
||||
sGCHasRun = false;
|
||||
sPendingLoadCount = 0;
|
||||
sLoadingInProgress = PR_FALSE;
|
||||
sPostGCEventsToConsole = PR_FALSE;
|
||||
|
|
|
@ -464,6 +464,18 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static bool gcHasRun = false;
|
||||
if(!gcHasRun)
|
||||
{
|
||||
JSRuntime* rt = JS_GetRuntime(mCycleCollectionContext->GetJSContext());
|
||||
if(!rt)
|
||||
NS_RUNTIMEABORT("Failed to get JS runtime!");
|
||||
uint32 gcNumber = JS_GetGCParameter(rt, JSGC_NUMBER);
|
||||
if(!gcNumber)
|
||||
NS_RUNTIMEABORT("Cannot cycle collect if GC has not run first!");
|
||||
gcHasRun = true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
NS_ASSERTION(!mJSRoots.ops, "Didn't call FinishCycleCollection?");
|
||||
|
||||
|
|
|
@ -3287,7 +3287,6 @@ class nsCycleCollectorRunner : public nsRunnable
|
|||
PRBool mRunning;
|
||||
PRBool mShutdown;
|
||||
PRBool mCollected;
|
||||
PRBool mJSGCHasRun;
|
||||
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
|
@ -3335,8 +3334,7 @@ public:
|
|||
mReply(mLock, "cycle collector reply condvar"),
|
||||
mRunning(PR_FALSE),
|
||||
mShutdown(PR_FALSE),
|
||||
mCollected(PR_FALSE),
|
||||
mJSGCHasRun(PR_FALSE)
|
||||
mCollected(PR_FALSE)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
@ -3347,7 +3345,7 @@ public:
|
|||
|
||||
MutexAutoLock autoLock(mLock);
|
||||
|
||||
if (!mRunning || !mJSGCHasRun)
|
||||
if (!mRunning)
|
||||
return 0;
|
||||
|
||||
nsAutoTPtrArray<PtrInfo, 4000> whiteNodes;
|
||||
|
@ -3388,14 +3386,6 @@ public:
|
|||
mRequest.Notify();
|
||||
mReply.Wait();
|
||||
}
|
||||
|
||||
void JSGCHasRun()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
MutexAutoLock autoLock(mLock);
|
||||
mJSGCHasRun = PR_TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
// Holds a reference.
|
||||
|
@ -3404,43 +3394,6 @@ static nsCycleCollectorRunner* sCollectorRunner;
|
|||
// Holds a reference.
|
||||
static nsIThread* sCollectorThread;
|
||||
|
||||
static JSBool
|
||||
nsCycleCollector_gccallback(JSContext *cx, JSGCStatus status)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (status == JSGC_END) {
|
||||
if (sCollectorRunner)
|
||||
sCollectorRunner->JSGCHasRun();
|
||||
|
||||
nsCOMPtr<nsIJSRuntimeService> rts =
|
||||
do_GetService(nsIXPConnect::GetCID());
|
||||
NS_WARN_IF_FALSE(rts, "Failed to get XPConnect?!");
|
||||
if (rts)
|
||||
rts->UnregisterGCCallback(nsCycleCollector_gccallback);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
class nsCycleCollectorGCHookRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsCOMPtr<nsIJSRuntimeService> rts =
|
||||
do_GetService(nsIXPConnect::GetCID());
|
||||
if (!rts) {
|
||||
NS_RUNTIMEABORT("This must never fail!");
|
||||
}
|
||||
|
||||
rts->RegisterGCCallback(nsCycleCollector_gccallback);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsCycleCollector_startup()
|
||||
{
|
||||
|
@ -3449,17 +3402,11 @@ nsCycleCollector_startup()
|
|||
|
||||
sCollector = new nsCycleCollector();
|
||||
|
||||
// We can't get XPConnect yet as it hasn't been initialized yet.
|
||||
nsRefPtr<nsCycleCollectorGCHookRunnable> hook =
|
||||
new nsCycleCollectorGCHookRunnable();
|
||||
nsresult rv = NS_DispatchToCurrentThread(hook);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsCycleCollectorRunner> runner =
|
||||
new nsCycleCollectorRunner(sCollector);
|
||||
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
rv = NS_NewThread(getter_AddRefs(thread), runner);
|
||||
nsresult rv = NS_NewThread(getter_AddRefs(thread), runner);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
runner.swap(sCollectorRunner);
|
||||
|
|
Загрузка…
Ссылка в новой задаче