From d2439c4be7afb9bb809b95fd4b217cdb85f04b4a Mon Sep 17 00:00:00 2001
From: David Lovemore
Date: Thu, 21 Aug 2014 15:53:57 +0100
Subject: [PATCH] Added experimental control over write barrier eagerness.
The write barrier is only raised after three unnecessary scans.
Copied from Perforce
Change: 186975
ServerID: perforce.ravenbrook.com
---
mps/code/config.h | 6 ++++++
mps/code/mpmst.h | 1 +
mps/code/seg.c | 1 +
mps/code/trace.c | 13 ++++++++++++-
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/mps/code/config.h b/mps/code/config.h
index ac5d7a849ec..59a44ee3780 100644
--- a/mps/code/config.h
+++ b/mps/code/config.h
@@ -635,6 +635,12 @@
{ 36 * 1024, 0.45 } /* second gen, after which dynamic */ \
}
+/* 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
#endif /* config_h */
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h
index 219858f0f54..ba0be7aba58 100644
--- a/mps/code/mpmst.h
+++ b/mps/code/mpmst.h
@@ -300,6 +300,7 @@ 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; /* */
} GCSegStruct;
diff --git a/mps/code/seg.c b/mps/code/seg.c
index ef930071850..e5923c170f7 100644
--- a/mps/code/seg.c
+++ b/mps/code/seg.c
@@ -1082,6 +1082,7 @@ 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;
diff --git a/mps/code/trace.c b/mps/code/trace.c
index 4f5b1477d81..bbe09b2d2c6 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.c
@@ -1105,6 +1105,7 @@ 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. */
@@ -1135,8 +1136,18 @@ static Res traceScanSegRes(TraceSet ts, Rank rank, Arena arena, Seg seg)
* scan, consistent with the recorded SegSummary?
*/
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;
+ }
+ } else {
+ ((GCSeg)seg)->unnecessaryScans = 0;
+ }
- if (arena->incremental) {
+ if (considerBarrier) {
if(res != ResOK || !wasTotal) {
/* scan was partial, so... */
/* scanned summary should be ORed into segment summary. */