diff --git a/mps/src/mpm.h b/mps/src/mpm.h index 680e7ff4748..8ab2864e818 100644 --- a/mps/src/mpm.h +++ b/mps/src/mpm.h @@ -1,6 +1,6 @@ /* impl.h.mpm: MEMORY POOL MANAGER DEFINITIONS * - * $HopeName: MMsrc!mpm.h(trunk.41) $ + * $HopeName: MMsrc!mpm.h(trunk.42) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. */ @@ -322,6 +322,8 @@ extern TraceSet (TraceSetUnion)(TraceSet ts1, TraceSet ts2); extern Bool (TraceSetIsMember)(TraceSet ts, TraceId id); extern Bool ScanStateCheck(ScanState ss); +extern void ScanStateSetSummary(ScanState ss, RefSet summary); +extern RefSet ScanStateSummary(ScanState ss); extern Bool TraceIdCheck(TraceId id); extern Bool TraceSetCheck(TraceSet ts); extern Bool TraceCheck(Trace trace); @@ -340,7 +342,7 @@ extern Size TraceGreyEstimate(Arena arena, RefSet refSet); BEGIN \ Shift SCANzoneShift = (ss)->zoneShift; \ RefSet SCANwhite = (ss)->white; \ - RefSet SCANsummary = (ss)->summary; \ + RefSet SCANsummary = (ss)->unfixedSummary; \ Word SCANt; \ { @@ -366,7 +368,7 @@ extern Size TraceGreyEstimate(Arena arena, RefSet refSet); #define TRACE_SCAN_END(ss) \ } \ - (ss)->summary = SCANsummary; \ + (ss)->unfixedSummary = SCANsummary; \ END extern Res TraceScanArea(ScanState ss, Addr *base, Addr *limit); diff --git a/mps/src/mpmst.h b/mps/src/mpmst.h index 1ffe75e7de4..bc8377197fd 100644 --- a/mps/src/mpmst.h +++ b/mps/src/mpmst.h @@ -1,6 +1,6 @@ /* impl.h.mpmst: MEMORY POOL MANAGER DATA STRUCTURES * - * $HopeName: MMsrc!mpmst.h(trunk.31) $ + * $HopeName: MMsrc!mpmst.h(trunk.32) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. * * .readership: MM developers. @@ -412,7 +412,7 @@ typedef struct RootStruct { * ss->fix mps_ss->fix * ss->zoneShift mps_ss->w0 * ss->white mps_ss->w1 - * ss->summary mps_ss->w2 + * ss->unfixedSummary mps_ss->w2 * See impl.h.mps.ss and impl.c.mpsi.check.ss. This is why the * Sig field is in the middle of this structure. * @@ -426,13 +426,13 @@ typedef struct ScanStateStruct { Res (*fix)(ScanState, Addr *);/* fix function */ Word zoneShift; /* copy of arena->zoneShift. See .ss.zone */ RefSet white; /* white set, for inline fix test */ - RefSet summary; /* accumulated summary of scanned references */ + RefSet unfixedSummary; /* accumulated summary of scanned references */ Sig sig; /* design.mps.sig */ Arena arena; /* owning arena */ TraceSet traces; /* traces to scan for */ Rank rank; /* reference rank of scanning */ Bool wasMarked; /* design.mps.fix.protocol.was-ready */ - RefSet fixed; /* accumulated summary of fixed references */ + RefSet fixedSummary; /* accumulated summary of fixed references */ } ScanStateStruct; diff --git a/mps/src/mpsi.c b/mps/src/mpsi.c index a47a36c430d..2a7ff1de2b4 100644 --- a/mps/src/mpsi.c +++ b/mps/src/mpsi.c @@ -1,6 +1,6 @@ /* impl.c.mpsi: MEMORY POOL SYSTEM C INTERFACE LAYER * - * $HopeName: MMsrc!mpsi.c(trunk.26) $ + * $HopeName: MMsrc!mpsi.c(trunk.27) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. * * .purpose: This code bridges between the MPS interface to C, @@ -52,7 +52,7 @@ #include "mps.h" #include "mpsavm.h" /* only for mps_space_create */ -SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.26) $"); +SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.27) $"); /* mpsi_check -- check consistency of interface mappings @@ -140,7 +140,7 @@ static Bool mpsi_check(void) CHECKL(CHECKFIELDAPPROX(mps_ss_s, fix, ScanStateStruct, fix)); CHECKL(CHECKFIELD(mps_ss_s, w0, ScanStateStruct, zoneShift)); CHECKL(CHECKFIELD(mps_ss_s, w1, ScanStateStruct, white)); - CHECKL(CHECKFIELD(mps_ss_s, w2, ScanStateStruct, summary)); + CHECKL(CHECKFIELD(mps_ss_s, w2, ScanStateStruct, unfixedSummary)); /* Check ld_s/LDStruct compatibility by hand */ /* .check.ld: See also impl.h.mpmst.ld.struct and impl.h.mps.ld */ diff --git a/mps/src/poolams.c b/mps/src/poolams.c index 7244a1ab47c..e40925bad01 100644 --- a/mps/src/poolams.c +++ b/mps/src/poolams.c @@ -1,6 +1,6 @@ /* impl.c.poolams: AUTOMATIC MARK & SWEEP POOL CLASS * - * $HopeName: MMsrc!poolams.c(trunk.4) $ + * $HopeName: MMsrc!poolams.c(trunk.5) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. * * NOTES @@ -19,7 +19,7 @@ #include "mpm.h" #include "mpscams.h" -SRCID(poolams, "$HopeName: MMsrc!poolams.c(trunk.4) $"); +SRCID(poolams, "$HopeName: MMsrc!poolams.c(trunk.5) $"); /* These two BT utility functions should be in the BT module. * See design.mps.poolams.bt.utilities */ @@ -632,9 +632,6 @@ static Res AMSScan(ScanState ss, Pool pool, Seg seg) Bool scanAllObjects; AVERT(ScanState, ss); - AVER(ss->summary == RefSetEMPTY); /* to make afterSummary correct */ - AVER(ss->fixed == RefSetEMPTY); /* to make afterSummary correct */ - AVERT(Pool, pool); ams = PoolPoolAMS(pool); AVERT(AMS, ams); @@ -651,6 +648,15 @@ static Res AMSScan(ScanState ss, Pool pool, Seg seg) AVER(!scanOnce || scanAllObjects); /* scanOnce implies scanAllObjects */ + + /* If the scanner isn't going to scan all the objects then the */ + /* summary of the unscanned objects must be added into the scan */ + /* state summary, so that it's a valid summary of the entire */ + /* segment on return. See design.mps.poolams.summary.scan.part. */ + if(!scanAllObjects) + ScanStateSetSummary(ss, RefSetUnion(ScanStateSummary(ss), + SegSummary(seg))); + if (scanOnce) { Bool wasMarked = group->marked; /* for checking */ @@ -675,16 +681,6 @@ static Res AMSScan(ScanState ss, Pool pool, Seg seg) } - AVER(RefSetSub(ss->summary, SegSummary(seg))); - - if (!scanAllObjects) { /* design.mps.poolams.summary */ - /* design.mps.poolams.summary.scan.part.summary */ - ss->summary = RefSetUnion(ss->summary, SegSummary(seg)); - /* design.mps.poolams.summary.scan.part.fixed */ - ss->fixed = RefSetUnion(ss->fixed, RefSetInter(SegSummary(seg), - ss->white)); - } - return ResOK; } diff --git a/mps/src/poolawl.c b/mps/src/poolawl.c index d2faad15ab7..c47dee78cdc 100644 --- a/mps/src/poolawl.c +++ b/mps/src/poolawl.c @@ -1,6 +1,6 @@ /* impl.c.poolawl: AUTOMATIC WEAK LINKED POOL CLASS * - * $HopeName: MMsrc!poolawl.c(trunk.14) $ + * $HopeName: MMsrc!poolawl.c(trunk.15) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. * * READERSHIP @@ -16,7 +16,7 @@ #include "mpm.h" #include "mpscawl.h" -SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.14) $"); +SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.15) $"); #define AWLSig ((Sig)0x519b7a37) /* SIGPooLAWL */ @@ -445,6 +445,14 @@ static Res AWLScan(ScanState ss, Pool pool, Seg seg) base = SegBase(arena, seg); limit = SegLimit(arena, seg); + /* If the scanner isn't going to scan all the objects then the */ + /* summary of the unscanned objects must be added into the scan */ + /* state summary, so that it's a valid summary of the entire */ + /* segment on return. */ + if(SegWhite(seg) != RefSetEMPTY) + ScanStateSetSummary(ss, RefSetUnion(ScanStateSummary(ss), + SegSummary(seg))); + notFinished: finished = TRUE; p = base; @@ -500,7 +508,7 @@ notFinished: } if(!finished) goto notFinished; - + return ResOK; } diff --git a/mps/src/trace.c b/mps/src/trace.c index a5718b719ac..7f8ff82a0c5 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.39) $ + * $HopeName: MMsrc!trace.c(trunk.40) $ * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. */ #include "mpm.h" -SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.39) $"); +SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.40) $"); /* ScanStateCheck -- check consistency of a ScanState object */ @@ -390,7 +390,6 @@ static Res TraceFlip(Trace trace) ss.fix = TraceFix; ss.zoneShift = ArenaZoneShift(arena); ss.white = trace->white; - ss.summary = RefSetEMPTY; ss.arena = arena; ss.traces = TraceSetSingle(trace->ti); ss.wasMarked = TRUE; @@ -535,6 +534,40 @@ static Bool traceFindGrey(Seg *segReturn, Rank *rankReturn, } +/* ScanStateSetSummary -- set the summary of scanned references + * + * This function sets unfixedSummary and fixedSummary such that + * ScanStateSummary will return the summary passed. Subsequently + * fixed references are accumulated into this result. + */ + +void ScanStateSetSummary(ScanState ss, RefSet summary) +{ + AVERT(ScanState, ss); + + ss->fixedSummary = RefSetEMPTY; + ss->unfixedSummary = summary; +} + + +/* ScanStateSummary -- calculate the summary of scanned references + * + * The summary of the scanned references is the summary of the + * unfixed references, minus the white set, plus the summary of the + * fixed references. This is because TraceFix is called for all + * references in the white set, and accumulates a summary of + * references after they have been fixed. + */ + +RefSet ScanStateSummary(ScanState ss) +{ + AVERT(ScanState, ss); + + return TraceSetUnion(ss->fixedSummary, + TraceSetDiff(ss->unfixedSummary, ss->white)); +} + + /* TraceScan -- scan a segment to remove greyness * * @@@@ During scanning, the segment should be write-shielded to @@ -562,8 +595,8 @@ static Res TraceScan(TraceSet ts, Rank rank, ss.traces = ts; ss.fix = TraceFix; ss.zoneShift = arena->zoneShift; - ss.summary = RefSetEMPTY; - ss.fixed = RefSetEMPTY; + ss.unfixedSummary = RefSetEMPTY; + ss.fixedSummary = RefSetEMPTY; ss.arena = arena; ss.wasMarked = TRUE; ss.white = RefSetEMPTY; @@ -580,28 +613,12 @@ static Res TraceScan(TraceSet ts, Rank rank, if(res != ResOK) goto failScan; - /* .scan.post-condition: */ - /* The summary of reference seens by scan (ss.summary) is a subset */ - /* of the summary previously computed (SegSummary). There are two */ - /* reasons that it is not an equality relation: */ + /* See design.mps.scan.summary.subset. */ + AVER(RefSetSub(ss.unfixedSummary, SegSummary(seg))); - /* 1. if the segment has had objects forwarded onto it then its summary */ - /* will get unioned with the summary of the segment that the object was */ - /* forwarded from. This may increase the summary. The forwarded object */ - /* of course may have a smaller summary (if such a thing were to be */ - /* computed) and so subsequent scanning of the segment may reduce the */ - /* summmary. (The forwarding process may erroneously introduce zones */ - /* into the destination's summary). */ - - /* 2. A write barrier hit will set the summary to RefSetUNIV. */ - - /* The reason that ss.summary is always a subset of the previous summary */ - /* is due to an "optimization" which has not been made in TraceFix. See */ - /* .fix.fixed.all */ - - AVER(RefSetSub(ss.summary, SegSummary(seg))); - SegSetSummary(seg, TraceSetUnion(ss.fixed, - TraceSetDiff(ss.summary, ss.white))); + /* 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 */ @@ -779,16 +796,16 @@ Res TraceFix(ScanState ss, Ref *refIO) } /* .fix.fixed.all: */ - /* ss->fixed is accumulated for all the pointers whether or not they are */ - /* genuine references. We could accumulate fewer pointers here, if a */ - /* pointer fails the SegOfAddr test then we know it isn't a reference, so */ - /* we needn't accumulate it into the fixed summary. The design allows */ - /* this, but it breaks a useful post-condition on scanning. See */ - /* .scan.post-condition. (if the accumulation of ss->fixed was moved the */ - /* accuracy of ss->fixed would vary according to the "width" of the white */ - /* summary). */ - - ss->fixed = RefSetAdd(ss->arena, ss->fixed, *refIO); + /* ss->fixedSummary is accumulated for all the pointers whether */ + /* or not they are genuine references. We could accumulate fewer */ + /* pointers here, if a pointer fails the SegOfAddr test then we */ + /* know it isn't a reference, so we needn't accumulate it into the */ + /* fixed summary. The design allows this, but it breaks a useful */ + /* post-condition on scanning. See .scan.post-condition. (if */ + /* the accumulation of ss->fixedSummary was moved the accuracy */ + /* of ss->fixedSummary would vary according to the "width" of the */ + /* white summary). */ + ss->fixedSummary = RefSetAdd(ss->arena, ss->fixedSummary, *refIO); return ResOK; }