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:
parent
5d0a6ddf00
commit
39de4f1fa1
28 changed files with 1020 additions and 640 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
261
mps/src/buffer.c
261
mps/src/buffer.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
172
mps/src/pool.c
172
mps/src/pool.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
637
mps/src/trace.c
637
mps/src/trace.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue