mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-18 20:00:36 -08:00
Added more control over write barrier. in particular separated scans after a hit.
Copied from Perforce Change: 186988 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
46d723c9dc
commit
b4460043e6
4 changed files with 21 additions and 13 deletions
|
|
@ -637,10 +637,18 @@
|
|||
|
||||
/* Experimental Scan Barrier threshold
|
||||
*
|
||||
* The number of unecessary scans performed, before raising the write
|
||||
* barrier to remember the refset summary.
|
||||
*/
|
||||
#define TRACE_SCAN_BARRIER_THRESHOLD 3
|
||||
/* Number of bits needed to keep the seg scan count */
|
||||
#define SEG_SCANS_BITS 10
|
||||
/* The number of unecessary scans performed, before raising the write
|
||||
* barrier to remember the refset summary. */
|
||||
#define SEG_SCANS_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
|
||||
/* 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
|
||||
|
||||
#endif /* config_h */
|
||||
|
||||
|
|
|
|||
|
|
@ -285,6 +285,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 */
|
||||
} SegStruct;
|
||||
|
||||
|
||||
|
|
@ -300,7 +301,6 @@ typedef struct GCSegStruct { /* GC segment structure */
|
|||
RingStruct greyRing; /* link in list of grey segs */
|
||||
RefSet summary; /* summary of references out of seg */
|
||||
Buffer buffer; /* non-NULL if seg is buffered */
|
||||
unsigned unnecessaryScans; /* consecutive unnecessary scans performed */
|
||||
Sig sig; /* <design/sig/> */
|
||||
} GCSegStruct;
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +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->depth = 0;
|
||||
seg->firstTract = NULL;
|
||||
|
||||
|
|
@ -1082,7 +1083,6 @@ static Res gcSegInit(Seg seg, Pool pool, Addr base, Size size,
|
|||
|
||||
gcseg->summary = RefSetEMPTY;
|
||||
gcseg->buffer = NULL;
|
||||
gcseg->unnecessaryScans = 0;
|
||||
RingInit(&gcseg->greyRing);
|
||||
gcseg->sig = GCSegSig;
|
||||
|
||||
|
|
|
|||
|
|
@ -1105,7 +1105,6 @@ static Res traceScanSegRes(TraceSet ts, Rank rank, Arena arena, Seg seg)
|
|||
} else { /* scan it */
|
||||
ScanStateStruct ssStruct;
|
||||
ScanState ss = &ssStruct;
|
||||
Bool considerBarrier = FALSE;
|
||||
ScanStateInit(ss, ts, arena, rank, white);
|
||||
|
||||
/* Expose the segment to make sure we can scan it. */
|
||||
|
|
@ -1138,16 +1137,14 @@ static Res traceScanSegRes(TraceSet ts, Rank rank, Arena arena, Seg seg)
|
|||
AVER(RefSetSub(ScanStateUnfixedSummary(ss), SegSummary(seg)));
|
||||
if (ZoneSetInter(ScanStateUnfixedSummary(ss), white) == ZoneSetEMPTY) {
|
||||
/* a scan was not necessary */
|
||||
if (((GCSeg)seg)->unnecessaryScans < TRACE_SCAN_BARRIER_THRESHOLD) {
|
||||
((GCSeg)seg)->unnecessaryScans++;
|
||||
} else {
|
||||
considerBarrier = TRUE;
|
||||
}
|
||||
if (seg->scans > 0)
|
||||
seg->scans--;
|
||||
} else {
|
||||
((GCSeg)seg)->unnecessaryScans = 0;
|
||||
if (seg->scans < SEG_SCANS_AFTER_NEEDED_SCAN)
|
||||
seg->scans = SEG_SCANS_AFTER_NEEDED_SCAN;
|
||||
}
|
||||
|
||||
if (considerBarrier) {
|
||||
if (seg->scans == 0) {
|
||||
if(res != ResOK || !wasTotal) {
|
||||
/* scan was partial, so... */
|
||||
/* scanned summary should be ORed into segment summary. */
|
||||
|
|
@ -1217,6 +1214,9 @@ 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;
|
||||
|
||||
if((mode & SegSM(seg) & AccessREAD) != 0) { /* read barrier? */
|
||||
Trace trace;
|
||||
TraceId ti;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue