1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-11 16:52:40 -07:00

Merging mmdevel_action2

Copied from Perforce
 Change: 17498
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 1997-04-15 15:24:00 +01:00
parent 5d0a6ddf00
commit 39de4f1fa1
28 changed files with 1020 additions and 640 deletions

View file

@ -1,6 +1,6 @@
/* impl.c.amcss: POOL CLASS AMC STRESS TEST
*
* $HopeName: MMsrc!amcss.c(trunk.11) $
* $HopeName: MMsrc!amcss.c(trunk.12) $
* Copyright (C) 1996 Harlequin Group, all rights reserved
*/
@ -91,8 +91,9 @@ static void *test(void *arg, size_t s)
collections = c;
printf("\nCollection %u, %lu objects.\n",
c, (unsigned long)i);
for(r=0; r<NR_EXACT_ROOTS; ++r)
assert(dylan_check(exact_roots[r]));
for(r = 0; r < NR_EXACT_ROOTS; ++r)
assert(exact_roots[r] == OBJNULL ||
dylan_check(exact_roots[r]));
}
if(rnd() & 1)

View file

@ -1,6 +1,6 @@
/* impl.c.arenacl: ARENA IMPLEMENTATION USING CLIENT MEMORY
*
* $HopeName: MMsrc!arenacl.c(MMdevel_sw_eq.5) $
* $HopeName: MMsrc!arenacl.c(trunk.2) $
*
* Copyright (C) 1996 Harlequin Group, all rights reserved.
*
@ -41,7 +41,7 @@
#error "Client arena not configured"
#endif
SRCID(arenacl, "$HopeName: MMsrc!arenacl.c(MMdevel_sw_eq.5) $");
SRCID(arenacl, "$HopeName: MMsrc!arenacl.c(trunk.2) $");
Bool ArenaCheck(Arena arena)
{
@ -430,14 +430,6 @@ Size ArenaCommitted(Space space)
return size;
}
/* SegCheck -- check the consistency of a segment structure */
Bool SegCheck(Seg seg)
{
CHECKU(Pool, seg->pool);
/* .seg.check-little: all other fields can't be checked */
return TRUE;
}
/* preferences... */
@ -548,14 +540,7 @@ static Res ChunkSegAlloc(Seg *segReturn, SegPref pref, Size pages, Pool pool,
found:
/* Initialize the generic segment structure. */
seg = &chunk->pageTable[base].the.head;
seg->pool = pool;
seg->p = NULL;
seg->rank = RankEXACT; /* exact by default */
seg->condemned = TraceIdNONE;
seg->pm = AccessSetEMPTY; /* see impl.c.shield */
seg->sm = AccessSetEMPTY;
seg->depth = 0;
SegInit(seg, pool);
/* Allocate the first page, and, if there is more than one page,
* allocate the rest of the pages and store the multi-page information
@ -667,6 +652,8 @@ void SegFree(Space space, Seg seg)
limit = SegLimit(space, seg);
SegFinish(seg);
/* Remember the base address of the segment so it can be */
/* unmapped .free.unmap */
base = PageBase(chunk, pi);

View file

@ -1,7 +1,7 @@
/* impl.c.arenavm: VIRTUAL MEMORY BASED ARENA IMPLEMENTATION
*
* $HopeName: MMsrc!arenavm.c(trunk.13) $
* Copyright (C) 1996,1997 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!arenavm.c(trunk.14) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* This is the implementation of the Segment abstraction from the VM
* abstraction. Use of this arena implies use of a VM.
@ -14,7 +14,7 @@
#include "mpm.h"
SRCID(arenavm, "$HopeName: MMsrc!arenavm.c(trunk.13) $");
SRCID(arenavm, "$HopeName: MMsrc!arenavm.c(trunk.14) $");
/* Space Arena Projection
@ -262,18 +262,6 @@ Bool ArenaCheck(Arena arena)
}
/* SegCheck -- check the consistency of a segment structure */
Bool SegCheck(Seg seg)
{
CHECKU(Pool, seg->pool);
/* .seg.check-little: all other fields can't be checked */
return TRUE;
}
/* preferences... */
Bool SegPrefCheck(SegPref pref)
{
CHECKS(SegPref, pref);
@ -311,6 +299,7 @@ Res SegPrefExpress (SegPref sp, SegPrefKind kind, void *p)
}
}
/* SegAlloc -- allocate a segment from the arena */
Res SegAlloc(Seg *segReturn, SegPref pref, Space space, Size size, Pool pool)
@ -369,17 +358,7 @@ found:
/* Initialize the generic segment structure. */
seg = &arena->pageTable[base].the.head;
seg->pool = pool;
seg->p = NULL;
seg->rank = RankEXACT; /* exact by default */
seg->condemned = TraceIdNONE;
seg->grey = TraceSetEMPTY;
seg->buffer = NULL;
RingInit(&seg->poolRing);
seg->pm = AccessSetEMPTY; /* see impl.c.shield */
seg->sm = AccessSetEMPTY;
seg->depth = 0;
SegInit(seg, pool);
/* Allocate the first page, and, if there is more than one page,
* allocate the rest of the pages and store the multi-page information
@ -428,6 +407,8 @@ void SegFree(Space space, Seg seg)
pi = page - arena->pageTable;
AVER(pi <= arena->pages);
SegFinish(seg);
/* Remember the base address of the segment so it can be */
/* unmapped .free.unmap */
base = PageBase(arena, pi);

View file

@ -1,7 +1,7 @@
/* impl.c.buffer: ALLOCATION BUFFER IMPLEMENTATION
*
* $HopeName: MMsrc!buffer.c(trunk.20) $
* Copyright (C) 1996 Harlequin Group, all rights reserved
* $HopeName: MMsrc!buffer.c(MMdevel_action2.4) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* This is (part of) the implementation of allocation buffers.
*
@ -29,108 +29,7 @@
#include "mpm.h"
SRCID(buffer, "$HopeName: MMsrc!buffer.c(trunk.20) $");
/* BufferCreate -- create an allocation buffer in a pool
*
* design.mps.buffer.method.create
*/
Res BufferCreate(Buffer *bufferReturn, Pool pool, Rank rank)
{
Res res;
Buffer buffer;
Space space;
void *p;
AVER(bufferReturn != NULL);
AVERT(Pool, pool);
/* The PoolClass should support buffer protocols */
AVER((pool->class->attr & AttrBUF)); /* .trans.mod */
AVER(RankCheck(rank));
space = PoolSpace(pool);
/* Allocate the buffer structure. */
res = SpaceAlloc(&p, space, sizeof(BufferStruct));
if(res != ResOK) return res;
buffer = p;
/* Initialize the buffer. See impl.h.mpmst for a definition of the
* structure */
/* sig and serial comes later .init.sig-serial */
buffer->space = space;
buffer->pool = pool;
buffer->seg = NULL;
buffer->rank = rank;
buffer->base = (Addr)0;
buffer->apStruct.init = (Addr)0;
buffer->apStruct.alloc = (Addr)0;
buffer->apStruct.limit = (Addr)0;
buffer->alignment = pool->alignment; /* .trans.mod */
RingInit(&buffer->poolRing);
buffer->shieldMode = AccessSetEMPTY;
buffer->p = NULL;
buffer->i = 0;
/* Dispatch to the pool class method to perform any extra */
/* initialization of the buffer. */
res = (*pool->class->bufferInit)(pool, buffer);
if(res != ResOK) {
SpaceFree(space, (Addr)buffer, sizeof(BufferStruct));
return res;
}
/* .init.sig-serial: Now that it's initialized, sign the buffer,
* give it a serial number, and check it. */
buffer->sig = BufferSig;
buffer->serial = pool->bufferSerial; /* .trans.mod */
++pool->bufferSerial;
AVERT(Buffer, buffer);
/* Attach the initialized buffer to the pool. */
RingAppend(&pool->bufferRing, &buffer->poolRing);
*bufferReturn = buffer;
return ResOK;
}
/* BufferDestroy -- destroy an allocation buffer
*
* design.mps.buffer.method.destroy
*/
void BufferDestroy(Buffer buffer)
{
Space space;
Pool pool;
AVERT(Buffer, buffer);
/* Make a copy of the space before the buffer gets finished. */
space = buffer->space;
pool = buffer->pool;
/* The PoolClass should support buffer protocols */
AVER((pool->class->attr & AttrBUF)); /* .trans.mod */
AVER(BufferIsReady(buffer));
/* Detach the buffer from its owning pool. */
RingRemove(&buffer->poolRing);
/* Dispatch to the pool class method to finish the buffer. */
(*pool->class->bufferFinish)(pool, buffer);
/* Unsign the finished buffer. */
buffer->sig = SigInvalid;
/* Finish off the generic buffer fields and deallocate the */
/* buffer structure. */
RingFinish(&buffer->poolRing);
SpaceFree(space, (Addr)buffer, sizeof(BufferStruct));
}
SRCID(buffer, "$HopeName: MMsrc!buffer.c(MMdevel_action2.4) $");
/* BufferCheck
@ -145,29 +44,159 @@ Bool BufferCheck(Buffer buffer)
CHECKL(buffer->serial < buffer->pool->bufferSerial); /* .trans.mod */
CHECKU(Space, buffer->space);
CHECKU(Pool, buffer->pool);
/* seg and rank checked in anomalous order */
CHECKL(RankCheck(buffer->rank)); /* design.mps.check.type.no-sig */
CHECKL(RankSetCheck(buffer->rankSet));
if(buffer->seg != NULL) {
CHECKL(SegCheck(buffer->seg)); /* design.mps.check.type.no-sig */
CHECKL(SegCheck(buffer->seg)); /* design.mps.check.type.no-sig */
CHECKL(buffer->seg->buffer == buffer);
CHECKL(buffer->rank == buffer->seg->rank);
CHECKL(buffer->rankSet == buffer->seg->rankSet);
}
CHECKL(buffer->base <= buffer->apStruct.init);
CHECKL(buffer->apStruct.init <= buffer->apStruct.alloc);
CHECKL(buffer->apStruct.alloc <= buffer->apStruct.limit ||
buffer->apStruct.limit == 0);
buffer->apStruct.limit == 0);
CHECKL(buffer->alignment == buffer->pool->alignment);
CHECKL(AlignCheck(buffer->alignment));
CHECKL(AddrIsAligned(buffer->base, buffer->alignment));
CHECKL(AddrIsAligned(buffer->apStruct.init, buffer->alignment));
CHECKL(AddrIsAligned(buffer->apStruct.alloc, buffer->alignment));
CHECKL(AddrIsAligned(buffer->apStruct.limit, buffer->alignment));
CHECKL(RingCheck(&buffer->poolRing)); /* design.mps.check.type.no-sig */
CHECKL(RingCheck(&buffer->poolRing)); /* design.mps.check.type.no-sig */
/* buffer->p, and buffer->i are arbitrary and cannot be checked */
return TRUE;
}
/* BufferCreate -- create an allocation buffer
*
* design.mps.buffer.method.create
*/
Res BufferCreate(Buffer *bufferReturn, Pool pool, Rank rank)
{
Res res;
Buffer buffer;
Space space;
void *p;
AVER(bufferReturn != NULL);
AVERT(Pool, pool);
AVER(RankCheck(rank));
space = PoolSpace(pool);
/* Allocate the buffer structure. */
res = SpaceAlloc(&p, space, sizeof(BufferStruct));
if(res != ResOK) goto failAlloc;
buffer = p;
res = BufferInit(buffer, pool, rank);
if(res != ResOK) goto failInit;
*bufferReturn = buffer;
return ResOK;
failInit:
SpaceFree(space, (Addr)buffer, sizeof(BufferStruct));
failAlloc:
return res;
}
/* BufferInit -- initialize an allocation buffer */
Res BufferInit(Buffer buffer, Pool pool, Rank rank)
{
Res res;
AVER(buffer != NULL);
AVERT(Pool, pool);
/* The PoolClass should support buffer protocols */
AVER((pool->class->attr & AttrBUF)); /* .trans.mod */
AVER(RankCheck(rank));
/* Initialize the buffer. See impl.h.mpmst for a definition of the */
/* structure. sig and serial comes later .init.sig-serial */
buffer->space = PoolSpace(pool);
buffer->pool = pool;
buffer->seg = NULL;
buffer->rankSet = RankSetSingle(rank);
buffer->base = (Addr)0;
buffer->apStruct.init = (Addr)0;
buffer->apStruct.alloc = (Addr)0;
buffer->apStruct.limit = (Addr)0;
buffer->alignment = pool->alignment; /* .trans.mod */
RingInit(&buffer->poolRing);
buffer->p = NULL;
buffer->i = 0;
/* Dispatch to the pool class method to perform any extra */
/* initialization of the buffer. */
res = (*pool->class->bufferInit)(pool, buffer);
if(res != ResOK) return res;
/* .init.sig-serial: Now that it's initialized, sign the buffer, */
/* give it a serial number, and check it. */
buffer->sig = BufferSig;
buffer->serial = pool->bufferSerial; /* .trans.mod */
++pool->bufferSerial;
AVERT(Buffer, buffer);
/* Attach the initialized buffer to the pool. */
RingAppend(&pool->bufferRing, &buffer->poolRing);
return ResOK;
}
/* BufferDestroy -- destroy an allocation buffer
*
* design.mps.buffer.method.destroy
*/
void BufferDestroy(Buffer buffer)
{
Space space;
AVERT(Buffer, buffer);
space = buffer->space;
BufferFinish(buffer);
SpaceFree(space, (Addr)buffer, sizeof(BufferStruct));
}
/* BufferFinish -- finish an allocation buffer */
void BufferFinish(Buffer buffer)
{
Pool pool;
AVERT(Buffer, buffer);
pool = buffer->pool;
/* The PoolClass should support buffer protocols */
AVER((pool->class->attr & AttrBUF)); /* .trans.mod */
AVER(BufferIsReady(buffer));
/* Detach the buffer from its owning pool. */
RingRemove(&buffer->poolRing);
/* Dispatch to the pool class method to finish the buffer. */
(*pool->class->bufferFinish)(pool, buffer);
/* Pool should make sure buffer is not attached. */
/* @@@@ Are there other conditions? */
AVER(BufferIsReset(buffer));
/* Unsign the finished buffer. */
buffer->sig = SigInvalid;
/* Finish off the generic buffer fields. */
RingFinish(&buffer->poolRing);
}
/* BufferSet/Reset -- set/reset a buffer
*
* Set sets the buffer base, init, alloc, and limit fields so that
@ -182,9 +211,13 @@ Bool BufferCheck(Buffer buffer)
void BufferSet(Buffer buffer, Seg seg, Addr base, Addr init, Addr limit)
{
AVERT(Buffer, buffer);
AVER(SegCheck(seg));
AVER(BufferIsReady(buffer));
/* No check for base, init, limit */
AVER(SegCheck(seg));
AVER(seg->buffer == NULL);
AVER(SegBase(buffer->space, seg) <= base);
AVER(base <= init);
AVER(limit == 0 || init <= limit);
AVER(limit == 0 || limit <= SegLimit(buffer->space, seg));
buffer->seg = seg;
seg->buffer = buffer;
@ -198,6 +231,7 @@ void BufferReset(Buffer buffer)
{
AVERT(Buffer, buffer);
AVER(BufferIsReady(buffer));
AVER(buffer->seg->buffer == buffer);
buffer->seg->buffer = NULL;
buffer->seg = NULL;
@ -419,12 +453,11 @@ Res BufferDescribe(Buffer buffer, mps_lib_FILE *stream)
" Space $P\n", (WriteFP)buffer->space,
" Pool $P\n", (WriteFP)buffer->pool,
" Seg $P\n", (WriteFP)buffer->seg,
" rank $U\n", (WriteFU)buffer->rank,
" rankSet $U\n", (WriteFU)buffer->rankSet,
" base $A init $A alloc $A limit $A\n",
buffer->base, buffer->apStruct.init,
buffer->apStruct.alloc, buffer->apStruct.limit,
" alignment $W\n", (WriteFW)buffer->alignment,
" shieldMode $B\n", (WriteFB)buffer->shieldMode,
" p $P i $U\n", buffer->p, (WriteFU)buffer->i,
"} Buffer $P ($U)\n", (WriteFP)buffer, (WriteFU)buffer->serial,
NULL);

View file

@ -1,6 +1,6 @@
/* impl.h.misc: MISCELLANEOUS DEFINITIONS
*
* $HopeName: MMsrc!misc.h(trunk.9) $
* $HopeName: MMsrc!misc.h(MMdevel_action2.2) $
* Copyright (C) 1994,1995,1996 Harlequin Group, all rights reserved
*
* Small general things which are useful for C but aren't part of the
@ -126,7 +126,7 @@ typedef const struct SrcIdStruct {
#define BS_DEL(ty, s, i) BS_DIFF(s, BS_SINGLE(ty, i))
#define BS_SUPER(s1, s2) (BS_INTER(s1, s2) == s2)
#define BS_SUB(s1, s2) BS_SUPER(s2, s1)
#define BS_IS_SINGLE(s) (((s) & (s)-1) == 0)
#define BS_IS_SINGLE(s) (((s) & ((s)-1)) == 0)
#endif /* misc_h */

View file

@ -1,7 +1,7 @@
/* impl.h.mpm: MEMORY POOL MANAGER DEFINITIONS
*
* $HopeName: MMsrc!mpm.h(trunk.22) $
* Copyright (C) 1996,1997 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!mpm.h(trunk.23) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*/
#ifndef mpm_h
@ -255,16 +255,13 @@ extern Res PoolCreateV(Pool *poolReturn, Space space,
extern void PoolDestroy(Pool pool);
extern Res PoolAlloc(Addr *pReturn, Pool pool, Size size);
extern void PoolFree(Pool pool, Addr old, Size size);
extern Res PoolCondemn(RefSet *condemnedReturn, Pool pool,
Space space, TraceId ti);
extern void PoolGrey(Pool pool, Space space, TraceId ti);
extern Res PoolScan(ScanState ss, Pool pool, Bool *finishedReturn);
extern Res PoolCondemn(Pool pool, Trace trace, Seg seg);
extern void PoolGrey(Pool pool, Trace trace, Seg seg);
extern Res PoolScan(ScanState ss, Pool pool, Seg seg);
extern Res (PoolFix)(Pool pool, ScanState ss, Seg seg, Addr *refIO);
#define PoolFix(pool, ss, seg, refIO) \
((*(pool)->class->fix)(pool, ss, seg, refIO))
extern void PoolReclaim(Pool pool, Space space, TraceId ti);
extern void PoolAccess(Pool pool, Seg seg, AccessSet mode);
extern void PoolReclaim(Pool pool, Trace trace, Seg seg);
extern void PoolTrivFinish(Pool pool);
extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size);
@ -281,47 +278,50 @@ extern void PoolNoBufferExpose(Pool pool, Buffer buffer);
extern void PoolNoBufferCover(Pool pool, Buffer buffer);
extern Res PoolNoDescribe(Pool pool, mps_lib_FILE *stream);
extern Res PoolTrivDescribe(Pool pool, mps_lib_FILE *stream);
extern Res PoolNoCondemn(RefSet *condemnedReturn, Pool pool, Space space, TraceId ti);
extern void PoolNoGrey(Pool pool, Space space, TraceId ti);
extern Res PoolNoScan(ScanState ss, Pool pool, Bool *finishedReturn);
extern Res PoolNoCondemn(Pool pool, Trace trace, Seg seg);
extern void PoolNoGrey(Pool pool, Trace trace, Seg seg);
extern void PoolTrivGrey(Pool pool, Trace trace, Seg seg);
extern Res PoolNoScan(ScanState ss, Pool pool, Seg seg);
extern Res PoolNoFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
extern void PoolNoReclaim(Pool pool, Space space, TraceId ti);
extern void PoolNoAccess(Pool pool, Seg seg, AccessSet mode);
extern void PoolNoReclaim(Pool pool, Trace trace, Seg seg);
/* Trace Interface -- see impl.c.trace */
#define TraceSetSingle(ti) BS_SINGLE(TraceSet, ti)
#define TraceSetIsMember(ts, ti)BS_IS_MEMBER(ts, ti)
#define TraceSetAdd(ts, ti) BS_ADD(TraceSet, ts, ti)
#define TraceSetDel(ts, ti) BS_DEL(TraceSet, ts, ti)
#define TraceSetUnion(ts1, ts2) BS_UNION(ts1, ts2)
#define TraceSetInter(ts1, ts2) BS_INTER(ts1, ts2)
#define TraceSetDiff(ts1, ts2) BS_DIFF(ts1, ts2)
#define TraceSetSuper(ts1, ts2) BS_SUPER(ts1, ts2)
extern TraceSet (TraceSetAdd)(TraceSet ts, TraceId id);
extern TraceSet (TraceSetDel)(TraceSet ts, TraceId id);
extern TraceSet (TraceSetUnion)(TraceSet ts1, TraceSet ts2);
extern Bool (TraceSetIsMember)(TraceSet ts, TraceId id);
extern Res TraceCreate(TraceId *tiReturn, Space space);
extern void TraceDestroy(Space space, TraceId ti);
extern Bool ScanStateCheck(ScanState ss);
extern Bool TraceIdCheck(TraceId id);
extern Bool TraceSetCheck(TraceSet ts);
extern Bool TraceCheck(Trace trace);
extern Res TraceFlip(Space space, TraceId ti, RefSet condemned);
extern Size TracePoll(Space space, TraceId ti);
extern Res TraceRunAtomic(Space space, TraceId ti);
extern Res TraceRun(Space space, TraceId ti, Bool *finishedReturn);
extern Res TraceCreate(Trace *traceReturn, Space space);
extern void TraceDestroy(Trace trace);
extern Res TraceStart(Trace trace, Pool pool);
extern Res TracePoll(Trace trace);
extern void TraceAccess(Space space, Seg seg, AccessSet mode);
extern Res TraceFix(ScanState ss, Ref *refIO);
extern void TraceSegGreyen(Space space, Seg seg, TraceSet ts);
/* Equivalent to impl.h.mps MPS_SCAN_BEGIN */
#define TRACE_SCAN_BEGIN(ss) \
BEGIN \
Shift SCANzoneShift = (ss)->zoneShift; \
RefSet SCANcondemned = (ss)->condemned; \
RefSet SCANwhite = (ss)->white; \
RefSet SCANsummary = (ss)->summary; \
Word SCANt; \
{
@ -331,7 +331,7 @@ extern Res TraceFix(ScanState ss, Ref *refIO);
#define TRACE_FIX1(ss, ref) \
(SCANt = (Word)1<<((Word)(ref)>>SCANzoneShift&(MPS_WORD_WIDTH-1)), \
SCANsummary |= SCANt, \
SCANcondemned & SCANt)
SCANwhite & SCANt)
/* Equivalent to impl.h.mps MPS_FIX2 */
@ -355,6 +355,14 @@ extern Res TraceScanArea(ScanState ss, Addr *base, Addr *limit);
extern Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit);
/* Action Interface -- see design.mps.action */
extern Bool ActionCheck(Action action);
extern void ActionInit(Action action, Pool pool);
extern void ActionFinish(Action action);
extern void ActionPoll(Space space);
/* Space Interface -- see impl.c.space */
extern Res SpaceCreate(Space *spaceReturn, Addr base, Size size);
@ -373,7 +381,8 @@ extern void SpaceFree(Space space, Addr base, Size size);
#define SpaceTraceRing(space) (&(space)->traceRing)
#define SpaceThreadRing(space) (&(space)->threadRing)
#define SpaceEpoch(space) ((space)->epoch) /* .epoch.ts */
#define SpaceTrace(space, ti) (&(space)->trace[ti])
#define SpaceZoneShift(space) ((space)->zoneShift)
/* Arena Interface -- see impl.c.arena* */
@ -401,6 +410,8 @@ extern Bool SegOfAddr(Seg *segReturn, Space space, Addr addr);
extern Seg SegFirst(Space space);
extern Seg SegNext(Space space, Seg seg);
extern Bool SegCheck(Seg seg);
extern void SegInit(Seg seg, Pool pool);
extern void SegFinish(Seg seg);
/* Buffer Interface -- see impl.c.buffer */
@ -413,7 +424,7 @@ extern Res BufferReserve(Addr *pReturn, Buffer buffer, Size size);
extern Res BufferFill(Addr *pReturn, Buffer buffer, Size size);
extern Bool BufferCommit(Buffer buffer, Addr p, Size size);
extern Bool BufferTrip(Buffer buffer, Addr p, Size size);
extern void BufferInit(Buffer buffer, Pool pool, Rank rank);
extern Res BufferInit(Buffer buffer, Pool pool, Rank rank);
extern void BufferFinish(Buffer buffer);
extern void BufferSet(Buffer buffer, Seg seg, Addr base, Addr init, Addr limit);
extern void BufferReset(Buffer buffer);
@ -458,6 +469,11 @@ extern Res FormatDescribe(Format format, mps_lib_FILE *stream);
/* Reference Interface -- see impl.c.ref */
extern Bool RankCheck(Rank rank);
extern Bool RankSetCheck(RankSet rankSet);
#define RankSetIsMember(rs, r) BS_IS_MEMBER(rs, r)
#define RankSetSingle(r) BS_SINGLE(RankSet, r)
#define RankSetIsSingle(r) BS_IS_SINGLE(r)
#define RefSetZone(space, addr) \
(((Word)(addr) >> space->zoneShift) & (MPS_WORD_WIDTH - 1))
@ -522,7 +538,7 @@ extern Bool RootCheck(Root root);
extern Res RootDescribe(Root root, mps_lib_FILE *stream);
extern Bool RootIsAtomic(Root root);
extern Rank RootRank(Root root);
extern void RootGrey(Root root, TraceId ti);
extern void RootGrey(Root root, Trace trace);
extern Res RootScan(ScanState ss, Root root);
extern Space RootSpace(Root root);

View file

@ -1,7 +1,7 @@
/* impl.h.mpmst: MEMORY POOL MANAGER DATA STRUCTURES
*
* $HopeName: MMsrc!mpmst.h(trunk.19) $
* Copyright (C) 1996,1997 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!mpmst.h(MMdevel_action2.11) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* .readership: MM developers.
*
@ -94,11 +94,10 @@ typedef struct PoolClassStruct {
PoolBufferExposeMethod bufferExpose; /* remove protection */
PoolBufferCoverMethod bufferCover; /* reinstate protection */
PoolCondemnMethod condemn; /* condemn (some or all) objects */
PoolGreyMethod grey; /* grey uncondemned objects */
PoolGreyMethod grey; /* grey non-white objects */
PoolScanMethod scan; /* find references during tracing */
PoolFixMethod fix; /* referent reachable during tracing */
PoolReclaimMethod reclaim; /* reclaim dead objects after tracing */
PoolAccessMethod access; /* handle an access to shielded memory */
PoolDescribeMethod describe; /* describe the contents of the pool */
Sig endSig; /* .class.end-sig */
} PoolClassStruct;
@ -125,6 +124,8 @@ typedef struct PoolStruct { /* generic structure */
RingStruct bufferRing; /* allocation buffers are attached to pool */
Serial bufferSerial; /* serial of next buffer */
RingStruct segRing; /* segs are attached to pool */
RingStruct actionRing; /* actions are attached to pool */
Serial actionSerial; /* serial of next action */
Align alignment; /* alignment for units */
} PoolStruct;
@ -262,26 +263,20 @@ typedef struct VMStruct {
/* SegStruct -- segment structure
*
* .seg: Segments are the basic units of memory allocation from
* the arena, and also the units of scanning, shielding, and colour
* for the MPM (pool classes may subdivide segments and be able to
* maintain colour on a finer grain (down to the object level for example)).
*
* .seg.pm: The pm field is used by both the shield (impl.c.shield)
* and the ANSI fake protection (impl.c.protan).
*
* .seg.pool: This field must be first. See
* design.mps.arena.vm.assume.pointer-conversion for why.
* the arena. See design.mps.seg.
*/
typedef struct SegStruct { /* segment structure */
Pool pool; /* MUST BE FIRST, see .seg.pool */
Pool pool; /* MUST BE FIRST (design.mps.seg.field.pool) */
Bool single; /* single page segment */
Rank rank; /* rank of all references in this seg */
RankSet rankSet; /* ranks of references in this seg */
AccessSet pm, sm; /* protection and shield modes */
Size depth; /* see impl.c.shield.def.depth */
void *p; /* pointer for use of owning pool */
TraceId condemned; /* seg condemned? for which trace? */
TraceSet black; /* traces for which seg is black */
TraceSet grey; /* traces for which seg is grey */
TraceSet white; /* traces for which seg is white */
RefSet summary; /* summary of references out of seg */
Buffer buffer; /* non-NULL if seg is buffered */
RingStruct poolRing; /* link in list of segs in pool */
} SegStruct;
@ -386,18 +381,13 @@ typedef struct BufferStruct {
Space space; /* owning space */
Pool pool; /* owning pool */
Seg seg; /* segment being buffered */
Rank rank; /* rank of references being created */
Rank rankSet; /* ranks of references being created */
Addr base; /* base address of allocation buffer */
APStruct apStruct; /* the allocation point */
Align alignment; /* allocation alignment */
RingStruct poolRing; /* buffers are attached to pools */
AccessSet shieldMode; /* shielding for allocated memory */
#if 0
Bool exposed; /* is buffer memory exposed? */
TraceSet grey; /* colour for allocated memory */
#endif
void *p;
int i; /* (p and i) closure variables (for pool) */
void *p; /* closure variable for pool */
int i; /* closure variable for pool */
} BufferStruct;
@ -511,7 +501,8 @@ typedef struct RootStruct {
Space space; /* owning space */
RingStruct spaceRing; /* attachment to space */
Rank rank; /* rank of references in this root */
TraceSet grey; /* marked but not scanned for per trace */
TraceSet grey; /* traces for which root is grey */
RefSet summary; /* summary of references in root */
RootVar var; /* union discriminator */
union RootUnion {
struct {
@ -537,7 +528,7 @@ typedef struct RootStruct {
} RootStruct;
/* ScanState and TraceStruct
/* ScanState
*
* .ss: See impl.c.trace.
*
@ -545,16 +536,13 @@ typedef struct RootStruct {
* external scan state structure (mps_ss_s) thus:
* ss->fix mps_ss->fix
* ss->zoneShift mps_ss->w0
* ss->condemned mps_ss->w1
* ss->white mps_ss->w1
* ss->summary mps_ss->w2
* See impl.h.mps.ss and impl.c.mpsi.check.ss. This is why the
* Sig field is in the middle of this structure.
*
* .ss.zone: The zoneShift field is therefore declared as Word
* rather than Shift.
*
* The weakSplat field forms part of the design for weakness.
* See design.mps.weakness.
*/
#define ScanStateSig ((Sig)0x5195CA95)
@ -562,21 +550,45 @@ typedef struct RootStruct {
typedef struct ScanStateStruct {
Res (*fix)(ScanState, Addr *);/* fix function */
Word zoneShift; /* copy of space->zoneShift. See .ss.zone */
RefSet condemned; /* condemned set, for inline fix test */
RefSet white; /* white set, for inline fix test */
RefSet summary; /* accumulated summary of scanned references */
Sig sig; /* design.mps.sig */
Space space; /* owning space */
TraceId traceId; /* trace ID of scan */
TraceSet traces; /* traces to scan for */
Rank rank; /* reference rank of scanning */
Addr weakSplat; /* value of weak refs to unforwarded objects */
Bool wasMarked; /* design.mps.fix.protocol.was-ready */
} ScanStateStruct;
/* TraceStruct -- tracer state structure */
#define TraceSig ((Sig)0x51924ACE)
typedef struct TraceStruct {
RefSet condemned; /* summary of comdemnded set */
Sig sig; /* design.mps.sig */
TraceId ti; /* index into TraceSets */
Space space; /* owning space */
RefSet white; /* superset of refs in white set */
TraceState state; /* current state of trace */
Size interval; /* polling interval */
} TraceStruct;
/* ActionStruct -- action structure
*
* See design.mps.action.
*/
#define ActionSig ((Sig)0x519AC209)
typedef struct ActionStruct {
Sig sig; /* design.mps.sig */
Serial serial; /* from pool->actionSerial */
Pool pool; /* owning pool */
RingStruct poolRing; /* link in list of actions in pool */
} ActionStruct;
/* SpaceStruct -- the space structure
*
* See impl.c.space.
@ -599,6 +611,7 @@ typedef struct SpaceStruct {
LockStruct lockStruct; /* space's lock */
Size pollThreshold; /* see impl.c.mpsi.poll and SpacePoll */
Bool insidePoll; /* prevent recursive polling, see SpacePoll */
Size actionInterval; /* see SpacePoll */
/* arena fields (impl.c.arena*) */
ArenaStruct arenaStruct; /* the arena */
@ -629,6 +642,7 @@ typedef struct SpaceStruct {
/* trace fields (impl.c.trace) */
TraceSet busyTraces; /* set of running traces */
TraceSet flippedTraces; /* set of running and flipped traces */
TraceStruct trace[TRACE_MAX]; /* trace structures. See
design.mps.trace.intance.limit */

View file

@ -1,7 +1,7 @@
/* impl.h.mpmtypes: MEMORY POOL MANAGER TYPES
*
* $HopeName: MMsrc!mpmtypes.h(trunk.18) $
* Copyright (C) 1996,1997 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!mpmtypes.h(MMdevel_action2.9) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* .readership: MM developers.
* .design: design.mps.type
@ -39,9 +39,11 @@ typedef Addr Ref; /* design.mps.type.ref */
typedef void *Pointer; /* design.mps.type.pointer */
typedef Word RefSet; /* design.mps.refset */
typedef unsigned Rank; /* design.mps.ref */
typedef unsigned RankSet;
typedef Size Epoch; /* design.mps.ld */
typedef unsigned TraceId; /* design.mps.tracer */
typedef unsigned TraceSet; /* design.mps.tracer */
typedef unsigned TraceState; /* design.mps.tracer */
typedef unsigned AccessSet; /* design.mps.type.access-set */
typedef unsigned Attr; /* design.mps.type.attr */
typedef int RootVar; /* design.mps.type.rootvar */
@ -66,6 +68,7 @@ typedef struct VMStruct *VM; /* impl.c.vm* */
typedef struct RootStruct *Root; /* impl.c.root */
typedef struct ThreadStruct *Thread; /* impl.c.th* */
typedef Word EventType; /* impl.c.event */
typedef struct ActionStruct *Action; /* design.mps.action */
/* Pool*Method -- see design.mps.class-interface */
@ -83,15 +86,12 @@ typedef Bool (*PoolBufferTripMethod) (Pool pool, Buffer buffer,
typedef void (*PoolBufferExposeMethod) (Pool pool, Buffer buffer);
typedef void (*PoolBufferCoverMethod) (Pool pool, Buffer buffer);
typedef Res (*PoolDescribeMethod) (Pool pool, mps_lib_FILE *stream);
typedef Res (*PoolCondemnMethod) (RefSet *condemnedReturn, Pool pool,
Space space, TraceId ti);
typedef void (*PoolGreyMethod) (Pool pool, Space space, TraceId ti);
typedef Res (*PoolScanMethod) (ScanState ss, Pool pool,
Bool *finishedReturn);
typedef Res (*PoolCondemnMethod) (Pool pool, Trace trace, Seg seg);
typedef void (*PoolGreyMethod) (Pool pool, Trace trace, Seg seg);
typedef Res (*PoolScanMethod) (ScanState ss, Pool pool, Seg seg);
typedef Res (*PoolFixMethod) (Pool pool, ScanState ss, Seg seg,
Ref *refIO);
typedef void (*PoolReclaimMethod) (Pool pool, Space space, TraceId ti);
typedef void (*PoolAccessMethod) (Pool pool, Seg seg, AccessSet mode);
typedef void (*PoolReclaimMethod) (Pool pool, Trace trace, Seg seg);
/* Format*Method -- see design.mps.format-interface */
@ -125,7 +125,8 @@ typedef Res (*RootScanRegMethod)(ScanState ss, Thread thread, void *p,
#define TraceIdNONE ((TraceId)-1) /* design.mps.tracer */
#define RefSetEMPTY BS_EMPTY(RefSet)
#define RefSetUNIV BS_UNIV(RefSet)
#define TraceSetEMPTY BS_EMPTY(TraceSet) /* design.mps.tracer */
#define TraceSetEMPTY BS_EMPTY(TraceSet) /* design.mps.tracer */
#define RankSetEMPTY BS_EMPTY(RankSet)
#define AttrFMT ((Attr)(1<<0)) /* design.mps.type.attr */
#define AttrSCAN ((Attr)(1<<1))
#define AttrPM_NO_READ ((Attr)(1<<2))
@ -200,6 +201,17 @@ enum {
};
/* TraceStates -- see design.mps.tracer */
enum {
TraceINIT,
TraceUNFLIPPED,
TraceFLIPPED,
TraceRECLAIM,
TraceFINISHED
};
/* Types for WriteF formats */
/* These should be used with calls to WriteF. */
/* These must be unpromotable types. */
@ -214,8 +226,11 @@ typedef void *(*WriteFF)(void);
typedef int WriteFC; /* Promoted */
/* These names are intended to be mnemonic. They are derived from selected
* letters as indicated, using the transliteration in design.mps.sig.
/* Event Codes -- see design.mps.telemetry
*
* These names are intended to be mnemonic. They are derived from
* selected letters as indicated, using the transliteration in
* guide.hex.trans.
*/
#define EventEventTime ((EventType)0xEF213E77) /* EVent TIME */
@ -234,4 +249,5 @@ typedef int WriteFC; /* Promoted */
#define EventVMMap ((EventType)0xEFF33AB7) /* EVent VM MAP */
#define EventVMUnmap ((EventType)0xEFF3093B) /* EVent VM UNMaP */
#endif /* mpmtypes_h */

View file

@ -1,7 +1,7 @@
/* impl.c.mpsi: MEMORY POOL SYSTEM C INTERFACE LAYER
*
* $HopeName: MMsrc!mpsi.c(trunk.21) $
* Copyright (C) 1996 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!mpsi.c(MMdevel_action2.3) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* .purpose: This code bridges between the MPS interface to C,
* impl.h.mps, and the internal MPM interfaces, as defined by
@ -52,7 +52,7 @@
#include "mpm.h"
#include "mps.h"
SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.21) $");
SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(MMdevel_action2.3) $");
/* mpsi_check -- check consistency of interface mappings
@ -139,7 +139,7 @@ static Bool mpsi_check(void)
/* design.mps.interface.c.pun.addr. */
CHECKL(CHECKFIELDAPPROX(mps_ss_s, fix, ScanStateStruct, fix));
CHECKL(CHECKFIELD(mps_ss_s, w0, ScanStateStruct, zoneShift));
CHECKL(CHECKFIELD(mps_ss_s, w1, ScanStateStruct, condemned));
CHECKL(CHECKFIELD(mps_ss_s, w1, ScanStateStruct, white));
CHECKL(CHECKFIELD(mps_ss_s, w2, ScanStateStruct, summary));
/* Check ld_s/LDStruct compatibility by hand */

View file

@ -1,7 +1,7 @@
#
# BUILD FOR OSF/1, ALPHA, DIGITAL C PLATFORM
#
# $HopeName: MMsrc!o1alcc.gmk(trunk.4) $
# $HopeName: MMsrc!o1alcc.gmk(trunk.5) $
#
# Copyright (C) 1995,1997 Harlequin Group, all rights reserved
#
@ -18,7 +18,7 @@ MPM = assert.c ring.c mpsliban.c mpm.c bt.c \
arenavm.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protan.c shield.c mpsi.c ld.c vmo1.c \
mpsioan.c event.c
mpsioan.c event.c action.c seg.c
MPMS = sso1al.s
AMC = amc.c
LO = lo.c

View file

@ -1,7 +1,7 @@
#
# BUILD FOR OSF/1, ALPHA, GCC PLATFORM
#
# $HopeName: MMsrc!o1algc.gmk(trunk.9) $
# $HopeName: MMsrc!o1algc.gmk(trunk.10) $
#
# Copyright (C) 1995,1997 Harlequin Group, all rights reserved
#
@ -18,7 +18,7 @@ MPM = assert.c ring.c mpsliban.c mpm.c bt.c \
arenavm.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protan.c shield.c mpsi.c ld.c vmo1.c \
mpsioan.c event.c
mpsioan.c event.c action.c seg.c
MPMS = sso1al.s
AMC = amc.c
LO = lo.c

View file

@ -1,7 +1,7 @@
/* impl.c.pool: POOL IMPLEMENTATION
*
* $HopeName: MMsrc!pool.c(trunk.23) $
* Copyright (C) 1994,1995,1996,1997 Harlequin Group, all rights reserved
* $HopeName: MMsrc!pool.c(MMdevel_action2.10) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* This is the implementation of the generic pool interface. The
* functions here dispatch to pool-specific methods.
@ -12,7 +12,7 @@
#include "mpm.h"
SRCID(pool, "$HopeName: MMsrc!pool.c(trunk.23) $");
SRCID(pool, "$HopeName: MMsrc!pool.c(MMdevel_action2.10) $");
Bool PoolClassCheck(PoolClass class)
@ -39,7 +39,6 @@ Bool PoolClassCheck(PoolClass class)
CHECKL(FUNCHECK(class->scan));
CHECKL(FUNCHECK(class->fix));
CHECKL(FUNCHECK(class->reclaim));
CHECKL(FUNCHECK(class->access));
CHECKL(FUNCHECK(class->describe));
CHECKL(class->endSig == PoolClassSig);
return TRUE;
@ -55,6 +54,7 @@ Bool PoolCheck(Pool pool)
CHECKL(RingCheck(&pool->spaceRing));
CHECKL(RingCheck(&pool->bufferRing));
CHECKL(RingCheck(&pool->segRing));
CHECKL(RingCheck(&pool->actionRing));
/* Cannot check pool->bufferSerial */
CHECKL(AlignCheck(pool->alignment));
return TRUE;
@ -91,8 +91,10 @@ Res PoolInitV(Pool pool, Space space,
RingInit(&pool->spaceRing);
RingInit(&pool->bufferRing);
RingInit(&pool->segRing);
RingInit(&pool->actionRing);
pool->bufferSerial = (Serial)0;
pool->actionSerial = (Serial)0;
pool->alignment = MPS_PF_ALIGN;
RingAppend(SpacePoolRing(space), &pool->spaceRing);
/* Initialise signature last; see design.mps.sig */
pool->sig = PoolSig;
@ -106,12 +108,16 @@ Res PoolInitV(Pool pool, Space space,
if(res != ResOK)
goto failInit;
/* Add initialized pool to list of pools in space. */
RingAppend(SpacePoolRing(space), &pool->spaceRing);
EVENT3(PoolInit, pool, space, class);
return ResOK;
failInit:
pool->sig = SigInvalid; /* Leave space->poolSerial incremented */
RingFinish(&pool->actionRing);
RingFinish(&pool->segRing);
RingFinish(&pool->bufferRing);
RingRemove(&pool->spaceRing);
@ -177,21 +183,12 @@ void PoolFinish(Pool pool)
/* Do any class-specific finishing. */
(*pool->class->finish)(pool);
/* There must be no buffers attached to the pool at */
/* this point. The class-specific finish method is */
/* allowed to remove them. */
AVER(RingCheckSingle(&pool->bufferRing));
/* There must be no segments attached to the pool at */
/* this point. The class-specific finish method is */
/* allowed to remove them. */
AVER(RingCheckSingle(&pool->segRing));
/* Detach the pool from the space, and unsig it. */
RingRemove(&pool->spaceRing);
pool->sig = SigInvalid;
/* .ring.finish: Finish the generic fields. See .ring.init */
RingFinish(&pool->actionRing);
RingFinish(&pool->segRing);
RingFinish(&pool->bufferRing);
RingFinish(&pool->spaceRing);
@ -250,34 +247,44 @@ void PoolFree(Pool pool, Addr old, Size size)
EVENT3(PoolFree, (Word)pool, (Word)old, (Word)size);
}
Res PoolCondemn(RefSet *condemnedReturn, Pool pool,
Space space, TraceId ti)
Res PoolCondemn(Pool pool, Trace trace, Seg seg)
{
AVER(condemnedReturn != NULL);
AVERT(Pool, pool);
AVERT(Space, space);
AVER(pool->space == space);
AVERT(TraceId, ti);
AVER(ti != TraceIdNONE);
return (*pool->class->condemn)(condemnedReturn, pool, space, ti);
AVERT(Trace, trace);
AVERT(Seg, seg);
AVER(pool->space == trace->space);
AVER(seg->pool == pool);
return (*pool->class->condemn)(pool, trace, seg);
}
void PoolGrey(Pool pool, Space space, TraceId ti)
void PoolGrey(Pool pool, Trace trace, Seg seg)
{
AVERT(Pool, pool);
AVERT(Space, space);
AVER(pool->space == space);
AVERT(TraceId, ti);
AVER(ti != TraceIdNONE);
(*pool->class->grey)(pool, space, ti);
AVERT(Trace, trace);
AVERT(Seg, seg);
AVER(pool->space == trace->space);
AVER(seg->pool == pool);
(*pool->class->grey)(pool, trace, seg);
}
Res PoolScan(ScanState ss, Pool pool, Bool *finishedReturn)
Res PoolScan(ScanState ss, Pool pool, Seg seg)
{
AVERT(ScanState, ss);
AVERT(Pool, pool);
AVER(finishedReturn != NULL);
return (*pool->class->scan)(ss, pool, finishedReturn);
AVERT(Seg, seg);
AVER(ss->space == pool->space);
/* The segment must belong to the pool. */
AVER(pool == seg->pool);
/* Should only scan for a rank for which there are references */
/* in the segment. */
AVER(RankSetIsMember(seg->rankSet, ss->rank));
/* Should only scan segments which contain grey objects. */
AVER(TraceSetInter(seg->grey, ss->traces) != TraceSetEMPTY);
return (*pool->class->scan)(ss, pool, seg);
}
/* See impl.h.mpm for macro version; see design.mps.pool.req.fix */
@ -286,23 +293,30 @@ Res (PoolFix)(Pool pool, ScanState ss, Seg seg, Addr *refIO)
AVERT(Pool, pool);
AVERT(ScanState, ss);
AVERT(Seg, seg);
AVER(pool == seg->pool);
AVER(refIO != NULL);
/* Should only be fixing references to white segments. */
AVER(TraceSetInter(seg->white, ss->traces) != TraceSetEMPTY);
return PoolFix(pool, ss, seg, refIO);
}
void PoolReclaim(Pool pool, Space space, TraceId ti)
{
AVERT(Pool, pool);
AVERT(Space, space);
AVER(pool->space == space);
(*pool->class->reclaim)(pool, space, ti);
}
void PoolAccess(Pool pool, Seg seg, AccessSet mode)
void PoolReclaim(Pool pool, Trace trace, Seg seg)
{
AVERT(Pool, pool);
AVERT(Trace, trace);
AVERT(Seg, seg);
(*pool->class->access)(pool, seg, mode);
AVER(pool->space == trace->space);
AVER(seg->pool == pool);
/* There shouldn't be any grey things left for this trace. */
AVER(!TraceSetIsMember(seg->grey, trace->ti));
/* Should only be reclaiming segments which are still white. */
AVER(TraceSetIsMember(seg->white, trace->ti));
(*pool->class->reclaim)(pool, trace, seg);
}
@ -353,6 +367,12 @@ Space (PoolSpace)(Pool pool)
}
/* PoolSegAlloc -- allocate a segment in a pool
*
* @@@@ There's no need for this routine. The segment could be
* attached in SegInit.
*/
Res PoolSegAlloc(Seg *segReturn, SegPref pref, Pool pool, Size size)
{
Res res;
@ -375,6 +395,12 @@ Res PoolSegAlloc(Seg *segReturn, SegPref pref, Pool pool, Size size)
}
/* PoolSegFree -- free a segment from a pool
*
* @@@@ There's no need for this routine. The segment could be
* detached in SegFinish.
*/
void PoolSegFree(Pool pool, Seg seg)
{
Space space;
@ -477,32 +503,34 @@ void PoolTrivFree(Pool pool, Addr old, Size size)
NOOP; /* trivial free has no effect */
}
Res PoolNoBufferInit(Pool pool, Buffer buf)
Res PoolNoBufferInit(Pool pool, Buffer buffer)
{
AVERT(Pool, pool);
UNUSED(buffer);
NOTREACHED;
return ResUNIMPL;
}
/* The generic method initialised all generic fields; */
/* This doesn't override any fields */
Res PoolTrivBufferInit(Pool pool, Buffer buf)
Res PoolTrivBufferInit(Pool pool, Buffer buffer)
{
AVERT(Pool, pool);
UNUSED(buffer);
return ResOK;
}
void PoolNoBufferFinish(Pool pool, Buffer buf)
void PoolNoBufferFinish(Pool pool, Buffer buffer)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
AVERT(Buffer, buffer);
NOTREACHED;
}
void PoolTrivBufferFinish(Pool pool, Buffer buf)
void PoolTrivBufferFinish(Pool pool, Buffer buffer)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
AVERT(Buffer, buffer);
NOOP;
}
@ -555,29 +583,48 @@ Res PoolTrivDescribe(Pool pool, mps_lib_FILE *stream)
return WriteF(stream, " No class-specific description available.\n", NULL);
}
Res PoolNoCondemn(RefSet *condemnedReturn, Pool pool, Space space, TraceId ti)
Res PoolNoCondemn(Pool pool, Trace trace, Seg seg)
{
AVER(condemnedReturn != NULL);
AVERT(Pool, pool);
AVERT(Space, space);
AVER(TraceIdCheck(ti));
AVERT(Trace, trace);
AVERT(Seg, seg);
NOTREACHED;
return ResUNIMPL;
}
void PoolNoGrey(Pool pool, Space space, TraceId ti)
void PoolNoGrey(Pool pool, Trace trace, Seg seg)
{
AVERT(Pool, pool);
AVERT(Space, space);
AVER(TraceIdCheck(ti));
AVERT(Trace, trace);
AVERT(Seg, seg);
NOTREACHED;
}
Res PoolNoScan(ScanState ss, Pool pool, Bool *finishedReturn)
void PoolTrivGrey(Pool pool, Trace trace, Seg seg)
{
AVERT(Pool, pool);
AVERT(Trace, trace);
AVERT(Seg, seg);
/* @@@@ The trivial grey method probably shouldn't exclude */
/* the white segments, since they might also contain grey objects. */
/* It's probably also the Tracer's responsibility to raise the */
/* shield. */
/* @@@@ This should be calculated by comparing colour */
/* with the mutator colour. For the moment we assume */
/* a read-barrier collector. */
if(!TraceSetIsMember(seg->white, trace->ti)) {
seg->grey = TraceSetAdd(seg->grey, trace->ti);
ShieldRaise(trace->space, seg, AccessREAD | AccessWRITE);
}
}
Res PoolNoScan(ScanState ss, Pool pool, Seg seg)
{
AVERT(ScanState, ss);
AVERT(Pool, pool);
AVER(finishedReturn != NULL);
AVERT(Seg, seg);
NOTREACHED;
return ResUNIMPL;
}
@ -592,17 +639,10 @@ Res PoolNoFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
return ResUNIMPL;
}
void PoolNoReclaim(Pool pool, Space space, TraceId ti)
{
AVERT(Pool, pool);
AVERT(Space, space);
AVER(TraceIdCheck(ti));
NOTREACHED;
}
void PoolNoAccess(Pool pool, Seg seg, AccessSet mode)
void PoolNoReclaim(Pool pool, Trace trace, Seg seg)
{
AVERT(Pool, pool);
AVERT(Trace, trace);
AVERT(Seg, seg);
NOTREACHED;
}

View file

@ -1,6 +1,6 @@
/* impl.c.poolmfs: MANUAL FIXED SMALL UNIT POOL
*
* $HopeName: MMsrc!poolmfs.c(trunk.15) $
* $HopeName: MMsrc!poolmfs.c(trunk.16) $
* Copyright (C) 1994,1995,1996 Harlequin Group, all rights reserved
*
* This is the implementation of the MFS pool class.
@ -35,7 +35,7 @@
#include "mpm.h"
#include "poolmfs.h"
SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.15) $");
SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.16) $");
/* == Round up ==
@ -282,7 +282,6 @@ static PoolClassStruct PoolClassMFSStruct = {
PoolNoScan, /* scan */
PoolNoFix, /* fix */
PoolNoReclaim, /* reclaim */
PoolNoAccess, /* access */
MFSDescribe, /* describe */
PoolClassSig /* impl.h.mpmst.class.end-sig */
};

View file

@ -2,8 +2,8 @@
*
* MANUAL RANK GUARDIAN POOL
*
* $HopeName: MMsrc!poolmrg.c(trunk.5) $
* Copyright(C) 1995,1997 Harlequin Group, all rights reserved
* $HopeName: MMsrc!poolmrg.c(MMdevel_action2.8) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* READERSHIP
*
@ -29,7 +29,7 @@
#include "poolmrg.h"
SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(trunk.5) $");
SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(MMdevel_action2.8) $");
#define MRGSig ((Sig)0x519B0349)
@ -83,8 +83,7 @@ static Index indexOfLinkPart(Addr a, Space space)
typedef struct MRGGroupStruct {
Sig sig; /* impl.h.misc.sig */
RingStruct group; /* design.mps.poolmrg.group.group */
TraceSet grey; /* design.mps.poolmrg.group.grey */
RingStruct group; /* design.mps.poolmrg.group.group */
Seg refseg; /* design.mps.poolmrg.group.segs */
Seg linkseg; /* design.mps.poolmrg.group.segs */
} MRGGroupStruct;
@ -149,13 +148,13 @@ static Res MRGGroupCreate(MRGGroup *groupReturn, MRG mrg)
}
AVER((Addr)(&linkpart[i]) <= SegLimit(space, linkseg));
AVER((Addr)(&refpart[i]) <= SegLimit(space, refseg));
refseg->rank = RankFINAL;
refseg->rankSet = RankSetSingle(RankFINAL); /* design.mps.seg.field.rankSet.start */
refseg->summary = RefSetUNIV; /* design.mps.seg.field.summary.start */
group->refseg = refseg;
group->linkseg = linkseg;
refseg->p = group;
linkseg->p = group;
group->grey = TraceSetEMPTY;
RingInit(&group->group);
RingAppend(&mrg->group, &group->group);
group->sig = MRGGroupSig;
@ -180,9 +179,7 @@ static Res MRGGroupScan(ScanState ss, MRGGroup group, MRG mrg)
space = PoolSpace(MRGPool(mrg));
ShieldExpose(space, group->refseg);
guardians = mrg->extendBy / sizeof(Addr); /* per seg */
guardians = mrg->extendBy / sizeof(Addr); /* per seg */
AVER(guardians > 0);
base = SegBase(space, group->refseg);
refpart = (Addr *)base;
@ -202,10 +199,6 @@ static Res MRGGroupScan(ScanState ss, MRGGroup group, MRG mrg)
}
} TRACE_SCAN_END(ss);
group->grey = TraceSetDel(group->grey, ss->traceId);
ShieldLower(space, group->refseg, AccessREAD | AccessWRITE);
ShieldCover(space, group->refseg);
return ResOK;
}
@ -385,97 +378,27 @@ static Res MRGDescribe(Pool pool, mps_lib_FILE *stream)
return ResOK;
}
static void MRGGrey(Pool pool, Space space, TraceId ti)
{
MRG mrg;
Ring r;
AVERT(Pool, pool);
mrg = PoolPoolMRG(pool);
AVERT(MRG, mrg);
AVERT(Space, space);
AVERT(TraceId, ti);
RING_FOR(r, &mrg->group) {
MRGGroup group;
group = RING_ELT(MRGGroup, group, r);
group->grey = TraceSetAdd(group->grey, ti);
ShieldRaise(space, group->refseg, AccessREAD | AccessWRITE);
}
}
static Res MRGScan(ScanState ss, Pool pool, Bool *finishedReturn)
static Res MRGScan(ScanState ss, Pool pool, Seg seg)
{
MRG mrg;
Res res;
MRGGroup group;
AVERT(ScanState, ss);
AVERT(Pool, pool);
mrg = PoolPoolMRG(pool);
AVERT(MRG, mrg);
AVER(finishedReturn != NULL);
if(ss->rank == RankFINAL) {
Ring r;
RING_FOR(r, &mrg->group) {
MRGGroup group;
group = RING_ELT(MRGGroup, group, r);
if(TraceSetIsMember(group->grey, ss->traceId)) {
res = MRGGroupScan(ss, group, mrg);
if(res != ResOK) {
return res;
}
*finishedReturn = FALSE;
return ResOK;
}
}
}
*finishedReturn = TRUE;
return ResOK;
}
/* .amc.copy: This code is an almost exact copy of the analogous
* method in impl.c.amc. This is worrying.
*/
static void MRGAccess(Pool pool, Seg seg, AccessSet mode)
{
Space space;
MRG mrg;
MRGGroup group;
Res res;
ScanStateStruct ss;
AVERT(Pool, pool);
mrg = PoolPoolMRG(pool);
AVERT(MRG, mrg);
AVERT(Seg, seg);
AVER(seg->pool == pool);
/* Cannot check AccessSet */
space = PoolSpace(pool);
AVER(seg->rankSet == RankSetSingle(RankFINAL));
AVER(TraceSetInter(seg->grey, ss->traces) != TraceSetEMPTY);
group = (MRGGroup)seg->p;
AVER(seg == group->refseg);
ss.fix = TraceFix;
ss.zoneShift = space->zoneShift;
ss.summary = RefSetEMPTY;
ss.space = space;
ss.sig = ScanStateSig;
ss.rank = RankEXACT; /* .access.exact */
ss.weakSplat = (Addr)0xadd4badd;
res = MRGGroupScan(ss, group, mrg);
if(res != ResOK) return res;
/* impl.c.amc.access.multi (!) */
for(ss.traceId = 0; ss.traceId < TRACE_MAX; ++ss.traceId) {
if(TraceSetIsMember(space->busyTraces, ss.traceId)) {
ss.condemned = space->trace[ss.traceId].condemned;
res = MRGGroupScan(&ss, group, mrg);
AVER(res == ResOK); /* impl.c.amc.access.error (!) */
}
}
return ResOK;
}
static PoolClassStruct PoolClassMRGStruct = {
@ -495,11 +418,10 @@ static PoolClassStruct PoolClassMRGStruct = {
PoolNoBufferExpose, /* bufferExpose */
PoolNoBufferCover, /* bufferCover */
PoolNoCondemn, /* condemn */
MRGGrey, /* grey */
PoolTrivGrey, /* grey */
MRGScan, /* scan */
PoolNoFix, /* fix */
PoolNoReclaim, /* reclaim */
MRGAccess, /* access */
MRGDescribe, /* describe */
PoolClassSig /* impl.h.mpmst.class.end-sig */
};

View file

@ -1,7 +1,7 @@
/* impl.c.poolmv: MANUAL VARIABLE POOL
*
* $HopeName: MMsrc!poolmv.c(trunk.17) $
* Copyright (C) 1994, 1995 Harlequin Group, all rights reserved
* $HopeName: MMsrc!poolmv.c(MMdevel_action2.2) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* **** RESTRICTION: This pool may not allocate from the arena control
* pool, since it is used to implement that pool.
@ -9,8 +9,8 @@
* poolPool.
*
* An observation: Freeing memory introduces more information
* into the system than allocating it. This causes the problem described
* in note 2.
* into the system than allocating it. This causes the problem
* described in note 2.
*
* Notes
* 1. Need to measure typical fragmentation levels and adjust the
@ -37,7 +37,7 @@
#include "poolmfs.h"
#include "mpscmv.h"
SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(trunk.17) $");
SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(MMdevel_action2.2) $");
#define BLOCKPOOL(mv) (MFSPool(&(mv)->blockPoolStruct))
@ -626,7 +626,6 @@ static PoolClassStruct PoolClassMVStruct = {
PoolNoScan, /* scan */
PoolNoFix, /* fix */
PoolNoReclaim, /* relcaim */
PoolNoAccess, /* access */
MVDescribe, /* describe */
PoolClassSig /* impl.h.mpmst.class.end-sig */
};

View file

@ -1,19 +1,16 @@
/* impl.c.pooln
/* impl.c.pooln: NULL POOL
*
* NULL POOL
* $HopeName: MMsrc!pooln.c(MMdevel_action2.7) $
* Copyright(C) 1997 The Harlequin Group Limited. All rights reserved.
*
* $HopeName: MMsrc!pooln.c(MMdevel_lib.2) $
*
* Copyright(C) 1995 Harlequin Group, all rights reserved
*
* This is the implementation of the null pool class. Begin null it
* all functions are implemented in a trivial manner.
* This is the implementation of the null pool class. Begin null it
* all functions are implemented in a trivial manner.
*/
#include "mpm.h"
#include "pooln.h"
SRCID(pooln, "$HopeName: MMsrc!pooln.c(MMdevel_lib.2) $");
SRCID(pooln, "$HopeName: MMsrc!pooln.c(MMdevel_action2.7) $");
typedef struct PoolNStruct {
@ -90,6 +87,8 @@ static Res NBufferInit(Pool pool, Buffer buffer)
poolN = PoolPoolN(pool);
AVERT(PoolN, poolN);
UNUSED(buffer);
return ResLIMIT; /* limit of nil buffers exceeded */
}
@ -172,8 +171,7 @@ static Res NDescribe(Pool pool, mps_lib_FILE *stream)
return ResOK;
}
static Res NCondemn(RefSet *condemnedReturn, Pool pool,
Space space, TraceId ti)
static Res NCondemn(Pool pool, Trace trace, Seg seg)
{
PoolN poolN;
@ -181,13 +179,13 @@ static Res NCondemn(RefSet *condemnedReturn, Pool pool,
poolN = PoolPoolN(pool);
AVERT(PoolN, poolN);
AVER(condemnedReturn != NULL);
AVERT(Space, space);
AVERT(Trace, trace);
AVERT(Seg, seg);
return ResOK;
}
static void NMark(Pool pool, Space space, TraceId ti)
static void NGrey(Pool pool, Trace trace, Seg seg)
{
PoolN poolN;
@ -195,10 +193,11 @@ static void NMark(Pool pool, Space space, TraceId ti)
poolN = PoolPoolN(pool);
AVERT(PoolN, poolN);
AVERT(Space, space);
AVERT(Trace, trace);
AVERT(Seg, seg);
}
static Res NScan(ScanState ss, Pool pool, Bool *finishedReturn)
static Res NScan(ScanState ss, Pool pool, Seg seg)
{
PoolN poolN;
@ -206,8 +205,8 @@ static Res NScan(ScanState ss, Pool pool, Bool *finishedReturn)
poolN = PoolPoolN(pool);
AVERT(PoolN, poolN);
AVER(finishedReturn != NULL);
AVERT(ScanState, ss);
AVERT(Seg, seg);
return ResOK;
}
@ -221,25 +220,14 @@ static Res NFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
AVERT(PoolN, poolN);
AVERT(ScanState, ss);
UNUSED(refIO);
AVERT(Seg, seg);
NOTREACHED; /* since we don't allocate any objects, should never
* be called upon to fix a reference */
return ResFAIL;
}
static void NReclaim(Pool pool, Space space, TraceId ti)
{
PoolN poolN;
AVERT(Pool, pool);
poolN = PoolPoolN(pool);
AVERT(PoolN, poolN);
AVERT(Space, space);
/* all unmarked and condemned objects reclaimed */
}
static void NAccess(Pool pool, Seg seg, AccessSet mode)
static void NReclaim(Pool pool, Trace trace, Seg seg)
{
PoolN poolN;
@ -247,9 +235,9 @@ static void NAccess(Pool pool, Seg seg, AccessSet mode)
poolN = PoolPoolN(pool);
AVERT(PoolN, poolN);
AVERT(Trace, trace);
AVERT(Seg, seg);
UNUSED(mode);
/* deal with access to segment */
/* all unmarked and white objects reclaimed */
}
static PoolClassStruct PoolClassNStruct = {
@ -269,11 +257,10 @@ static PoolClassStruct PoolClassNStruct = {
NBufferExpose, /* bufferExpose */
NBufferCover, /* bufferCover */
NCondemn, /* condemn */
NMark, /* grey */
NGrey, /* grey */
NScan, /* scan */
NFix, /* fix */
NReclaim, /* reclaim */
NAccess, /* access */
NDescribe, /* describe */
PoolClassSig /* impl.h.mpmst.class.end-sig */
};

View file

@ -1,7 +1,7 @@
/* impl.c.protan: ANSI MEMORY PROTECTION
*
* $HopeName: MMsrc!protan.c(trunk.2) $
* Copyright (C) 1996,1997 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!protan.c(trunk.3) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* READERSHIP
*
@ -15,7 +15,7 @@
#include "mpm.h"
SRCID(protan, "$HopeName: MMsrc!protan.c(trunk.2) $");
SRCID(protan, "$HopeName: MMsrc!protan.c(MMdevel_action2.2) $");
void ProtSetup(void)
{
@ -46,7 +46,7 @@ void ProtSync(Space space)
while(seg != NULL) {
if(seg->pm != AccessSetEMPTY) { /* design.mps.protan.fun.sync.seg */
ShieldEnter(space);
PoolAccess(seg->pool, seg, seg->pm);
TraceAccess(space, seg, seg->pm);
ShieldLeave(space);
synced = FALSE;
}

View file

@ -1,7 +1,7 @@
/* impl.c.ref: REFERENCES
*
* $HopeName: MMsrc!ref.c(trunk.5) $
* Copyright (C) 1995 Harlequin Group, all rights reserved
* $HopeName: MMsrc!ref.c(MMdevel_action2.3) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved
*
* Ref is an alias for Addr which can be used to document where
* references are being passed.
@ -18,13 +18,13 @@
* for IsMember. Add is used to implement reference summaries,
* which provide a remembered set. IsMember is used to inline part
* of the Fix function, and provide good discrimination of the
* condemned set. It is expected that the discrimination provided
* white set. It is expected that the discrimination provided
* will be useful for distinguishing segments and groups of segments.
*/
#include "mpm.h"
SRCID(ref, "$HopeName: MMsrc!ref.c(trunk.5) $");
SRCID(ref, "$HopeName: MMsrc!ref.c(MMdevel_action2.3) $");
Bool RankCheck(Rank rank)
{
@ -33,6 +33,13 @@ Bool RankCheck(Rank rank)
}
Bool RankSetCheck(RankSet rankSet)
{
CHECKL(rankSet < (1uL << RankMAX));
return TRUE;
}
/* RefSetOfSeg -- calculate the reference set of segment addresses
*
* .rsos.def: The reference set of a segment is the union of the

View file

@ -1,21 +1,23 @@
/* impl.c.root
/* impl.c.root: ROOT IMPLEMENTATION
*
* ROOT IMPLEMENTATION
* $HopeName: MMsrc!root.c(MMdevel_action2.4) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*
* $HopeName: MMsrc!root.c(trunk.18) $
*
* Copyright (C) 1995,1996 Harlequin Group, all rights reserved
*
* .scope: This is the implementation of the root datatype.
*
* .design: For design, see design.mps.root and design.mps.root-interface
* .scope: This is the implementation of the root datatype.
* .design: For design, see design.mps.root and
* design.mps.root-interface
*/
#include "mpm.h"
SRCID(root, "$HopeName: MMsrc!root.c(trunk.18) $");
SRCID(root, "$HopeName: MMsrc!root.c(MMdevel_action2.4) $");
/* RootCheck -- check the consistency of a root structure
*
* .rootcheck: Keep synchonized with impl.h.mpmst.root
*/
/* .rootcheck: Keep synchonized with impl.h.mpmst.root */
Bool RootCheck(Root root)
{
CHECKS(Root, root);
@ -85,6 +87,7 @@ static Res create(Root *rootReturn, Space space,
root->var = type;
root->the = *theUnionP;
root->grey = TraceSetEMPTY;
root->summary = RefSetUNIV;
/* See design.mps.space.root-ring */
RingInit(&root->spaceRing);
@ -201,12 +204,12 @@ Rank RootRank(Root root)
return root->rank;
}
void RootGrey(Root root, TraceId ti)
void RootGrey(Root root, Trace trace)
{
AVERT(Root, root);
AVER(TraceIdCheck(ti));
AVERT(Trace, trace);
root->grey = TraceSetAdd(root->grey, ti);
root->grey = TraceSetAdd(root->grey, trace->ti);
}
Res RootScan(ScanState ss, Root root)
@ -217,7 +220,7 @@ Res RootScan(ScanState ss, Root root)
AVERT(ScanState, ss);
AVER(root->rank == ss->rank);
if(!TraceSetIsMember(root->grey, ss->traceId))
if(TraceSetInter(root->grey, ss->traces) == TraceSetEMPTY)
return ResOK;
switch(root->var) {
@ -251,7 +254,7 @@ Res RootScan(ScanState ss, Root root)
NOTREACHED;
}
root->grey = TraceSetDel(root->grey, ss->traceId);
root->grey = TraceSetDiff(root->grey, ss->traces);
return ResOK;
}
@ -275,11 +278,11 @@ Res RootDescribe(Root root, mps_lib_FILE *stream)
(WriteFU)root->space->serial,
" rank $U\n", (WriteFU)root->rank,
" grey $B\n", (WriteFB)root->grey,
" summary $B\n", (WriteFB)root->summary,
NULL);
if(res != ResOK) return res;
switch(root->var)
{
switch(root->var) {
case RootTABLE:
res = WriteF(stream,
" table base $A limit $A\n",

View file

@ -1,7 +1,7 @@
#
# BUILD FOR SOLARIS/SPARC/GCC PLATFORM
#
# $HopeName: MMsrc!sospgc.gmk(trunk.8) $
# $HopeName: MMsrc!sospgc.gmk(trunk.9) $
# Copyright (C) 1995,1997 Harlequin Group, all rights reserved
#
# This is the GNU makefile for platform.sospgc.
@ -14,7 +14,7 @@ MPM = assert.c ring.c mpsliban.c mpm.c bt.c \
arenavm.c vmso.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protso.c shield.c mpsi.c ld.c \
mpsioan.c event.c
mpsioan.c event.c action.c seg.c
MPMPS = sssosp.S
AMC = amc.c
LO = lo.c
@ -22,7 +22,8 @@ MRG = poolmrg.c
DW = fmtdy.c dw.c
SW = assert.c ring.c mpm.c arenacl.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c \
action.c seg.c
LIBS = -lm
TESTLIB = testlib.c

View file

@ -1,7 +1,7 @@
#
# BUILD FOR Solaris/UltraSPARC/SunPro C PLATFORM
#
# $HopeName: MMsrc!soussc.gmk(trunk.5) $
# $HopeName: MMsrc!soussc.gmk(trunk.6) $
#
# This is the GNU makefile for platform.soussc
#
@ -13,7 +13,7 @@ MPM = assert.c ring.c mpsliban.c mpm.c bt.c \
arenavm.c vmso.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protso.c shield.c mpsi.c ld.c \
mpsioan.c event.c
mpsioan.c event.c action.c seg.c
MPMPS = ssussp.s
AMC = amc.c
MRG = poolmrg.c
@ -21,7 +21,8 @@ LO = lo.c
DW = fmtdy.c dw.c
SW = assert.c ring.c mpm.c arenacl.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c \
action.c seg.c
LIBS = -lm
TESTLIB = testlib.c

View file

@ -1,11 +1,9 @@
# impl.gmk.suspgc: BUILD FOR SUNOS/SPARC/GCC PLATFORM
#
# BUILD FOR SUNOS/SPARC/GCC PLATFORM
#
# $HopeName: MMsrc!suspgc.gmk(trunk.24) $
# Copyright (C) 1995,1997 Harlequin Group, all rights reserved
#
# This is the GNU makefile for platform.suspgc.
# $HopeName: MMsrc!suspgc.gmk(MMdevel_action2.4) $
# Copyright (C) 1995,1996,1997 Harlequin Group, all rights reserved.
#
# This is the GNU makefile for platform.suspgc.
PFM = suspgc
@ -13,7 +11,7 @@ MPM = assert.c ring.c mpsliban.c mpm.c bt.c \
arenavm.c vmsu.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protsu.c shield.c mpsi.c ld.c \
mpsioan.c event.c
mpsioan.c event.c action.c seg.c
MPMS = sssusp.s
AMC = amc.c
LO = lo.c
@ -21,7 +19,8 @@ MRG = poolmrg.c
DW = fmtdy.c dw.c
SW = assert.c ring.c mpm.c arenacl.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c \
poolepdl.c action.c seg.c
LIBS = -lm

View file

@ -1,7 +1,7 @@
#
# BUILD FOR SUNOS/SPARC/LCC PLATFORM
#
# $HopeName: MMsrc!susplc.gmk(trunk.4) $
# $HopeName: MMsrc!susplc.gmk(trunk.5) $
# Copyright (C) 1996,1997 Harlequin Group, all rights reserved
#
# This is the GNU makefile for platform.susplc.
@ -13,7 +13,7 @@ MPM = assert.c ring.c mpsliban.c mpm.c bt.c \
arenavm.c vmsu.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protsu.c shield.c mpsi.c ld.c \
mpsioan.c event.c
mpsioan.c event.c action.c seg.c
MPMS = sssusp.s
AMC = amc.c
LO = lo.c
@ -21,7 +21,8 @@ MRG = poolmrg.c
DW = fmtdy.c dw.c
SW = assert.c ring.c mpm.c arenacl.c space.c pool.c poolmfs.c \
poolmv.c root.c format.c buffer.c lockan.c ref.c \
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c
trace.c than.c protsw.c shield.c mpsisw.c ld.c ssan.c poolepdl.c \
action.c seg.c
TESTLIB = testlib.c

View file

@ -1,121 +1,349 @@
/* impl.c.trace: GENERIC TRACER IMPLEMENTATION
*
* $HopeName: MMsrc!trace.c(trunk.18) $
* $HopeName: MMsrc!trace.c(MMdevel_action2.15) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*/
#include "mpm.h"
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.18) $");
SRCID(trace, "$HopeName: MMsrc!trace.c(MMdevel_action2.15) $");
/* ScanStateCheck -- check consistency of a ScanState object */
Bool ScanStateCheck(ScanState ss)
{
TraceId ti;
RefSet white;
CHECKS(ScanState, ss);
CHECKL(FUNCHECK(ss->fix));
CHECKU(Space, ss->space);
CHECKL(TraceSetCheck(ss->traces));
CHECKL(TraceSetSuper(ss->space->busyTraces, ss->traces));
white = RefSetEMPTY;
for(ti = 0; ti < TRACE_MAX; ++ti)
if(TraceSetIsMember(ss->traces, ti))
white = RefSetUnion(white, ss->space->trace[ti].white);
CHECKL(ss->white == white);
CHECKL(ss->zoneShift == ss->space->zoneShift);
CHECKL(RankCheck(ss->rank));
CHECKL(ss->condemned == ss->space->trace[ss->traceId].condemned);
CHECKL(BoolCheck(ss->wasMarked));
return TRUE;
}
/* TraceIdCheck -- check that a TraceId is valid */
Bool TraceIdCheck(TraceId ti)
{
CHECKL(ti == TraceIdNONE || ti < TRACE_MAX);
return TRUE;
}
/* TraceSetCheck -- check that a TraceSet is valid */
Bool TraceSetCheck(TraceSet ts)
{
CHECKL(ts < (1uL << TRACE_MAX));
return TRUE;
}
Res TraceCreate(TraceId *tiReturn, Space space)
/* TraceCheck -- check consistency of Trace object */
Bool TraceCheck(Trace trace)
{
CHECKS(Trace, trace);
CHECKU(Space, trace->space);
CHECKL(TraceIdCheck(trace->ti));
CHECKL(trace == &trace->space->trace[trace->ti]);
CHECKL(TraceSetIsMember(trace->space->busyTraces, trace->ti));
/* Can't check trace->white -- not in O(1) anyway. */
/* Use trace->state to check more invariants. */
switch(trace->state) {
case TraceINIT:
/* @@@@ What can be checked here? */
break;
case TraceUNFLIPPED:
CHECKL(!TraceSetIsMember(trace->space->flippedTraces, trace->ti));
/* @@@@ Assert that mutator is grey for trace. */
break;
case TraceFLIPPED:
CHECKL(TraceSetIsMember(trace->space->flippedTraces, trace->ti));
/* @@@@ Assert that mutator is black for trace. */
break;
case TraceRECLAIM:
CHECKL(TraceSetIsMember(trace->space->flippedTraces, trace->ti));
/* @@@@ Assert that grey set is empty for trace. */
break;
case TraceFINISHED:
CHECKL(TraceSetIsMember(trace->space->flippedTraces, trace->ti));
/* @@@@ Assert that grey and white sets is empty for trace. */
break;
default:
NOTREACHED;
}
/* @@@@ Check trace->interval? */
return TRUE;
}
/* TraceCreate -- create a Trace object
*
* Allocates and initializes a new Trace object with a TraceId
* which is not currently active.
*
* Returns ResLIMIT if there aren't any available trace IDs.
*
* Trace objects are allocated directly from a small array in the
* space structure which is indexed by the TraceId. This is so
* that it's always possible to start a trace (provided there's
* a free TraceId) even if there's no available memory.
*
* This code is written to be adaptable to allocating Trace
* objects dynamically.
*/
Res TraceCreate(Trace *traceReturn, Space space)
{
TraceId ti;
Trace trace;
/* .single-collection */
AVER(TRACE_MAX == 1);
AVER(TRACE_MAX == 1); /* .single-collection */
AVER(tiReturn != NULL);
AVER(traceReturn != NULL);
AVERT(Space, space);
/* allocate free TraceId */
/* Find a free trace ID */
for(ti = 0; ti < TRACE_MAX; ++ti)
if(!TraceSetIsMember(space->busyTraces, ti))
goto found;
return ResLIMIT;
return ResLIMIT; /* no trace IDs available */
found:
space->trace[ti].condemned = RefSetEMPTY;
trace = SpaceTrace(space, ti);
space->busyTraces = TraceSetAdd(space->busyTraces, ti);
*tiReturn = ti;
trace->space = space;
trace->white = RefSetEMPTY;
trace->ti = ti;
trace->state = TraceINIT;
trace->interval = (Size)4096; /* @@@@ should be progress control */
trace->sig = TraceSig;
AVERT(Trace, trace);
*traceReturn = trace;
return ResOK;
}
void TraceDestroy(Space space, TraceId ti)
/* TraceDestroy -- destroy a trace object
*
* Finish and deallocate a Trace object, freeing up a TraceId.
*
* This code does not allow a Trace to be destroyed while it is
* active. It would be possible to allow this, but the colours
* of segments etc. would need to be reset to black.
*/
void TraceDestroy(Trace trace)
{
AVERT(Space, space);
space->busyTraces = TraceSetDel(space->busyTraces, ti);
AVERT(Trace, trace);
AVER(trace->state == TraceFINISHED);
trace->sig = SigInvalid;
trace->space->busyTraces =
TraceSetDel(trace->space->busyTraces, trace->ti);
trace->space->flippedTraces =
TraceSetDel(trace->space->flippedTraces, trace->ti);
}
Res TraceFlip(Space space, TraceId ti, RefSet condemned)
/* TraceStart -- condemn a set of objects and start collection
*
* TraceStart should be passed a trace with state TraceINIT, i.e.
* recently returned from TraceCreate.
*
* .start.black: All segments are black w.r.t. a newly allocated trace.
* However, if TraceStart initialized segments to black when it
* calculated the grey set then this condition could be relaxed, making
* it easy to destroy traces half-way through.
*/
Res TraceStart(Trace trace, Pool pool)
{
Ring ring;
Ring node;
Trace trace;
ScanStateStruct ss;
Res res;
Ring ring, node;
Space space;
Seg seg;
AVERT(Space, space);
AVERT(Trace, trace);
AVERT(Pool, pool);
AVER((pool->class->attr & AttrGC) != 0);
AVER(trace->state == TraceINIT);
AVER(trace->white == RefSetEMPTY);
ShieldSuspend(space);
trace = &space->trace[ti];
AVER(trace->condemned == RefSetEMPTY);
trace->condemned = condemned;
/* Update location dependency structures. condemned is
* a conservative approximation of the refset of refs which
* may move during this collection.
* @@@@ It is too conservative. Not everything condemned will
* necessarily move.
*/
LDAge(space, condemned);
/* Grey all the roots and pools. */
ring = SpacePoolRing(space);
/* Identify the condemned set and turn it white. */
space = trace->space;
ring = PoolSegRing(pool);
node = RingNext(ring);
while(node != ring) {
Ring next = RingNext(node);
Pool pool = RING_ELT(Pool, spaceRing, node);
seg = RING_ELT(Seg, poolRing, node);
if((pool->class->attr & AttrSCAN) != 0)
PoolGrey(pool, space, ti); /* implicitly excludes condemned set */
AVER(!TraceSetIsMember(seg->white, trace->ti)); /* .start.black */
/* Give the pool the opportunity to turn the segment white. */
/* If it fails, unwind. */
res = PoolCondemn(pool, trace, seg);
if(res != ResOK) goto failCondemn;
/* Add the segment to the approximation of the white set the */
/* pool made it white. */
if(TraceSetIsMember(seg->white, trace->ti))
trace->white = RefSetUnion(trace->white, RefSetOfSeg(space, seg));
node = next;
}
/* If there is nothing white then there can be nothing grey, */
/* so everything is black and we can proceed straight to */
/* reclaim. We have to reclaim because we want to guarantee */
/* to the pool that for every condemn there will be a reclaim. */
/* @@@@ We can also shortcut if there is nothing grey. */
/* @@@@ This should be in design. */
if(trace->white == RefSetEMPTY) {
space->flippedTraces = TraceSetAdd(space->flippedTraces, trace->ti);
trace->state = TraceRECLAIM;
return ResOK;
}
/* Turn everything else grey. */
/* @@@@ Instead of iterating over all the segments, we could */
/* iterate over all pools which are scannable and thence over */
/* all their segments. This might be better if the minority */
/* of segments are scannable. Perhaps we should choose */
/* dynamically which method to use. */
seg = SegFirst(space);
while(seg != NULL) {
/* Segment should be either black or white by now. */
AVER(!TraceSetIsMember(seg->grey, trace->ti));
/* A segment can only be grey if it contains some references. */
/* This is indicated by the rankSet begin non-empty. Such */
/* segments may only belong to scannable pools. */
if(seg->rankSet != RankSetEMPTY) {
/* Segments with ranks may only belong to scannable pools. */
AVER((seg->pool->class->attr & AttrSCAN) != 0);
/* Turn the segment grey if there might be a reference in it */
/* to the white set. This is done by seeing if the summary */
/* of references in the segment intersects with the approximation */
/* to the white set. */
if(RefSetInter(seg->summary, trace->white) != RefSetEMPTY)
PoolGrey(pool, trace, seg);
}
seg = SegNext(space, seg);
}
ring = SpaceRootRing(space);
node = RingNext(ring);
while(node != ring) {
Ring next = RingNext(node);
Root root = RING_ELT(Root, spaceRing, node);
RootGrey(root, ti);
if(RefSetInter(root->summary, trace->white) != RefSetEMPTY)
RootGrey(root, trace);
node = next;
}
ss.fix = TraceFix;
ss.zoneShift = space->zoneShift;
ss.condemned = space->trace[ti].condemned;
ss.summary = RefSetEMPTY;
ss.space = space;
ss.traceId = ti;
ss.weakSplat = (Addr)0xadd4badd;
ss.sig = ScanStateSig;
trace->state = TraceUNFLIPPED;
return ResOK;
/* PoolCodemn failed, possibly half-way through whitening the condemned */
/* set. This loop empties the white set again. */
failCondemn:
ring = PoolSegRing(pool);
node = RingNext(ring);
while(node != ring) {
Ring next = RingNext(node);
seg = RING_ELT(Seg, poolRing, node);
seg->white = TraceSetDel(seg->white, trace->ti);
node = next;
}
return res;
}
/* TraceSetGreyen -- turn a segment more grey
*
* Adds the trace set ts to the greyness of the segment and adjusts
* the shielding on the segment appropriately. (If it causes the
* segment to become grey for a flipped trace the shield is raised.)
* @@@@ Why does it seem to be write and a read barrier?
*/
void TraceSegGreyen(Space space, Seg seg, TraceSet ts)
{
TraceSet grey;
AVERT(Space, space);
AVERT(Seg, seg);
AVER(TraceSetCheck(ts));
grey = seg->grey;
grey = TraceSetUnion(grey, ts);
if(grey != seg->grey &&
TraceSetInter(grey, space->flippedTraces) != TraceSetEMPTY)
ShieldRaise(space, seg, AccessREAD | AccessWRITE);
seg->grey = grey;
}
static Res TraceFlip(Trace trace)
{
Ring ring;
Ring node;
Space space;
ScanStateStruct ss;
Res res;
AVERT(Trace, trace);
space = trace->space;
ShieldSuspend(space);
AVER(trace->state == TraceUNFLIPPED);
/* @@@@ MUST TRIP ALL BUFFERS to make sure they don't */
/* contain unscanned objects. */
/* Update location dependency structures. white is */
/* a conservative approximation of the refset of refs which */
/* may move during this collection. */
/* @@@@ It is too conservative. Not everything white will */
/* necessarily move. */
LDAge(space, trace->white);
/* The trace is marked as flipped here, apparently prematurely, */
/* so that TraceSegGreyen will DTRT when things are scanned below. */
/* @@@@ This isn't right. When flippedTraces is changed _all_ */
/* grey segments should have their shield modes fixed up anyway. */
trace->state = TraceFLIPPED;
space->flippedTraces = TraceSetAdd(space->flippedTraces, trace->ti);
/* At the moment we must scan all roots, because we don't have */
/* a mechanism for shielding them. There can't be any weak or */
@ -125,10 +353,21 @@ Res TraceFlip(Space space, TraceId ti, RefSet condemned)
/* @@@@ This isn't correct if there are higher ranking roots than */
/* data in pools. */
ss.fix = TraceFix;
ss.zoneShift = SpaceZoneShift(space);
ss.white = trace->white;
ss.summary = RefSetEMPTY;
ss.space = space;
ss.traces = TraceSetSingle(trace->ti);
ss.wasMarked = TRUE;
ss.sig = ScanStateSig;
for(ss.rank = RankAMBIG; ss.rank <= RankEXACT; ++ss.rank) {
ring = SpaceRootRing(space);
node = RingNext(ring);
AVERT(ScanState, &ss);
while(node != ring) {
Ring next = RingNext(node);
Root root = RING_ELT(Root, spaceRing, node);
@ -153,45 +392,225 @@ Res TraceFlip(Space space, TraceId ti, RefSet condemned)
return ResOK;
}
static void TraceReclaim(Space space, TraceId ti)
static void TraceReclaim(Trace trace)
{
Ring node;
Space space;
Seg seg;
node = RingNext(&space->poolRing);
while(node != &space->poolRing) {
Ring next = RingNext(node);
Pool pool = RING_ELT(Pool, spaceRing, node);
AVERT(Trace, trace);
AVER(trace->state == TraceRECLAIM);
if((pool->class->attr & AttrGC) != 0)
PoolReclaim(pool, space, ti);
space = trace->space;
seg = SegFirst(space);
while(seg != NULL) {
Seg next = SegNext(space, seg);
node = next;
/* There shouldn't be any grey stuff left for this trace. */
AVER(!TraceSetIsMember(seg->grey, trace->ti));
if(TraceSetIsMember(seg->white, trace->ti)) {
AVER((seg->pool->class->attr & AttrGC) != 0);
PoolReclaim(seg->pool, trace, seg);
}
seg = next;
}
trace->state = TraceFINISHED;
}
Size TracePoll(Space space, TraceId ti)
/* FindGrey -- find a grey segment
*
* This function finds a segment which is grey for any of the traces
* in ts and which does not have a higher rank than any other such
* segment (i.e. a next segment to scan).
*
* This is equivalent to choosing a grey node from the grey set
* of a partition.
*
* @@@@ This must be optimised by using better data structures at
* the cost of some bookkeeping elsewhere, esp. during fix.
*/
static Bool FindGrey(Seg *segReturn, Rank *rankReturn,
Space space, TraceId ti)
{
Rank rank;
Seg seg;
AVER(segReturn != NULL);
AVERT(Space, space);
AVER(TraceIdCheck(ti));
for(rank = 0; rank < RankMAX; ++rank)
for(seg = SegFirst(space); seg != NULL; seg = SegNext(space, seg))
if(RankSetIsMember(seg->rankSet, rank) &&
TraceSetIsMember(seg->grey, ti)) {
*segReturn = seg;
*rankReturn = rank;
return TRUE;
}
return FALSE;
}
/* TraceScan -- scan a segment to remove greyness */
static Res TraceScan(TraceSet ts, Rank rank,
Space space, Seg seg)
{
Res res;
Bool finished;
Trace trace;
ScanStateStruct ss;
TraceId ti;
trace = &space->trace[ti];
AVER(TraceSetCheck(ts));
AVER(RankCheck(rank));
AVERT(Seg, seg);
/* The reason for scanning a segment is that it's grey. */
AVER(TraceSetInter(ts, seg->grey) != TraceSetEMPTY);
if(trace->condemned != RefSetEMPTY) {
res = TraceRun(space, ti, &finished);
AVER(res == ResOK); /* @@@@ */
if(finished) {
TraceReclaim(space, ti);
TraceDestroy(space, ti);
return SPACE_POLL_MAX;
}
ss.rank = rank;
ss.traces = ts;
ss.fix = TraceFix;
ss.zoneShift = space->zoneShift;
ss.summary = RefSetEMPTY;
ss.space = space;
ss.wasMarked = TRUE;
ss.white = RefSetEMPTY;
for(ti = 0; ti < TRACE_MAX; ++ti)
if(TraceSetIsMember(ss.traces, ti))
ss.white = RefSetUnion(ss.white, SpaceTrace(space, ti)->white);
ss.sig = ScanStateSig;
AVERT(ScanState, &ss);
/* Expose the segment to make sure we can scan it. */
ShieldExpose(space, seg);
res = PoolScan(&ss, seg->pool, seg);
if(res != ResOK) {
ShieldCover(space, seg);
return res;
}
/* We need to calculate a rate depending on the amount of work */
/* remaining and the deadline for the collection to finish. */
return (Size)4096; /* @@@@ */
ss.sig = SigInvalid; /* just in case */
/* The segment has been scanned, so remove the greyness from it. */
seg->grey = TraceSetDiff(seg->grey, ts);
/* If the segment is no longer grey for any flipped trace it */
/* doesn't need to be behind the read barrier. */
if(TraceSetInter(seg->grey, space->flippedTraces) == TraceSetEMPTY)
ShieldLower(space, seg, AccessREAD | AccessWRITE);
/* Cover the segment again, now it's been scanned. */
ShieldCover(space, seg);
return res;
}
void TraceAccess(Space space, Seg seg, AccessSet mode)
{
Res res;
AVERT(Space, space);
AVERT(Seg, seg);
UNUSED(mode);
/* @@@@ Need to establish what it is necessary to do with the segment. */
/* At the moment we're assuming that it must be scanned. What about */
/* write barrier faults? */
/* The only reason we protect at the moment is for a read barrier. */
/* In this case, the segment must be grey for a trace which is */
/* flipped. */
AVER(TraceSetInter(seg->grey, space->flippedTraces) != TraceSetEMPTY);
/* design.mps.poolamc.access.multi */
res = TraceScan(space->busyTraces, /* @@@@ Should just be flipped traces? */
RankEXACT, /* @@@@ Surely this is conservative? */
space, seg);
AVER(res == ResOK); /* design.mps.poolamc.access.error */
/* The pool should've done the job of removing the greyness that */
/* was causing the segment to be protected, so that the mutator */
/* can go ahead and access it. */
AVER(TraceSetInter(seg->grey, space->flippedTraces) == TraceSetEMPTY);
}
static Res TraceRun(Trace trace)
{
Res res;
Space space;
Seg seg;
Rank rank;
AVERT(Trace, trace);
AVER(trace->state == TraceFLIPPED);
space = trace->space;
if(FindGrey(&seg, &rank, space, trace->ti)) {
AVER((seg->pool->class->attr & AttrSCAN) != 0);
res = TraceScan(TraceSetSingle(trace->ti), rank,
space, seg);
if(res != ResOK) return res;
} else
trace->state = TraceRECLAIM;
return ResOK;
}
/* TracePoll -- make some progress in tracing
*
* @@@@ This should accept some sort of progress control.
*/
Res TracePoll(Trace trace)
{
Space space;
Res res;
AVERT(Trace, trace);
space = trace->space;
switch(trace->state) {
case TraceUNFLIPPED: {
res = TraceFlip(trace);
if(res != ResOK) return res;
} break;
case TraceFLIPPED: {
res = TraceRun(trace);
if(res != ResOK) return res;
} break;
case TraceRECLAIM: {
TraceReclaim(trace);
} break;
case TraceFINISHED:
case TraceINIT:
NOOP;
break;
default:
NOTREACHED;
break;
}
return ResOK;
}
Res TraceFix(ScanState ss, Ref *refIO)
{
Ref ref;
@ -203,7 +622,7 @@ Res TraceFix(ScanState ss, Ref *refIO)
ref = *refIO;
if(SegOfAddr(&seg, ss->space, ref))
if(ss->traceId == seg->condemned) {
if(TraceSetInter(seg->white, ss->traces) != TraceSetEMPTY) {
pool = seg->pool;
return PoolFix(pool, ss, seg, refIO);
}
@ -211,11 +630,12 @@ Res TraceFix(ScanState ss, Ref *refIO)
return ResOK;
}
/* == Scan Area ==
/* TraceScanArea -- scan contiguous area of references
*
* This is a convenience function for scanning the contiguous area
* [base, limit). i.e. it calls fix on all words from base up
* to limit, inclusive of base and exclusive of limit.
* This is a convenience function for scanning the contiguous area
* [base, limit). i.e. it calls fix on all words from base up
* to limit, inclusive of base and exclusive of limit.
*/
Res TraceScanArea(ScanState ss, Addr *base, Addr *limit)
@ -244,10 +664,11 @@ Res TraceScanArea(ScanState ss, Addr *base, Addr *limit)
return ResOK;
}
/* == Scan Area Tagged ==
/* TraceScanAreaTagged -- scan contiguous area of tagged references
*
* This is as TraceScanArea except words are only fixed if they
* are multiples of four. i.e. look like 4-byte aligned pointers.
* This is as TraceScanArea except words are only fixed if they
* are multiples of four. i.e. look like 4-byte aligned pointers.
*/
Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit)
@ -277,57 +698,3 @@ Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit)
return ResOK;
}
Res TraceRun(Space space, TraceId ti, Bool *finishedReturn)
{
Res res;
ScanStateStruct ss;
AVERT(Space, space);
AVER(finishedReturn != NULL);
ss.fix = TraceFix;
ss.zoneShift = space->zoneShift;
ss.condemned = space->trace[ti].condemned;
ss.summary = RefSetEMPTY;
ss.space = space;
ss.traceId = ti;
ss.sig = ScanStateSig;
for(ss.rank = 0; ss.rank < RankMAX; ++ss.rank) {
Ring ring;
Ring node;
if(ss.rank == RankWEAK) {
ss.weakSplat = (Addr)0;
} else {
ss.weakSplat = (Addr)0xadd4badd;
}
ring = SpacePoolRing(space);
node = RingNext(ring);
while(node != ring) {
Ring next = RingNext(node);
Pool pool = RING_ELT(Pool, spaceRing, node);
Bool finished;
if((pool->class->attr & AttrSCAN) != 0) {
res = PoolScan(&ss, pool, &finished);
if(res != ResOK) return res;
if(!finished) {
*finishedReturn = FALSE;
return ResOK;
}
}
node = next;
}
}
ss.sig = SigInvalid; /* just in case */
*finishedReturn = TRUE;
return ResOK;
}

View file

@ -1,7 +1,7 @@
/* impl.c.vman: ANSI VM: MALLOC-BASED PSUEDO MEMORY MAPPING
*
* $HopeName: MMsrc!vman.c(trunk.13) $
* Copyright (C) 1996,1997 Harlequin Group, all rights reserved.
* $HopeName: MMsrc!vman.c(MMdevel_action2.2) $
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
*/
#include "mpm.h"
@ -13,7 +13,7 @@
#include <stdlib.h> /* for malloc and free */
#include <string.h> /* for memset */
SRCID(vman, "$HopeName: MMsrc!vman.c(trunk.13) $");
SRCID(vman, "$HopeName: MMsrc!vman.c(MMdevel_action2.2) $");
#define SpaceVM(_space) (&(_space)->arenaStruct.vmStruct)
@ -58,7 +58,7 @@ Res VMCreate(Space *spaceReturn, Size size, Addr base)
vm->block = malloc((Size)(size + VMAN_ALIGN));
if(vm->block == NULL) {
free(vm);
free(space);
return ResMEMORY;
}

View file

@ -1,9 +1,10 @@
# ==== NTI3MV NMAKE FILE ====
# ==== NTALMV NMAKE FILE ====
#
# $HopeName: MMsrc!ntalmv.nmk(trunk.8) $
# $HopeName: MMsrc!ntalmv.nmk(trunk.9) $
#
# Copyright (C) 1995 Harlequin Group, all rights reserved
#
PFM = ntalmv
PFMDEFS = /DWIN32 /D_WINDOWS
@ -11,12 +12,13 @@ MPM = <assert> <ring> <mpsliban> <mpm> <bt> \
<arenavm> <vmnt> <space> <pool> <poolmfs> \
<poolmv> <root> <format> <buffer> <locknt> \
<ref> <trace> <protnt> <shield> \
<than> <ssan> <mpsi> <mpsint> <ld>
<than> <ssan> <mpsi> <mpsint> <ld> <action> <seg>
SW = <assert> <ring> <mpm> \
<arenacl> <space> <pool> <poolmfs> \
<poolmv> <root> <format> <buffer> <locknt> \
<ref> <trace> <protsw> <shield> \
<than> <ssan> <mpsisw> <mpsint> <ld> <poolepdl>
<than> <ssan> <mpsisw> <mpsint> <ld> <poolepdl> \
<action> <seg>
AMC = <amc>
LO = <lo>
MRG = <poolmrg>

View file

@ -1,6 +1,6 @@
# ==== NTI3MV NMAKE FILE ====
#
# $HopeName: MMsrc!nti3mv.nmk(trunk.30) $
# $HopeName: MMsrc!nti3mv.nmk(trunk.31) $
#
# Copyright (C) 1995,1996,1997 Harlequin Group, all rights reserved
#
@ -11,12 +11,14 @@ MPM = <assert> <ring> <mpsliban> <mpm> <bt> \
<arenavm> <vmnt> <space> <pool> <poolmfs> \
<poolmv> <root> <format> <buffer> <locknt> \
<ref> <trace> <protnt> <shield> \
<thnti3> <ssnti3> <mpsi> <mpsint> <ld>
<thnti3> <ssnti3> <mpsi> <mpsint> <ld> \
<action> <seg>
SW = <assert> <ring> <mpm> \
<arenacl> <space> <pool> <poolmfs> \
<poolmv> <root> <format> <buffer> <locknt> \
<ref> <trace> <protsw> <shield> \
<thnti3> <ssnti3> <mpsisw> <mpsint> <ld> <poolepdl>
<thnti3> <ssnti3> <mpsisw> <mpsint> <ld> <poolepdl> \
<action> <seg>
AMC = <amc>
LO = <lo>
MRG = <poolmrg>

View file

@ -1,6 +1,6 @@
# ==== NTI3MV NMAKE FILE ====
# ==== NTPPMV NMAKE FILE ====
#
# $HopeName: MMsrc!ntppmv.nmk(trunk.8) $
# $HopeName: MMsrc!ntppmv.nmk(trunk.9) $
#
# Copyright (C) 1995 Harlequin Group, all rights reserved
#
@ -11,12 +11,14 @@ MPM = <assert> <ring> <mpsliban> <mpm> <bt> \
<arenavm> <vmnt> <space> <pool> <poolmfs> \
<poolmv> <root> <format> <buffer> <locknt> \
<ref> <trace> <protnt> <shield> \
<than> <ssan> <mpsi> <mpsint> <ld>
<than> <ssan> <mpsi> <mpsint> <ld> \
<action> <seg>
SW = <assert> <ring> <mpm> \
<arenacl> <space> <pool> <poolmfs> \
<poolmv> <root> <format> <buffer> <locknt> \
<ref> <trace> <protnt> <shield> \
<than> <ssan> <mpsisw> <mpsint> <ld> <poolepdl>
<than> <ssan> <mpsisw> <mpsint> <ld> <poolepdl> \
<action> <seg>
AMC = <amc>
LO = <lo>
MRG = <poolmrg>