1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-24 06:20:43 -08:00

Don't turn on the alloctable in amsbufferempty when it's shared with nonwhitetable and the colour tables are in use -- this will turn any grey grains in the segment invalid.

Add more checking to AMS, including the table use invariant.

Copied from Perforce
 Change: 185434
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-04-10 18:16:29 +01:00
parent 8da860f464
commit 4e30c7d2b8

View file

@ -74,6 +74,11 @@ Bool AMSSegCheck(AMSSeg amsseg)
CHECKD_NOSIG(BT, amsseg->nongreyTable);
CHECKD_NOSIG(BT, amsseg->nonwhiteTable);
/* If tables are shared, they mustn't both be in use. */
CHECKL(!(amsseg->ams->shareAllocTable
&& amsseg->allocTableInUse
&& amsseg->colourTablesInUse));
return TRUE;
}
@ -167,6 +172,10 @@ static Res amsCreateTables(AMS ams, BT *allocReturn,
goto failWhite;
}
/* Invalidate the colour tables in checking varieties. */
AVER((BTResRange(nongreyTable, 0, length), TRUE));
AVER((BTSetRange(nonwhiteTable, 0, length), TRUE));
*allocReturn = allocTable;
*nongreyReturn = nongreyTable;
*nonwhiteReturn = nonwhiteTable;
@ -1023,7 +1032,8 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
AVER(limitIndex <= amsseg->firstFree);
if (limitIndex == amsseg->firstFree) /* is it at the end? */ {
amsseg->firstFree = initIndex;
} else { /* start using allocTable */
} else if (!ams->shareAllocTable || !amsseg->colourTablesInUse) {
/* start using allocTable */
amsseg->allocTableInUse = TRUE;
BTSetRange(amsseg->allocTable, 0, amsseg->firstFree);
if (amsseg->firstFree < amsseg->grains)
@ -1415,16 +1425,20 @@ static Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
/* doing that here (this can be called from RootScan, during flip). */
clientRef = *refIO;
AVER_CRITICAL(SegBase(seg) <= clientRef);
AVER_CRITICAL(clientRef < SegLimit(seg)); /* see .ref-limit */
base = AddrSub((Addr)clientRef, format->headerSize);
/* can get an ambiguous reference too close to the base of the
* segment, so when we subtract the header we are not in the
* segment any longer. This isn't a real reference,
* so we can just skip it. */
if (base < SegBase(seg)) {
return ResOK;
AVER_CRITICAL(ss->rank == RankAMBIG);
return ResOK;
}
i = AMS_ADDR_INDEX(seg, base);
AVER_CRITICAL(i < amsseg->grains);
AVER_CRITICAL(!AMS_IS_INVALID_COLOUR(seg, i));
ss->wasMarked = TRUE;