Copied from Perforce
 Change: 190304
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2016-03-22 15:20:56 +00:00
commit 6250eecb4e
3 changed files with 63 additions and 10 deletions

View file

@ -88,6 +88,11 @@ Bool MPMCheck(void)
* <design/sp/#sol.depth.constraint>. */
CHECKL(StackProbeDEPTH * sizeof(Word) < PageSize());
/* Check these values will fit in their bitfield. */
CHECKL(WB_DEFER_INIT <= ((1ul << WB_DEFER_BITS) - 1));
CHECKL(WB_DEFER_DELAY <= ((1ul << WB_DEFER_BITS) - 1));
CHECKL(WB_DEFER_HIT <= ((1ul << WB_DEFER_BITS) - 1));
return TRUE;
}

View file

@ -33,6 +33,28 @@ a one-word "summary" of the zones referenced by a segment. That
summary can be compared with the "white set" of a trace by a simple
logical AND operation.
Write Barrier Processes
-----------------------
.scan.summary: As the MPS scans a segment during garbage collection,
it accumulates a summary of references. This summary is represented
by single word ``ZoneSet``, derived from the bit patterns of the
references. After the scan the MPS can decide to store the summary
with the segment, and use it in future garbage collections to avoid
future scans.
If the summary does not intersect any of the zones containing
condemned objects, the MPS does not have to scan them in order to
determine if those objects are live.
The mutator could update the references in a segment and make the
summary invalid. To avoid this, when the MPS stores a summary, it
raises a write barrier on the segment memory. If the mutator does
update the segment, the barrier is hit, and the MPS resets the
summary, so that the segment will be scanned in future.
[At this point I was interrupted by a man from Porlock.]
@ -42,20 +64,40 @@ Write barrier deferral
.deferral: Both scanning and the write barrier cost CPU time, and
these must be balanced. There is no point spending 1000 CPU units
raising a write barrier to avoid 10 CPU units of scanning cost.
Therefore we do not raise the write barrier immediately.
The MPS balances these costs with write barrier deferral. The write
barrier is not immediately raised when a segment is scanned. Instead,
we store a deferral count with the segment. Each time the segment is
"boring" scanned the count is decremented. A boring scan is one that
found no interesting references (to white objects). The write barrier
is raised only when the count reaches zero. The count is reset after
three events:
.deferral.heuristic: We apply a simple heuristic: A segment which was
found to be "interesting" while scanning is likely to be interesting
again, and so raising the write barrier is not worthwhile. If we scan
a segment several times and find it "boring" then we raise the barrier
to avoid future boring scans.
1. segment creation (``WB_DEFER_INIT``)
.def.boring: A scan is "boring" if it was unnecessary for a garbage
collection because it found no references to condemned objects.
2. an interesting scan (``WB_DEFER_DELAY``)
.def.interesting: A scan is "interesting" if it was not boring
(.def.boring). Note that this does not mean it preserved comdemned
objects, only that we would have scanned it even if we had had the
scan summary beforehand.
3. a barrier hit (``WB_DEFER_HIT``)
.deferral.count: We store a deferral count with the segment. The
count is decremented after each boring scan (.def.boring). The write
barrier is raised only when the count reaches zero.
.deferral.reset: The count is reset after three events:
1. segment creation (``WB_DEFER_INIT``)
2. an interesting scan (``WB_DEFER_DELAY``)
3. a barrier hit (``WB_DEFER_HIT``)
.deferral.dabble: The set of objects condemend by the garbage
collector changes, and so does what is interesting or boring. For
example, a collection of a nursery space in zone 3 might be followed
by a collection of a top generation in zone 7. This will upset
.deferral.heuristic somewhat. We assume that the garbage collector
will spend most of its time repeatedly collecting the same zones.
Improvements

View file

@ -368,6 +368,12 @@ Format methods
object format has a non-zero
:c:macro:`MPS_KEY_FMT_HEADER_SIZE`.
.. note::
The MPS will ask for padding objects of any size aligned to
the pool alignment, no matter what size objects the pool
holds. For example, a pool holding only two-word objects may
still be asked to create padding objects 2048 bytes long.
.. c:type:: mps_res_t (*mps_fmt_scan_t)(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)