mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-17 01:34:21 +00:00
Don't allow pools to whiten segments without condemning objects, so that a condemned size of zero implies no white segments, allowing quick trace destruction.
Copied from Perforce Change: 190607 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
b9f6d7d1c7
commit
27e38efbda
3 changed files with 32 additions and 9 deletions
|
|
@ -1170,9 +1170,13 @@ static Res AMSWhiten(Pool pool, Trace trace, Seg seg)
|
|||
amsseg->newGrains = uncondemned;
|
||||
amsseg->marksChanged = FALSE; /* <design/poolams/#marked.condemn> */
|
||||
amsseg->ambiguousFixes = FALSE;
|
||||
trace->condemned += AMSGrainsSize(ams, amsseg->oldGrains);
|
||||
|
||||
SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace));
|
||||
if (amsseg->oldGrains > 0) {
|
||||
trace->condemned += AMSGrainsSize(ams, amsseg->oldGrains);
|
||||
SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace));
|
||||
} else {
|
||||
amsseg->colourTablesInUse = FALSE;
|
||||
}
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -791,8 +791,12 @@ static Res AWLWhiten(Pool pool, Trace trace, Seg seg)
|
|||
PoolGenAccountForAge(&awl->pgen, AWLGrainsSize(awl, awlseg->newGrains - uncondemned), FALSE);
|
||||
awlseg->oldGrains += awlseg->newGrains - uncondemned;
|
||||
awlseg->newGrains = uncondemned;
|
||||
trace->condemned += AWLGrainsSize(awl, awlseg->oldGrains);
|
||||
SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace));
|
||||
|
||||
if (awlseg->oldGrains > 0) {
|
||||
trace->condemned += AWLGrainsSize(awl, awlseg->oldGrains);
|
||||
SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace));
|
||||
}
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -339,7 +339,12 @@ static ZoneSet traceSetWhiteUnion(TraceSet ts, Arena arena)
|
|||
}
|
||||
|
||||
|
||||
/* TraceIsEmpty -- return TRUE if trace has no condemned segments */
|
||||
/* TraceIsEmpty -- return TRUE if trace has no condemned segments
|
||||
*
|
||||
* .empty.size: If the trace has a condemned size of zero, then it has
|
||||
* no white segments, because we don't allow pools to whiten segments
|
||||
* with no white objects in.
|
||||
*/
|
||||
|
||||
Bool TraceIsEmpty(Trace trace)
|
||||
{
|
||||
|
|
@ -354,6 +359,7 @@ Res TraceAddWhite(Trace trace, Seg seg)
|
|||
{
|
||||
Res res;
|
||||
Pool pool;
|
||||
Size condemnedBefore;
|
||||
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
|
|
@ -362,18 +368,25 @@ Res TraceAddWhite(Trace trace, Seg seg)
|
|||
pool = SegPool(seg);
|
||||
AVERT(Pool, pool);
|
||||
|
||||
condemnedBefore = trace->condemned;
|
||||
|
||||
/* Give the pool the opportunity to turn the segment white. */
|
||||
/* If it fails, unwind. */
|
||||
res = PoolWhiten(pool, trace, seg);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
/* Add the segment to the approximation of the white set if the */
|
||||
/* pool made it white. */
|
||||
if(TraceSetIsMember(SegWhite(seg), trace)) {
|
||||
if (TraceSetIsMember(SegWhite(seg), trace)) {
|
||||
/* Pools must not condemn empty segments, otherwise we can't tell
|
||||
when a trace is empty and safe to destroy. See .empty.size. */
|
||||
AVER(trace->condemned > condemnedBefore);
|
||||
|
||||
/* Add the segment to the approximation of the white set if the
|
||||
pool made it white. */
|
||||
trace->white = ZoneSetUnion(trace->white, ZoneSetOfSeg(trace->arena, seg));
|
||||
|
||||
/* if the pool is a moving GC, then condemned objects may move */
|
||||
if(PoolHasAttr(pool, AttrMOVINGGC)) {
|
||||
if (PoolHasAttr(pool, AttrMOVINGGC)) {
|
||||
trace->mayMove = ZoneSetUnion(trace->mayMove,
|
||||
ZoneSetOfSeg(trace->arena, seg));
|
||||
}
|
||||
|
|
@ -1532,11 +1545,13 @@ static Res traceCondemnAll(Trace trace)
|
|||
Ring segNode, nextSegNode;
|
||||
RING_FOR(segNode, PoolSegRing(pool), nextSegNode) {
|
||||
Seg seg = SegOfPoolRing(segNode);
|
||||
|
||||
AVERT(Seg, seg);
|
||||
|
||||
res = TraceAddWhite(trace, seg);
|
||||
if (res != ResOK)
|
||||
goto failBegin;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue