mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-24 05:47:36 +00:00
Short-circuit the cases where we set the greyness or summary of a segment to the same as it was before in all cases, rather than just in a few restricted cases in amc.
This was the result of noticing a large number of SetSetGrey events that set the segment to the same greyness when scanning ambiguous references. Copied from Perforce Change: 179567 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
847bd516aa
commit
85f3d6bbb4
3 changed files with 31 additions and 38 deletions
|
|
@ -1664,8 +1664,7 @@ static void amcFixInPlace(Pool pool, Seg seg, ScanState ss, Ref *refIO)
|
|||
return;
|
||||
}
|
||||
SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
|
||||
if(SegRankSet(seg) != RankSetEMPTY)
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1727,9 +1726,6 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
Buffer buffer; /* buffer to allocate new copy into */
|
||||
amcGen gen; /* generation of old copy of object */
|
||||
TraceSet grey; /* greyness of object being relocated */
|
||||
TraceSet toGrey; /* greyness of object's destination */
|
||||
RefSet summary; /* summary of object being relocated */
|
||||
RefSet toSummary; /* summary of object's destination */
|
||||
Seg toSeg; /* segment to which object is being relocated */
|
||||
|
||||
/* <design/trace/#fix.noaver> */
|
||||
|
|
@ -1786,9 +1782,7 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
/* Segment only needs greying if there are new traces for */
|
||||
/* which we are nailing. */
|
||||
if(!TraceSetSub(ss->traces, SegNailed(seg))) {
|
||||
if(SegRankSet(seg) != RankSetEMPTY) {
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
}
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
|
||||
}
|
||||
res = ResOK;
|
||||
|
|
@ -1823,16 +1817,8 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
/* Since we're moving an object from one segment to another, */
|
||||
/* union the greyness and the summaries together. */
|
||||
grey = TraceSetUnion(ss->traces, SegGrey(seg));
|
||||
toGrey = SegGrey(toSeg);
|
||||
if(TraceSetDiff(grey, toGrey) != TraceSetEMPTY
|
||||
&& SegRankSet(seg) != RankSetEMPTY) {
|
||||
SegSetGrey(toSeg, TraceSetUnion(toGrey, grey));
|
||||
}
|
||||
summary = SegSummary(seg);
|
||||
toSummary = SegSummary(toSeg);
|
||||
if(RefSetDiff(summary, toSummary) != RefSetEMPTY) {
|
||||
SegSetSummary(toSeg, RefSetUnion(toSummary, summary));
|
||||
}
|
||||
SegSetGrey(toSeg, TraceSetUnion(SegGrey(toSeg), grey));
|
||||
SegSetSummary(toSeg, RefSetUnion(SegSummary(toSeg), SegSummary(seg)));
|
||||
|
||||
/* <design/trace/#fix.copy> */
|
||||
(void)AddrCopy(newRef, ref, length); /* .exposed.seg */
|
||||
|
|
@ -1877,9 +1863,6 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
Buffer buffer; /* buffer to allocate new copy into */
|
||||
amcGen gen; /* generation of old copy of object */
|
||||
TraceSet grey; /* greyness of object being relocated */
|
||||
TraceSet toGrey; /* greyness of object's destination */
|
||||
RefSet summary; /* summary of object being relocated */
|
||||
RefSet toSummary; /* summary of object's destination */
|
||||
Seg toSeg; /* segment to which object is being relocated */
|
||||
|
||||
/* <design/trace/#fix.noaver> */
|
||||
|
|
@ -1937,8 +1920,7 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
/* Segment only needs greying if there are new traces for */
|
||||
/* which we are nailing. */
|
||||
if(!TraceSetSub(ss->traces, SegNailed(seg))) {
|
||||
if(SegRankSet(seg) != RankSetEMPTY)
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
|
||||
}
|
||||
res = ResOK;
|
||||
|
|
@ -1976,14 +1958,8 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
/* Since we're moving an object from one segment to another, */
|
||||
/* union the greyness and the summaries together. */
|
||||
grey = TraceSetUnion(ss->traces, SegGrey(seg));
|
||||
toGrey = SegGrey(toSeg);
|
||||
if(TraceSetDiff(grey, toGrey) != TraceSetEMPTY
|
||||
&& SegRankSet(seg) != RankSetEMPTY)
|
||||
SegSetGrey(toSeg, TraceSetUnion(toGrey, grey));
|
||||
summary = SegSummary(seg);
|
||||
toSummary = SegSummary(toSeg);
|
||||
if(RefSetDiff(summary, toSummary) != RefSetEMPTY)
|
||||
SegSetSummary(toSeg, RefSetUnion(toSummary, summary));
|
||||
SegSetGrey(toSeg, TraceSetUnion(SegGrey(toSeg), grey));
|
||||
SegSetSummary(toSeg, RefSetUnion(SegSummary(toSeg), SegSummary(seg)));
|
||||
|
||||
/* <design/trace/#fix.copy> */
|
||||
(void)AddrCopy(newBase, AddrSub(ref, headerSize), length); /* .exposed.seg */
|
||||
|
|
|
|||
|
|
@ -267,7 +267,12 @@ void SegSetGrey(Seg seg, TraceSet grey)
|
|||
{
|
||||
AVERT(Seg, seg);
|
||||
AVER(TraceSetCheck(grey));
|
||||
seg->class->setGrey(seg, grey);
|
||||
AVER(SegRankSet(seg) != RankSetEMPTY);
|
||||
|
||||
/* Don't dispatch to the class method if there's no actual change in
|
||||
greyness, or if the segment doesn't contain any references. */
|
||||
if (grey != SegGrey(seg) && SegRankSet(seg) != RankSetEMPTY)
|
||||
seg->class->setGrey(seg, grey);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -295,6 +300,7 @@ void SegSetRankSet(Seg seg, RankSet rankSet)
|
|||
{
|
||||
AVERT(Seg, seg);
|
||||
AVER(RankSetCheck(rankSet));
|
||||
AVER(rankSet != RankSetEMPTY || SegSummary(seg) == RefSetEMPTY);
|
||||
seg->class->setRankSet(seg, rankSet);
|
||||
}
|
||||
|
||||
|
|
@ -304,11 +310,13 @@ void SegSetRankSet(Seg seg, RankSet rankSet)
|
|||
void SegSetSummary(Seg seg, RefSet summary)
|
||||
{
|
||||
AVERT(Seg, seg);
|
||||
AVER(summary == RefSetEMPTY || SegRankSet(seg) != RankSetEMPTY);
|
||||
|
||||
#ifdef PROTECTION_NONE
|
||||
summary = RefSetUNIV;
|
||||
#endif
|
||||
seg->class->setSummary(seg, summary);
|
||||
if (summary != SegSummary(seg))
|
||||
seg->class->setSummary(seg, summary);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1150,6 +1158,10 @@ static void gcSegSetGreyInternal(Seg seg, TraceSet oldGrey, TraceSet grey)
|
|||
AVER(RankSetIsSingle(seg->rankSet));
|
||||
for(rank = 0; rank < RankLIMIT; ++rank)
|
||||
if (RankSetIsMember(seg->rankSet, rank)) {
|
||||
/* NOTE: We push the segment onto the front of the queue, so that
|
||||
we preserve some locality of scanning, and so that we tend to
|
||||
forward objects that are closely linked to the same or nearby
|
||||
segments. */
|
||||
RingInsert(ArenaGreyRing(arena, rank), &gcseg->greyRing);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -525,13 +525,15 @@ static Res rootFlip(Root root, void *p)
|
|||
* The main job of traceFlip is to scan references which can't be protected
|
||||
* from the mutator, changing the colour of the mutator from grey to black
|
||||
* with respect to a trace. The mutator threads are suspended while this
|
||||
* is happening, and the mutator perceives and instantaneous change in all
|
||||
* is happening, and the mutator perceives an instantaneous change in all
|
||||
* the references, enforced by the shield (barrier) system.
|
||||
*
|
||||
* NOTE: We don't have a way to shield the roots, so they are all scanned
|
||||
* here. This is a coincidence. There is no particular reason that the
|
||||
* roots have to be scanned at flip time. (The thread registers are unlikely
|
||||
* ever to be protectable on stock hardware, however.)
|
||||
* here. This is a coincidence. There is no theoretical reason that the
|
||||
* roots have to be scanned at flip time, provided we could protect them
|
||||
* from the mutator. (The thread registers are unlikely ever to be
|
||||
* protectable on stock hardware, however, as they were -- kind of -- on
|
||||
* Lisp machines.)
|
||||
*
|
||||
* NOTE: Ambiguous references may only exist in roots, because we can't
|
||||
* shield the exact roots and defer them for later scanning (after ambiguous
|
||||
|
|
@ -1254,9 +1256,12 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode)
|
|||
Trace trace;
|
||||
TraceId ti;
|
||||
Rank rank;
|
||||
TraceSet traces;
|
||||
|
||||
AVER(SegRankSet(seg) != RankSetEMPTY);
|
||||
|
||||
/* Pick set of traces to scan for: */
|
||||
TraceSet traces = arena->flippedTraces;
|
||||
traces = arena->flippedTraces;
|
||||
rank = TraceRankForAccess(arena, seg);
|
||||
res = traceScanSeg(traces, rank, arena, seg);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue