1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-26 08:41:47 -07:00

Tidying up naming of write barrier deferral.

Copied from Perforce
 Change: 189960
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2016-03-13 13:26:24 +00:00
parent 0b3c65766e
commit 83fc7866c9
4 changed files with 46 additions and 28 deletions

View file

@ -659,20 +659,32 @@
{ 36 * 1024, 0.45 } /* second gen, after which dynamic */ \
}
/* Experimental Scan Barrier threshold
/* Write barrier deferral
*
* Defer using the write barrier for the remembered set until a number
* of unnecessary scans have been performed on a segment. Avoids
* memory protection costs when scanning might be cheaper. See job003975.
*
* TODO: These settings were determined by trial and error, but should
* be based on measurement of the protection overhead on each
* platform. We know it's extremely different between OS X and
* Windows, for example.
*
* TODO: Consider basing the count on the amount of time that has
* passed in the mutator rather than the number of scans.
*/
/* Number of bits needed to keep the seg scan count */
#define SEG_SCANS_BITS 10
/* Number of bits needed to keep the write barrier deferral count */
#define WB_DEFER_BITS 3
/* The number of unecessary scans performed, before raising the write
* barrier to remember the refset summary. */
#define SEG_SCANS_INIT 3
barrier to maintian the remembered set. */
#define WB_DEFER_INIT 3
/* The number of unecessary scans performed, before raising the write
* barrier to remember the refset summary, after a necessary scan */
#define SEG_SCANS_AFTER_NEEDED_SCAN 3
barrier to remember the refset summary, after a necessary scan */
#define WB_DEFER_DELAY WB_DEFER_INIT
/* The number of unecessary scans performed, before raising the write
* barrier to remember the refset summary, after a barrier hit */
#define SEG_SCANS_AFTER_HIT 1
#define WB_DEFER_AFTER_HIT 1
#endif /* config_h */

View file

@ -281,7 +281,7 @@ typedef struct SegStruct { /* segment structure */
TraceSet white : TraceLIMIT; /* traces for which seg is white */
TraceSet nailed : TraceLIMIT; /* traces for which seg has nailed objects */
RankSet rankSet : RankLIMIT; /* ranks of references in this seg */
unsigned scans : SEG_SCANS_BITS; /* use write barrier after this many scans */
Count defer : WB_DEFER_BITS; /* defer write barrier for this many scans */
} SegStruct;

View file

@ -160,7 +160,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size,
seg->grey = TraceSetEMPTY;
seg->pm = AccessSetEMPTY;
seg->sm = AccessSetEMPTY;
seg->scans = SEG_SCANS_INIT;
seg->defer = WB_DEFER_INIT;
seg->depth = 0;
seg->firstTract = NULL;

View file

@ -1089,6 +1089,7 @@ static Res traceScanSegRes(TraceSet ts, Rank rank, Arena arena, Seg seg)
Bool wasTotal;
ZoneSet white;
Res res;
RefSet summary;
/* The reason for scanning a segment is that it's grey. */
AVER(TraceSetInter(ts, SegGrey(seg)) != TraceSetEMPTY);
@ -1134,28 +1135,33 @@ static Res traceScanSegRes(TraceSet ts, Rank rank, Arena arena, Seg seg)
* scan, consistent with the recorded SegSummary?
*/
AVER(RefSetSub(ScanStateUnfixedSummary(ss), SegSummary(seg)));
/* Remembered set and write barrier */
/* Was the scan necessary? Did the segment refer to the white set */
if (ZoneSetInter(ScanStateUnfixedSummary(ss), white) == ZoneSetEMPTY) {
/* a scan was not necessary */
if (seg->scans > 0)
seg->scans--;
if (seg->defer > 0)
--seg->defer;
} else {
if (seg->scans < SEG_SCANS_AFTER_NEEDED_SCAN)
seg->scans = SEG_SCANS_AFTER_NEEDED_SCAN;
if (seg->defer < WB_DEFER_DELAY)
seg->defer = WB_DEFER_DELAY;
}
if (seg->scans == 0) {
if(res != ResOK || !wasTotal) {
/* scan was partial, so... */
/* scanned summary should be ORed into segment summary. */
SegSetSummary(seg, RefSetUnion(SegSummary(seg), ScanStateSummary(ss)));
} else {
/* all objects on segment have been scanned, so... */
/* scanned summary should replace the segment summary. */
SegSetSummary(seg, ScanStateSummary(ss));
}
/* Only apply the write barrier if it is not deferred. */
/* TODO: This discards information we collected during
scanning. Consider keeping the summary but changing the
invariant on shielding instead. */
if (seg->defer == 0) {
/* If we scanned every reference in the segment then we have a
complete summary we can set. Otherwise, we just have
information about more zones that the segment refers to. */
if (res == ResOK && wasTotal)
summary = ScanStateSummary(ss);
else
summary = RefSetUnion(SegSummary(seg), ScanStateSummary(ss));
} else {
SegSetSummary(seg, RefSetUNIV);
summary = RefSetUNIV;
}
SegSetSummary(seg, summary);
ScanStateFinish(ss);
}
@ -1215,7 +1221,7 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode)
EVENT3(TraceAccess, arena, seg, mode);
if ((mode & SegSM(seg) & AccessWRITE) != 0) /* write barrier? */
seg->scans = SEG_SCANS_AFTER_HIT;
seg->defer = WB_DEFER_AFTER_HIT;
if((mode & SegSM(seg) & AccessREAD) != 0) { /* read barrier? */
Trace trace;