diff --git a/mps/code/mpm.c b/mps/code/mpm.c index aba1ac2f5cb..882a46b7092 100644 --- a/mps/code/mpm.c +++ b/mps/code/mpm.c @@ -88,6 +88,11 @@ Bool MPMCheck(void) * . */ 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; } diff --git a/mps/design/write-barrier.txt b/mps/design/write-barrier.txt index affdaa49c5d..f2bd86c7e7d 100644 --- a/mps/design/write-barrier.txt +++ b/mps/design/write-barrier.txt @@ -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 diff --git a/mps/manual/source/topic/format.rst b/mps/manual/source/topic/format.rst index 7db5c8a1178..ec1f707aea3 100644 --- a/mps/manual/source/topic/format.rst +++ b/mps/manual/source/topic/format.rst @@ -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)