mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 10:31:37 -08:00
Because of the requirement to make popped objects dead in a timely fashion, we can only implement lightweight pops to an address in the buffer. in particular we can't support pending pops, which means that there's no need for the fields in the allocation point that support pending pops.
Copied from Perforce Change: 187232 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
fce7e87366
commit
9dc8bd1e70
10 changed files with 58 additions and 361 deletions
|
|
@ -30,10 +30,6 @@
|
|||
SRCID(buffer, "$Id$");
|
||||
|
||||
|
||||
/* forward declarations */
|
||||
static void BufferFrameNotifyPopPending(Buffer buffer);
|
||||
|
||||
|
||||
/* BufferCheck -- check consistency of a buffer
|
||||
*
|
||||
* See .ap.async. */
|
||||
|
|
@ -52,15 +48,6 @@ Bool BufferCheck(Buffer buffer)
|
|||
CHECKL(buffer->emptySize <= buffer->fillSize);
|
||||
CHECKL(buffer->alignment == buffer->pool->alignment);
|
||||
CHECKL(AlignCheck(buffer->alignment));
|
||||
CHECKL(BoolCheck(buffer->ap_s._enabled));
|
||||
|
||||
if (buffer->ap_s._enabled) {
|
||||
/* no useful check for frameptr - mutator may be updating it */
|
||||
CHECKL(BoolCheck(buffer->ap_s._lwpoppending));
|
||||
} else {
|
||||
CHECKL(buffer->ap_s._lwpoppending == FALSE);
|
||||
CHECKL(buffer->ap_s._frameptr == NULL);
|
||||
}
|
||||
|
||||
/* If any of the buffer's fields indicate that it is reset, make */
|
||||
/* sure it is really reset. Otherwise, check various properties */
|
||||
|
|
@ -81,8 +68,6 @@ Bool BufferCheck(Buffer buffer)
|
|||
/* Nothing reliable to check for lightweight frame state */
|
||||
CHECKL(buffer->poolLimit == (Addr)0);
|
||||
} else {
|
||||
Addr aplimit;
|
||||
|
||||
/* The buffer is attached to a region of memory. */
|
||||
/* Check consistency. */
|
||||
CHECKL(buffer->mode & BufferModeATTACHED);
|
||||
|
|
@ -101,14 +86,6 @@ Bool BufferCheck(Buffer buffer)
|
|||
CHECKL(AddrIsAligned(buffer->ap_s.limit, buffer->alignment));
|
||||
CHECKL(AddrIsAligned(buffer->poolLimit, buffer->alignment));
|
||||
|
||||
/* .lwcheck: If LW frames are enabled, the buffer may become */
|
||||
/* trapped asynchronously. It can't become untrapped */
|
||||
/* asynchronously, though. See <design/alloc-frame/#lw-frame.pop>. */
|
||||
/* Read a snapshot value of the limit field. Use this to determine */
|
||||
/* if we are trapped, and to permit more useful checking when not */
|
||||
/* yet trapped. */
|
||||
aplimit = buffer->ap_s.limit;
|
||||
|
||||
/* If the buffer isn't trapped then "limit" should be the limit */
|
||||
/* set by the owning pool. Otherwise, "init" is either at the */
|
||||
/* same place it was at flip (.commit.before) or has been set */
|
||||
|
|
@ -119,12 +96,10 @@ Bool BufferCheck(Buffer buffer)
|
|||
/* request.dylan.170429.sol.zero_). */
|
||||
/* .. _request.dylan.170429.sol.zero: https://info.ravenbrook.com/project/mps/import/2001-11-05/mmprevol/request/dylan/170429 */
|
||||
|
||||
if ((buffer->ap_s._enabled && aplimit == (Addr)0) /* see .lwcheck */
|
||||
|| (!buffer->ap_s._enabled && BufferIsTrapped(buffer))) {
|
||||
if (BufferIsTrapped(buffer)) {
|
||||
/* .check.use-trapped: This checking function uses BufferIsTrapped, */
|
||||
/* So BufferIsTrapped can't do checking as that would cause an */
|
||||
/* infinite loop. */
|
||||
CHECKL(aplimit == (Addr)0);
|
||||
if (buffer->mode & BufferModeFLIPPED) {
|
||||
CHECKL(buffer->ap_s.init == buffer->initAtFlip
|
||||
|| buffer->ap_s.init == buffer->ap_s.alloc);
|
||||
|
|
@ -133,7 +108,6 @@ Bool BufferCheck(Buffer buffer)
|
|||
}
|
||||
/* Nothing special to check in the logged mode. */
|
||||
} else {
|
||||
CHECKL(aplimit == buffer->poolLimit); /* see .lwcheck */
|
||||
CHECKL(buffer->initAtFlip == (Addr)0);
|
||||
}
|
||||
}
|
||||
|
|
@ -230,9 +204,6 @@ static Res BufferInit(Buffer buffer, BufferClass class,
|
|||
buffer->ap_s.init = (mps_addr_t)0;
|
||||
buffer->ap_s.alloc = (mps_addr_t)0;
|
||||
buffer->ap_s.limit = (mps_addr_t)0;
|
||||
buffer->ap_s._frameptr = NULL;
|
||||
buffer->ap_s._enabled = FALSE;
|
||||
buffer->ap_s._lwpoppending = FALSE;
|
||||
buffer->poolLimit = (Addr)0;
|
||||
buffer->rampCount = 0;
|
||||
|
||||
|
|
@ -319,8 +290,6 @@ void BufferDetach(Buffer buffer, Pool pool)
|
|||
/* Ask the owning pool to do whatever it needs to before the */
|
||||
/* buffer is detached (e.g. copy buffer state into pool state). */
|
||||
(*pool->class->bufferEmpty)(pool, buffer, init, limit);
|
||||
/* Use of lightweight frames must have been disabled by now */
|
||||
AVER(BufferFrameState(buffer) == BufferFrameDISABLED);
|
||||
|
||||
/* run any class-specific detachment method */
|
||||
buffer->class->detach(buffer);
|
||||
|
|
@ -346,7 +315,6 @@ void BufferDetach(Buffer buffer, Pool pool)
|
|||
buffer->poolLimit = (Addr)0;
|
||||
buffer->mode &=
|
||||
~(BufferModeATTACHED|BufferModeFLIPPED|BufferModeTRANSITION);
|
||||
BufferFrameSetState(buffer, BufferFrameDISABLED);
|
||||
|
||||
EVENT2(BufferEmpty, buffer, spare);
|
||||
}
|
||||
|
|
@ -383,11 +351,6 @@ void BufferFinish(Buffer buffer)
|
|||
|
||||
AVER(BufferIsReady(buffer));
|
||||
|
||||
/* <design/alloc-frame/#lw-frame.sync.trip> */
|
||||
if (BufferIsTrappedByMutator(buffer)) {
|
||||
BufferFrameNotifyPopPending(buffer);
|
||||
}
|
||||
|
||||
BufferDetach(buffer, pool);
|
||||
|
||||
/* Dispatch to the buffer class method to perform any */
|
||||
|
|
@ -463,44 +426,6 @@ static void BufferSetUnflipped(Buffer buffer)
|
|||
}
|
||||
|
||||
|
||||
/* BufferFrameState
|
||||
*
|
||||
* Returns the frame state of a buffer. See
|
||||
* <design/alloc-frame/#lw-frame.states>. */
|
||||
|
||||
FrameState BufferFrameState(Buffer buffer)
|
||||
{
|
||||
AVERT(Buffer, buffer);
|
||||
if (buffer->ap_s._enabled) {
|
||||
if (buffer->ap_s._lwpoppending) {
|
||||
return BufferFramePOP_PENDING;
|
||||
} else {
|
||||
AVER(buffer->ap_s._frameptr == NULL);
|
||||
return BufferFrameVALID;
|
||||
}
|
||||
} else {
|
||||
AVER(buffer->ap_s._frameptr == NULL);
|
||||
AVER(buffer->ap_s._lwpoppending == FALSE);
|
||||
return BufferFrameDISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* BufferFrameSetState
|
||||
*
|
||||
* Sets the frame state of a buffer. Only the mutator may set the
|
||||
* PopPending state. See <design/alloc-frame/#lw-frame.states>. */
|
||||
|
||||
void BufferFrameSetState(Buffer buffer, FrameState state)
|
||||
{
|
||||
AVERT(Buffer, buffer);
|
||||
AVER(state == BufferFrameVALID || state == BufferFrameDISABLED);
|
||||
buffer->ap_s._frameptr = NULL;
|
||||
buffer->ap_s._lwpoppending = FALSE;
|
||||
buffer->ap_s._enabled = (state == BufferFrameVALID);
|
||||
}
|
||||
|
||||
|
||||
/* BufferSetAllocAddr
|
||||
*
|
||||
* Sets the init & alloc pointers of a buffer. */
|
||||
|
|
@ -518,32 +443,6 @@ void BufferSetAllocAddr(Buffer buffer, Addr addr)
|
|||
}
|
||||
|
||||
|
||||
/* BufferFrameNotifyPopPending
|
||||
*
|
||||
* Notifies the pool when a lightweight frame pop operation has been
|
||||
* deferred and needs to be processed. See
|
||||
* <design/alloc-frame/#lw-frame.sync.trip>. */
|
||||
|
||||
static void BufferFrameNotifyPopPending(Buffer buffer)
|
||||
{
|
||||
AllocFrame frame;
|
||||
Pool pool;
|
||||
AVER(BufferIsTrappedByMutator(buffer));
|
||||
AVER(BufferFrameState(buffer) == BufferFramePOP_PENDING);
|
||||
frame = (AllocFrame)buffer->ap_s._frameptr;
|
||||
/* Unset PopPending state & notify the pool */
|
||||
BufferFrameSetState(buffer, BufferFrameVALID);
|
||||
/* If the frame is no longer trapped, undo the trap by resetting */
|
||||
/* the AP limit pointer */
|
||||
if (!BufferIsTrapped(buffer)) {
|
||||
buffer->ap_s.limit = buffer->poolLimit;
|
||||
}
|
||||
pool = BufferPool(buffer);
|
||||
(*pool->class->framePopPending)(pool, buffer, frame);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* BufferFramePush
|
||||
*
|
||||
* See <design/alloc-frame/>. */
|
||||
|
|
@ -555,17 +454,12 @@ Res BufferFramePush(AllocFrame *frameReturn, Buffer buffer)
|
|||
AVER(frameReturn != NULL);
|
||||
|
||||
|
||||
/* Process any flip or PopPending */
|
||||
/* Process any flip */
|
||||
if (!BufferIsReset(buffer) && buffer->ap_s.limit == (Addr)0) {
|
||||
/* .fill.unflip: If the buffer is flipped then we unflip the buffer. */
|
||||
if (buffer->mode & BufferModeFLIPPED) {
|
||||
BufferSetUnflipped(buffer);
|
||||
}
|
||||
|
||||
/* check for PopPending */
|
||||
if (BufferIsTrappedByMutator(buffer)) {
|
||||
BufferFrameNotifyPopPending(buffer);
|
||||
}
|
||||
}
|
||||
pool = BufferPool(buffer);
|
||||
return (*pool->class->framePush)(frameReturn, pool, buffer);
|
||||
|
|
@ -702,11 +596,6 @@ Res BufferFill(Addr *pReturn, Buffer buffer, Size size,
|
|||
BufferSetUnflipped(buffer);
|
||||
}
|
||||
|
||||
/* <design/alloc-frame/#lw-frame.sync.trip> */
|
||||
if (BufferIsTrappedByMutator(buffer)) {
|
||||
BufferFrameNotifyPopPending(buffer);
|
||||
}
|
||||
|
||||
/* .fill.logged: If the buffer is logged then we leave it logged. */
|
||||
next = AddrAdd(buffer->ap_s.alloc, size);
|
||||
if (next > (Addr)buffer->ap_s.alloc &&
|
||||
|
|
@ -807,8 +696,6 @@ Bool BufferTrip(Buffer buffer, Addr p, Size size)
|
|||
AVER(buffer->ap_s.limit == 0);
|
||||
/* Of course we should be trapped. */
|
||||
AVER(BufferIsTrapped(buffer));
|
||||
/* But the mutator shouldn't have caused the trap */
|
||||
AVER(!BufferIsTrappedByMutator(buffer));
|
||||
|
||||
/* The init and alloc fields should be equal at this point, because */
|
||||
/* the step .commit.update has happened. */
|
||||
|
|
@ -955,21 +842,7 @@ void BufferReassignSeg(Buffer buffer, Seg seg)
|
|||
Bool BufferIsTrapped(Buffer buffer)
|
||||
{
|
||||
/* Can't check buffer, see .check.use-trapped */
|
||||
return BufferIsTrappedByMutator(buffer)
|
||||
|| ((buffer->mode & (BufferModeFLIPPED|BufferModeLOGGED)) != 0);
|
||||
}
|
||||
|
||||
|
||||
/* BufferIsTrappedByMutator
|
||||
*
|
||||
* Indicates whether the mutator trapped the buffer. See
|
||||
* <design/alloc-frame/#lw-frame.sync.trip> and .ap.async. */
|
||||
|
||||
Bool BufferIsTrappedByMutator(Buffer buffer)
|
||||
{
|
||||
AVER(!buffer->ap_s._lwpoppending || buffer->ap_s._enabled);
|
||||
/* Can't check buffer, see .check.use-trapped */
|
||||
return buffer->ap_s._lwpoppending;
|
||||
return (buffer->mode & (BufferModeFLIPPED|BufferModeLOGGED)) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -273,8 +273,6 @@ extern Res PoolNoFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf);
|
|||
extern Res PoolTrivFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf);
|
||||
extern Res PoolNoFramePop(Pool pool, Buffer buf, AllocFrame frame);
|
||||
extern Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame);
|
||||
extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame);
|
||||
extern void PoolTrivFramePopPending(Pool pool, Buffer buf, AllocFrame frame);
|
||||
extern Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr);
|
||||
extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsVisitor f,
|
||||
void *p, size_t s);
|
||||
|
|
@ -800,7 +798,6 @@ extern Addr BufferScanLimit(Buffer buffer);
|
|||
extern void BufferReassignSeg(Buffer buffer, Seg seg);
|
||||
|
||||
extern Bool BufferIsTrapped(Buffer buffer);
|
||||
extern Bool BufferIsTrappedByMutator(Buffer buffer);
|
||||
|
||||
extern void BufferRampBegin(Buffer buffer, AllocPattern pattern);
|
||||
extern Res BufferRampEnd(Buffer buffer);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ typedef struct mps_pool_class_s {
|
|||
PoolRampEndMethod rampEnd; /* end a ramp pattern */
|
||||
PoolFramePushMethod framePush; /* push an allocation frame */
|
||||
PoolFramePopMethod framePop; /* pop an allocation frame */
|
||||
PoolFramePopPendingMethod framePopPending; /* notify pending pop */
|
||||
PoolAddrObjectMethod addrObject; /* find client pointer to object */
|
||||
PoolWalkMethod walk; /* walk over a segment */
|
||||
PoolFreeWalkMethod freewalk; /* walk over free blocks */
|
||||
|
|
|
|||
|
|
@ -226,8 +226,6 @@ typedef Res (*PoolFramePushMethod)(AllocFrame *frameReturn,
|
|||
Pool pool, Buffer buf);
|
||||
typedef Res (*PoolFramePopMethod)(Pool pool, Buffer buf,
|
||||
AllocFrame frame);
|
||||
typedef void (*PoolFramePopPendingMethod)(Pool pool, Buffer buf,
|
||||
AllocFrame frame);
|
||||
typedef Res (*PoolAddrObjectMethod)(Addr *pReturn,
|
||||
Pool pool, Seg seg, Addr addr);
|
||||
typedef void (*PoolWalkMethod)(Pool pool, Seg seg, FormattedObjectsVisitor f,
|
||||
|
|
@ -321,14 +319,6 @@ enum {
|
|||
#define BufferModeTRANSITION ((BufferMode)(1<<3))
|
||||
|
||||
|
||||
/* Buffer frame states. See <design/alloc-frame/#lw-frame.states> */
|
||||
enum {
|
||||
BufferFrameVALID = 1,
|
||||
BufferFramePOP_PENDING,
|
||||
BufferFrameDISABLED
|
||||
};
|
||||
|
||||
|
||||
/* Rank constants -- see <design/type/#rank> */
|
||||
/* These definitions must match <code/mps.h#rank>. */
|
||||
/* This is checked by <code/mpsi.c#check>. */
|
||||
|
|
|
|||
|
|
@ -305,9 +305,6 @@ typedef struct mps_ap_s { /* allocation point descriptor */
|
|||
mps_addr_t init; /* limit of initialized memory */
|
||||
mps_addr_t alloc; /* limit of allocated memory */
|
||||
mps_addr_t limit; /* limit of available memory */
|
||||
mps_addr_t _frameptr; /* lightweight frame pointer */
|
||||
mps_bool_t _enabled; /* lightweight frame status */
|
||||
mps_bool_t _lwpoppending; /* lightweight pop pending? */
|
||||
} mps_ap_s;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -950,7 +950,7 @@ mps_res_t (mps_ap_frame_push)(mps_frame_t *frame_o, mps_ap_t mps_ap)
|
|||
return MPS_RES_FAIL;
|
||||
}
|
||||
|
||||
if (!mps_ap->_lwpoppending && mps_ap->init < mps_ap->limit) {
|
||||
if (mps_ap->init < mps_ap->limit) {
|
||||
/* Valid state for a lightweight push */
|
||||
*frame_o = (mps_frame_t)mps_ap->init;
|
||||
return MPS_RES_OK;
|
||||
|
|
@ -996,14 +996,12 @@ mps_res_t (mps_ap_frame_pop)(mps_ap_t mps_ap, mps_frame_t frame)
|
|||
buf = BufferOfAP(mps_ap);
|
||||
AVER(TESTT(Buffer, buf));
|
||||
|
||||
if (mps_ap->_enabled
|
||||
&& BufferBase(buf) <= (Addr)frame
|
||||
/* FIXME: is it thread-safe to read BufferBase here? */
|
||||
if (BufferBase(buf) <= (Addr)frame
|
||||
&& (mps_addr_t)frame < mps_ap->init)
|
||||
{
|
||||
/* Lightweight pop to address in same buffer */
|
||||
mps_ap->_frameptr = (mps_addr_t)frame; /* record pending pop */
|
||||
mps_ap->_lwpoppending = TRUE;
|
||||
mps_ap->limit = (mps_addr_t)0; /* trap the buffer */
|
||||
/* Lightweight pop to earlier address in same buffer */
|
||||
mps_ap->init = mps_ap->alloc = (mps_addr_t)frame;
|
||||
return MPS_RES_OK;
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ Bool PoolClassCheck(PoolClass class)
|
|||
CHECKL(FUNCHECK(class->rampEnd));
|
||||
CHECKL(FUNCHECK(class->framePush));
|
||||
CHECKL(FUNCHECK(class->framePop));
|
||||
CHECKL(FUNCHECK(class->framePopPending));
|
||||
CHECKL(FUNCHECK(class->addrObject));
|
||||
CHECKL(FUNCHECK(class->walk));
|
||||
CHECKL(FUNCHECK(class->freewalk));
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ void PoolClassMixInBuffer(PoolClass class)
|
|||
/* By default, buffered pools treat frame operations as NOOPs */
|
||||
class->framePush = PoolTrivFramePush;
|
||||
class->framePop = PoolTrivFramePop;
|
||||
class->framePopPending = PoolTrivFramePopPending;
|
||||
class->bufferClass = BufferClassGet;
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +137,6 @@ DEFINE_CLASS(AbstractPoolClass, class)
|
|||
class->rampEnd = PoolNoRampEnd;
|
||||
class->framePush = PoolNoFramePush;
|
||||
class->framePop = PoolNoFramePop;
|
||||
class->framePopPending = PoolNoFramePopPending;
|
||||
class->addrObject = PoolNoAddrObject;
|
||||
class->walk = PoolNoWalk;
|
||||
class->freewalk = PoolTrivFreeWalk;
|
||||
|
|
@ -598,16 +596,6 @@ Res PoolNoFramePop(Pool pool, Buffer buf, AllocFrame frame)
|
|||
}
|
||||
|
||||
|
||||
void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Buffer, buf);
|
||||
/* frame is of an abstract type & can't be checked */
|
||||
UNUSED(frame);
|
||||
NOTREACHED;
|
||||
}
|
||||
|
||||
|
||||
Res PoolTrivFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf)
|
||||
{
|
||||
AVER(frameReturn != NULL);
|
||||
|
|
@ -627,16 +615,6 @@ Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame)
|
|||
}
|
||||
|
||||
|
||||
void PoolTrivFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Buffer, buf);
|
||||
/* frame is of an abstract type & can't be checked */
|
||||
UNUSED(frame);
|
||||
NOOP;
|
||||
}
|
||||
|
||||
|
||||
Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
|
||||
{
|
||||
AVER(pReturn != NULL);
|
||||
|
|
|
|||
|
|
@ -462,8 +462,6 @@ found:
|
|||
AVERT(Seg, seg);
|
||||
/* put the segment on the buffer chain */
|
||||
sncRecordAllocatedSeg(buffer, seg);
|
||||
/* Permit the use of lightweight frames - .lw-frame-state */
|
||||
BufferFrameSetState(buffer, BufferFrameVALID);
|
||||
*baseReturn = SegBase(seg);
|
||||
*limitReturn = SegLimit(seg);
|
||||
return ResOK;
|
||||
|
|
@ -485,9 +483,6 @@ static void SNCBufferEmpty(Pool pool, Buffer buffer,
|
|||
AVER(SegLimit(seg) == limit);
|
||||
snc = PoolSNC(pool);
|
||||
AVERT(SNC, snc);
|
||||
AVER(BufferFrameState(buffer) == BufferFrameVALID);
|
||||
/* .lw-frame-state */
|
||||
BufferFrameSetState(buffer, BufferFrameDISABLED);
|
||||
|
||||
arena = BufferArena(buffer);
|
||||
|
||||
|
|
@ -503,7 +498,7 @@ static void SNCBufferEmpty(Pool pool, Buffer buffer,
|
|||
|
||||
/* SNCScanLimit -- limit of scannable objects in segment */
|
||||
|
||||
static Addr SNCScanLimit(Arena arena, Seg seg)
|
||||
static Addr SNCScanLimit(Seg seg)
|
||||
{
|
||||
Addr limit;
|
||||
Buffer buf;
|
||||
|
|
@ -511,27 +506,9 @@ static Addr SNCScanLimit(Arena arena, Seg seg)
|
|||
if (buf == NULL) {
|
||||
/* Segment is unbuffered: entire segment scannable */
|
||||
limit = SegLimit(seg);
|
||||
} else if (BufferFrameState(buf) != BufferFramePOP_PENDING) {
|
||||
/* No pop pending: scannable up to limit of initialized objects. */
|
||||
limit = BufferScanLimit(buf);
|
||||
} else {
|
||||
Addr addr = (Addr)buf->ap_s._frameptr;
|
||||
if (addr == NULL) {
|
||||
/* Pop pending to bottom of stack */
|
||||
limit = BufferBase(buf);
|
||||
} else {
|
||||
Seg popSeg;
|
||||
Bool foundSeg = SegOfAddr(&popSeg, arena, addr);
|
||||
AVER(foundSeg);
|
||||
if (popSeg == seg) {
|
||||
/* Pop pending to address in same segment */
|
||||
AVER(addr <= BufferScanLimit(buf)); /* check direction of pop */
|
||||
limit = addr;
|
||||
} else {
|
||||
/* Pop pending to address in different segment */
|
||||
limit = BufferBase(buf);
|
||||
}
|
||||
}
|
||||
/* Segment is buffered: scannable up to limit of initialized objects. */
|
||||
limit = BufferScanLimit(buf);
|
||||
}
|
||||
return limit;
|
||||
}
|
||||
|
|
@ -553,7 +530,7 @@ static Res SNCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
|
|||
|
||||
format = pool->format;
|
||||
base = SegBase(seg);
|
||||
limit = SNCScanLimit(PoolArena(pool), seg);
|
||||
limit = SNCScanLimit(seg);
|
||||
|
||||
if (base < limit) {
|
||||
res = (*format->scan)(&ss->ss_s, base, limit);
|
||||
|
|
@ -575,16 +552,11 @@ static Res SNCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
|
|||
|
||||
static Res SNCFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf)
|
||||
{
|
||||
FrameState state;
|
||||
AVER(frameReturn != NULL);
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Buffer, buf);
|
||||
|
||||
state = BufferFrameState(buf);
|
||||
/* Should have been notified of pending pops before this */
|
||||
AVER(state == BufferFrameVALID || state == BufferFrameDISABLED);
|
||||
if (state == BufferFrameDISABLED) {
|
||||
AVER(BufferIsReset(buf)); /* The buffer must be reset */
|
||||
if (BufferIsReset(buf)) {
|
||||
AVER(sncBufferTopSeg(buf) == NULL); /* The stack must be empty */
|
||||
/* Use NULL to indicate an empty stack. .lw-frame-null */
|
||||
*frameReturn = NULL;
|
||||
|
|
@ -609,7 +581,7 @@ static Res SNCFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf)
|
|||
}
|
||||
|
||||
|
||||
static void SNCFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
|
||||
static Res SNCFramePop(Pool pool, Buffer buf, AllocFrame frame)
|
||||
{
|
||||
Addr addr;
|
||||
SNC snc;
|
||||
|
|
@ -618,8 +590,6 @@ static void SNCFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
|
|||
/* frame is an Addr and can't be directly checked */
|
||||
snc = PoolSNC(pool);
|
||||
AVERT(SNC, snc);
|
||||
|
||||
AVER(BufferFrameState(buf) == BufferFrameVALID);
|
||||
|
||||
if (frame == NULL) {
|
||||
/* corresponds to a pop to bottom of stack. .lw-frame-null */
|
||||
|
|
@ -646,19 +616,9 @@ static void SNCFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
|
|||
BufferDetach(buf, pool);
|
||||
sncPopPartialSegChain(snc, buf, seg);
|
||||
BufferAttach(buf, SegBase(seg), SegLimit(seg), addr, (Size)0);
|
||||
/* Permit the use of lightweight frames - .lw-frame-state */
|
||||
BufferFrameSetState(buf, BufferFrameVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Res SNCFramePop(Pool pool, Buffer buf, AllocFrame frame)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Buffer, buf);
|
||||
BufferFrameSetState(buf, BufferFrameVALID);
|
||||
SNCFramePopPending(pool, buf, frame);
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
|
@ -683,7 +643,7 @@ static void SNCWalk(Pool pool, Seg seg, FormattedObjectsVisitor f,
|
|||
snc = PoolSNC(pool);
|
||||
AVERT(SNC, snc);
|
||||
format = pool->format;
|
||||
limit = SNCScanLimit(PoolArena(pool), seg);
|
||||
limit = SNCScanLimit(seg);
|
||||
|
||||
while(object < limit) {
|
||||
(*f)(object, format, pool, p, s);
|
||||
|
|
@ -759,7 +719,6 @@ DEFINE_POOL_CLASS(SNCPoolClass, this)
|
|||
this->scan = SNCScan;
|
||||
this->framePush = SNCFramePush;
|
||||
this->framePop = SNCFramePop;
|
||||
this->framePopPending = SNCFramePopPending;
|
||||
this->walk = SNCWalk;
|
||||
this->bufferClass = SNCBufClassGet;
|
||||
this->totalSize = SNCTotalSize;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue