diff --git a/mps/code/buffer.c b/mps/code/buffer.c index 31ba7af7ec5..55253c2c5ff 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -1174,11 +1174,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; } diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 2e7c251d5d6..31aefeb0232 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -672,9 +672,9 @@ extern Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at); extern Res SegDescribe(Seg seg, mps_lib_FILE *stream, Count depth); extern void SegSetSummary(Seg seg, RefSet summary); extern Bool SegHasBuffer(Seg seg); -extern Bool SegGetBuffer(Buffer *bufferReturn, Seg seg); -extern Buffer SegBuffer(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); diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 065088e9cf0..6ae1dd6c9e6 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -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 */ diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index 5d8070eaa46..db8845f4f10 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -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); diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 116bfdab465..c3d610392e0 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -197,7 +197,7 @@ static void AMCSegSketch(Seg seg, char *pbSketch, size_t cbSketch) pbSketch[2] = 'W'; /* White */ } - if (!SegGetBuffer(&buffer, seg)) { + if (!SegBuffer(&buffer, seg)) { pbSketch[3] = '_'; } else { Bool mut = BufferIsMutator(buffer); @@ -284,7 +284,7 @@ static Res AMCSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth) if(res != ResOK) return res; - if (SegGetBuffer(&buffer, seg)) + if (SegBuffer(&buffer, seg)) init = BufferGetInit(buffer); else init = limit; @@ -1111,7 +1111,7 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg) AVERT(Trace, trace); - if (SegGetBuffer(&buffer, seg)) { + if (SegBuffer(&buffer, seg)) { AVERT(Buffer, buffer); if(!BufferIsMutator(buffer)) { /* forwarding buffer */ @@ -1269,7 +1269,7 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn, NailboardClearNewNails(board); p = SegBase(seg); - while (SegGetBuffer(&buffer, seg)) { + while (SegBuffer(&buffer, seg)) { limit = BufferScanLimit(buffer); if(p >= limit) { AVER(p == limit); @@ -1370,7 +1370,7 @@ static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) base = AddrAdd(SegBase(seg), format->headerSize); /* */ - while (SegGetBuffer(&buffer, seg)) { + while (SegBuffer(&buffer, seg)) { limit = AddrAdd(BufferScanLimit(buffer), format->headerSize); if(base >= limit) { @@ -1907,7 +1907,7 @@ static Res AMCAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr) arena = PoolArena(pool); base = SegBase(seg); - if (SegGetBuffer(&buffer, seg)) { + 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 diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 11107488727..8ac7a6e4015 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -543,7 +543,7 @@ static Res AMSSegDescribe(Seg seg, mps_lib_FILE *stream, Count depth) if (res != ResOK) return res; - hasBuffer = SegGetBuffer(&buffer, seg); + hasBuffer = SegBuffer(&buffer, seg); res = WriteF(stream, depth, " AMS $P\n", (WriteFP)amsseg->ams, @@ -1143,7 +1143,7 @@ static Res AMSWhiten(Pool pool, Trace trace, Seg seg) amsseg->allocTableInUse = TRUE; } - if (SegGetBuffer(&buffer, seg)) { /* */ + if (SegBuffer(&buffer, seg)) { /* */ Index scanLimitIndex, limitIndex; scanLimitIndex = AMS_ADDR_INDEX(seg, BufferScanLimit(buffer)); limitIndex = AMS_ADDR_INDEX(seg, BufferLimit(buffer)); @@ -1230,7 +1230,7 @@ static Res amsIterate(Seg seg, AMSObjectFunction f, void *closure) p = SegBase(seg); limit = SegLimit(seg); - hasBuffer = SegGetBuffer(&buffer, seg); + hasBuffer = SegBuffer(&buffer, seg); while (p < limit) { /* loop over the objects in the segment */ if (hasBuffer && p == BufferScanLimit(buffer) && p != BufferLimit(buffer)) { diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 1d815707ae4..5831019a972 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -724,7 +724,7 @@ static Res AWLWhiten(Pool pool, Trace trace, Seg seg) /* see */ AVER(SegWhite(seg) == TraceSetEMPTY); - if (!SegGetBuffer(&buffer, seg)) { + if (!SegBuffer(&buffer, seg)) { awlRangeWhiten(awlseg, 0, awlseg->grains); uncondemnedGrains = (Count)0; } else { @@ -792,7 +792,7 @@ static void AWLGrey(Pool pool, Trace trace, Seg seg) AWLSeg awlseg = MustBeA(AWLSeg, seg); SegSetGrey(seg, TraceSetAdd(SegGrey(seg), trace)); - if (SegGetBuffer(&buffer, seg)) { + if (SegBuffer(&buffer, seg)) { Addr base = SegBase(seg); AWLRangeGrey(awlseg, @@ -880,7 +880,7 @@ static Res awlScanSinglePass(Bool *anyScannedReturn, *anyScannedReturn = FALSE; p = base; - if (SegGetBuffer(&buffer, seg) && BufferScanLimit(buffer) != BufferLimit(buffer)) + if (SegBuffer(&buffer, seg) && BufferScanLimit(buffer) != BufferLimit(buffer)) bufferScanLimit = BufferScanLimit(buffer); else bufferScanLimit = limit; @@ -1029,7 +1029,7 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg) AWLSeg awlseg = MustBeA(AWLSeg, seg); Addr base = SegBase(seg); Buffer buffer; - Bool hasBuffer = SegGetBuffer(&buffer, seg); + Bool hasBuffer = SegBuffer(&buffer, seg); Format format = pool->format; Count reclaimedGrains = (Count)0; Count preservedInPlaceCount = (Count)0; @@ -1162,7 +1162,7 @@ static void AWLWalk(Pool pool, Seg seg, FormattedObjectsVisitor f, Index i; Buffer buffer; - if (SegGetBuffer(&buffer, seg)) { + if (SegBuffer(&buffer, seg)) { if (object == BufferScanLimit(buffer) && BufferScanLimit(buffer) != BufferLimit(buffer)) { /* skip over buffered area */ diff --git a/mps/code/poollo.c b/mps/code/poollo.c index c33ea3af9af..e796f5690e5 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -313,7 +313,7 @@ static void loSegReclaim(LOSeg loseg, Trace trace) p = base; while(p < limit) { Buffer buffer; - Bool hasBuffer = SegGetBuffer(&buffer, seg); + Bool hasBuffer = SegBuffer(&buffer, seg); Addr q; Index i; @@ -406,7 +406,7 @@ static void LOWalk(Pool pool, Seg seg, FormattedObjectsVisitor f, Index j; Buffer buffer; - if (SegGetBuffer(&buffer, seg)) { + if (SegBuffer(&buffer, seg)) { if(object == BufferScanLimit(buffer) && BufferScanLimit(buffer) != BufferLimit(buffer)) { /* skip over buffered area */ @@ -659,7 +659,7 @@ static Res LOWhiten(Pool pool, Trace trace, Seg seg) grains = loSegGrains(loseg); /* Whiten allocated objects; leave free areas black. */ - if (SegGetBuffer(&buffer, seg)) { + if (SegBuffer(&buffer, seg)) { Addr base = SegBase(seg); Index scanLimitIndex = loIndexOfAddr(base, lo, BufferScanLimit(buffer)); Index limitIndex = loIndexOfAddr(base, lo, BufferLimit(buffer)); diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index 640d637b24a..fd294087fbc 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -568,7 +568,7 @@ static Res SNCFramePop(Pool pool, Buffer buf, AllocFrame frame) AVER(foundSeg); AVER(SegPool(seg) == pool); - if (SegGetBuffer(&segBuf, seg) && segBuf == 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); diff --git a/mps/code/seg.c b/mps/code/seg.c index c6f1e46a3fd..2ab652f4f8d 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -336,27 +336,17 @@ void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary) Bool SegHasBuffer(Seg seg) { - return SegBuffer(seg) != NULL; + Buffer buffer; + return SegBuffer(&buffer, seg); } -/* SegBuffer -- return the buffer of a segment */ +/* SegBuffer -- get the buffer of a segment */ -Buffer SegBuffer(Seg seg) +Bool SegBuffer(Buffer *bufferReturn, Seg seg) { AVERT_CRITICAL(Seg, seg); /* .seg.critical */ - return Method(Seg, seg, buffer)(seg); -} - - -Bool SegGetBuffer(Buffer *bufferReturn, Seg seg) -{ - Buffer buffer = SegBuffer(seg); - if (buffer != NULL) { - *bufferReturn = buffer; - return TRUE; - } - return FALSE; + return Method(Seg, seg, buffer)(bufferReturn, seg); } @@ -365,12 +355,20 @@ Bool SegGetBuffer(Buffer *bufferReturn, 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) @@ -380,7 +378,7 @@ Addr SegBufferScanLimit(Seg seg) AVERT(Seg, seg); - if (!SegGetBuffer(&buf, seg)) { + if (!SegBuffer(&buf, seg)) { /* Segment is unbuffered: entire segment scannable */ limit = SegLimit(seg); } else { @@ -665,7 +663,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(!SegGetBuffer(&buffer, seg) || BufferLimit(buffer) <= at); + AVER(!SegBuffer(&buffer, seg) || BufferLimit(buffer) <= at); if (seg->queued) ShieldFlush(arena); /* see */ @@ -847,11 +845,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; } @@ -860,8 +859,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; } @@ -1401,7 +1408,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; @@ -1410,7 +1417,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; } @@ -1431,6 +1443,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. @@ -1641,7 +1662,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; @@ -1666,7 +1688,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; diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index bb9aa73b822..cbdbef76c4c 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -603,7 +603,7 @@ static void AMSTStressBufferedSeg(Seg seg, Buffer buffer) AVERT(Seg, seg); AVERT(Buffer, buffer); - AVER(SegGetBuffer(&segBuf, seg) && segBuf == buffer); + AVER(SegBuffer(&segBuf, seg) && segBuf == buffer); amstseg = Seg2AMSTSeg(seg); AVERT(AMSTSeg, amstseg); limit = BufferLimit(buffer);