mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-17 01:34:21 +00:00
Updates from review by nb <https://info.ravenbrook.com/mail/2016/03/21/18-36-14/0/>.
Copied from Perforce Change: 190304 ServerID: perforce.ravenbrook.com
This commit is contained in:
commit
6250eecb4e
3 changed files with 63 additions and 10 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue