Bug 773755 - don't force a cycle collection with 0 suspected objects, r=mccr8

This commit is contained in:
Olli Pettay 2012-07-15 13:30:39 +03:00
Родитель 337061262c
Коммит 557617a764
1 изменённых файлов: 31 добавлений и 31 удалений

Просмотреть файл

@ -115,14 +115,16 @@ static PRLogModuleInfo* gJSDiagnostics;
#define NS_CC_SKIPPABLE_DELAY 400 // ms
// Force a CC after this long if there's anything in the purple buffer.
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
// objects in the purple buffer.
#define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
#define NS_CC_FORCED_PURPLE_LIMIT 10
// Don't allow an incremental GC to lock out the CC for too long.
#define NS_MAX_CC_LOCKEDOUT_TIME (5 * PR_USEC_PER_SEC) // 5 seconds
// Trigger a CC if the purple buffer exceeds this size when we check it.
#define NS_CC_PURPLE_LIMIT 250
#define NS_CC_PURPLE_LIMIT 200
#define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
@ -3005,6 +3007,25 @@ DoMergingCC(bool aForced)
}
static void
FireForgetSkippable(PRUint32 aSuspected, bool aRemoveChildless)
{
PRTime startTime = PR_Now();
nsCycleCollector_forgetSkippable(aRemoveChildless);
sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
++sCleanupsSinceLastGC;
PRTime delta = PR_Now() - startTime;
if (sMinForgetSkippableTime > delta) {
sMinForgetSkippableTime = delta;
}
if (sMaxForgetSkippableTime < delta) {
sMaxForgetSkippableTime = delta;
}
sTotalForgetSkippableTime += delta;
sRemovedPurples += (aSuspected - sPreviousSuspectedCount);
++sForgetSkippableBeforeCC;
}
//static
void
nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
@ -3031,14 +3052,13 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
// nsCycleCollector_forgetSkippable may mark some gray js to black.
if (sCleanupsSinceLastGC < 2 && aExtraForgetSkippableCalls >= 0) {
for (;sCleanupsSinceLastGC < 2; ++sCleanupsSinceLastGC) {
nsCycleCollector_forgetSkippable();
while (sCleanupsSinceLastGC < 2) {
FireForgetSkippable(nsCycleCollector_suspectedCount(), false);
}
}
for (PRInt32 i = 0; i < aExtraForgetSkippableCalls; ++i) {
nsCycleCollector_forgetSkippable();
++sCleanupsSinceLastGC;
FireForgetSkippable(nsCycleCollector_suspectedCount(), false);
}
bool mergingCC = DoMergingCC(aForced);
@ -3183,26 +3203,8 @@ ShouldTriggerCC(PRUint32 aSuspected)
{
return sNeedsFullCC ||
aSuspected > NS_CC_PURPLE_LIMIT ||
sLastCCEndTime + NS_CC_FORCED < PR_Now();
}
static void
TimerFireForgetSkippable(PRUint32 aSuspected, bool aRemoveChildless)
{
PRTime startTime = PR_Now();
nsCycleCollector_forgetSkippable(aRemoveChildless);
sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
++sCleanupsSinceLastGC;
PRTime delta = PR_Now() - startTime;
if (sMinForgetSkippableTime > delta) {
sMinForgetSkippableTime = delta;
}
if (sMaxForgetSkippableTime < delta) {
sMaxForgetSkippableTime = delta;
}
sTotalForgetSkippableTime += delta;
sRemovedPurples += (aSuspected - sPreviousSuspectedCount);
++sForgetSkippableBeforeCC;
(aSuspected > NS_CC_FORCED_PURPLE_LIMIT &&
sLastCCEndTime + NS_CC_FORCED < PR_Now());
}
static void
@ -3236,7 +3238,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
PRUint32 suspected = nsCycleCollector_suspectedCount();
if (isLateTimerFire && ShouldTriggerCC(suspected)) {
if (sCCTimerFireCount == numEarlyTimerFires + 1) {
TimerFireForgetSkippable(suspected, true);
FireForgetSkippable(suspected, true);
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
// Our efforts to avoid a CC have failed, so we return to let the
// timer fire once more to trigger a CC.
@ -3249,7 +3251,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
}
} else if ((sPreviousSuspectedCount + 100) <= suspected) {
// Only do a forget skippable if there are more than a few new objects.
TimerFireForgetSkippable(suspected, false);
FireForgetSkippable(suspected, false);
}
if (isLateTimerFire) {
@ -3351,9 +3353,7 @@ nsJSContext::MaybePokeCC()
return;
}
if (sNeedsFullCC ||
nsCycleCollector_suspectedCount() > 100 ||
sLastCCEndTime + NS_CC_FORCED < PR_Now()) {
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
sCCTimerFireCount = 0;
CallCreateInstance("@mozilla.org/timer;1", &sCCTimer);
if (!sCCTimer) {