diff --git a/mps/src/trace.c b/mps/src/trace.c index 14da1f4b3e1..1b688a53293 100644 --- a/mps/src/trace.c +++ b/mps/src/trace.c @@ -1,12 +1,12 @@ /* impl.c.trace: GENERIC TRACER IMPLEMENTATION * - * $HopeName: MMsrc!trace.c(trunk.41) $ + * $HopeName: MMsrc!trace.c(trunk.42) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. */ #include "mpm.h" -SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.41) $"); +SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.42) $"); /* ScanStateCheck -- check consistency of a ScanState object */ @@ -587,8 +587,9 @@ static Res TraceScan(TraceSet ts, Rank rank, Arena arena, Seg seg) { Res res; - ScanStateStruct ss; TraceId ti; + RefSet white; + ScanStateStruct ss; AVER(TraceSetCheck(ts)); AVER(RankCheck(rank)); @@ -598,48 +599,53 @@ static Res TraceScan(TraceSet ts, Rank rank, AVER(TraceSetInter(ts, SegGrey(seg)) != TraceSetEMPTY); EVENT_UUPPP(TraceScan, ts, rank, arena, seg, &ss); - ss.rank = rank; - ss.traces = ts; - ss.fix = TraceFix; - ss.zoneShift = arena->zoneShift; - ss.unfixedSummary = RefSetEMPTY; - ss.fixedSummary = RefSetEMPTY; - ss.arena = arena; - ss.wasMarked = TRUE; - ss.white = RefSetEMPTY; + white = RefSetEMPTY; for(ti = 0; ti < TRACE_MAX; ++ti) - if(TraceSetIsMember(ss.traces, ti)) - ss.white = RefSetUnion(ss.white, ArenaTrace(arena, ti)->white); - ss.sig = ScanStateSig; - AVERT(ScanState, &ss); + if(TraceSetIsMember(ts, ti)) + white = RefSetUnion(white, ArenaTrace(arena, ti)->white); - /* Expose the segment to make sure we can scan it. */ - ShieldExpose(arena, seg); + /* only scan a segment if it refers to the white set */ + if (RefSetInter(white, SegSummary(seg)) != RefSetEMPTY) { + ss.rank = rank; + ss.traces = ts; + ss.fix = TraceFix; + ss.zoneShift = arena->zoneShift; + ss.unfixedSummary = RefSetEMPTY; + ss.fixedSummary = RefSetEMPTY; + ss.arena = arena; + ss.wasMarked = TRUE; + ss.white = white; + ss.sig = ScanStateSig; + AVERT(ScanState, &ss); + + /* Expose the segment to make sure we can scan it. */ + ShieldExpose(arena, seg); + + res = PoolScan(&ss, SegPool(seg), seg); - res = PoolScan(&ss, SegPool(seg), seg); - if(res != ResOK) - goto failScan; + if(res != ResOK) { + ShieldCover(arena, seg); + return res; + } + + /* Cover the segment again, now it's been scanned. */ + ShieldCover(arena, seg); - /* See design.mps.scan.summary.subset. */ - AVER(RefSetSub(ss.unfixedSummary, SegSummary(seg))); - - /* All objects on the segment have been scanned, so the scanned */ - /* summary should replace the segment summary. */ - SegSetSummary(seg, ScanStateSummary(&ss)); - - ss.sig = SigInvalid; /* just in case */ + /* See design.mps.scan.summary.subset. */ + AVER(RefSetSub(ss.unfixedSummary, SegSummary(seg))); + + /* All objects on the segment have been scanned, so the scanned */ + /* summary should replace the segment summary. */ + SegSetSummary(seg, ScanStateSummary(&ss)); + + ss.sig = SigInvalid; /* just in case */ + } /* The segment has been scanned, so remove the greyness from it. */ SegSetGrey(seg, TraceSetDiff(SegGrey(seg), ts)); - /* Cover the segment again, now it's been scanned. */ - ShieldCover(arena, seg); - return ResOK; -failScan: - ShieldCover(arena, seg); - return res; }