From 6149e805bc11e773c6dc84acdf1fc5cacbaac75a Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Tue, 3 Apr 2012 12:23:11 -0700 Subject: [PATCH] Bug 742570 - Change API for compartment GCs (r=igor) --- dom/workers/WorkerPrivate.cpp | 1 + js/src/builtin/TestingFunctions.cpp | 6 +++++- js/src/jsapi.cpp | 21 +++------------------ js/src/jsfriendapi.cpp | 18 +++++++++--------- js/src/jsfriendapi.h | 14 ++++++++++++-- js/src/jsgc.cpp | 13 ------------- js/src/jsgc.h | 3 --- js/xpconnect/src/XPCComponents.cpp | 3 +++ js/xpconnect/src/nsXPConnect.cpp | 2 ++ 9 files changed, 35 insertions(+), 46 deletions(-) diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 1dbf218281a2..96b87882994d 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -3891,6 +3891,7 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking, { AssertIsOnWorkerThread(); + js::PrepareForFullGC(JS_GetRuntime(aCx)); if (aShrinking) { js::ShrinkingGC(aCx, js::gcreason::DOM_WORKER); } diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index fa5f04281137..83bc3c5cc7b6 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -32,7 +32,11 @@ GC(JSContext *cx, unsigned argc, jsval *vp) size_t preBytes = cx->runtime->gcBytes; #endif - JS_CompartmentGC(cx, comp); + if (comp) + PrepareCompartmentForGC(comp); + else + PrepareForFullGC(cx->runtime); + GCForReason(cx, gcreason::API); char buf[256] = { '\0' }; #ifndef JS_MORE_DETERMINISTIC diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index d1e5dbaf4c17..4b72d292673d 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2859,27 +2859,12 @@ JS_IsGCMarkingTracer(JSTracer *trc) return IS_GC_MARKING_TRACER(trc); } -extern JS_PUBLIC_API(void) -JS_CompartmentGC(JSContext *cx, JSCompartment *comp) -{ - AssertNoGC(cx); - - /* We cannot GC the atoms compartment alone; use a full GC instead. */ - JS_ASSERT(comp != cx->runtime->atomsCompartment); - - if (comp) { - PrepareCompartmentForGC(comp); - GC(cx, GC_NORMAL, gcreason::API); - } else { - PrepareForFullGC(cx->runtime); - GC(cx, GC_NORMAL, gcreason::API); - } -} - JS_PUBLIC_API(void) JS_GC(JSContext *cx) { - JS_CompartmentGC(cx, NULL); + AssertNoGC(cx); + PrepareForFullGC(cx->runtime); + GC(cx, GC_NORMAL, gcreason::API); } JS_PUBLIC_API(void) diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 5662ca1b8516..e3141471e57e 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -132,33 +132,33 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObj } JS_FRIEND_API(void) -js::GCForReason(JSContext *cx, gcreason::Reason reason) +js::PrepareCompartmentForGC(JSCompartment *comp) { - PrepareForFullGC(cx->runtime); - GC(cx, GC_NORMAL, reason); + comp->scheduleGC(); } JS_FRIEND_API(void) -js::CompartmentGCForReason(JSContext *cx, JSCompartment *comp, gcreason::Reason reason) +js::PrepareForFullGC(JSRuntime *rt) { - /* We cannot GC the atoms compartment alone; use a full GC instead. */ - JS_ASSERT(comp != cx->runtime->atomsCompartment); + for (CompartmentsIter c(rt); !c.done(); c.next()) + c->scheduleGC(); +} - PrepareCompartmentForGC(comp); +JS_FRIEND_API(void) +js::GCForReason(JSContext *cx, gcreason::Reason reason) +{ GC(cx, GC_NORMAL, reason); } JS_FRIEND_API(void) js::ShrinkingGC(JSContext *cx, gcreason::Reason reason) { - PrepareForFullGC(cx->runtime); GC(cx, GC_SHRINK, reason); } JS_FRIEND_API(void) js::IncrementalGC(JSContext *cx, gcreason::Reason reason) { - PrepareForFullGC(cx->runtime); GCSlice(cx, GC_NORMAL, reason); } diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index a38da10ada68..b532585b167a 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -667,10 +667,20 @@ enum Reason { } /* namespace gcreason */ extern JS_FRIEND_API(void) -GCForReason(JSContext *cx, gcreason::Reason reason); +PrepareCompartmentForGC(JSCompartment *comp); extern JS_FRIEND_API(void) -CompartmentGCForReason(JSContext *cx, JSCompartment *comp, gcreason::Reason reason); +PrepareForFullGC(JSRuntime *rt); + +/* + * When triggering a GC using one of the functions below, it is first necessary + * to select the compartments to be collected. To do this, you can call + * PrepareCompartmentForGC on each compartment, or you can call PrepareForFullGC + * to select all compartments. Failing to select any compartment is an error. + */ + +extern JS_FRIEND_API(void) +GCForReason(JSContext *cx, gcreason::Reason reason); extern JS_FRIEND_API(void) ShrinkingGC(JSContext *cx, gcreason::Reason reason); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 88955da435d3..6a1ea1b19e73 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -2824,19 +2824,6 @@ GCHelperThread::doSweep() #endif /* JS_THREADSAFE */ -void -PrepareForFullGC(JSRuntime *rt) -{ - for (CompartmentsIter c(rt); !c.done(); c.next()) - c->scheduleGC(); -} - -void -PrepareCompartmentForGC(JSCompartment *comp) -{ - comp->scheduleGC(); -} - } /* namespace js */ static bool diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 4fd197368792..5bac733c2b59 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -1386,9 +1386,6 @@ ShrinkGCBuffers(JSRuntime *rt); extern void PrepareForFullGC(JSRuntime *rt); -extern void -PrepareCompartmentForGC(JSCompartment *comp); - /* * Kinds of js_GC invocation. */ diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 97ac9ae50bfd..3c71a76608e0 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -3620,6 +3620,7 @@ nsXPCComponents_Utils::GetWeakReference(const JS::Value &object, JSContext *cx, NS_IMETHODIMP nsXPCComponents_Utils::ForceGC(JSContext *cx) { + js::PrepareForFullGC(JS_GetRuntime(cx)); js::GCForReason(cx, js::gcreason::COMPONENT_UTILS); return NS_OK; } @@ -3628,6 +3629,7 @@ nsXPCComponents_Utils::ForceGC(JSContext *cx) NS_IMETHODIMP nsXPCComponents_Utils::ForceShrinkingGC(JSContext *cx) { + js::PrepareForFullGC(JS_GetRuntime(cx)); js::ShrinkingGC(cx, js::gcreason::COMPONENT_UTILS); return NS_OK; } @@ -3655,6 +3657,7 @@ class PreciseGCRunnable : public nsRunnable } } + js::PrepareForFullGC(JS_GetRuntime(mCx)); if (mShrinking) js::ShrinkingGC(mCx, js::gcreason::COMPONENT_UTILS); else diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 9e2c38a104e4..66c490e91160 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -414,6 +414,7 @@ nsXPConnect::Collect(PRUint32 reason, PRUint32 kind) return; JSContext *cx = ccx.GetJSContext(); + JSRuntime *rt = GetRuntime()->GetJSRuntime(); // We want to scan the current thread for GC roots only if it was in a // request prior to the Collect call to avoid false positives during the @@ -423,6 +424,7 @@ nsXPConnect::Collect(PRUint32 reason, PRUint32 kind) js::AutoSkipConservativeScan ascs(cx); MOZ_ASSERT(reason < js::gcreason::NUM_REASONS); js::gcreason::Reason gcreason = (js::gcreason::Reason)reason; + js::PrepareForFullGC(rt); if (kind == nsGCShrinking) { js::ShrinkingGC(cx, gcreason); } else if (kind == nsGCIncremental) {