Bug 1661293 - Make nsJSContext::MaybePokeGC trigger EAGER_ALLOC_TRIGGER major GCs instead of just eager minor GCs r=jonco,smaug

Differential Revision: https://phabricator.services.mozilla.com/D100368
This commit is contained in:
Steve Fink 2022-03-03 04:21:48 +00:00
parent c3b0f38d01
commit c4fe49a03c
7 changed files with 51 additions and 8 deletions

View File

@ -1661,8 +1661,14 @@ void nsJSContext::MaybePokeGC() {
}
JSRuntime* rt = CycleCollectedJSRuntime::Get()->Runtime();
if (JS::IsIdleGCTaskNeeded(rt)) {
sScheduler.PokeMinorGC(JS::GCReason::EAGER_NURSERY_COLLECTION);
JS::GCReason reason = JS::WantEagerMinorGC(rt);
if (reason != JS::GCReason::NO_REASON) {
MOZ_ASSERT(reason == JS::GCReason::EAGER_NURSERY_COLLECTION);
sScheduler.PokeMinorGC(reason);
}
reason = JS::WantEagerMajorGC(rt);
if (reason != JS::GCReason::NO_REASON) {
PokeGC(reason, nullptr, 0);
}
}

View File

@ -1237,7 +1237,9 @@ JS_GetExternalStringCallbacks(JSString* str);
namespace JS {
extern JS_PUBLIC_API bool IsIdleGCTaskNeeded(JSRuntime* rt);
extern JS_PUBLIC_API GCReason WantEagerMinorGC(JSRuntime* rt);
extern JS_PUBLIC_API GCReason WantEagerMajorGC(JSRuntime* rt);
extern JS_PUBLIC_API void MaybeRunNurseryCollection(JSRuntime* rt,
JS::GCReason reason);

View File

@ -1654,6 +1654,33 @@ void GCRuntime::maybeGC() {
}
}
JS::GCReason GCRuntime::wantMajorGC() {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
// This implementation parallels maybeGC() above.
// From gcIfRequested().
if (majorGCRequested()) {
return majorGCTriggerReason;
}
if (isIncrementalGCInProgress()) {
return JS::GCReason::NO_REASON;
}
JS::GCReason reason = JS::GCReason::NO_REASON;
for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) {
if (checkEagerAllocTrigger(zone->gcHeapSize, zone->gcHeapThreshold) ||
checkEagerAllocTrigger(zone->mallocHeapSize,
zone->mallocHeapThreshold)) {
zone->scheduleGC();
reason = JS::GCReason::EAGER_ALLOC_TRIGGER;
}
}
return reason;
}
bool GCRuntime::checkEagerAllocTrigger(const HeapSize& size,
const HeapThreshold& threshold) {
double thresholdBytes =

View File

@ -330,6 +330,7 @@ class GCRuntime {
bool triggerZoneGC(Zone* zone, JS::GCReason reason, size_t usedBytes,
size_t thresholdBytes);
void maybeGC();
JS::GCReason wantMajorGC();
bool checkEagerAllocTrigger(const HeapSize& size,
const HeapThreshold& threshold);
// The return value indicates whether a major GC was performed.

View File

@ -1279,9 +1279,15 @@ JS_PUBLIC_API void JS_RemoveExtraGCRootsTracer(JSContext* cx,
return cx->runtime()->gc.removeBlackRootsTracer(traceOp, data);
}
JS_PUBLIC_API bool JS::IsIdleGCTaskNeeded(JSRuntime* rt) {
// Currently, we only collect nursery during idle time.
return rt->gc.nursery().shouldCollect();
JS_PUBLIC_API JS::GCReason JS::WantEagerMinorGC(JSRuntime* rt) {
if (rt->gc.nursery().shouldCollect()) {
return JS::GCReason::EAGER_NURSERY_COLLECTION;
}
return JS::GCReason::NO_REASON;
}
JS_PUBLIC_API JS::GCReason JS::WantEagerMajorGC(JSRuntime* rt) {
return rt->gc.wantMajorGC();
}
JS_PUBLIC_API void JS::MaybeRunNurseryCollection(JSRuntime* rt,

View File

@ -210,7 +210,8 @@ class CycleCollectedJSContext : dom::PerThreadAtomCache, private JS::JobQueue {
MOZ_CAN_RUN_SCRIPT_BOUNDARY
virtual void AfterProcessTask(uint32_t aRecursionDepth);
// Check whether we need an idle minor GC task.
// Check whether any eager thresholds have been reached, which would mean
// an idle GC task (minor or major) would be useful.
virtual void MaybePokeGC();
uint32_t RecursionDepth() const;

View File

@ -376,7 +376,7 @@ class CycleCollectedJSRuntime {
bool IsIdleGCTaskNeeded() {
return !HasPendingIdleGCTask() && Runtime() &&
JS::IsIdleGCTaskNeeded(Runtime());
JS::WantEagerMinorGC(Runtime()) != JS::GCReason::NO_REASON;
}
public: