Closed Bug 936514 Opened 11 years ago Closed 11 years ago

GC: In source documentation on the collector needs updating

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla28

People

(Reporter: jonco, Assigned: jonco)

Details

Attachments

(1 file)

The documentation comment at the start of jsgc.cpp is pretty out of date, and could use expanding to cover full/zone GCs, incremental sweeping and incremental resets.
Also see bug 928378.
Attached patch gc-docSplinter Review
Here's some documentation for the file.
Attachment #8337706 - Flags: review?(wmccloskey)
Comment on attachment 8337706 [details] [diff] [review] gc-doc Review of attachment 8337706 [details] [diff] [review]: ----------------------------------------------------------------- Thanks, this is great! ::: js/src/jsgc.cpp @@ +32,5 @@ > + * - the collection must be run by calling js::GCSlice() rather than js::GC() > + * - the GC mode must have been set to JSGC_MODE_INCREMENTAL with > + * JS_SetGCParameter() > + * - no thread may have an AutoKeepAtoms instance on the stack > + * - there are no exclusive threads using the runtime I think we are able to do incremental GC if exclusive threads are present. @@ +34,5 @@ > + * JS_SetGCParameter() > + * - no thread may have an AutoKeepAtoms instance on the stack > + * - there are no exclusive threads using the runtime > + * - incremental GC must not have been disabled by calling > + * JS::DisableIncrementalGC() Looks like this function doesn't have any callers. Maybe you should mention the JSCLASS_IMPLEMENTS_BARRIERS thing though. That's internal to the engine. @@ +51,5 @@ > + * > + * The collector proceeds through the following states, the current state being > + * held in JSRuntime::gcIncrementalState: > + * > + * - MARK_ROOTS - marks all roots Maybe "marks the stack and other roots" @@ +75,5 @@ > + * > + * ... JS code runs ... > + * > + * Slice n: MARK: Mark stack is completely drained. > + * SWEEP: Sweeping is started and some sweeping done. How about "Select first group of zones to sweep and sweep them." @@ +79,5 @@ > + * SWEEP: Sweeping is started and some sweeping done. > + * > + * ... JS code runs ... > + * > + * Slice n+1: SWEEP: Sweep zone groups and continue marking unswept zones. "Mark objects in unswept zones that were newly identified as alive (see below). Then sweep more zone groups." @@ +100,3 @@ > * > + * Incremental collection requires close collaboration with the mutator (i.e., > + * JS code) to garantee correctness. The problem is that between slices the garantee @@ +107,5 @@ > + * We use a snapshot-at-the-beginning algorithm to do this. This means that we > + * promise to mark at least everything that is reachable at the beginning of > + * collection. To implement it we mark the old contents of every non-root memory > + * location written to by the mutator while the collection is in progress, using > + * write barriers. This is described in gc/Barrier.h. The old comment had more detail on write barriers. Can you include more of that, or merge them somehow? @@ +119,5 @@ > + * mutator code was allowed to run after the start of sweeping, it could observe > + * the state of the cache and create a new reference to an object that was just > + * about to be destroyed. > + * > + * Sweeping all finializable objects in one go would introduce long pauses, so finializable @@ +121,5 @@ > + * about to be destroyed. > + * > + * Sweeping all finializable objects in one go would introduce long pauses, so > + * instead sweeping broken up into groups of zones. Zones which are not yet > + * being swept are still marked, so the issue above does not apply. The order of It also might be easier to explain this with an example. Say that object |a| from zone A points to object |b| in zone B and neither object was marked when we transitioned to the SWEEP phase. Imagine we sweep B first and then return to the mutator. It's possible that the mutator could cause |a| to become alive through a read barrier (perhaps it was a shape that was accessed via a shape table). Then we would need to mark |b|, which |a| points to, but |b| has already been swept. @@ +141,5 @@ > + * that incremental collection is no longer possible. In this case, the collection > + * is 'reset' by ResetIncrementalGC(). If we are in the mark state, this just > + * stops marking, but if we have started sweeping already, we continue until we > + * have swept the current zone group. Following a reset, a new non-incremental > + * collection is started. Nowadays I think we reset only in extreme cases. Most of the time we just finish the GC in one last slice. Can you mention that?
Attachment #8337706 - Flags: review?(wmccloskey) → review+
Comment on attachment 8337706 [details] [diff] [review] gc-doc Review of attachment 8337706 [details] [diff] [review]: ----------------------------------------------------------------- Great! Naive questions that perhaps the comment could answer: ::: js/src/jsgc.cpp @@ +21,5 @@ > + * the runtime. > + * > + * It is possible for an incremental collection that started out as a full GC to > + * become a zone GC if new zones are created during the course of the > + * collection. Can a zone GC become a full GC (I thought maybe this happened sometimes on memory pressure...)? @@ +141,5 @@ > + * that incremental collection is no longer possible. In this case, the collection > + * is 'reset' by ResetIncrementalGC(). If we are in the mark state, this just > + * stops marking, but if we have started sweeping already, we continue until we > + * have swept the current zone group. Following a reset, a new non-incremental > + * collection is started. I'd be curious to hear what the extreme cases are. I'd also be curious to hear what the cases that cause us to finish the GC in one last slice are.
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla28
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: