diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 7d913fce8004..5f0c683aa581 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1294,11 +1294,10 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason, if (aIncremental == IncrementalGC) { MOZ_ASSERT(aShrinking == NonShrinkingGC); - JS::StartIncrementalGC(sRuntime, aReason, aSliceMillis); - } else if (aShrinking == ShrinkingGC) { - JS::ShrinkingGC(sRuntime, aReason); + JS::StartIncrementalGC(sRuntime, GC_NORMAL, aReason, aSliceMillis); } else { - JS::GCForReason(sRuntime, aReason); + JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL; + JS::GCForReason(sRuntime, gckind, aReason); } } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 47cf553b4c7c..2da1743c253c 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -6020,14 +6020,14 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking, JS::PrepareForFullGC(rt); if (aShrinking) { - JS::ShrinkingGC(rt, JS::gcreason::DOM_WORKER); + JS::GCForReason(rt, GC_SHRINK, JS::gcreason::DOM_WORKER); if (!aCollectChildren) { LOG(("Worker %p collected idle garbage\n", this)); } } else { - JS::GCForReason(rt, JS::gcreason::DOM_WORKER); + JS::GCForReason(rt, GC_NORMAL, JS::gcreason::DOM_WORKER); LOG(("Worker %p collected garbage\n", this)); } } diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 439fb5805163..c2da39a2356e 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -31,6 +31,17 @@ typedef enum JSGCMode { JSGC_MODE_INCREMENTAL = 2 } JSGCMode; +/* + * Kinds of js_GC invocation. + */ +typedef enum JSGCInvocationKind { + /* Normal invocation. */ + GC_NORMAL = 0, + + /* Minimize GC triggers and release empty GC chunks right away. */ + GC_SHRINK = 1 +} JSGCInvocationKind; + namespace JS { #define GCREASONS(D) \ @@ -168,20 +179,16 @@ SkipZoneForGC(Zone *zone); */ /* - * Performs a non-incremental collection of all selected zones. Some objects - * that are unreachable from the program may still be alive afterwards because - * of internal references. + * Performs a non-incremental collection of all selected zones. + * + * If the gckind argument is GC_NORMAL, then some objects that are unreachable + * from the program may still be alive afterwards because of internal + * references; if GC_SHRINK is passed then caches and other temporary references + * to objects will be cleared and all unreferenced objects will be removed from + * the system. */ extern JS_FRIEND_API(void) -GCForReason(JSRuntime *rt, gcreason::Reason reason); - -/* - * Perform a non-incremental collection after clearing caches and other - * temporary references to objects. This will remove all unreferenced objects - * in the system. - */ -extern JS_FRIEND_API(void) -ShrinkingGC(JSRuntime *rt, gcreason::Reason reason); +GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason); /* * Incremental GC: @@ -216,7 +223,8 @@ ShrinkingGC(JSRuntime *rt, gcreason::Reason reason); * shorter than the requested interval. */ extern JS_FRIEND_API(void) -StartIncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); +StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, + int64_t millis = 0); /* * Perform a slice of an ongoing incremental collection. When this function diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index faf5484aa35f..8718f4c8fe42 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -238,10 +238,8 @@ GC(JSContext *cx, unsigned argc, jsval *vp) else JS::PrepareForFullGC(cx->runtime()); - if (shrinking) - JS::ShrinkingGC(cx->runtime(), JS::gcreason::API); - else - JS::GCForReason(cx->runtime(), JS::gcreason::API); + JSGCInvocationKind gckind = shrinking ? GC_SHRINK : GC_NORMAL; + JS::GCForReason(cx->runtime(), gckind, JS::gcreason::API); char buf[256] = { '\0' }; #ifndef JS_MORE_DETERMINISTIC diff --git a/js/src/jsapi-tests/testGCFinalizeCallback.cpp b/js/src/jsapi-tests/testGCFinalizeCallback.cpp index 99673d6dd1c7..b7c681b9aabb 100644 --- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp +++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp @@ -24,7 +24,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Full GC, incremental. */ FinalizeCalls = 0; JS::PrepareForFullGC(rt); - JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(rt->gc.isFullGc()); CHECK(checkMultipleGroups()); @@ -41,7 +41,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Compartment GC, non-incremental, single compartment. */ FinalizeCalls = 0; JS::PrepareZoneForGC(global1->zone()); - JS::GCForReason(rt, JS::gcreason::API); + JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); CHECK(checkFinalizeStatus()); @@ -52,7 +52,7 @@ BEGIN_TEST(testGCFinalizeCallback) JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global3->zone()); - JS::GCForReason(rt, JS::gcreason::API); + JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); CHECK(checkFinalizeStatus()); @@ -61,7 +61,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Compartment GC, incremental, single compartment. */ FinalizeCalls = 0; JS::PrepareZoneForGC(global1->zone()); - JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); @@ -73,7 +73,7 @@ BEGIN_TEST(testGCFinalizeCallback) JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global3->zone()); - JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(!rt->gc.isFullGc()); CHECK(checkMultipleGroups()); diff --git a/js/src/jsapi-tests/testPreserveJitCode.cpp b/js/src/jsapi-tests/testPreserveJitCode.cpp index fd7d328a3e0c..40ee89a8d030 100644 --- a/js/src/jsapi-tests/testPreserveJitCode.cpp +++ b/js/src/jsapi-tests/testPreserveJitCode.cpp @@ -65,10 +65,10 @@ testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts) CHECK_EQUAL(value.toInt32(), 45); CHECK_EQUAL(countIonScripts(global), 1u); - GCForReason(rt, gcreason::API); + GCForReason(rt, GC_NORMAL, gcreason::API); CHECK_EQUAL(countIonScripts(global), remainingIonScripts); - ShrinkingGC(rt, gcreason::API); + GCForReason(rt, GC_SHRINK, gcreason::API); CHECK_EQUAL(countIonScripts(global), 0u); return true; diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index d01113d93802..20bd5ea2f798 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -428,7 +428,7 @@ class AutoLeaveZeal JS_GetGCZeal(cx_, &zeal_, &frequency_); JS_SetGCZeal(cx_, 0, 0); JS::PrepareForFullGC(JS_GetRuntime(cx_)); - JS::ShrinkingGC(JS_GetRuntime(cx_), JS::gcreason::DEBUG_GC); + JS::GCForReason(JS_GetRuntime(cx_), GC_SHRINK, JS::gcreason::DEBUG_GC); } ~AutoLeaveZeal() { JS_SetGCZeal(cx_, zeal_, frequency_); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 41aca0d0ec4f..5e88e90be572 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -196,21 +196,17 @@ JS::SkipZoneForGC(Zone *zone) } JS_FRIEND_API(void) -JS::GCForReason(JSRuntime *rt, gcreason::Reason reason) +JS::GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) { - rt->gc.gc(GC_NORMAL, reason); + MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); + rt->gc.gc(gckind, reason); } JS_FRIEND_API(void) -JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason) +JS::StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis) { - rt->gc.gc(GC_SHRINK, reason); -} - -JS_FRIEND_API(void) -JS::StartIncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis) -{ - rt->gc.startGC(GC_NORMAL, reason, millis); + MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); + rt->gc.startGC(gckind, reason, millis); } JS_FRIEND_API(void) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index d37156aa400e..1d6002154c01 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -903,17 +903,6 @@ TraceRuntime(JSTracer *trc); extern void ReleaseAllJITCode(FreeOp *op); -/* - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* Minimize GC triggers and release empty GC chunks right away. */ - GC_SHRINK = 1 -} JSGCInvocationKind; - extern void PrepareForDebugGC(JSRuntime *rt); diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index e6aa4593281e..6af61cbdd8ed 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -2750,7 +2750,7 @@ nsXPCComponents_Utils::ForceGC() { JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); PrepareForFullGC(rt); - GCForReason(rt, gcreason::COMPONENT_UTILS); + GCForReason(rt, GC_NORMAL, gcreason::COMPONENT_UTILS); return NS_OK; } @@ -2800,7 +2800,7 @@ nsXPCComponents_Utils::ForceShrinkingGC() { JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); PrepareForFullGC(rt); - ShrinkingGC(rt, gcreason::COMPONENT_UTILS); + GCForReason(rt, GC_SHRINK, gcreason::COMPONENT_UTILS); return NS_OK; } @@ -2823,10 +2823,8 @@ class PreciseGCRunnable : public nsRunnable } PrepareForFullGC(rt); - if (mShrinking) - ShrinkingGC(rt, gcreason::COMPONENT_UTILS); - else - GCForReason(rt, gcreason::COMPONENT_UTILS); + JSGCInvocationKind gckind = mShrinking ? GC_SHRINK : GC_NORMAL; + GCForReason(rt, gckind, gcreason::COMPONENT_UTILS); mCallback->Callback(); return NS_OK; diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index e4e6b5be3d4e..0e10a427c394 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -1025,7 +1025,7 @@ CycleCollectedJSRuntime::GarbageCollect(uint32_t aReason) const JS::gcreason::Reason gcreason = static_cast(aReason); JS::PrepareForFullGC(mJSRuntime); - JS::GCForReason(mJSRuntime, gcreason); + JS::GCForReason(mJSRuntime, GC_NORMAL, gcreason); } void