From ed8cd9432d6200bbd8e4f833fcd7b18e9f2af18c Mon Sep 17 00:00:00 2001 From: David Lovemore Date: Thu, 30 Aug 2012 13:48:41 +0100 Subject: In tracescanareatagged use the alignments of pools in the condemned set to determine mask. Copied from Perforce Change: 179117 ServerID: perforce.ravenbrook.com --- mps/code/trace.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'mps/code/trace.c') diff --git a/mps/code/trace.c b/mps/code/trace.c index a12800d4dd9..0f8d84ba3ac 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -138,6 +138,7 @@ Bool TraceCheck(Trace trace) CHECKL(TraceIdCheck(trace->ti)); CHECKL(trace == &trace->arena->trace[trace->ti]); CHECKL(TraceSetIsMember(trace->arena->busyTraces, trace)); + CHECKL(AlignCheck(trace->whiteMinAlign)); CHECKL(ZoneSetSub(trace->mayMove, trace->white)); /* Use trace->state to check more invariants. */ switch(trace->state) { @@ -367,6 +368,10 @@ Res TraceAddWhite(Trace trace, Seg seg) trace->mayMove = ZoneSetUnion(trace->mayMove, ZoneSetOfSeg(trace->arena, seg)); } + /* This is used to eliminate unaligned references in TraceScanAreaTagged */ + if(pool->alignment < trace->whiteMinAlign) { + trace->whiteMinAlign = pool->alignment; + } } return ResOK; @@ -656,6 +661,7 @@ found: trace->arena = arena; trace->why = why; + trace->whiteMinAlign = (Align)1 << (MPS_WORD_WIDTH - 1); trace->white = ZoneSetEMPTY; trace->mayMove = ZoneSetEMPTY; trace->ti = ti; @@ -1402,13 +1408,37 @@ Res TraceScanArea(ScanState ss, Addr *base, Addr *limit) /* TraceScanAreaTagged -- scan contiguous area of tagged references * - * This is as TraceScanArea except words are only fixed if they are - * tagged as Dylan references (i.e., bottom two bits are zero). @@@@ - * This Dylan-specificness should be generalized in some way. */ - + * This is as TraceScanArea except words are only fixed they are tagged + * as zero according to the minimum alignment of the condemned set. + */ Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit) { - return TraceScanAreaMasked(ss, base, limit, (Word)3); + TraceSet ts; + TraceId ti; + Trace trace; + Arena arena; + Word mask; + + AVERT(ScanState, ss); + + /* This calculation of the mask could be moved to ScanStateInit + * but there is little point as we probably only do a couple of ambiguous + * scan per thread per flip. */ + /* NOTE: An optimisation that maybe worth considering is setting some of the + * top bits in the mask as an early catch of addresses outside the arena. + * This might help slightly on 64-bit windows. However these are picked up + * soon afterwards by later checks. The bottom bits are more important + * to check as we ignore them in AMCFix, so the non-reference could + * otherwise end up pinning an object. */ + mask = (Word)-1; + ts = ss->traces; + arena = ss->arena; + TRACE_SET_ITER(ti, trace, ts, arena) + AVER(WordIsP2(trace->whiteMinAlign)); + mask = mask & (trace->whiteMinAlign - 1); + TRACE_SET_ITER_END(ti, trace, ts, arena); + + return TraceScanAreaMasked(ss, base, limit, mask); } @@ -1423,6 +1453,7 @@ Res TraceScanAreaMasked(ScanState ss, Addr *base, Addr *limit, Word mask) Addr *p; Ref ref; + AVERT(ScanState, ss); AVER(base != NULL); AVER(limit != NULL); AVER(base < limit); -- cgit v1.2.1