author | Jon Coppeard <jcoppeard@mozilla.com> |
Tue, 22 Nov 2016 10:32:11 +0000 | |
changeset 371075 | 45b2377336150fcbe2a477e1719b0059956c5b5d |
parent 371074 | fdc0f9d0f338042f35c0d8d56555801b63a277da |
child 371076 | e453f2aaef941b6516ff8852282741369771c7ad |
push id | 1419 |
push user | jlund@mozilla.com |
push date | Mon, 10 Apr 2017 20:44:07 +0000 |
treeherder | mozilla-release@5e6801b73ef6 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | billm |
bugs | 1318384 |
milestone | 53.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/gc/GCRuntime.h | file | annotate | diff | comparison | revisions | |
js/src/jsgc.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsgc.h | file | annotate | diff | comparison | revisions |
--- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -942,32 +942,33 @@ class GCRuntime friend class BackgroundAllocTask; friend class AutoMaybeStartBackgroundAllocation; bool wantBackgroundAllocation(const AutoLockGC& lock) const; void startBackgroundAllocTaskIfIdle(); void requestMajorGC(JS::gcreason::Reason reason); SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis); - void budgetIncrementalGC(SliceBudget& budget, AutoLockForExclusiveAccess& lock); + void budgetIncrementalGC(JS::gcreason::Reason reason, SliceBudget& budget, + AutoLockForExclusiveAccess& lock); void resetIncrementalGC(AbortReason reason, AutoLockForExclusiveAccess& lock); // Assert if the system state is such that we should never // receive a request to do GC work. void checkCanCallAPI(); // Check if the system state is such that GC has been supressed // or otherwise delayed. MOZ_MUST_USE bool checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason); gcstats::ZoneGCStats scanZonesBeforeGC(); void collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::Reason reason) JS_HAZ_GC_CALL; MOZ_MUST_USE bool gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::Reason reason); - bool shouldRepeatForDeadZone(); + bool shouldRepeatForDeadZone(JS::gcreason::Reason reason); void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason, AutoLockForExclusiveAccess& lock); void pushZealSelectedObjects(); void purgeRuntime(AutoLockForExclusiveAccess& lock); MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, AutoLockForExclusiveAccess& lock); bool shouldPreserveJITCode(JSCompartment* comp, int64_t currentTime, JS::gcreason::Reason reason);
--- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -5999,33 +5999,34 @@ gc::IsIncrementalGCUnsafe(JSRuntime* rt) if (!rt->gc.isIncrementalGCAllowed()) return gc::AbortReason::IncrementalDisabled; return gc::AbortReason::None; } void -GCRuntime::budgetIncrementalGC(SliceBudget& budget, AutoLockForExclusiveAccess& lock) +GCRuntime::budgetIncrementalGC(JS::gcreason::Reason reason, SliceBudget& budget, + AutoLockForExclusiveAccess& lock) { AbortReason unsafeReason = IsIncrementalGCUnsafe(rt); + if (unsafeReason == AbortReason::None) { + if (reason == JS::gcreason::COMPARTMENT_REVIVED) + unsafeReason = gc::AbortReason::CompartmentRevived; + else if (mode != JSGC_MODE_INCREMENTAL) + unsafeReason = gc::AbortReason::ModeChange; + } + if (unsafeReason != AbortReason::None) { resetIncrementalGC(unsafeReason, lock); budget.makeUnlimited(); stats.nonincremental(unsafeReason); return; } - if (mode != JSGC_MODE_INCREMENTAL) { - resetIncrementalGC(AbortReason::ModeChange, lock); - budget.makeUnlimited(); - stats.nonincremental(AbortReason::ModeChange); - return; - } - if (isTooMuchMalloc()) { budget.makeUnlimited(); stats.nonincremental(AbortReason::MallocBytesTrigger); } bool reset = false; for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { if (zone->usage.gcBytes() >= zone->threshold.gcTriggerBytes()) { @@ -6173,17 +6174,17 @@ GCRuntime::gcCycle(bool nonincrementalBy // the caller expects this GC to collect certain objects, and we need // to make sure to collect everything possible. if (reason != JS::gcreason::ALLOC_TRIGGER) resetIncrementalGC(gc::AbortReason::NonIncrementalRequested, session.lock); stats.nonincremental(gc::AbortReason::NonIncrementalRequested); budget.makeUnlimited(); } else { - budgetIncrementalGC(budget, session.lock); + budgetIncrementalGC(reason, budget, session.lock); } /* The GC was reset, so we need a do-over. */ if (prevState != State::NotActive && !isIncrementalGCInProgress()) return true; TraceMajorGCStart(); @@ -6293,18 +6294,20 @@ GCRuntime::checkIfGCAllowedInCurrentStat if (deterministicOnly && !IsDeterministicGCReason(reason)) return false; #endif return true; } bool -GCRuntime::shouldRepeatForDeadZone() -{ +GCRuntime::shouldRepeatForDeadZone(JS::gcreason::Reason reason) +{ + MOZ_ASSERT_IF(reason == JS::gcreason::COMPARTMENT_REVIVED, !isIncremental); + if (!isIncremental || isIncrementalGCInProgress()) return false; for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) { if (c->scheduledForDestruction) return true; } @@ -6340,25 +6343,24 @@ GCRuntime::collect(bool nonincrementalBy do { poked = false; bool wasReset = gcCycle(nonincrementalByAPI, budget, reason); bool repeatForDeadZone = false; if (poked && cleanUpEverything) { /* Need to re-schedule all zones for GC. */ JS::PrepareForFullGC(rt->contextFromMainThread()); - } else if (shouldRepeatForDeadZone() && !wasReset) { + } else if (shouldRepeatForDeadZone(reason) && !wasReset) { /* * This code makes an extra effort to collect compartments that we * thought were dead at the start of the GC. See the large comment * in beginMarkPhase. */ repeatForDeadZone = true; reason = JS::gcreason::COMPARTMENT_REVIVED; - nonincrementalByAPI = true; } /* * If we reset an existing GC, we need to start a new one. Also, we * repeat GCs that happen during shutdown (the gcShouldCleanUpEverything * case) until we can be sure that no additional garbage is created * (which typically happens if roots are dropped during finalizers). */
--- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -55,17 +55,18 @@ enum class State { D(None) \ D(NonIncrementalRequested) \ D(AbortRequested) \ D(KeepAtomsSet) \ D(IncrementalDisabled) \ D(ModeChange) \ D(MallocBytesTrigger) \ D(GCBytesTrigger) \ - D(ZoneChange) + D(ZoneChange) \ + D(CompartmentRevived) enum class AbortReason { #define MAKE_REASON(name) name, GC_ABORT_REASONS(MAKE_REASON) #undef MAKE_REASON }; /* * Map from C++ type to alloc kind for non-object types. JSObject does not have