mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
bug 713916 - DOMGCFinishedCallback should schedule just GC buffer shrinking, not a full shrinking GC. r=bent
This commit is contained in:
parent
7c688c1bdd
commit
e832967458
@ -129,6 +129,8 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||
// a page) and doing the actual GC.
|
||||
#define NS_GC_DELAY 4000 // ms
|
||||
|
||||
#define NS_SHRINK_GC_BUFFERS_DELAY 4000 // ms
|
||||
|
||||
// The amount of time we wait from the first request to GC to actually
|
||||
// doing the first GC.
|
||||
#define NS_FIRST_GC_DELAY 10000 // ms
|
||||
@ -142,6 +144,7 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||
// if you add statics here, add them to the list in nsJSRuntime::Startup
|
||||
|
||||
static nsITimer *sGCTimer;
|
||||
static nsITimer *sShrinkGCBuffersTimer;
|
||||
static nsITimer *sCCTimer;
|
||||
|
||||
static bool sGCHasRun;
|
||||
@ -1098,8 +1101,9 @@ nsJSContext::~nsJSContext()
|
||||
void
|
||||
nsJSContext::DestroyJSContext()
|
||||
{
|
||||
if (!mContext)
|
||||
if (!mContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear our entry in the JSContext, bugzilla bug 66413
|
||||
::JS_SetContextPrivate(mContext, nsnull);
|
||||
@ -1108,14 +1112,14 @@ nsJSContext::DestroyJSContext()
|
||||
Preferences::UnregisterCallback(JSOptionChangedCallback,
|
||||
js_options_dot_str, this);
|
||||
|
||||
bool do_gc = mGCOnDestruction && !sGCTimer;
|
||||
|
||||
if (mGCOnDestruction) {
|
||||
PokeGC();
|
||||
}
|
||||
|
||||
// Let xpconnect destroy the JSContext when it thinks the time is right.
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
xpc->ReleaseJSContext(mContext, !do_gc);
|
||||
} else if (do_gc) {
|
||||
::JS_DestroyContext(mContext);
|
||||
xpc->ReleaseJSContext(mContext, true);
|
||||
} else {
|
||||
::JS_DestroyContextNoGC(mContext);
|
||||
}
|
||||
@ -3224,6 +3228,7 @@ nsJSContext::GarbageCollectNow(bool shrinkingGC)
|
||||
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
||||
|
||||
KillGCTimer();
|
||||
KillShrinkGCBuffersTimer();
|
||||
|
||||
// Reset sPendingLoadCount in case the timer that fired was a
|
||||
// timer we scheduled due to a normal GC timer firing while
|
||||
@ -3239,6 +3244,18 @@ nsJSContext::GarbageCollectNow(bool shrinkingGC)
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::ShrinkGCBuffersNow()
|
||||
{
|
||||
NS_TIME_FUNCTION_MIN(1.0);
|
||||
SAMPLE_LABEL("GC", "ShrinkGCBuffersNow");
|
||||
|
||||
KillShrinkGCBuffersTimer();
|
||||
|
||||
JS_ShrinkGCBuffers(nsJSRuntime::sRuntime);
|
||||
}
|
||||
|
||||
//Static
|
||||
void
|
||||
nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener)
|
||||
@ -3296,6 +3313,14 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
nsJSContext::GarbageCollectNow();
|
||||
}
|
||||
|
||||
void
|
||||
ShrinkGCBuffersTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
NS_RELEASE(sShrinkGCBuffersTimer);
|
||||
|
||||
nsJSContext::ShrinkGCBuffersNow();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
@ -3359,6 +3384,26 @@ nsJSContext::PokeGC()
|
||||
first = false;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSContext::PokeShrinkGCBuffers()
|
||||
{
|
||||
if (sShrinkGCBuffersTimer) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallCreateInstance("@mozilla.org/timer;1", &sShrinkGCBuffersTimer);
|
||||
|
||||
if (!sShrinkGCBuffersTimer) {
|
||||
// Failed to create timer (probably because we're in XPCOM shutdown)
|
||||
return;
|
||||
}
|
||||
|
||||
sShrinkGCBuffersTimer->InitWithFuncCallback(ShrinkGCBuffersTimerFired, nsnull,
|
||||
NS_SHRINK_GC_BUFFERS_DELAY,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSContext::MaybePokeCC()
|
||||
@ -3400,6 +3445,17 @@ nsJSContext::KillGCTimer()
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillShrinkGCBuffersTimer()
|
||||
{
|
||||
if (sShrinkGCBuffersTimer) {
|
||||
sShrinkGCBuffersTimer->Cancel();
|
||||
|
||||
NS_RELEASE(sShrinkGCBuffersTimer);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillCCTimer()
|
||||
@ -3465,10 +3521,11 @@ DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't end up scheduling a GC, and there are unused
|
||||
// chunks waiting to expire, make sure we will GC again soon.
|
||||
if (!sGCTimer && JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS) > 0) {
|
||||
nsJSContext::PokeGC();
|
||||
// If we didn't end up scheduling a GC, make sure that we release GC buffers
|
||||
// soon after canceling previous shrinking attempt
|
||||
nsJSContext::KillShrinkGCBuffersTimer();
|
||||
if (!sGCTimer) {
|
||||
nsJSContext::PokeShrinkGCBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3808,6 +3865,7 @@ void
|
||||
nsJSRuntime::Shutdown()
|
||||
{
|
||||
nsJSContext::KillGCTimer();
|
||||
nsJSContext::KillShrinkGCBuffersTimer();
|
||||
nsJSContext::KillCCTimer();
|
||||
|
||||
NS_IF_RELEASE(gNameSpaceManager);
|
||||
|
@ -183,11 +183,15 @@ public:
|
||||
static void LoadEnd();
|
||||
|
||||
static void GarbageCollectNow(bool shrinkingGC = false);
|
||||
static void ShrinkGCBuffersNow();
|
||||
static void CycleCollectNow(nsICycleCollectorListener *aListener = nsnull);
|
||||
|
||||
static void PokeGC();
|
||||
static void KillGCTimer();
|
||||
|
||||
static void PokeShrinkGCBuffers();
|
||||
static void KillShrinkGCBuffersTimer();
|
||||
|
||||
static void PokeCC();
|
||||
static void MaybePokeCC();
|
||||
static void KillCCTimer();
|
||||
|
Loading…
Reference in New Issue
Block a user