Expose CycleCollectFull in nsIDOMWindowUtils to force a full CC.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
Gabriel Ivăncescu 2023-08-29 19:08:01 +03:00
parent 00146e3243
commit 2f405d211a
No known key found for this signature in database
GPG Key ID: 4CEE4FF41CC69382
6 changed files with 49 additions and 1 deletions

View File

@ -3871,6 +3871,13 @@ nsDOMWindowUtils::SetNextPaintSyncId(int32_t aSyncId)
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::CycleCollectFull()
{
nsJSContext::CycleCollectFullNow();
return NS_OK;
}
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)

View File

@ -1583,6 +1583,22 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
gCCStats.FinishCycleCollectionSlice();
}
//static
void
nsJSContext::CycleCollectFullNow()
{
if (!NS_IsMainThread()) {
return;
}
PROFILER_LABEL("nsJSContext", "CycleCollectFullNow",
js::ProfileEntry::Category::CC);
gCCStats.PrepareForCycleCollectionSlice(0);
nsCycleCollector_collectFull();
gCCStats.FinishCycleCollectionSlice();
}
//static
void
nsJSContext::RunCycleCollectorSlice()

View File

@ -94,6 +94,7 @@ public:
// called even if the previous collection was GC.
static void CycleCollectNow(nsICycleCollectorListener *aListener = nullptr,
int32_t aExtraForgetSkippableCalls = 0);
static void CycleCollectFullNow();
// Run a cycle collector slice, using a heuristic to decide how long to run it.
static void RunCycleCollectorSlice();

View File

@ -1842,6 +1842,9 @@ interface nsIDOMWindowUtils : nsISupports {
void forceUseCounterFlush(in nsIDOMNode aNode);
void setNextPaintSyncId(in long aSyncId);
/* Force a full cycle collection, including garbage collection and freeing all SnowWhites. */
void cycleCollectFull();
};
[scriptable, uuid(c694e359-7227-4392-a138-33c0cc1f15a6)]

View File

@ -1239,6 +1239,7 @@ enum ccType
{
SliceCC, /* If a CC is in progress, continue it. Otherwise, start a new one. */
ManualCC, /* Explicitly triggered. */
FullCC, /* Explicitly triggered, always doing a full collection. */
ShutdownCC /* Shutdown CC, used for finding leaks. */
};
@ -3692,6 +3693,8 @@ nsCycleCollector::Collect(ccType aCCType,
if (Collect(aCCType, aBudget, aManualListener)) {
collectedAny = true;
}
} else if (aCCType == FullCC && collectedAny) {
FreeSnowWhite(true);
}
MOZ_ASSERT_IF(aCCType != SliceCC, IsIdle());
@ -3808,7 +3811,7 @@ nsCycleCollector::BeginCollection(ccType aCCType,
// On a WantAllTraces CC, force a synchronous global GC to prevent
// hijinks from ForgetSkippable and compartmental GCs.
bool forceGC = isShutdown || (mLogger && mLogger->IsAllTraces());
bool forceGC = isShutdown || aCCType == FullCC || (mLogger && mLogger->IsAllTraces());
// BeginCycleCollectionCallback() might have started an IGC, and we need
// to finish it before we run FixGrayBits.
@ -4137,6 +4140,22 @@ nsCycleCollector_collect(nsICycleCollectorListener* aManualListener)
data->mCollector->Collect(ManualCC, unlimitedBudget, aManualListener);
}
void
nsCycleCollector_collectFull()
{
CollectorData* data = sCollectorData.get();
// We should have started the cycle collector by now.
MOZ_ASSERT(data);
MOZ_ASSERT(data->mCollector);
PROFILER_LABEL("nsCycleCollector", "collectFull",
js::ProfileEntry::Category::CC);
SliceBudget unlimitedBudget = SliceBudget::unlimited();
data->mCollector->Collect(FullCC, unlimitedBudget, NULL);
}
void
nsCycleCollector_collectSlice(SliceBudget& budget,
bool aPreferShorterSlices)

View File

@ -47,6 +47,8 @@ already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink();
void nsCycleCollector_collect(nsICycleCollectorListener* aManualListener);
void nsCycleCollector_collectFull();
void nsCycleCollector_collectSlice(js::SliceBudget& budget,
bool aPreferShorterSlices = false);