Revert "1376614 - Pass budget to forgetSkippable and return early when budget has been used"

This reverts commit d28a0aef504d68c33220c5358b2f12b7e891d304.
This commit is contained in:
win7-7 2026-01-28 20:07:23 +02:00 committed by wuggy
commit 4890ee7978
3 changed files with 18 additions and 50 deletions

View file

@ -1325,13 +1325,7 @@ FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
FinishAnyIncrementalGC();
bool earlyForgetSkippable =
sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS;
int64_t budgetMs = aDeadline.IsNull() ?
kForgetSkippableSliceDuration :
int64_t((aDeadline - TimeStamp::Now()).ToMilliseconds());
js::SliceBudget budget = js::SliceBudget(js::TimeBudget(budgetMs));
nsCycleCollector_forgetSkippable(budget, aRemoveChildless, earlyForgetSkippable);
nsCycleCollector_forgetSkippable(aRemoveChildless, earlyForgetSkippable);
sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
++sCleanupsSinceLastGC;
PRTime delta = PR_Now() - startTime;

View file

@ -1053,9 +1053,7 @@ public:
for (; !iter.Done(); iter.Next()) {
nsPurpleBufferEntry& e = iter.Get();
if (e.mObject) {
if (!aVisitor.Visit(*this, &e)) {
return;
}
aVisitor.Visit(*this, &e);
}
// Visit call above may have cleared the entry, or the entry was empty
@ -1068,9 +1066,7 @@ public:
break;
}
if (otherEntry.mObject) {
if (!aVisitor.Visit(*this, &otherEntry)) {
return;
}
aVisitor.Visit(*this, &otherEntry);
// Visit may have cleared otherEntry.
if (otherEntry.mObject) {
e.Swap(otherEntry);
@ -1131,7 +1127,6 @@ public:
// that will have no children in the cycle collector graph will also be
// removed. CanSkip() may be run on these children.
void RemoveSkippable(nsCycleCollector* aCollector,
js::SliceBudget& aBudget,
bool aRemoveChildlessNodes,
bool aAsyncSnowWhiteFreeing,
CC_ForgetSkippableCallback aCb);
@ -1171,7 +1166,7 @@ struct SelectPointersVisitor
{
}
bool
void
Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
{
MOZ_ASSERT(aEntry->mObject, "Null object in purple buffer");
@ -1181,7 +1176,6 @@ struct SelectPointersVisitor
AddPurpleRoot(mBuilder, aEntry->mObject, aEntry->mParticipant)) {
aBuffer.Remove(aEntry);
}
return true;
}
private:
@ -1285,8 +1279,7 @@ public:
void Suspect(void* aPtr, nsCycleCollectionParticipant* aCp,
nsCycleCollectingAutoRefCnt* aRefCnt);
uint32_t SuspectedCount();
void ForgetSkippable(js::SliceBudget& aBudget, bool aRemoveChildlessNodes,
bool aAsyncSnowWhiteFreeing);
void ForgetSkippable(bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing);
bool FreeSnowWhite(bool aUntilNoSWInPurpleBuffer);
// This method assumes its argument is already canonicalized.
@ -2653,7 +2646,7 @@ public:
}
}
bool
void
Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
{
MOZ_ASSERT(aEntry->mObject, "Null object in purple buffer");
@ -2665,7 +2658,6 @@ public:
mObjects.InfallibleAppend(swo);
aBuffer.Remove(aEntry);
}
return true;
}
bool HasSnowWhiteObjects() const
@ -2738,12 +2730,10 @@ class RemoveSkippableVisitor : public SnowWhiteKiller
{
public:
RemoveSkippableVisitor(nsCycleCollector* aCollector,
js::SliceBudget& aBudget,
bool aRemoveChildlessNodes,
bool aAsyncSnowWhiteFreeing,
CC_ForgetSkippableCallback aCb)
: SnowWhiteKiller(aCollector)
, mBudget(aBudget)
, mRemoveChildlessNodes(aRemoveChildlessNodes)
, mAsyncSnowWhiteFreeing(aAsyncSnowWhiteFreeing)
, mDispatchedDeferredDeletion(false)
@ -2764,17 +2754,9 @@ public:
}
}
bool
void
Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
{
if (mBudget.isOverBudget()) {
return false;
}
// CanSkip calls can be a bit slow, so increase the likelihood that
// isOverBudget actually checks whether we're over the time budget.
mBudget.step(5);
MOZ_ASSERT(aEntry->mObject, "null mObject in purple buffer");
if (!aEntry->mRefCnt->get()) {
if (!mAsyncSnowWhiteFreeing) {
@ -2783,21 +2765,19 @@ public:
mDispatchedDeferredDeletion = true;
nsCycleCollector_dispatchDeferredDeletion(false);
}
return true;
return;
}
void* o = aEntry->mObject;
nsCycleCollectionParticipant* cp = aEntry->mParticipant;
ToParticipant(o, &cp);
if (aEntry->mRefCnt->IsPurple() && !cp->CanSkip(o, false) &&
(!mRemoveChildlessNodes || MayHaveChild(o, cp))) {
return true;
return;
}
aBuffer.Remove(aEntry);
return true;
}
private:
js::SliceBudget& mBudget;
bool mRemoveChildlessNodes;
bool mAsyncSnowWhiteFreeing;
bool mDispatchedDeferredDeletion;
@ -2806,12 +2786,11 @@ private:
void
nsPurpleBuffer::RemoveSkippable(nsCycleCollector* aCollector,
js::SliceBudget& aBudget,
bool aRemoveChildlessNodes,
bool aAsyncSnowWhiteFreeing,
CC_ForgetSkippableCallback aCb)
{
RemoveSkippableVisitor visitor(aCollector, aBudget, aRemoveChildlessNodes,
RemoveSkippableVisitor visitor(aCollector, aRemoveChildlessNodes,
aAsyncSnowWhiteFreeing, aCb);
VisitEntries(visitor);
}
@ -2842,8 +2821,7 @@ nsCycleCollector::FreeSnowWhite(bool aUntilNoSWInPurpleBuffer)
}
void
nsCycleCollector::ForgetSkippable(js::SliceBudget& aBudget,
bool aRemoveChildlessNodes,
nsCycleCollector::ForgetSkippable(bool aRemoveChildlessNodes,
bool aAsyncSnowWhiteFreeing)
{
CheckThreadSafety();
@ -2867,7 +2845,7 @@ nsCycleCollector::ForgetSkippable(js::SliceBudget& aBudget,
}
MOZ_ASSERT(!mScanInProgress,
"Don't forget skippable or free snow-white while scan is in progress.");
mPurpleBuf.RemoveSkippable(this, aBudget, aRemoveChildlessNodes,
mPurpleBuf.RemoveSkippable(this, aRemoveChildlessNodes,
aAsyncSnowWhiteFreeing, mForgetSkippableCB);
}
@ -2989,7 +2967,7 @@ public:
{
}
bool
void
Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
{
MOZ_ASSERT(aEntry->mObject,
@ -3003,17 +2981,16 @@ public:
PtrInfo* pi = mGraph.FindNode(obj);
if (!pi) {
return true;
return;
}
MOZ_ASSERT(pi->mParticipant, "No dead objects should be in the purple buffer.");
if (MOZ_UNLIKELY(mLogger)) {
mLogger->NoteIncrementalRoot((uint64_t)pi->mPointer);
}
if (pi->mColor == black) {
return true;
return;
}
FloodBlackNode(mCount, mFailed, pi);
return true;
}
private:
@ -4069,8 +4046,7 @@ nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB)
}
void
nsCycleCollector_forgetSkippable(js::SliceBudget& aBudget,
bool aRemoveChildlessNodes,
nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes,
bool aAsyncSnowWhiteFreeing)
{
CollectorData* data = sCollectorData.get();
@ -4083,8 +4059,7 @@ nsCycleCollector_forgetSkippable(js::SliceBudget& aBudget,
js::ProfileEntry::Category::CC);
TimeLog timeLog;
data->mCollector->ForgetSkippable(aBudget,
aRemoveChildlessNodes,
data->mCollector->ForgetSkippable(aRemoveChildlessNodes,
aAsyncSnowWhiteFreeing);
timeLog.Checkpoint("ForgetSkippable()");
}

View file

@ -30,8 +30,7 @@ void nsCycleCollector_setBeforeUnlinkCallback(CC_BeforeUnlinkCallback aCB);
typedef void (*CC_ForgetSkippableCallback)(void);
void nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB);
void nsCycleCollector_forgetSkippable(js::SliceBudget& aBudget,
bool aRemoveChildlessNodes = false,
void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false,
bool aAsyncSnowWhiteFreeing = false);
void nsCycleCollector_prepareForGarbageCollection();