Bug 758034 - Clean up browser GC API (r=smaug)

This commit is contained in:
Bill McCloskey 2012-06-30 14:16:32 -07:00
parent 6133aa3f77
commit 0dd01290a1
9 changed files with 57 additions and 42 deletions

View File

@ -968,10 +968,10 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
#endif
for (int i = 0; i < 3; i++) {
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS, nsGCNormal, true);
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
}
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS, nsGCNormal, true);
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
return NS_OK;
}

View File

@ -205,8 +205,10 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData)
{
if (sGCOnMemoryPressure) {
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking,
true);
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC,
nsJSContext::NonCompartmentGC,
nsJSContext::ShrinkingGC);
nsJSContext::CycleCollectNow();
}
return NS_OK;
@ -2860,13 +2862,15 @@ FullGCTimerFired(nsITimer* aTimer, void* aClosure)
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
nsGCNormal, true);
nsJSContext::IncrementalGC);
}
//static
void
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
bool aGlobal)
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
IsIncremental aIncremental,
IsCompartment aCompartment,
IsShrinking aShrinking)
{
NS_TIME_FUNCTION_MIN(1.0);
SAMPLE_LABEL("GC", "GarbageCollectNow");
@ -2883,15 +2887,15 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
sPendingLoadCount = 0;
sLoadingInProgress = false;
if (!nsContentUtils::XPConnect()) {
if (!nsContentUtils::XPConnect() || !nsJSRuntime::sRuntime) {
return;
}
// Use compartment GC when we're not asked to do a shrinking GC nor
// global GC and compartment GC has been called less than
// NS_MAX_COMPARTMENT_GC_COUNT times after the previous global GC.
if (!sDisableExplicitCompartmentGC &&
aGckind != nsGCShrinking && !aGlobal &&
aShrinking != ShrinkingGC && aCompartment != NonCompartmentGC &&
sCompartmentGCCount < NS_MAX_COMPARTMENT_GC_COUNT) {
js::PrepareForFullGC(nsJSRuntime::sRuntime);
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
@ -2903,7 +2907,11 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
cx->mActive = false;
}
if (js::IsGCScheduled(nsJSRuntime::sRuntime)) {
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
if (aIncremental == IncrementalGC) {
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
} else {
js::GCForReason(nsJSRuntime::sRuntime, aReason);
}
}
return;
}
@ -2911,7 +2919,12 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
cx->mActive = false;
}
nsContentUtils::XPConnect()->GarbageCollect(aReason, aGckind);
js::PrepareForFullGC(nsJSRuntime::sRuntime);
if (aIncremental == IncrementalGC) {
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
} else {
js::GCForReason(nsJSRuntime::sRuntime, aReason);
}
}
//static
@ -2997,7 +3010,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
if (sCCLockedOut) {
// We're in the middle of an incremental GC; finish it first
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED, nsGCNormal, true);
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED);
}
SAMPLE_LABEL("GC", "CycleCollectNow");
@ -3146,7 +3159,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
nsGCIncremental, false);
nsJSContext::IncrementalGC,
nsJSContext::CompartmentGC);
}
void
@ -3202,7 +3216,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
}
// Finish the current incremental GC
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED, nsGCNormal, true);
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED);
}
++sCCTimerFireCount;

View File

@ -146,9 +146,25 @@ public:
static void LoadStart();
static void LoadEnd();
enum IsCompartment {
CompartmentGC,
NonCompartmentGC
};
enum IsShrinking {
ShrinkingGC,
NonShrinkingGC
};
enum IsIncremental {
IncrementalGC,
NonIncrementalGC
};
static void GarbageCollectNow(js::gcreason::Reason reason,
PRUint32 aGckind,
bool aGlobal);
IsIncremental aIncremental = NonIncrementalGC,
IsCompartment aCompartment = NonCompartmentGC,
IsShrinking aShrinking = NonShrinkingGC);
static void ShrinkGCBuffersNow();
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
// called even if the previous collection was GC.

View File

@ -744,14 +744,14 @@ ContentChild::RecvActivateA11y()
bool
ContentChild::RecvGarbageCollect()
{
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
return true;
}
bool
ContentChild::RecvCycleCollect()
{
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
nsJSContext::CycleCollectNow();
return true;
}

View File

@ -366,12 +366,6 @@ interface nsIXPCFunctionThisTranslator : nsISupports
#define NS_XPCONNECT_CID \
{ 0xcb6593e0, 0xf9b2, 0x11d2, \
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
enum nsGCType {
nsGCNormal,
nsGCShrinking,
nsGCIncremental
};
%}
[uuid(26efd266-3e33-4dc9-8233-e13bb8d9c452)]
@ -698,9 +692,8 @@ interface nsIXPConnect : nsISupports
/**
* Trigger a JS garbage collection.
* Use a js::gcreason::Reason from jsfriendapi.h for the kind.
* Use the nsGCType enum for the kind.
*/
void GarbageCollect(in PRUint32 reason, in PRUint32 kind);
void GarbageCollect(in PRUint32 reason);
/**
* Signals a good place to do an incremental GC slice, because the

View File

@ -327,7 +327,7 @@ nsXPConnect::NeedCollect()
}
void
nsXPConnect::Collect(PRUint32 reason, PRUint32 kind)
nsXPConnect::Collect(PRUint32 reason)
{
// We're dividing JS objects into 2 categories:
//
@ -377,20 +377,13 @@ nsXPConnect::Collect(PRUint32 reason, PRUint32 kind)
JSRuntime *rt = GetRuntime()->GetJSRuntime();
js::PrepareForFullGC(rt);
if (kind == nsGCShrinking) {
js::ShrinkingGC(rt, gcreason);
} else if (kind == nsGCIncremental) {
js::IncrementalGC(rt, gcreason);
} else {
MOZ_ASSERT(kind == nsGCNormal);
js::GCForReason(rt, gcreason);
}
js::GCForReason(rt, gcreason);
}
NS_IMETHODIMP
nsXPConnect::GarbageCollect(PRUint32 reason, PRUint32 kind)
nsXPConnect::GarbageCollect(PRUint32 reason)
{
Collect(reason, kind);
Collect(reason);
return NS_OK;
}

View File

@ -537,7 +537,7 @@ public:
virtual nsresult FinishTraverse();
virtual nsCycleCollectionParticipant *GetParticipant();
virtual bool NeedCollect();
virtual void Collect(PRUint32 reason, PRUint32 kind);
virtual void Collect(PRUint32 reason);
XPCCallContext *GetCycleCollectionContext()
{

View File

@ -2637,7 +2637,7 @@ nsCycleCollector::GCIfNeeded(bool aForceGC)
// mJSRuntime->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.
mJSRuntime->Collect(aForceGC ? js::gcreason::SHUTDOWN_CC : js::gcreason::CC_FORCED, nsGCNormal);
mJSRuntime->Collect(aForceGC ? js::gcreason::SHUTDOWN_CC : js::gcreason::CC_FORCED);
timeLog.Checkpoint("GC()");
}

View File

@ -72,9 +72,8 @@ struct nsCycleCollectionJSRuntime
/**
* Runs the JavaScript GC. |reason| is a gcreason::Reason from jsfriendapi.h.
* |kind| is a nsGCType from nsIXPConnect.idl.
*/
virtual void Collect(PRUint32 reason, PRUint32 kind) = 0;
virtual void Collect(PRUint32 reason) = 0;
/**
* Get the JS cycle collection participant.