mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 16:51:06 -07:00
Merge branch/2016-04-20/seghasbuffer.
Copied from Perforce Change: 192173 ServerID: perforce.ravenbrook.com
This commit is contained in:
commit
fa7547e296
11 changed files with 131 additions and 83 deletions
|
|
@ -1135,7 +1135,7 @@ static void segBufAttach(Buffer buffer, Addr base, Addr limit,
|
|||
found = SegOfAddr(&seg, arena, base);
|
||||
AVER(found);
|
||||
AVER(segbuf->seg == NULL);
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
AVER(SegBase(seg) <= base);
|
||||
AVER(limit <= SegLimit(seg));
|
||||
|
||||
|
|
@ -1152,11 +1152,8 @@ static void segBufAttach(Buffer buffer, Addr base, Addr limit,
|
|||
static void segBufDetach(Buffer buffer)
|
||||
{
|
||||
SegBuf segbuf = MustBeA(SegBuf, buffer);
|
||||
Seg seg;
|
||||
|
||||
seg = segbuf->seg;
|
||||
AVER(seg != NULL);
|
||||
SegSetBuffer(seg, NULL);
|
||||
Seg seg = segbuf->seg;
|
||||
SegUnsetBuffer(seg);
|
||||
segbuf->seg = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -672,8 +672,10 @@ extern Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at);
|
|||
extern Res SegAbsDescribe(Seg seg, mps_lib_FILE *stream, Count depth);
|
||||
extern Res SegDescribe(Seg seg, mps_lib_FILE *stream, Count depth);
|
||||
extern void SegSetSummary(Seg seg, RefSet summary);
|
||||
extern Buffer SegBuffer(Seg seg);
|
||||
extern Bool SegHasBuffer(Seg seg);
|
||||
extern Bool SegBuffer(Buffer *bufferReturn, Seg seg);
|
||||
extern void SegSetBuffer(Seg seg, Buffer buffer);
|
||||
extern void SegUnsetBuffer(Seg seg);
|
||||
extern Addr SegBufferScanLimit(Seg seg);
|
||||
extern Bool SegCheck(Seg seg);
|
||||
extern Bool GCSegCheck(GCSeg gcseg);
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ typedef struct SegClassStruct {
|
|||
SegSetSummaryMethod setSummary; /* set the segment summary */
|
||||
SegBufferMethod buffer; /* get the segment buffer */
|
||||
SegSetBufferMethod setBuffer; /* set the segment buffer */
|
||||
SegUnsetBufferMethod unsetBuffer; /* unset the segment buffer */
|
||||
SegSetGreyMethod setGrey; /* change greyness of segment */
|
||||
SegSetWhiteMethod setWhite; /* change whiteness of segment */
|
||||
SegSetRankSetMethod setRankSet; /* change rank set of segment */
|
||||
|
|
|
|||
|
|
@ -160,8 +160,9 @@ typedef void (*SegSetRankSetMethod)(Seg seg, RankSet rankSet);
|
|||
typedef void (*SegSetRankSummaryMethod)(Seg seg, RankSet rankSet,
|
||||
RefSet summary);
|
||||
typedef void (*SegSetSummaryMethod)(Seg seg, RefSet summary);
|
||||
typedef Buffer (*SegBufferMethod)(Seg seg);
|
||||
typedef Bool (*SegBufferMethod)(Buffer *bufferReturn, Seg seg);
|
||||
typedef void (*SegSetBufferMethod)(Seg seg, Buffer buffer);
|
||||
typedef void (*SegUnsetBufferMethod)(Seg seg);
|
||||
typedef Res (*SegDescribeMethod)(Seg seg, mps_lib_FILE *stream, Count depth);
|
||||
typedef Res (*SegMergeMethod)(Seg seg, Seg segHi,
|
||||
Addr base, Addr mid, Addr limit);
|
||||
|
|
|
|||
|
|
@ -197,8 +197,7 @@ static void AMCSegSketch(Seg seg, char *pbSketch, size_t cbSketch)
|
|||
pbSketch[2] = 'W'; /* White */
|
||||
}
|
||||
|
||||
buffer = SegBuffer(seg);
|
||||
if(buffer == NULL) {
|
||||
if (!SegBuffer(&buffer, seg)) {
|
||||
pbSketch[3] = '_';
|
||||
} else {
|
||||
Bool mut = BufferIsMutator(buffer);
|
||||
|
|
@ -243,6 +242,7 @@ static Res AMCSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth)
|
|||
Align step;
|
||||
Size row;
|
||||
char abzSketch[5];
|
||||
Buffer buffer;
|
||||
|
||||
if (!TESTC(amcSeg, amcseg))
|
||||
return ResPARAM;
|
||||
|
|
@ -277,8 +277,8 @@ static Res AMCSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth)
|
|||
if (res != ResOK)
|
||||
return res;
|
||||
|
||||
if (SegBuffer(seg) != NULL)
|
||||
init = BufferGetInit(SegBuffer(seg));
|
||||
if (SegBuffer(&buffer, seg))
|
||||
init = BufferGetInit(buffer);
|
||||
else
|
||||
init = limit;
|
||||
|
||||
|
|
@ -1100,8 +1100,7 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
|
|||
|
||||
AVERT(Trace, trace);
|
||||
|
||||
buffer = SegBuffer(seg);
|
||||
if(buffer != NULL) {
|
||||
if (SegBuffer(&buffer, seg)) {
|
||||
AVERT(Buffer, buffer);
|
||||
|
||||
if(!BufferIsMutator(buffer)) { /* forwarding buffer */
|
||||
|
|
@ -1250,6 +1249,7 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn,
|
|||
Addr p, limit;
|
||||
Nailboard board;
|
||||
Res res;
|
||||
Buffer buffer;
|
||||
|
||||
EVENT3(AMCScanBegin, amc, seg, ss); /* TODO: consider using own event */
|
||||
|
||||
|
|
@ -1258,8 +1258,8 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn,
|
|||
NailboardClearNewNails(board);
|
||||
|
||||
p = SegBase(seg);
|
||||
while(SegBuffer(seg) != NULL) {
|
||||
limit = BufferScanLimit(SegBuffer(seg));
|
||||
while (SegBuffer(&buffer, seg)) {
|
||||
limit = BufferScanLimit(buffer);
|
||||
if(p >= limit) {
|
||||
AVER(p == limit);
|
||||
goto returnGood;
|
||||
|
|
@ -1342,6 +1342,7 @@ static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
|
|||
Format format;
|
||||
AMC amc = MustBeA(AMCZPool, pool);
|
||||
Res res;
|
||||
Buffer buffer;
|
||||
|
||||
AVER(totalReturn != NULL);
|
||||
AVERT(ScanState, ss);
|
||||
|
|
@ -1358,8 +1359,8 @@ static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
|
|||
|
||||
base = AddrAdd(SegBase(seg), format->headerSize);
|
||||
/* <design/poolamc/#seg-scan.loop> */
|
||||
while(SegBuffer(seg) != NULL) {
|
||||
limit = AddrAdd(BufferScanLimit(SegBuffer(seg)),
|
||||
while (SegBuffer(&buffer, seg)) {
|
||||
limit = AddrAdd(BufferScanLimit(buffer),
|
||||
format->headerSize);
|
||||
if(base >= limit) {
|
||||
/* @@@@ Are we sure we don't need scan the rest of the */
|
||||
|
|
@ -1719,13 +1720,13 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
|
|||
|
||||
/* Free the seg if we can; fixes .nailboard.limitations.middle. */
|
||||
if(preservedInPlaceCount == 0
|
||||
&& (SegBuffer(seg) == NULL)
|
||||
&& (!SegHasBuffer(seg))
|
||||
&& (SegNailed(seg) == TraceSetEMPTY)) {
|
||||
|
||||
amcGen gen = amcSegGen(seg);
|
||||
|
||||
/* We may not free a buffered seg. */
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
|
||||
PoolGenFree(&gen->pgen, seg, 0, SegSize(seg), 0, MustBeA(amcSeg, seg)->deferred);
|
||||
}
|
||||
|
|
@ -1767,7 +1768,7 @@ static void AMCReclaim(Pool pool, Trace trace, Seg seg)
|
|||
|
||||
/* We may not free a buffered seg. (But all buffered + condemned */
|
||||
/* segs should have been nailed anyway). */
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
|
||||
STATISTIC(trace->reclaimSize += SegSize(seg));
|
||||
|
||||
|
|
@ -1884,6 +1885,7 @@ static Res AMCAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
|
|||
Res res;
|
||||
Arena arena;
|
||||
Addr base, limit; /* range of objects on segment */
|
||||
Buffer buffer;
|
||||
|
||||
AVER(pReturn != NULL);
|
||||
AVERT(Pool, pool);
|
||||
|
|
@ -1894,7 +1896,7 @@ static Res AMCAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
|
|||
|
||||
arena = PoolArena(pool);
|
||||
base = SegBase(seg);
|
||||
if (SegBuffer(seg) != NULL) {
|
||||
if (SegBuffer(&buffer, seg)) {
|
||||
/* We use BufferGetInit here (and not BufferScanLimit) because we
|
||||
* want to be able to find objects that have been allocated and
|
||||
* committed since the last flip. These objects lie between the
|
||||
|
|
@ -1906,7 +1908,7 @@ static Res AMCAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
|
|||
* *must* point inside a live object and we stop skipping once we
|
||||
* have found it. The init pointer serves this purpose.
|
||||
*/
|
||||
limit = BufferGetInit(SegBuffer(seg));
|
||||
limit = BufferGetInit(buffer);
|
||||
} else {
|
||||
limit = SegLimit(seg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ static void AMSSegFinish(Seg seg)
|
|||
ams = amsseg->ams;
|
||||
AVERT(AMS, ams);
|
||||
arena = PoolArena(AMSPool(ams));
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
|
||||
/* keep the destructions in step with AMSSegInit failure cases */
|
||||
amsDestroyTables(ams, amsseg->allocTable, amsseg->nongreyTable,
|
||||
|
|
@ -514,10 +514,9 @@ failCreateTablesLo:
|
|||
|
||||
/* AMSSegDescribe -- describe an AMS segment */
|
||||
|
||||
#define WRITE_BUFFER_LIMIT(stream, seg, i, buffer, accessor, code) \
|
||||
#define WRITE_BUFFER_LIMIT(i, accessor, code) \
|
||||
BEGIN \
|
||||
if ((buffer) != NULL \
|
||||
&& (i) == AMS_ADDR_INDEX(seg, accessor(buffer))) { \
|
||||
if (hasBuffer && (i) == AMS_ADDR_INDEX(seg, accessor(buffer))) { \
|
||||
Res _res = WriteF(stream, 0, code, NULL); \
|
||||
if (_res != ResOK) return _res; \
|
||||
} \
|
||||
|
|
@ -527,7 +526,8 @@ static Res AMSSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth)
|
|||
{
|
||||
AMSSeg amsseg = CouldBeA(AMSSeg, seg);
|
||||
Res res;
|
||||
Buffer buffer; /* the segment's buffer, if it has one */
|
||||
Buffer buffer;
|
||||
Bool hasBuffer;
|
||||
Index i;
|
||||
|
||||
if (!TESTC(AMSSeg, amsseg))
|
||||
|
|
@ -540,7 +540,7 @@ static Res AMSSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth)
|
|||
if (res != ResOK)
|
||||
return res;
|
||||
|
||||
buffer = SegBuffer(seg);
|
||||
hasBuffer = SegBuffer(&buffer, seg);
|
||||
|
||||
res = WriteF(stream, depth + 2,
|
||||
"AMS $P\n", (WriteFP)amsseg->ams,
|
||||
|
|
@ -583,9 +583,9 @@ static Res AMSSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth)
|
|||
return res;
|
||||
}
|
||||
|
||||
WRITE_BUFFER_LIMIT(stream, seg, i, buffer, BufferBase, "[");
|
||||
WRITE_BUFFER_LIMIT(stream, seg, i, buffer, BufferGetInit, "|");
|
||||
WRITE_BUFFER_LIMIT(stream, seg, i, buffer, BufferAlloc, ">");
|
||||
WRITE_BUFFER_LIMIT(i, BufferBase, "[");
|
||||
WRITE_BUFFER_LIMIT(i, BufferGetInit, "|");
|
||||
WRITE_BUFFER_LIMIT(i, BufferAlloc, ">");
|
||||
|
||||
if (AMS_ALLOCED(seg, i)) {
|
||||
if (amsseg->colourTablesInUse) {
|
||||
|
|
@ -605,8 +605,8 @@ static Res AMSSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth)
|
|||
if (res != ResOK)
|
||||
return res;
|
||||
|
||||
WRITE_BUFFER_LIMIT(stream, seg, i+1, buffer, BufferScanLimit, "<");
|
||||
WRITE_BUFFER_LIMIT(stream, seg, i+1, buffer, BufferLimit, "]");
|
||||
WRITE_BUFFER_LIMIT(i+1, BufferScanLimit, "<");
|
||||
WRITE_BUFFER_LIMIT(i+1, BufferLimit, "]");
|
||||
}
|
||||
|
||||
return ResOK;
|
||||
|
|
@ -730,7 +730,7 @@ static void AMSSegsDestroy(AMS ams)
|
|||
RING_FOR(node, ring, next) {
|
||||
Seg seg = SegOfPoolRing(node);
|
||||
AMSSeg amsseg = Seg2AMSSeg(seg);
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
AVERT(AMSSeg, amsseg);
|
||||
AVER(amsseg->ams == ams);
|
||||
AVER(amsseg->bufferedGrains == 0);
|
||||
|
|
@ -965,7 +965,7 @@ static Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
|
|||
seg = AMSSeg2Seg(amsseg);
|
||||
|
||||
if (SegRankSet(seg) == rankSet
|
||||
&& SegBuffer(seg) == NULL
|
||||
&& !SegHasBuffer(seg)
|
||||
/* Can't use a white or grey segment, see d.m.p.fill.colour. */
|
||||
&& SegWhite(seg) == TraceSetEMPTY
|
||||
&& SegGrey(seg) == TraceSetEMPTY)
|
||||
|
|
@ -1140,8 +1140,7 @@ static Res AMSWhiten(Pool pool, Trace trace, Seg seg)
|
|||
amsseg->allocTableInUse = TRUE;
|
||||
}
|
||||
|
||||
buffer = SegBuffer(seg);
|
||||
if (buffer != NULL) { /* <design/poolams/#condemn.buffer> */
|
||||
if (SegBuffer(&buffer, seg)) { /* <design/poolams/#condemn.buffer> */
|
||||
Index scanLimitIndex, limitIndex;
|
||||
scanLimitIndex = AMS_ADDR_INDEX(seg, BufferScanLimit(buffer));
|
||||
limitIndex = AMS_ADDR_INDEX(seg, BufferLimit(buffer));
|
||||
|
|
@ -1208,6 +1207,7 @@ static Res amsIterate(Seg seg, AMSObjectFunction f, void *closure)
|
|||
Index i;
|
||||
Addr p, next, limit;
|
||||
Buffer buffer;
|
||||
Bool hasBuffer;
|
||||
|
||||
AVERT(Seg, seg);
|
||||
AVERT(AMSObjectFunction, f);
|
||||
|
|
@ -1227,16 +1227,15 @@ static Res amsIterate(Seg seg, AMSObjectFunction f, void *closure)
|
|||
|
||||
p = SegBase(seg);
|
||||
limit = SegLimit(seg);
|
||||
buffer = SegBuffer(seg);
|
||||
hasBuffer = SegBuffer(&buffer, seg);
|
||||
|
||||
while (p < limit) { /* loop over the objects in the segment */
|
||||
if (buffer != NULL
|
||||
&& p == BufferScanLimit(buffer) && p != BufferLimit(buffer)) {
|
||||
if (hasBuffer && p == BufferScanLimit(buffer) && p != BufferLimit(buffer)) {
|
||||
/* skip buffer */
|
||||
next = BufferLimit(buffer);
|
||||
AVER(AddrIsAligned(next, alignment));
|
||||
} else {
|
||||
AVER((buffer == NULL)
|
||||
AVER(!hasBuffer
|
||||
|| (p < BufferScanLimit(buffer))
|
||||
|| (p >= BufferLimit(buffer))); /* not in the buffer */
|
||||
|
||||
|
|
@ -1634,7 +1633,7 @@ static void AMSReclaim(Pool pool, Trace trace, Seg seg)
|
|||
amsseg->colourTablesInUse = FALSE;
|
||||
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
|
||||
|
||||
if (amsseg->freeGrains == grains && SegBuffer(seg) == NULL) {
|
||||
if (amsseg->freeGrains == grains && !SegHasBuffer(seg)) {
|
||||
/* No survivors */
|
||||
AVER(amsseg->bufferedGrains == 0);
|
||||
PoolGenFree(ams->pgen, seg,
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ static void AWLFinish(Pool pool)
|
|||
RING_FOR(node, ring, nextNode) {
|
||||
Seg seg = SegOfPoolRing(node);
|
||||
AWLSeg awlseg = MustBeA(AWLSeg, seg);
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
AVERT(AWLSeg, awlseg);
|
||||
AVER(awlseg->bufferedGrains == 0);
|
||||
PoolGenFree(awl->pgen, seg,
|
||||
|
|
@ -627,7 +627,7 @@ static Res AWLBufferFill(Addr *baseReturn, Addr *limitReturn,
|
|||
|
||||
/* Only try to allocate in the segment if it is not already */
|
||||
/* buffered, and has the same ranks as the buffer. */
|
||||
if (SegBuffer(seg) == NULL
|
||||
if (!SegHasBuffer(seg)
|
||||
&& SegRankSet(seg) == BufferRankSet(buffer)
|
||||
&& AWLGrainsSize(awl, awlseg->freeGrains) >= size
|
||||
&& AWLSegAlloc(&base, &limit, awlseg, awl, size))
|
||||
|
|
@ -715,7 +715,7 @@ static Res AWLWhiten(Pool pool, Trace trace, Seg seg)
|
|||
{
|
||||
AWL awl = MustBeA(AWLPool, pool);
|
||||
AWLSeg awlseg = MustBeA(AWLSeg, seg);
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
Buffer buffer;
|
||||
Count agedGrains, uncondemnedGrains;
|
||||
|
||||
/* All parameters checked by generic PoolWhiten. */
|
||||
|
|
@ -724,7 +724,7 @@ static Res AWLWhiten(Pool pool, Trace trace, Seg seg)
|
|||
/* see <design/poolawl/#fun.condemn> */
|
||||
AVER(SegWhite(seg) == TraceSetEMPTY);
|
||||
|
||||
if(buffer == NULL) {
|
||||
if (!SegBuffer(&buffer, seg)) {
|
||||
awlRangeWhiten(awlseg, 0, awlseg->grains);
|
||||
uncondemnedGrains = (Count)0;
|
||||
} else {
|
||||
|
|
@ -781,6 +781,8 @@ static void AWLRangeGrey(AWLSeg awlseg, Index base, Index limit)
|
|||
|
||||
static void AWLGrey(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
Buffer buffer;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
|
|
@ -790,9 +792,8 @@ static void AWLGrey(Pool pool, Trace trace, Seg seg)
|
|||
AWLSeg awlseg = MustBeA(AWLSeg, seg);
|
||||
|
||||
SegSetGrey(seg, TraceSetAdd(SegGrey(seg), trace));
|
||||
if (SegBuffer(seg) != NULL) {
|
||||
if (SegBuffer(&buffer, seg)) {
|
||||
Addr base = SegBase(seg);
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
|
||||
AWLRangeGrey(awlseg,
|
||||
0,
|
||||
|
|
@ -866,7 +867,7 @@ static Res awlScanSinglePass(Bool *anyScannedReturn,
|
|||
AWL awl = MustBeA(AWLPool, pool);
|
||||
AWLSeg awlseg = MustBeA(AWLSeg, seg);
|
||||
Arena arena = PoolArena(pool);
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
Buffer buffer;
|
||||
Format format = pool->format;
|
||||
Addr base = SegBase(seg);
|
||||
Addr limit = SegLimit(seg);
|
||||
|
|
@ -879,7 +880,7 @@ static Res awlScanSinglePass(Bool *anyScannedReturn,
|
|||
|
||||
*anyScannedReturn = FALSE;
|
||||
p = base;
|
||||
if (buffer != NULL && BufferScanLimit(buffer) != BufferLimit(buffer))
|
||||
if (SegBuffer(&buffer, seg) && BufferScanLimit(buffer) != BufferLimit(buffer))
|
||||
bufferScanLimit = BufferScanLimit(buffer);
|
||||
else
|
||||
bufferScanLimit = limit;
|
||||
|
|
@ -1027,7 +1028,8 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
|
|||
AWL awl = MustBeA(AWLPool, pool);
|
||||
AWLSeg awlseg = MustBeA(AWLSeg, seg);
|
||||
Addr base = SegBase(seg);
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
Buffer buffer;
|
||||
Bool hasBuffer = SegBuffer(&buffer, seg);
|
||||
Format format = pool->format;
|
||||
Count reclaimedGrains = (Count)0;
|
||||
Count preservedInPlaceCount = (Count)0;
|
||||
|
|
@ -1046,7 +1048,7 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
|
|||
continue;
|
||||
}
|
||||
p = awlAddrOfIndex(base, awl, i);
|
||||
if (buffer != NULL
|
||||
if (hasBuffer
|
||||
&& p == BufferScanLimit(buffer)
|
||||
&& BufferScanLimit(buffer) != BufferLimit(buffer))
|
||||
{
|
||||
|
|
@ -1085,7 +1087,7 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
|
|||
trace->preservedInPlaceSize += preservedInPlaceSize;
|
||||
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
|
||||
|
||||
if (awlseg->freeGrains == awlseg->grains && buffer == NULL) {
|
||||
if (awlseg->freeGrains == awlseg->grains && !hasBuffer) {
|
||||
/* No survivors */
|
||||
AVER(awlseg->bufferedGrains == 0);
|
||||
PoolGenFree(awl->pgen, seg,
|
||||
|
|
@ -1158,9 +1160,9 @@ static void AWLWalk(Pool pool, Seg seg, FormattedObjectsVisitor f,
|
|||
/* free grain */
|
||||
Addr next;
|
||||
Index i;
|
||||
Buffer buffer;
|
||||
|
||||
if (SegBuffer(seg) != NULL) {
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
if (SegBuffer(&buffer, seg)) {
|
||||
if (object == BufferScanLimit(buffer)
|
||||
&& BufferScanLimit(buffer) != BufferLimit(buffer)) {
|
||||
/* skip over buffered area */
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ static Bool loSegFindFree(Addr *bReturn, Addr *lReturn,
|
|||
AVER(agrains <= loseg->freeGrains);
|
||||
AVER(size <= SegSize(seg));
|
||||
|
||||
if(SegBuffer(seg) != NULL)
|
||||
if (SegHasBuffer(seg))
|
||||
/* Don't bother trying to allocate from a buffered segment */
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -312,11 +312,12 @@ static void loSegReclaim(LOSeg loseg, Trace trace)
|
|||
*/
|
||||
p = base;
|
||||
while(p < limit) {
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
Buffer buffer;
|
||||
Bool hasBuffer = SegBuffer(&buffer, seg);
|
||||
Addr q;
|
||||
Index i;
|
||||
|
||||
if(buffer != NULL) {
|
||||
if (hasBuffer) {
|
||||
marked = TRUE;
|
||||
if (p == BufferScanLimit(buffer)
|
||||
&& BufferScanLimit(buffer) != BufferLimit(buffer)) {
|
||||
|
|
@ -403,9 +404,9 @@ static void LOWalk(Pool pool, Seg seg, FormattedObjectsVisitor f,
|
|||
Addr object = loAddrOfIndex(base, lo, i);
|
||||
Addr next;
|
||||
Index j;
|
||||
Buffer buffer;
|
||||
|
||||
if(SegBuffer(seg) != NULL) {
|
||||
Buffer buffer = SegBuffer(seg);
|
||||
if (SegBuffer(&buffer, seg)) {
|
||||
if(object == BufferScanLimit(buffer) &&
|
||||
BufferScanLimit(buffer) != BufferLimit(buffer)) {
|
||||
/* skip over buffered area */
|
||||
|
|
@ -518,7 +519,7 @@ static void LOFinish(Pool pool)
|
|||
RING_FOR(node, &pool->segRing, nextNode) {
|
||||
Seg seg = SegOfPoolRing(node);
|
||||
LOSeg loseg = MustBeA(LOSeg, seg);
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
AVER(!SegHasBuffer(seg));
|
||||
AVERT(LOSeg, loseg);
|
||||
AVER(loseg->bufferedGrains == 0);
|
||||
PoolGenFree(lo->pgen, seg,
|
||||
|
|
@ -658,8 +659,7 @@ static Res LOWhiten(Pool pool, Trace trace, Seg seg)
|
|||
grains = loSegGrains(loseg);
|
||||
|
||||
/* Whiten allocated objects; leave free areas black. */
|
||||
buffer = SegBuffer(seg);
|
||||
if (buffer != NULL) {
|
||||
if (SegBuffer(&buffer, seg)) {
|
||||
Addr base = SegBase(seg);
|
||||
Index scanLimitIndex = loIndexOfAddr(base, lo, BufferScanLimit(buffer));
|
||||
Index limitIndex = loIndexOfAddr(base, lo, BufferLimit(buffer));
|
||||
|
|
|
|||
|
|
@ -560,6 +560,7 @@ static Res SNCFramePop(Pool pool, Buffer buf, AllocFrame frame)
|
|||
Arena arena;
|
||||
Seg seg = NULL; /* suppress "may be used uninitialized" */
|
||||
Bool foundSeg;
|
||||
Buffer segBuf;
|
||||
|
||||
arena = PoolArena(pool);
|
||||
addr = (Addr)frame;
|
||||
|
|
@ -567,7 +568,7 @@ static Res SNCFramePop(Pool pool, Buffer buf, AllocFrame frame)
|
|||
AVER(foundSeg); /* <design/check/#.common> */
|
||||
AVER(SegPool(seg) == pool);
|
||||
|
||||
if (SegBuffer(seg) == buf) {
|
||||
if (SegBuffer(&segBuf, seg) && segBuf == buf) {
|
||||
/* don't need to change the segment - just the alloc pointers */
|
||||
AVER(addr <= BufferScanLimit(buf)); /* check direction of pop */
|
||||
BufferSetAllocAddr(buf, addr);
|
||||
|
|
|
|||
|
|
@ -332,12 +332,21 @@ void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary)
|
|||
}
|
||||
|
||||
|
||||
/* SegBuffer -- return the buffer of a segment */
|
||||
/* SegHasBuffer -- segment has a buffer? */
|
||||
|
||||
Buffer SegBuffer(Seg seg)
|
||||
Bool SegHasBuffer(Seg seg)
|
||||
{
|
||||
Buffer buffer;
|
||||
return SegBuffer(&buffer, seg);
|
||||
}
|
||||
|
||||
|
||||
/* SegBuffer -- get the buffer of a segment */
|
||||
|
||||
Bool SegBuffer(Buffer *bufferReturn, Seg seg)
|
||||
{
|
||||
AVERT_CRITICAL(Seg, seg); /* .seg.critical */
|
||||
return Method(Seg, seg, buffer)(seg);
|
||||
return Method(Seg, seg, buffer)(bufferReturn, seg);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -346,12 +355,20 @@ Buffer SegBuffer(Seg seg)
|
|||
void SegSetBuffer(Seg seg, Buffer buffer)
|
||||
{
|
||||
AVERT(Seg, seg);
|
||||
if (buffer != NULL)
|
||||
AVERT(Buffer, buffer);
|
||||
AVERT(Buffer, buffer);
|
||||
Method(Seg, seg, setBuffer)(seg, buffer);
|
||||
}
|
||||
|
||||
|
||||
/* SegUnsetBuffer -- remove the buffer from a segment */
|
||||
|
||||
void SegUnsetBuffer(Seg seg)
|
||||
{
|
||||
AVERT(Seg, seg);
|
||||
Method(Seg, seg, unsetBuffer)(seg);
|
||||
}
|
||||
|
||||
|
||||
/* SegBufferScanLimit -- limit of scannable objects in segment */
|
||||
|
||||
Addr SegBufferScanLimit(Seg seg)
|
||||
|
|
@ -361,8 +378,7 @@ Addr SegBufferScanLimit(Seg seg)
|
|||
|
||||
AVERT(Seg, seg);
|
||||
|
||||
buf = SegBuffer(seg);
|
||||
if (buf == NULL) {
|
||||
if (!SegBuffer(&buf, seg)) {
|
||||
/* Segment is unbuffered: entire segment scannable */
|
||||
limit = SegLimit(seg);
|
||||
} else {
|
||||
|
|
@ -627,6 +643,7 @@ Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at)
|
|||
Arena arena;
|
||||
Res res;
|
||||
void *p;
|
||||
Buffer buffer;
|
||||
|
||||
AVER(NULL != segLoReturn);
|
||||
AVER(NULL != segHiReturn);
|
||||
|
|
@ -642,7 +659,7 @@ Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at)
|
|||
|
||||
/* Can only split a buffered segment if the entire buffer is below
|
||||
* the split point. */
|
||||
AVER(SegBuffer(seg) == NULL || BufferLimit(SegBuffer(seg)) <= at);
|
||||
AVER(!SegBuffer(&buffer, seg) || BufferLimit(buffer) <= at);
|
||||
|
||||
if (seg->queued)
|
||||
ShieldFlush(arena); /* see <design/seg/#split-merge.shield> */
|
||||
|
|
@ -824,11 +841,12 @@ static void segNoSetRankSummary(Seg seg, RankSet rankSet, RefSet summary)
|
|||
|
||||
/* segNoBuffer -- non-method to return the buffer of a segment */
|
||||
|
||||
static Buffer segNoBuffer(Seg seg)
|
||||
static Bool segNoBuffer(Buffer *bufferReturn, Seg seg)
|
||||
{
|
||||
AVERT(Seg, seg);
|
||||
AVER(bufferReturn != NULL);
|
||||
NOTREACHED;
|
||||
return NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -837,8 +855,16 @@ static Buffer segNoBuffer(Seg seg)
|
|||
static void segNoSetBuffer(Seg seg, Buffer buffer)
|
||||
{
|
||||
AVERT(Seg, seg);
|
||||
if (buffer != NULL)
|
||||
AVERT(Buffer, buffer);
|
||||
AVERT(Buffer, buffer);
|
||||
NOTREACHED;
|
||||
}
|
||||
|
||||
|
||||
/* segNoSetBuffer -- non-method to set the buffer of a segment */
|
||||
|
||||
static void segNoUnsetBuffer(Seg seg)
|
||||
{
|
||||
AVERT(Seg, seg);
|
||||
NOTREACHED;
|
||||
}
|
||||
|
||||
|
|
@ -1345,7 +1371,7 @@ static void gcSegSetRankSummary(Seg seg, RankSet rankSet, RefSet summary)
|
|||
|
||||
/* gcSegBuffer -- GCSeg method to return the buffer of a segment */
|
||||
|
||||
static Buffer gcSegBuffer(Seg seg)
|
||||
static Bool gcSegBuffer(Buffer *bufferReturn, Seg seg)
|
||||
{
|
||||
GCSeg gcseg;
|
||||
|
||||
|
|
@ -1354,7 +1380,12 @@ static Buffer gcSegBuffer(Seg seg)
|
|||
AVERT_CRITICAL(GCSeg, gcseg); /* .seg.method.check */
|
||||
AVER_CRITICAL(&gcseg->segStruct == seg);
|
||||
|
||||
return gcseg->buffer;
|
||||
if (gcseg->buffer != NULL) {
|
||||
*bufferReturn = gcseg->buffer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1375,6 +1406,15 @@ static void gcSegSetBuffer(Seg seg, Buffer buffer)
|
|||
}
|
||||
|
||||
|
||||
/* gcSegUnsetBuffer -- GCSeg method to remove the buffer from a segment */
|
||||
|
||||
static void gcSegUnsetBuffer(Seg seg)
|
||||
{
|
||||
GCSeg gcseg = MustBeA_CRITICAL(GCSeg, seg); /* .seg.method.check */
|
||||
gcseg->buffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* gcSegMerge -- GCSeg merge method
|
||||
*
|
||||
* .buffer: Can't merge two segments both with buffers.
|
||||
|
|
@ -1582,7 +1622,8 @@ DEFINE_CLASS(Seg, Seg, klass)
|
|||
klass->finish = SegAbsFinish;
|
||||
klass->setSummary = segNoSetSummary;
|
||||
klass->buffer = segNoBuffer;
|
||||
klass->setBuffer = segNoSetBuffer;
|
||||
klass->setBuffer = segNoSetBuffer;
|
||||
klass->unsetBuffer = segNoUnsetBuffer;
|
||||
klass->setGrey = segNoSetGrey;
|
||||
klass->setWhite = segNoSetWhite;
|
||||
klass->setRankSet = segNoSetRankSet;
|
||||
|
|
@ -1607,7 +1648,8 @@ DEFINE_CLASS(Seg, GCSeg, klass)
|
|||
klass->finish = gcSegFinish;
|
||||
klass->setSummary = gcSegSetSummary;
|
||||
klass->buffer = gcSegBuffer;
|
||||
klass->setBuffer = gcSegSetBuffer;
|
||||
klass->setBuffer = gcSegSetBuffer;
|
||||
klass->unsetBuffer = gcSegUnsetBuffer;
|
||||
klass->setGrey = gcSegSetGrey;
|
||||
klass->setWhite = gcSegSetWhite;
|
||||
klass->setRankSet = gcSegSetRankSet;
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ static Res AMSTBufferFill(Addr *baseReturn, Addr *limitReturn,
|
|||
if (SegLimit(seg) == limit && SegBase(seg) == base) {
|
||||
if (amstseg->prev != NULL) {
|
||||
Seg segLo = AMSTSeg2Seg(amstseg->prev);
|
||||
if (SegBuffer(segLo) == NULL &&
|
||||
if (!SegHasBuffer(segLo) &&
|
||||
SegGrey(segLo) == SegGrey(seg) &&
|
||||
SegWhite(segLo) == SegWhite(seg)) {
|
||||
/* .merge */
|
||||
|
|
@ -599,10 +599,11 @@ static void AMSTStressBufferedSeg(Seg seg, Buffer buffer)
|
|||
AMST amst;
|
||||
Arena arena;
|
||||
Addr limit;
|
||||
Buffer segBuf;
|
||||
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Buffer, buffer);
|
||||
AVER(SegBuffer(seg) == buffer);
|
||||
AVER(SegBuffer(&segBuf, seg) && segBuf == buffer);
|
||||
amstseg = Seg2AMSTSeg(seg);
|
||||
AVERT(AMSTSeg, amstseg);
|
||||
limit = BufferLimit(buffer);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue