1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

Catch-up merge from master sources to branch/2014-01-15/nailboard.

Copied from Perforce
 Change: 185275
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-04-07 10:38:08 +01:00
commit 4e8b76ac54
85 changed files with 1427 additions and 1109 deletions

View file

@ -186,7 +186,6 @@ int main(int argc, char *argv[])
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 2 * testArenaSIZE);
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE);
MPS_ARGS_DONE(args);
die(mps_arena_create_k(&arena, mps_arena_class_vm(), args),
"mps_arena_create");
} MPS_ARGS_END(args);

View file

@ -1,7 +1,7 @@
/* arena.c: ARENA ALLOCATION FEATURES
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .sources: <design/arena/> is the main design document. */
@ -86,7 +86,7 @@ DEFINE_CLASS(AbstractArenaClass, class)
Bool ArenaClassCheck(ArenaClass class)
{
CHECKL(ProtocolClassCheck(&class->protocol));
CHECKD(ProtocolClass, &class->protocol);
CHECKL(class->name != NULL); /* Should be <=6 char C identifier */
CHECKL(class->size >= sizeof(ArenaStruct));
/* Offset of generic Pool within class-specific instance cannot be */
@ -147,7 +147,7 @@ Bool ArenaCheck(Arena arena)
if (arena->primary != NULL) {
CHECKD(Chunk, arena->primary);
}
CHECKL(RingCheck(&arena->chunkRing));
CHECKD_NOSIG(Ring, &arena->chunkRing);
/* nothing to check for chunkSerial */
CHECKD(ChunkCacheEntry, &arena->chunkCache);
@ -155,7 +155,9 @@ Bool ArenaCheck(Arena arena)
CHECKL(BoolCheck(arena->hasFreeCBS));
if (arena->hasFreeCBS)
CHECKL(CBSCheck(ArenaFreeCBS(arena)));
CHECKD(CBS, ArenaFreeCBS(arena));
CHECKL(BoolCheck(arena->zoned));
return TRUE;
}
@ -179,7 +181,7 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args)
AVER(arena != NULL);
AVERT(ArenaClass, class);
AVER(AlignCheck(alignment));
AVERT(Align, alignment);
if (ArgPick(&arg, args, MPS_KEY_ARENA_ZONED))
zoned = arg.val.b;
@ -224,7 +226,6 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args)
MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, arena->alignment);
MPS_ARGS_ADD(piArgs, MFSExtendSelf, FALSE);
MPS_ARGS_DONE(piArgs);
res = PoolInit(ArenaCBSBlockPool(arena), arena, PoolClassMFS(), piArgs);
} MPS_ARGS_END(piArgs);
AVER(res == ResOK); /* no allocation, no failure expected */
@ -234,7 +235,6 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args)
/* Initialise the freeCBS. */
MPS_ARGS_BEGIN(cbsiArgs) {
MPS_ARGS_ADD(cbsiArgs, CBSBlockPool, ArenaCBSBlockPool(arena));
MPS_ARGS_DONE(cbsiArgs);
res = CBSInit(ArenaFreeCBS(arena), arena, arena, alignment,
/* fastFind */ TRUE, arena->zoned, cbsiArgs);
} MPS_ARGS_END(cbsiArgs);
@ -286,7 +286,7 @@ Res ArenaCreate(Arena *arenaReturn, ArenaClass class, ArgList args)
AVER(arenaReturn != NULL);
AVERT(ArenaClass, class);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
/* We must initialise the event subsystem very early, because event logging
will start as soon as anything interesting happens and expect to write
@ -558,7 +558,7 @@ Res ControlAlloc(void **baseReturn, Arena arena, size_t size,
AVERT(Arena, arena);
AVER(baseReturn != NULL);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
AVER(arena->poolReady);
res = PoolAlloc(&base, ArenaControlPool(arena), (Size)size,
@ -1023,7 +1023,7 @@ Res ArenaAlloc(Addr *baseReturn, SegPref pref, Size size, Pool pool,
AVERT(SegPref, pref);
AVER(size > (Size)0);
AVERT(Pool, pool);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
arena = PoolArena(pool);
AVERT(Arena, arena);
@ -1321,7 +1321,7 @@ Res ArenaAddrObject(Addr *pReturn, Arena arena, Addr addr)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* arenacl.c: ARENA CLASS USING CLIENT MEMORY
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .design: See <design/arena/#client>.
*
@ -67,7 +67,7 @@ static Bool ClientChunkCheck(ClientChunk clChunk)
CHECKS(ClientChunk, clChunk);
chunk = ClientChunk2Chunk(clChunk);
CHECKL(ChunkCheck(chunk));
CHECKD(Chunk, chunk);
CHECKL(clChunk->freePages <= chunk->pages);
/* check they don't overlap (knowing the order) */
CHECKL((Addr)(chunk + 1) < (Addr)chunk->allocTable);
@ -201,7 +201,7 @@ static void ClientArenaVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[1].key = MPS_KEY_ARENA_CL_BASE;
args[1].val.addr = va_arg(varargs, Addr);
args[2].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -228,7 +228,7 @@ static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
AVER(arenaReturn != NULL);
AVER((ArenaClass)mps_arena_class_cl() == class);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
ArgRequire(&arg, args, MPS_KEY_ARENA_SIZE);
size = arg.val.size;
@ -434,6 +434,7 @@ DEFINE_ARENA_CLASS(ClientArenaClass, this)
this->free = ClientFree;
this->chunkInit = ClientChunkInit;
this->chunkFinish = ClientChunkFinish;
AVERT(ArenaClass, this);
}
@ -447,7 +448,7 @@ mps_arena_class_t mps_arena_class_cl(void)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -99,8 +99,8 @@ static Bool VMChunkCheck(VMChunk vmchunk)
CHECKS(VMChunk, vmchunk);
chunk = VMChunk2Chunk(vmchunk);
CHECKL(ChunkCheck(chunk));
CHECKL(VMCheck(vmchunk->vm));
CHECKD(Chunk, chunk);
CHECKD_NOSIG(VM, vmchunk->vm); /* <design/check/#hidden-type> */
CHECKL(VMAlign(vmchunk->vm) == ChunkPageSize(chunk));
CHECKL(vmchunk->overheadMappedLimit <= (Addr)chunk->pageTable);
CHECKD(SparseArray, &vmchunk->pages);
@ -174,7 +174,7 @@ static Bool VMArenaCheck(VMArena vmArena)
CHECKL(VMMapped(primary->vm) <= arena->committed);
}
CHECKL(RingCheck(&vmArena->spareRing));
CHECKD_NOSIG(Ring, &vmArena->spareRing);
/* FIXME: Can't check VMParams */
@ -438,7 +438,7 @@ static void VMArenaVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[0].key = MPS_KEY_ARENA_SIZE;
args[0].val.size = va_arg(varargs, Size);
args[1].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -493,7 +493,7 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
AVER(arenaReturn != NULL);
AVER(class == VMArenaClassGet());
AVER(ArgListCheck(args));
AVERT(ArgList, args);
ArgRequire(&arg, args, MPS_KEY_ARENA_SIZE);
userSize = arg.val.size;
@ -1159,6 +1159,7 @@ DEFINE_ARENA_CLASS(VMArenaClass, this)
this->compact = VMCompact;
this->describe = VMArenaDescribe;
this->pagesMarkAllocated = VMPagesMarkAllocated;
AVERT(ArenaClass, this);
}

View file

@ -1,7 +1,7 @@
/* arg.c: ARGUMENT LISTS
*
* $Id$
* Copyright (c) 2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2013-2014 Ravenbrook Limited. See end of file for license.
*
* .source: See <design/keyword-arguments.rst>.
*/
@ -52,7 +52,7 @@ Bool ArgCheckAddr(Arg arg) {
}
Bool ArgCheckPoolDebugOptions(Arg arg) {
CHECKL(PoolDebugOptionsCheck((PoolDebugOptions)arg->val.pool_debug_options));
CHECKD_NOSIG(PoolDebugOptions, (PoolDebugOptions)arg->val.pool_debug_options);
return TRUE;
}
@ -138,7 +138,7 @@ Bool ArgListCheck(ArgList args)
CHECKL(args != NULL);
for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i) {
CHECKL(i < MPS_ARGS_MAX);
CHECKL(ArgCheck(&args[i]));
CHECKD_NOSIG(Arg, &args[i]);
}
return TRUE;
}
@ -150,7 +150,7 @@ Bool ArgPick(ArgStruct *argOut, ArgList args, Key key) {
Index i;
AVER(argOut != NULL);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
AVERT(Key, key);
for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i)
@ -185,14 +185,14 @@ void ArgTrivVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
{
UNUSED(varargs);
args[0].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* boot.c: BOOTSTRAP ALLOCATOR
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .overview: A structure and protocols for allocating memory from a
* given block. Very simple, it basically just increments a pointer.
@ -101,7 +101,7 @@ Res BootAlloc(void **pReturn, BootBlock boot, size_t size, size_t align)
AVER(pReturn != NULL);
AVERT(BootBlock, boot);
AVER(size > 0);
AVER(AlignCheck((Align)align));
AVERT(Align, (Align)align);
/* Align alloc pointer up and bounds check. */
blockBase = PointerAlignUp(boot->alloc, align);
@ -127,7 +127,7 @@ Res BootAlloc(void **pReturn, BootBlock boot, size_t size, size_t align)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* bt.c: BIT TABLES
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* READERSHIP
*
@ -223,7 +223,7 @@ void BTDestroy(BT bt, Arena arena, Count length)
* discussed in review.impl.c.bt.4.
*/
static Bool BTCheck(BT bt)
Bool BTCheck(BT bt)
{
AVER(bt != NULL);
AVER(AddrIsAligned((Addr)bt, sizeof(Word)));
@ -252,7 +252,7 @@ Size (BTSize)(Count n)
Bool (BTGet)(BT t, Index i)
{
AVER(BTCheck(t));
AVERT(BT, t);
/* Can't check i */
/* see macro in <code/mpm.h> */
@ -267,7 +267,7 @@ Bool (BTGet)(BT t, Index i)
void (BTSet)(BT t, Index i)
{
AVER(BTCheck(t));
AVERT(BT, t);
/* Can't check i */
/* see macro in <code/mpm.h> */
@ -282,7 +282,7 @@ void (BTSet)(BT t, Index i)
void (BTRes)(BT t, Index i)
{
AVER(BTCheck(t));
AVERT(BT, t);
/* Can't check i */
/* see macro in <code/mpm.h> */
@ -297,7 +297,7 @@ void (BTRes)(BT t, Index i)
void BTSetRange(BT t, Index base, Index limit)
{
AVER(BTCheck(t));
AVERT(BT, t);
AVER(base < limit);
#define SINGLE_SET_RANGE(i) \
@ -319,7 +319,7 @@ void BTSetRange(BT t, Index base, Index limit)
Bool BTIsResRange(BT bt, Index base, Index limit)
{
AVER_CRITICAL(BTCheck(bt)); /* See .aver.critical */
AVERT_CRITICAL(BT, bt); /* See .aver.critical */
AVER_CRITICAL(base < limit);
/* Can't check range of base or limit */
@ -343,7 +343,7 @@ Bool BTIsResRange(BT bt, Index base, Index limit)
Bool BTIsSetRange(BT bt, Index base, Index limit)
{
AVER(BTCheck(bt));
AVERT(BT, bt);
AVER(base < limit);
/* Can't check range of base or limit */
@ -371,7 +371,7 @@ Bool BTIsSetRange(BT bt, Index base, Index limit)
void BTResRange(BT t, Index base, Index limit)
{
AVER(BTCheck(t));
AVERT(BT, t);
AVER(base < limit);
#define SINGLE_RES_RANGE(i) \
@ -884,8 +884,8 @@ Bool BTFindShortResRangeHigh(Index *baseReturn, Index *limitReturn,
Bool BTRangesSame(BT comparand, BT comparator, Index base, Index limit)
{
AVER(BTCheck(comparand));
AVER(BTCheck(comparator));
AVERT(BT, comparand);
AVERT(BT, comparator);
AVER(base < limit);
#define SINGLE_RANGES_SAME(i) \
@ -920,8 +920,8 @@ Bool BTRangesSame(BT comparand, BT comparator, Index base, Index limit)
void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit)
{
AVER(BTCheck(fromBT));
AVER(BTCheck(toBT));
AVERT(BT, fromBT);
AVERT(BT, toBT);
AVER(fromBT != toBT);
AVER(base < limit);
@ -955,8 +955,8 @@ void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit)
void BTCopyRange(BT fromBT, BT toBT, Index base, Index limit)
{
AVER(BTCheck(fromBT));
AVER(BTCheck(toBT));
AVERT(BT, fromBT);
AVERT(BT, toBT);
AVER(fromBT != toBT);
AVER(base < limit);
@ -999,8 +999,8 @@ void BTCopyOffsetRange(BT fromBT, BT toBT,
{
Index fromBit, toBit;
AVER(BTCheck(fromBT));
AVER(BTCheck(toBT));
AVERT(BT, fromBT);
AVERT(BT, toBT);
AVER(fromBT != toBT);
AVER(fromBase < fromLimit);
AVER(toBase < toLimit);
@ -1024,7 +1024,7 @@ Count BTCountResRange(BT bt, Index base, Index limit)
Count c = 0;
Index bit;
AVER(BTCheck(bt));
AVERT(BT, bt);
AVER(base < limit);
for (bit = base; bit < limit; ++bit)
@ -1035,7 +1035,7 @@ Count BTCountResRange(BT bt, Index base, Index limit)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* bt.h: Bit Table Interface
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .source: <design/bt/>
*/
@ -39,6 +39,7 @@ extern void (BTRes)(BT bt, Index index);
END
extern Bool BTCheck(BT bt);
extern Res BTCreate(BT *btReturn, Arena arena, Count length);
extern void BTDestroy(BT bt, Arena arena, Count length);
@ -76,7 +77,7 @@ extern Count BTCountResRange(BT bt, Index base, Index limit);
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* buffer.c: ALLOCATION BUFFER IMPLEMENTATION
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This is (part of) the implementation of allocation buffers.
* Several macros which also form part of the implementation are in
@ -45,7 +45,7 @@ Bool BufferCheck(Buffer buffer)
CHECKU(Arena, buffer->arena);
CHECKU(Pool, buffer->pool);
CHECKL(buffer->arena == buffer->pool->arena);
CHECKL(RingCheck(&buffer->poolRing)); /* <design/check/#type.no-sig> */
CHECKD_NOSIG(Ring, &buffer->poolRing);
CHECKL(BoolCheck(buffer->isMutator));
CHECKL(buffer->fillSize >= 0.0);
CHECKL(buffer->emptySize >= 0.0);
@ -205,7 +205,7 @@ static Res BufferInit(Buffer buffer, BufferClass class,
AVERT(BufferClass, class);
AVERT(Pool, pool);
/* The PoolClass should support buffer protocols */
AVER((pool->class->attr & AttrBUF)); /* .trans.mod */
AVER(PoolHasAttr(pool, AttrBUF));
arena = PoolArena(pool);
/* Initialize the buffer. See <code/mpmst.h> for a definition of */
@ -383,7 +383,7 @@ void BufferFinish(Buffer buffer)
pool = BufferPool(buffer);
/* The PoolClass should support buffer protocols */
AVER((pool->class->attr & AttrBUF)); /* .trans.mod */
AVER(PoolHasAttr(pool, AttrBUF));
AVER(BufferIsReady(buffer));
/* <design/alloc-frame/#lw-frame.sync.trip> */
@ -605,7 +605,7 @@ Res BufferReserve(Addr *pReturn, Buffer buffer, Size size,
AVER(size > 0);
AVER(SizeIsAligned(size, BufferPool(buffer)->alignment));
AVER(BufferIsReady(buffer));
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* Is there enough room in the unallocated portion of the buffer to */
/* satisfy the request? If so, just increase the alloc marker and */
@ -1182,7 +1182,7 @@ static Res bufferTrivDescribe(Buffer buffer, mps_lib_FILE *stream)
Bool BufferClassCheck(BufferClass class)
{
CHECKL(ProtocolClassCheck(&class->protocol));
CHECKD(ProtocolClass, &class->protocol);
CHECKL(class->name != NULL); /* Should be <=6 char C identifier */
CHECKL(class->size >= sizeof(BufferStruct));
CHECKL(FUNCHECK(class->varargs));
@ -1220,6 +1220,7 @@ DEFINE_CLASS(BufferClass, class)
class->setRankSet = bufferNoSetRankSet;
class->reassignSeg = bufferNoReassignSeg;
class->sig = BufferClassSig;
AVERT(BufferClass, class);
}
@ -1240,7 +1241,7 @@ Bool SegBufCheck(SegBuf segbuf)
CHECKS(SegBuf, segbuf);
buffer = &segbuf->bufferStruct;
CHECKL(BufferCheck(buffer));
CHECKD(Buffer, buffer);
CHECKL(RankSetCheck(segbuf->rankSet));
if (buffer->mode & BufferModeTRANSITION) {
@ -1250,7 +1251,7 @@ Bool SegBufCheck(SegBuf segbuf)
} else {
/* The buffer is attached to a segment. */
CHECKL(segbuf->seg != NULL);
CHECKL(SegCheck(segbuf->seg));
CHECKD(Seg, segbuf->seg);
/* To avoid recursive checking, leave it to SegCheck to make */
/* sure the buffer and segment fields tally. */
@ -1472,6 +1473,7 @@ DEFINE_CLASS(SegBufClass, class)
class->rankSet = segBufRankSet;
class->setRankSet = segBufSetRankSet;
class->reassignSeg = segBufReassignSeg;
AVERT(BufferClass, class);
}
@ -1485,7 +1487,7 @@ static void rankBufVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[0].key = MPS_KEY_RANK;
args[0].val.rank = va_arg(varargs, Rank);
args[1].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
/* rankBufInit -- RankBufClass init method */
@ -1499,10 +1501,10 @@ static Res rankBufInit(Buffer buffer, Pool pool, ArgList args)
AVERT(Buffer, buffer);
AVERT(Pool, pool);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
if (ArgPick(&arg, args, MPS_KEY_RANK))
rank = arg.val.rank;
AVER(RankCheck(rank));
AVERT(Rank, rank);
/* Initialize the superclass fields first via next-method call */
super = BUFFER_SUPERCLASS(RankBufClass);
@ -1532,12 +1534,13 @@ DEFINE_CLASS(RankBufClass, class)
class->name = "RANKBUF";
class->varargs = rankBufVarargs;
class->init = rankBufInit;
AVERT(BufferClass, class);
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* cbs.c: COALESCING BLOCK STRUCTURE IMPLEMENTATION
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .intro: This is a portable implementation of coalescing block
* structures.
@ -85,6 +85,7 @@ static Bool CBSBlockCheck(CBSBlock block)
/* See .enter-leave.simple. */
UNUSED(block); /* Required because there is no signature */
CHECKL(block != NULL);
/* Can't use CHECKD_NOSIG because TreeEMPTY is NULL. */
CHECKL(TreeCheck(cbsBlockTree(block)));
/* If the block is in the middle of being deleted, */
@ -245,9 +246,9 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment,
AVERT(Arena, arena);
AVER(cbs != NULL);
AVER(AlignCheck(alignment));
AVER(BoolCheck(fastFind));
AVER(BoolCheck(zoned));
AVERT(Align, alignment);
AVERT(Bool, fastFind);
AVERT(Bool, zoned);
if (ArgPick(&arg, args, CBSBlockPool))
blockPool = arg.val.pool;
@ -915,8 +916,8 @@ Res CBSFindInZones(Range rangeReturn, Range oldRangeReturn,
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(CBS, cbs);
/* AVER(ZoneSetCheck(zoneSet)); */
AVER(BoolCheck(high));
/* AVERT(ZoneSet, zoneSet); */
AVERT(Bool, high);
cbsFind = high ? CBSFindLast : CBSFindFirst;
splayFind = high ? SplayFindLast : SplayFindFirst;
@ -1086,7 +1087,7 @@ Res CBSDescribe(CBS cbs, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* check.h: ASSERTION INTERFACE
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* .aver: This header defines a family of AVER and NOTREACHED macros.
@ -85,9 +85,6 @@
*
* TODO: Should also allow the check level variable to come from an
* environment variable.
*
* TODO: CheckLevelDEEP asserts on arena creation with bootstrapping
* problems. It clearly hasn't been tried for a while. RB 2012-09-01
*/
enum {
@ -327,7 +324,7 @@ extern unsigned CheckLevel;
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,6 +1,6 @@
/* clock.h -- Fast clocks and timers
*
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* $Id$
*/
@ -15,10 +15,6 @@
*
* On platforms that support it, we want to stamp events with a very cheap
* and fast high-resolution timer.
*
* TODO: This is a sufficiently complicated nest of ifdefs that it should
* be quarantined in its own header with KEEP OUT signs attached.
* RB 2012-09-11
*/
/* Microsoft C provides an intrinsic for the Intel rdtsc instruction.
@ -169,7 +165,7 @@ typedef mps_clock_t EventClock;
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* dbgpool.c: POOL DEBUG MIXIN
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* .source: design.mps.object-debug
@ -34,8 +34,6 @@ typedef tagStruct *Tag;
/* tag init methods: copying the user-supplied data into the tag */
#define TagInitMethodCheck(f) FUNCHECK(f)
static void TagTrivInit(void* tag, va_list args)
{
UNUSED(tag); UNUSED(args);
@ -75,7 +73,7 @@ Bool PoolDebugMixinCheck(PoolDebugMixin debug)
/* Nothing to check about freeTemplate */
/* Nothing to check about freeSize */
if (debug->tagInit != NULL) {
CHECKL(TagInitMethodCheck(debug->tagInit));
CHECKL(FUNCHECK(debug->tagInit));
/* Nothing to check about tagSize */
CHECKD(Pool, debug->tagPool);
CHECKL(COMPATTYPE(Addr, void*)); /* tagPool relies on this */
@ -573,7 +571,7 @@ static void TagWalk(Pool pool, ObjectsStepMethod step, void *p)
AVERT(PoolDebugMixin, debug);
node = SplayTreeFirst(&debug->index);
while (node != NULL) {
while (node != TreeEMPTY) {
Tag tag = TagOfTree(node);
step(tag->addr, tag->size, NULL, pool, &tag->userdata, p);
@ -691,7 +689,7 @@ void PoolClassMixInDebug(PoolClass class)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -264,6 +264,9 @@ static void readLog(FILE *stream)
event->EventInit.f5,
MPS_WORD_WIDTH);
break;
default:
/* No special treatment needed. */
break;
}
(void)EVENT_CLOCK_PRINT(stdout, eventTime);

View file

@ -1,7 +1,7 @@
/* <code/eventdef.h> -- Event Logging Definitions
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .source: <design/telemetry/>
*
@ -31,14 +31,13 @@
* the median version when changing an existing event,
* and the major version when changing the format of the event file.
*
* TODO: These should go into a header that appears at the start of a
* telemetry stream, but they aren't currently used. Keep updating them
* anyway. RB 2012-09-07
* These are passed as parameters to the EventInit event at the start
* of a telemetry stream, allowing that stream to be identified.
*/
#define EVENT_VERSION_MAJOR ((unsigned)1)
#define EVENT_VERSION_MEDIAN ((unsigned)1)
#define EVENT_VERSION_MINOR ((unsigned)6)
#define EVENT_VERSION_MINOR ((unsigned)7)
/* EVENT_LIST -- list of event types and general properties
@ -192,7 +191,8 @@
/* new events for performance analysis of large heaps. */ \
EVENT(X, TraceCondemnZones , 0x0083, TRUE, Trace) \
EVENT(X, ArenaGenZoneAdd , 0x0084, TRUE, Arena) \
EVENT(X, ArenaUseFreeZone , 0x0085, TRUE, Arena)
EVENT(X, ArenaUseFreeZone , 0x0085, TRUE, Arena) \
/* EVENT(X, ArenaBlacklistZone , 0x0086, TRUE, Arena) */
/* Remember to update EventNameMAX and EventCodeMAX above!
@ -745,7 +745,7 @@
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -432,20 +432,23 @@ static void find(FBMState state, Size size, Bool high, FindDelete findDelete)
remainderLimit = origLimit = addrOfIndex(state, expectedLimit);
switch(findDelete) {
case FindDeleteNONE: {
case FindDeleteNONE:
/* do nothing */
} break;
case FindDeleteENTIRE: {
break;
case FindDeleteENTIRE:
remainderBase = remainderLimit;
} break;
case FindDeleteLOW: {
break;
case FindDeleteLOW:
expectedLimit = expectedBase + size;
remainderBase = addrOfIndex(state, expectedLimit);
} break;
case FindDeleteHIGH: {
break;
case FindDeleteHIGH:
expectedBase = expectedLimit - size;
remainderLimit = addrOfIndex(state, expectedBase);
} break;
break;
default:
cdie(0, "invalid findDelete");
break;
}
if (findDelete != FindDeleteNONE) {
@ -528,9 +531,7 @@ static void test(FBMState state, unsigned n) {
size = fbmRnd(ArraySize / 10) + 1;
high = fbmRnd(2) ? TRUE : FALSE;
switch(fbmRnd(6)) {
case 0:
case 1:
case 2: findDelete = FindDeleteNONE; break;
default: findDelete = FindDeleteNONE; break;
case 3: findDelete = FindDeleteLOW; break;
case 4: findDelete = FindDeleteHIGH; break;
case 5: findDelete = FindDeleteENTIRE; break;

View file

@ -20,6 +20,8 @@
#include "mpslib.h"
#include "mps.h"
#include "mpscamc.h"
#include "mpscams.h"
#include "mpscawl.h"
#include "mpsavm.h"
#include "fmtdy.h"
#include "fmtdytst.h"
@ -32,14 +34,8 @@
#define testArenaSIZE ((size_t)16<<20)
#define rootCOUNT 20
#define maxtreeDEPTH 12
#define maxtreeDEPTH 10
#define collectionCOUNT 10
#define genCOUNT 2
/* testChain -- generation parameters for the test */
static mps_gen_param_s testChain[genCOUNT] = {
{ 150, 0.85 }, { 170, 0.45 } };
/* global object counter */
@ -123,119 +119,90 @@ static void register_indirect_tree(mps_word_t tree, mps_arena_t arena)
}
}
static mps_addr_t test_awl_find_dependent(mps_addr_t addr)
{
testlib_unused(addr);
return NULL;
}
static void *root[rootCOUNT];
static void *test(void *arg, size_t s)
static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap,
mps_word_t (*make)(mps_word_t, mps_ap_t),
void (*reg)(mps_word_t, mps_arena_t))
{
size_t collections = 0;
size_t finals = 0;
size_t i;
object_count = 0;
printf("Making some %s finalized trees of objects.\n", name);
/* make some trees */
for(i = 0; i < rootCOUNT; ++i) {
root[i] = (void *)(*make)(maxtreeDEPTH, ap);
(*reg)((mps_word_t)root[i], arena);
}
printf("Losing all pointers to the trees.\n");
/* clean out the roots */
for(i = 0; i < rootCOUNT; ++i) {
root[i] = 0;
}
while (finals < object_count && collections < collectionCOUNT) {
mps_word_t final_this_time = 0;
printf("Collecting...");
(void)fflush(stdout);
die(mps_arena_collect(arena), "collect");
printf(" Done.\n");
++ collections;
while (mps_message_poll(arena)) {
mps_message_t message;
mps_addr_t objaddr;
cdie(mps_message_get(&message, arena,
mps_message_type_finalization()),
"get");
mps_message_finalization_ref(&objaddr, arena, message);
mps_message_discard(arena, message);
++ final_this_time;
}
finals += final_this_time;
printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST
" of %"PRIuLONGEST"\n", final_this_time, finals, object_count);
}
cdie(finals == object_count, "Not all objects were finalized.");
}
static void *test(mps_arena_t arena, mps_class_t pool_class)
{
mps_ap_t ap;
mps_fmt_t fmt;
mps_chain_t chain;
mps_word_t finals;
mps_pool_t amc;
mps_pool_t pool;
mps_root_t mps_root;
mps_arena_t arena;
mps_message_t message;
size_t i;
arena = (mps_arena_t)arg;
(void)s;
die(mps_fmt_create_A(&fmt, arena, dylan_fmt_A()), "fmt_create\n");
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&amc, arena, mps_class_amc(), fmt, chain),
"pool_create amc\n");
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent);
die(mps_pool_create_k(&pool, arena, pool_class, args),
"pool_create\n");
} MPS_ARGS_END(args);
die(mps_root_create_table(&mps_root, arena, mps_rank_exact(), (mps_rm_t)0,
root, (size_t)rootCOUNT),
"root_create\n");
die(mps_ap_create(&ap, amc, mps_rank_exact()), "ap_create\n");
die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create\n");
mps_message_type_enable(arena, mps_message_type_finalization());
mps_arena_park(arena);
object_count = 0;
printf("Making some finalized trees of objects.\n");
/* make some trees */
for(i = 0; i < rootCOUNT; ++i) {
root[i] = (void *)make_numbered_tree(maxtreeDEPTH, ap);
register_numbered_tree((mps_word_t)root[i], arena);
}
printf("Losing all pointers to the trees.\n");
/* clean out the roots */
for(i = 0; i < rootCOUNT; ++i) {
root[i] = 0;
}
finals = 0;
while ((finals < object_count) &&
(mps_collections(arena) < collectionCOUNT)) {
mps_word_t final_this_time = 0;
printf("Collecting...");
(void)fflush(stdout);
die(mps_arena_collect(arena), "collect");
printf(" Done.\n");
while (mps_message_poll(arena)) {
mps_addr_t objaddr;
cdie(mps_message_get(&message, arena,
mps_message_type_finalization()),
"get");
mps_message_finalization_ref(&objaddr, arena, message);
mps_message_discard(arena, message);
++ final_this_time;
}
finals += final_this_time;
printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST
" of %"PRIuLONGEST"\n",
final_this_time, finals, object_count);
}
object_count = 0;
printf("Making some indirectly finalized trees of objects.\n");
/* make some trees */
for(i = 0; i < rootCOUNT; ++i) {
root[i] = (void *)make_indirect_tree(maxtreeDEPTH, ap);
register_indirect_tree((mps_word_t)root[i], arena);
}
printf("Losing all pointers to the trees.\n");
/* clean out the roots */
for(i = 0; i < rootCOUNT; ++i) {
root[i] = 0;
}
finals = 0;
while ((finals < object_count) &&
(mps_collections(arena) < collectionCOUNT)) {
mps_word_t final_this_time = 0;
printf("Collecting...");
(void)fflush(stdout);
die(mps_arena_collect(arena), "collect");
printf(" Done.\n");
while (mps_message_poll(arena)) {
mps_addr_t objaddr;
cdie(mps_message_get(&message, arena,
mps_message_type_finalization()),
"get");
mps_message_finalization_ref(&objaddr, arena, message);
mps_message_discard(arena, message);
++ final_this_time;
}
finals += final_this_time;
printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST
" of %"PRIuLONGEST"\n",
final_this_time, finals, object_count);
}
test_trees("numbered", arena, ap, make_numbered_tree, register_numbered_tree);
test_trees("indirect", arena, ap, make_indirect_tree, register_indirect_tree);
mps_ap_destroy(ap);
mps_root_destroy(mps_root);
mps_pool_destroy(amc);
mps_chain_destroy(chain);
mps_pool_destroy(pool);
mps_fmt_destroy(fmt);
return NULL;
@ -246,14 +213,17 @@ int main(int argc, char *argv[])
{
mps_arena_t arena;
mps_thr_t thread;
void *r;
testlib_init(argc, argv);
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
"arena_create\n");
die(mps_thread_reg(&thread, arena), "thread_reg\n");
mps_tramp(&r, test, arena, 0);
test(arena, mps_class_amc());
/* TODO: test(arena, mps_class_ams()); */
/* TODO: test(arena, mps_class_awl()); */
mps_thread_dereg(thread);
mps_arena_destroy(arena);

View file

@ -1,7 +1,7 @@
/* format.c: OBJECT FORMATS
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2002 Global Graphics Software.
*
* DESIGN
@ -21,7 +21,7 @@ Bool FormatCheck(Format format)
CHECKS(Format, format);
CHECKU(Arena, format->arena);
CHECKL(format->serial < format->arena->formatSerial);
CHECKL(RingCheck(&format->arenaRing));
CHECKD_NOSIG(Ring, &format->arenaRing);
CHECKL(AlignCheck(format->alignment));
/* TODO: Define the concept of the maximum alignment it is possible to
request from the MPS, document and provide an interface to it, and then
@ -114,7 +114,7 @@ Res FormatCreate(Format *formatReturn, Arena arena, ArgList args)
AVER(formatReturn != NULL);
AVERT(Arena, arena);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
if (ArgPick(&arg, args, MPS_KEY_FMT_ALIGN))
fmtAlign = arg.val.align;
@ -217,7 +217,7 @@ Res FormatDescribe(Format format, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -60,6 +60,8 @@ DEFINE_POOL_CLASS(OOMPoolClass, this)
{
INHERIT_CLASS(this, AbstractAllocFreePoolClass);
this->alloc = OOMAlloc;
this->size = sizeof(PoolStruct);
AVERT(PoolClass, this);
}

View file

@ -25,6 +25,7 @@ CFLAGSCOMPILER := \
-Wshadow \
-Wstrict-aliasing=2 \
-Wstrict-prototypes \
-Wswitch-default \
-Wwrite-strings
CFLAGSCOMPILERSTRICT := -ansi -pedantic

View file

@ -331,8 +331,8 @@ int main(int argc, char *argv[]) {
double mort = 0.0;
cap = (size_t)strtoul(optarg, &p, 10);
switch(toupper(*p)) {
case 'G': cap *= 1024;
case 'M': cap *= 1024;
case 'G': cap *= 1024; /* fall through */
case 'M': cap *= 1024; /* fall through */
case 'K': p++; break;
default: cap = 0; break;
}
@ -356,6 +356,10 @@ int main(int argc, char *argv[]) {
case 'G': arenasize *= 1024;
case 'M': arenasize *= 1024;
case 'K': arenasize *= 1024; break;
case '\0': break;
default:
fprintf(stderr, "Bad arena size %s\n", optarg);
return EXIT_FAILURE;
}
}
break;

View file

@ -119,7 +119,7 @@ Bool GlobalsCheck(Globals arenaGlobals)
CHECKS(Globals, arenaGlobals);
arena = GlobalsArena(arenaGlobals);
CHECKL(arena->serial < arenaSerial);
CHECKL(RingCheck(&arenaGlobals->globalRing));
CHECKD_NOSIG(Ring, &arenaGlobals->globalRing);
CHECKL(MPSVersion() == arenaGlobals->mpsVersionString);
@ -138,16 +138,17 @@ Bool GlobalsCheck(Globals arenaGlobals)
CHECKL(arenaGlobals->emptyInternalSize >= 0.0);
CHECKL(BoolCheck(arenaGlobals->bufferLogging));
CHECKL(RingCheck(&arenaGlobals->poolRing));
CHECKL(RingCheck(&arenaGlobals->rootRing));
CHECKL(RingCheck(&arenaGlobals->rememberedSummaryRing));
CHECKD_NOSIG(Ring, &arenaGlobals->poolRing);
CHECKD_NOSIG(Ring, &arenaGlobals->rootRing);
CHECKD_NOSIG(Ring, &arenaGlobals->rememberedSummaryRing);
CHECKL(arenaGlobals->rememberedSummaryIndex < RememberedSummaryBLOCK);
/* <code/global.c#remembered.summary> RingIsSingle imples index == 0 */
CHECKL(!RingIsSingle(&arenaGlobals->rememberedSummaryRing) ||
arenaGlobals->rememberedSummaryIndex == 0);
CHECKL(RingCheck(&arena->formatRing));
CHECKL(RingCheck(&arena->messageRing));
/* Don't check enabledMessageTypes */
CHECKD_NOSIG(Ring, &arena->formatRing);
CHECKD_NOSIG(Ring, &arena->messageRing);
if (arena->enabledMessageTypes != NULL)
CHECKD_NOSIG(BT, arena->enabledMessageTypes);
CHECKL(BoolCheck(arena->isFinalPool));
if (arena->isFinalPool) {
CHECKD(Pool, arena->finalPool);
@ -155,7 +156,7 @@ Bool GlobalsCheck(Globals arenaGlobals)
CHECKL(arena->finalPool == NULL);
}
CHECKL(RingCheck(&arena->threadRing));
CHECKD_NOSIG(Ring, &arena->threadRing);
CHECKL(BoolCheck(arena->insideShield));
CHECKL(arena->shCacheLimit <= ShieldCacheSIZE);
@ -189,8 +190,8 @@ Bool GlobalsCheck(Globals arenaGlobals)
TRACE_SET_ITER_END(ti, trace, TraceSetUNIV, arena);
for(rank = 0; rank < RankLIMIT; ++rank)
CHECKL(RingCheck(&arena->greyRing[rank]));
CHECKL(RingCheck(&arena->chainRing));
CHECKD_NOSIG(Ring, &arena->greyRing[rank]);
CHECKD_NOSIG(Ring, &arena->chainRing);
CHECKL(arena->tracedSize >= 0.0);
CHECKL(arena->tracedTime >= 0.0);
@ -212,7 +213,7 @@ Bool GlobalsCheck(Globals arenaGlobals)
/* we also check the statics now. <design/arena/#static.check> */
CHECKL(BoolCheck(arenaRingInit));
CHECKL(RingCheck(&arenaRing));
CHECKD_NOSIG(Ring, &arenaRing);
CHECKL(BoolCheck(arena->emergency));
@ -632,7 +633,7 @@ Bool ArenaAccess(Addr addr, AccessSet mode, MutatorFaultContext context)
arenaClaimRingLock(); /* <design/arena/#lock.ring> */
mps_exception_info = context;
AVER(RingCheck(&arenaRing));
AVERT(Ring, &arenaRing);
RING_FOR(node, &arenaRing, nextNode) {
Globals arenaGlobals = RING_ELT(Globals, globalRing, node);

View file

@ -197,7 +197,6 @@ int main(int argc, char *argv[])
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE);
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE);
MPS_ARGS_DONE(args);
die(mps_arena_create_k(&arena, mps_arena_class_vm(), args),
"mps_arena_create");
} MPS_ARGS_END(args);

View file

@ -1,7 +1,7 @@
/* locus.c: LOCUS MANAGER
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* DESIGN
*
@ -89,7 +89,7 @@ static Bool GenDescCheck(GenDesc gen)
CHECKL(gen->mortality <= 1.0);
CHECKL(gen->proflow >= 0.0);
CHECKL(gen->proflow <= 1.0);
CHECKL(RingCheck(&gen->locusRing));
CHECKD_NOSIG(Ring, &gen->locusRing);
return TRUE;
}
@ -192,7 +192,7 @@ Bool ChainCheck(Chain chain)
CHECKS(Chain, chain);
CHECKU(Arena, chain->arena);
CHECKL(RingCheck(&chain->chainRing));
CHECKD_NOSIG(Ring, &chain->chainRing);
CHECKL(TraceSetCheck(chain->activeTraces));
CHECKL(chain->genCount > 0);
for (i = 0; i < chain->genCount; ++i) {
@ -370,7 +370,7 @@ Res ChainCondemnAll(Chain chain, Trace trace)
Ring segNode, nextSegNode;
AVERT(Pool, pool);
AVER((pool->class->attr & AttrGC) != 0);
AVER(PoolHasAttr(pool, AttrGC));
RING_FOR(segNode, PoolSegRing(pool), nextSegNode) {
Seg seg = SegOfPoolRing(segNode);
@ -458,7 +458,7 @@ Bool PoolGenCheck(PoolGen gen)
/* nothing to check about serial */
CHECKU(Pool, gen->pool);
CHECKU(Chain, gen->chain);
CHECKL(RingCheck(&gen->genRing));
CHECKD_NOSIG(Ring, &gen->genRing);
CHECKL(gen->newSize <= gen->totalSize);
return TRUE;
}
@ -501,14 +501,14 @@ void LocusFinish(Arena arena)
Bool LocusCheck(Arena arena)
{
/* Can't check arena, because this is part of ArenaCheck. */
CHECKL(GenDescCheck(&arena->topGen));
CHECKD(GenDesc, &arena->topGen);
return TRUE;
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -220,7 +220,6 @@ static void runArenaTest(size_t size,
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size);
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE);
MPS_ARGS_DONE(args);
die(mps_arena_create_k(&arena, mps_arena_class_vm(), args),
"mps_arena_create");
} MPS_ARGS_END(args);

View file

@ -1,7 +1,7 @@
/* message.c: MPS/CLIENT MESSAGES
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* DESIGN
*
@ -53,7 +53,7 @@ Bool MessageCheck(Message message)
CHECKS(Message, message);
CHECKU(Arena, message->arena);
CHECKD(MessageClass, message->class);
CHECKL(RingCheck(&message->queueRing));
CHECKD_NOSIG(Ring, &message->queueRing);
/* postedClock is uncheckable for clocked message types, */
/* but must be 0 for unclocked message types: */
CHECKL(MessageIsClocked(message) || (message->postedClock == 0));
@ -186,7 +186,7 @@ void MessageEmpty(Arena arena)
static Bool MessageTypeEnabled(Arena arena, MessageType type)
{
AVERT(Arena, arena);
AVER(MessageTypeCheck(type));
AVERT(MessageType, type);
return BTGet(arena->enabledMessageTypes, type);
}
@ -194,7 +194,7 @@ static Bool MessageTypeEnabled(Arena arena, MessageType type)
void MessageTypeEnable(Arena arena, MessageType type)
{
AVERT(Arena, arena);
AVER(MessageTypeCheck(type));
AVERT(MessageType, type);
BTSet(arena->enabledMessageTypes, type);
}
@ -204,7 +204,7 @@ void MessageTypeDisable(Arena arena, MessageType type)
Message message;
AVERT(Arena, arena);
AVER(MessageTypeCheck(type));
AVERT(MessageType, type);
/* Flush existing messages of this type */
while(MessageGet(&message, arena, type)) {
@ -252,7 +252,7 @@ Bool MessageGet(Message *messageReturn, Arena arena, MessageType type)
AVER(messageReturn != NULL);
AVERT(Arena, arena);
AVER(MessageTypeCheck(type));
AVERT(MessageType, type);
RING_FOR(node, &arena->messageRing, next) {
Message message = RING_ELT(Message, queueRing, node);
@ -427,7 +427,7 @@ const char *MessageNoGCStartWhy(Message message)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002, 2008 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* mpm.c: GENERAL MPM SUPPORT
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: Miscellaneous support for the implementation of the MPM
* and pool classes.
@ -132,7 +132,7 @@ Bool AlignCheck(Align align)
Bool (WordIsAligned)(Word word, Align align)
{
AVER(AlignCheck(align));
AVERT(Align, align);
return WordIsAligned(word, align);
}
@ -141,7 +141,7 @@ Bool (WordIsAligned)(Word word, Align align)
Word (WordAlignUp)(Word word, Align align)
{
AVER(AlignCheck(align));
AVERT(Align, align);
return WordAlignUp(word, align);
}
@ -167,7 +167,7 @@ Word (WordRoundUp)(Word word, Size modulus)
Word (WordAlignDown)(Word word, Align alignment)
{
AVER(AlignCheck(alignment));
AVERT(Align, alignment);
return WordAlignDown(word, alignment);
}
@ -212,7 +212,7 @@ Shift SizeLog2(Size size)
Addr (AddrAlignDown)(Addr addr, Align alignment)
{
AVER(AlignCheck(alignment));
AVERT(Align, alignment);
return AddrAlignDown(addr, alignment);
}
@ -604,7 +604,7 @@ Bool StringEqual(const char *s1, const char *s2)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -178,11 +178,13 @@ extern Bool PoolClassCheck(PoolClass class);
extern Bool PoolCheck(Pool pool);
extern Res PoolDescribe(Pool pool, mps_lib_FILE *stream);
/* Must be thread-safe. See <design/interface-c/#thread-safety>. */
#define PoolArena(pool) ((pool)->arena)
#define PoolAlignment(pool) ((pool)->alignment)
#define PoolSegRing(pool) (&(pool)->segRing)
#define PoolArenaRing(pool) (&(pool)->arenaRing)
#define PoolOfArenaRing(node) RING_ELT(Pool, arenaRing, node)
#define PoolHasAttr(pool, Attr) (((pool)->class->attr & (Attr)) != 0)
extern Bool PoolFormat(Format *formatReturn, Pool pool);
@ -263,10 +265,11 @@ extern Res PoolTrivFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf);
extern Res PoolNoFramePop(Pool pool, Buffer buf, AllocFrame frame);
extern Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame);
extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame);
extern void PoolTrivFramePopPending(Pool pool, Buffer buf, AllocFrame frame);
extern Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr);
extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step,
void *p, size_t s);
extern void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p);
extern void PoolTrivFreeWalk(Pool pool, FreeBlockStepMethod f, void *p);
extern PoolDebugMixin PoolNoDebugMixin(Pool pool);
extern BufferClass PoolNoBufferClass(void);

View file

@ -1,7 +1,7 @@
/* mpmtypes.h: MEMORY POOL MANAGER TYPES
*
* $Id$
* Copyright (c) 2001-2002, 2006 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2001 Global Graphics Software.
*
* .design: <design/type/>
@ -41,7 +41,7 @@ typedef unsigned Shift; /* <design/type/#shift> */
typedef unsigned Serial; /* <design/type/#serial> */
typedef Addr Ref; /* <design/type/#ref> */
typedef void *Pointer; /* <design/type/#pointer> */
typedef Word Clock; /* processor time */
typedef Word Clock; /* <design/type/#clock> */
typedef MPS_T_ULONGEST ULongest; /* <design/type/#ulongest> */
typedef mps_arg_s ArgStruct;
@ -60,7 +60,6 @@ typedef unsigned TraceSet; /* <design/trace/> */
typedef unsigned TraceState; /* <design/trace/> */
typedef unsigned AccessSet; /* <design/type/#access-set> */
typedef unsigned Attr; /* <design/type/#attr> */
typedef unsigned FormatVariety;
typedef int RootVar; /* <design/type/#rootvar> */
typedef Word *BT; /* <design/bt/> */
@ -300,16 +299,6 @@ typedef struct TraceMessageStruct *TraceMessage; /* trace end */
AttrGC | AttrINCR_RB | AttrINCR_WB | AttrMOVINGGC)
/* Format varieties */
enum {
FormatVarietyA = 1,
FormatVarietyB,
FormatVarietyAutoHeader,
FormatVarietyFixed,
FormatVarietyLIMIT
};
/* Segment preferences */
enum {
SegPrefHigh = 1,
@ -465,7 +454,7 @@ typedef double WriteFD;
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002, 2006 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* mpsi.c: MEMORY POOL SYSTEM C INTERFACE LAYER
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2002 Global Graphics Software.
*
* .purpose: This code bridges between the MPS interface to C,
@ -46,11 +46,6 @@
#include "mpm.h"
#include "mps.h"
#include "sac.h"
#include "chain.h"
/* TODO: Remove these includes when varargs support is removed. */
#include "mpsacl.h"
#include "mpsavm.h"
#include <stdarg.h>
@ -459,7 +454,7 @@ mps_res_t mps_fmt_create_k(mps_fmt_t *mps_fmt_o,
AVER(mps_fmt_o != NULL);
AVERT(Arena, arena);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
res = FormatCreate(&format, arena, args);
@ -657,7 +652,7 @@ mps_res_t mps_pool_create_k(mps_pool_t *mps_pool_o, mps_arena_t arena,
AVER(mps_pool_o != NULL);
AVERT(Arena, arena);
AVERT(PoolClass, class);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
res = PoolCreate(&pool, arena, class, args);
@ -1935,7 +1930,7 @@ void mps_chain_destroy(mps_chain_t chain)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -516,7 +516,8 @@ static void *test(void *arg, size_t s)
if (rnd() % patternFREQ == 0) {
switch(rnd() % 4) {
case 0: case 1:
case 0: /* fall through */
case 1:
die(mps_ap_alloc_pattern_begin(ap, ramp), "alloc_pattern_begin");
++rampCount;
break;
@ -528,7 +529,7 @@ static void *test(void *arg, size_t s)
--rampCount;
}
break;
case 3:
default:
die(mps_ap_alloc_pattern_reset(ap), "alloc_pattern_reset");
rampCount = 0;
break;

View file

@ -173,7 +173,6 @@ static void stress_with_arena_class(mps_arena_class_t aclass, Bool zoned)
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE);
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, zoned);
MPS_ARGS_DONE(args);
die(mps_arena_create_k(&arena, aclass, args),
"mps_arena_create");
} MPS_ARGS_END(args);

View file

@ -18,9 +18,6 @@
* .purpose.dispatch: Dispatch functions that implement the generic
* function dispatch mechanism for Pool Classes (PoolAlloc, PoolFix,
* etc.).
* .purpose.core: A selection of default, trivial, or useful methods
* that Pool Classes can use as the implementations for some of their
* methods (such as PoolTrivWhiten, PoolNoFix, etc.).
*
* SOURCES
*
@ -40,13 +37,14 @@ SRCID(pool, "$Id$");
Bool PoolClassCheck(PoolClass class)
{
CHECKL(ProtocolClassCheck(&class->protocol));
CHECKD(ProtocolClass, &class->protocol);
CHECKL(class->name != NULL); /* Should be <=6 char C identifier */
CHECKL(class->size >= sizeof(PoolStruct));
/* Offset of generic Pool within class-specific instance cannot be */
/* greater than the size of the class-specific portion of the instance */
CHECKL(class->offset <= (size_t)(class->size - sizeof(PoolStruct)));
CHECKL(AttrCheck(class->attr));
CHECKL(!(class->attr & AttrMOVINGGC) || (class->attr & AttrGC));
CHECKL(FUNCHECK(class->varargs));
CHECKL(FUNCHECK(class->init));
CHECKL(FUNCHECK(class->finish));
@ -89,16 +87,14 @@ Bool PoolCheck(Pool pool)
CHECKL(pool->serial < ArenaGlobals(pool->arena)->poolSerial);
CHECKD(PoolClass, pool->class);
CHECKU(Arena, pool->arena);
CHECKL(RingCheck(&pool->arenaRing));
CHECKL(RingCheck(&pool->bufferRing));
CHECKD_NOSIG(Ring, &pool->arenaRing);
CHECKD_NOSIG(Ring, &pool->bufferRing);
/* Cannot check pool->bufferSerial */
CHECKL(RingCheck(&pool->segRing));
CHECKD_NOSIG(Ring, &pool->segRing);
CHECKL(AlignCheck(pool->alignment));
/* normally pool->format iff pool->class->attr&AttrFMT, but not */
/* during pool initialization */
if (pool->format != NULL) {
CHECKL((pool->class->attr & AttrFMT) != 0);
}
/* normally pool->format iff PoolHasAttr(pool, AttrFMT), but during
* pool initialization pool->format may not yet be set. */
CHECKL(pool->format == NULL || PoolHasAttr(pool, AttrFMT));
CHECKL(pool->fillMutatorSize >= 0.0);
CHECKL(pool->emptyMutatorSize >= 0.0);
CHECKL(pool->fillInternalSize >= 0.0);
@ -289,9 +285,9 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size,
AVER(pReturn != NULL);
AVERT(Pool, pool);
AVER((pool->class->attr & AttrALLOC) != 0);
AVER(PoolHasAttr(pool, AttrALLOC));
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
res = (*pool->class->alloc)(pReturn, pool, size, withReservoirPermit);
if (res != ResOK)
@ -319,7 +315,7 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size,
void PoolFree(Pool pool, Addr old, Size size)
{
AVERT(Pool, pool);
AVER((pool->class->attr & AttrFREE) != 0);
AVER(PoolHasAttr(pool, AttrFREE));
AVER(old != NULL);
/* The pool methods should check that old is in pool. */
AVER(size > 0);
@ -384,6 +380,7 @@ Res PoolScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
AVER(totalReturn != NULL);
AVERT(ScanState, ss);
AVERT(Pool, pool);
AVER(PoolHasAttr(pool, AttrSCAN));
AVERT(Seg, seg);
AVER(ss->arena == pool->arena);

View file

@ -1,7 +1,7 @@
/* poolabs.c: ABSTRACT POOL CLASSES
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* PURPOSE
@ -65,12 +65,13 @@ void PoolClassMixInAllocFree(PoolClass class)
void PoolClassMixInBuffer(PoolClass class)
{
/* Can't check class because it's not initialized yet */
class->attr |= (AttrBUF | AttrBUF_RESERVE);
class->attr |= AttrBUF;
class->bufferFill = PoolTrivBufferFill;
class->bufferEmpty = PoolTrivBufferEmpty;
/* By default, buffered pools treat frame operations as NOOPs */
class->framePush = PoolTrivFramePush;
class->framePop = PoolTrivFramePop;
class->framePopPending = PoolTrivFramePopPending;
class->bufferClass = BufferClassGet;
}
@ -84,8 +85,10 @@ void PoolClassMixInScan(PoolClass class)
class->access = PoolSegAccess;
class->blacken = PoolTrivBlacken;
class->grey = PoolTrivGrey;
/* Scan is part of the scanning protocol - but there is */
/* no useful default method */
/* scan is part of the scanning protocol, but there is no useful
* default method.
*/
class->scan = NULL;
}
@ -95,6 +98,10 @@ void PoolClassMixInFormat(PoolClass class)
{
/* Can't check class because it's not initialized yet */
class->attr |= AttrFMT;
/* walk is part of the format protocol, but there is no useful
* default method.
*/
class->walk = NULL;
}
@ -103,10 +110,14 @@ void PoolClassMixInFormat(PoolClass class)
void PoolClassMixInCollect(PoolClass class)
{
/* Can't check class because it's not initialized yet */
class->attr |= (AttrGC | AttrINCR_RB);
class->attr |= AttrGC;
class->whiten = PoolTrivWhiten;
/* Fix & reclaim are part of the collection protocol - but there */
/* are no useful default methods for them. */
/* fix, fixEmergency and reclaim are part of the collection
* protocol, but there are no useful default methods for them.
*/
class->fix = NULL;
class->fixEmergency = NULL;
class->reclaim = NULL;
class->rampBegin = PoolTrivRampBegin;
class->rampEnd = PoolTrivRampEnd;
}
@ -145,7 +156,7 @@ DEFINE_CLASS(AbstractPoolClass, class)
class->framePopPending = PoolNoFramePopPending;
class->addrObject = PoolNoAddrObject;
class->walk = PoolNoWalk;
class->freewalk = PoolNoFreeWalk;
class->freewalk = PoolTrivFreeWalk;
class->bufferClass = PoolNoBufferClass;
class->describe = PoolTrivDescribe;
class->debugMixin = PoolNoDebugMixin;
@ -199,7 +210,7 @@ void PoolTrivFinish(Pool pool)
Res PoolTrivInit(Pool pool, ArgList args)
{
AVERT(Pool, pool);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
UNUSED(args);
return ResOK;
}
@ -210,7 +221,7 @@ Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size,
AVER(pReturn != NULL);
AVERT(Pool, pool);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
NOTREACHED;
return ResUNIMPL;
}
@ -221,7 +232,7 @@ Res PoolTrivAlloc(Addr *pReturn, Pool pool, Size size,
AVER(pReturn != NULL);
AVERT(Pool, pool);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
return ResLIMIT;
}
@ -251,7 +262,7 @@ Res PoolNoBufferFill(Addr *baseReturn, Addr *limitReturn,
AVERT(Pool, pool);
AVERT(Buffer, buffer);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
NOTREACHED;
return ResUNIMPL;
}
@ -268,7 +279,7 @@ Res PoolTrivBufferFill(Addr *baseReturn, Addr *limitReturn,
AVERT(Pool, pool);
AVERT(Buffer, buffer);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
res = PoolAlloc(&p, pool, size, withReservoirPermit);
if(res != ResOK) return res;
@ -596,7 +607,7 @@ Res PoolNoFramePop(Pool pool, Buffer buf, AllocFrame frame)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
/* frame is of a abstract type & can't be checked */
/* frame is of an abstract type & can't be checked */
UNUSED(frame);
NOTREACHED;
return ResUNIMPL;
@ -607,7 +618,7 @@ void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
/* frame is of a abstract type & can't be checked */
/* frame is of an abstract type & can't be checked */
UNUSED(frame);
NOTREACHED;
}
@ -626,12 +637,22 @@ Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
/* frame is of a abstract type & can't be checked */
/* frame is of an abstract type & can't be checked */
UNUSED(frame);
return ResOK;
}
void PoolTrivFramePopPending(Pool pool, Buffer buf, AllocFrame frame)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
/* frame is of an abstract type & can't be checked */
UNUSED(frame);
NOOP;
}
Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
{
AVER(pReturn != NULL);
@ -656,7 +677,7 @@ void PoolNoWalk(Pool pool, Seg seg,
}
void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
void PoolTrivFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
{
AVERT(Pool, pool);
AVER(FUNCHECK(f));
@ -677,7 +698,7 @@ BufferClass PoolNoBufferClass(void)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -341,6 +341,7 @@ DEFINE_SEG_CLASS(amcSegClass, class)
class->size = sizeof(amcSegStruct);
class->init = AMCSegInit;
class->describe = AMCSegDescribe;
AVERT(SegClass, class);
}
@ -484,7 +485,7 @@ static Bool amcGenCheck(amcGen gen)
amc = amcGenAMC(gen);
CHECKU(AMC, amc);
CHECKD(Buffer, gen->forward);
CHECKL(RingCheck(&gen->amcRing));
CHECKD_NOSIG(Ring, &gen->amcRing);
CHECKL((gen->pgen.totalSize == 0) == (gen->segs == 0));
arena = amc->poolStruct.arena;
CHECKL(gen->pgen.totalSize >= gen->segs * ArenaAlign(arena));
@ -526,7 +527,7 @@ typedef struct amcBufStruct {
static Bool amcBufCheck(amcBuf amcbuf)
{
CHECKS(amcBuf, amcbuf);
CHECKL(SegBufCheck(&amcbuf->segbufStruct));
CHECKD(SegBuf, &amcbuf->segbufStruct);
if(amcbuf->gen != NULL)
CHECKD(amcGen, amcbuf->gen);
CHECKL(BoolCheck(amcbuf->forHashArrays));
@ -632,6 +633,7 @@ DEFINE_BUFFER_CLASS(amcBufClass, class)
class->size = sizeof(amcBufStruct);
class->init = AMCBufInit;
class->finish = AMCBufFinish;
AVERT(BufferClass, class);
}
@ -776,7 +778,7 @@ static void AMCVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[1].key = MPS_KEY_CHAIN;
args[1].val.chain = va_arg(varargs, Chain);
args[2].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -2087,7 +2089,7 @@ static void AMCTraceEnd(Pool pool, Trace trace)
amc = Pool2AMC(pool);
AVERT(AMC, amc);
ti = trace->ti;
AVER(TraceIdCheck(ti));
AVERT(TraceId, ti);
STATISTIC_STAT ({
Count pRetMin = 100;
@ -2329,23 +2331,23 @@ static Res AMCDescribe(Pool pool, mps_lib_FILE *stream)
}
/* AMCPoolClass -- the class definition */
/* AMCZPoolClass -- the class definition */
DEFINE_POOL_CLASS(AMCPoolClass, this)
DEFINE_POOL_CLASS(AMCZPoolClass, this)
{
INHERIT_CLASS(this, AbstractCollectPoolClass);
INHERIT_CLASS(this, AbstractSegBufPoolClass);
PoolClassMixInFormat(this);
this->name = "AMC";
PoolClassMixInCollect(this);
this->name = "AMCZ";
this->size = sizeof(AMCStruct);
this->offset = offsetof(AMCStruct, poolStruct);
this->attr |= AttrMOVINGGC;
this->varargs = AMCVarargs;
this->init = AMCInit;
this->init = AMCZInit;
this->finish = AMCFinish;
this->bufferFill = AMCBufferFill;
this->bufferEmpty = AMCBufferEmpty;
this->whiten = AMCWhiten;
this->scan = AMCScan;
this->fix = AMCFix;
this->fixEmergency = AMCFixEmergency;
this->reclaim = AMCReclaim;
@ -2356,19 +2358,20 @@ DEFINE_POOL_CLASS(AMCPoolClass, this)
this->walk = AMCWalk;
this->bufferClass = amcBufClassGet;
this->describe = AMCDescribe;
AVERT(PoolClass, this);
}
/* AMCZPoolClass -- the class definition */
/* AMCPoolClass -- the class definition */
DEFINE_POOL_CLASS(AMCZPoolClass, this)
DEFINE_POOL_CLASS(AMCPoolClass, this)
{
INHERIT_CLASS(this, AMCPoolClass);
this->name = "AMCZ";
this->attr &= ~(AttrSCAN | AttrINCR_RB);
this->init = AMCZInit;
this->grey = PoolNoGrey;
this->scan = PoolNoScan;
INHERIT_CLASS(this, AMCZPoolClass);
PoolClassMixInScan(this);
this->name = "AMC";
this->init = AMCInit;
this->scan = AMCScan;
AVERT(PoolClass, this);
}
@ -2448,7 +2451,7 @@ static Bool AMCCheck(AMC amc)
CHECKD(Pool, &amc->poolStruct);
CHECKL(IsSubclassPoly(amc->poolStruct.class, EnsureAMCPoolClass()));
CHECKL(RankSetCheck(amc->rankSet));
CHECKL(RingCheck(&amc->genRing));
CHECKD_NOSIG(Ring, &amc->genRing);
CHECKL(BoolCheck(amc->gensBooted));
if(amc->gensBooted) {
CHECKD(amcGen, amc->nursery);

View file

@ -1,7 +1,7 @@
/* poolams.c: AUTOMATIC MARK & SWEEP POOL CLASS
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2002 Global Graphics Software.
*
*
@ -48,7 +48,7 @@ Bool AMSSegCheck(AMSSeg amsseg)
{
Seg seg = AMSSeg2Seg(amsseg);
CHECKS(AMSSeg, amsseg);
CHECKL(GCSegCheck(&amsseg->gcSegStruct));
CHECKD(GCSeg, &amsseg->gcSegStruct);
CHECKU(AMS, amsseg->ams);
CHECKL(AMS2Pool(amsseg->ams) == SegPool(seg));
CHECKD_NOSIG(Ring, &amsseg->segRing);
@ -60,7 +60,7 @@ Bool AMSSegCheck(AMSSeg amsseg)
CHECKL(BoolCheck(amsseg->allocTableInUse));
if (!amsseg->allocTableInUse)
CHECKL(amsseg->firstFree <= amsseg->grains);
CHECKL(amsseg->allocTable != NULL);
CHECKD_NOSIG(BT, amsseg->allocTable);
if (SegWhite(seg) != TraceSetEMPTY) {
/* <design/poolams/#colour.single> */
@ -71,8 +71,8 @@ Bool AMSSegCheck(AMSSeg amsseg)
CHECKL(BoolCheck(amsseg->marksChanged));
CHECKL(BoolCheck(amsseg->ambiguousFixes));
CHECKL(BoolCheck(amsseg->colourTablesInUse));
CHECKL(amsseg->nongreyTable != NULL);
CHECKL(amsseg->nonwhiteTable != NULL);
CHECKD_NOSIG(BT, amsseg->nongreyTable);
CHECKD_NOSIG(BT, amsseg->nonwhiteTable);
return TRUE;
}
@ -218,7 +218,7 @@ static Res AMSSegInit(Seg seg, Pool pool, Addr base, Size size,
AVERT(AMS, ams);
arena = PoolArena(pool);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
/* Initialize the superclass fields first via next-method call */
super = SEG_SUPERCLASS(AMSSegClass);
@ -609,6 +609,7 @@ DEFINE_CLASS(AMSSegClass, class)
class->merge = AMSSegMerge;
class->split = AMSSegSplit;
class->describe = AMSSegDescribe;
AVERT(SegClass, class);
}
@ -637,7 +638,7 @@ static Res AMSSegSizePolicy(Size *sizeReturn,
AVER(sizeReturn != NULL);
AVERT(Pool, pool);
AVER(size > 0);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
arena = PoolArena(pool);
@ -666,7 +667,7 @@ static Res AMSSegCreate(Seg *segReturn, Pool pool, Size size,
AVERT(Pool, pool);
AVER(size > 0);
AVERT(RankSet, rankSet);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
ams = Pool2AMS(pool);
AVERT(AMS,ams);
@ -734,7 +735,7 @@ static void AMSVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[2].key = MPS_KEY_AMS_SUPPORT_AMBIGUOUS;
args[2].val.b = va_arg(varargs, Bool);
args[3].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
static void AMSDebugVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
@ -763,7 +764,7 @@ static Res AMSInit(Pool pool, ArgList args)
ArgStruct arg;
AVERT(Pool, pool);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
if (ArgPick(&arg, args, MPS_KEY_CHAIN))
chain = arg.val.chain;
@ -932,7 +933,7 @@ static Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
AVERT(Buffer, buffer);
AVER(size > 0);
AVER(SizeIsAligned(size, PoolAlignment(pool)));
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* Check that we're not in the grey mutator phase (see */
/* <design/poolams/#fill.colour>). */
@ -996,7 +997,7 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
AVERT(Buffer,buffer);
AVER(BufferIsReady(buffer));
seg = BufferSeg(buffer);
AVER(SegCheck(seg));
AVERT(Seg, seg);
AVER(init <= limit);
AVER(AddrIsAligned(init, PoolAlignment(pool)));
AVER(AddrIsAligned(limit, PoolAlignment(pool)));
@ -1074,7 +1075,7 @@ static Res AMSCondemn(Pool pool, Trace trace, Seg seg)
AVERT(AMS, ams);
AVERT(Trace, trace);
AVER(SegCheck(seg));
AVERT(Seg, seg);
amsseg = Seg2AMSSeg(seg);
AVERT(AMSSeg, amsseg);
@ -1260,7 +1261,7 @@ static Res amsScanObject(Seg seg, Index i, Addr p, Addr next, void *clos)
AVER(clos != NULL);
closure = (amsScanClosure)clos;
AVERT(ScanState, closure->ss);
AVER(BoolCheck(closure->scanAllObjects));
AVERT(Bool, closure->scanAllObjects);
format = AMS2Pool(amsseg->ams)->format;
AVERT(Format, format);
@ -1306,7 +1307,7 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
ams = Pool2AMS(pool);
AVERT(AMS, ams);
arena = PoolArena(pool);
AVER(SegCheck(seg));
AVERT(Seg, seg);
amsseg = Seg2AMSSeg(seg);
AVERT(AMSSeg, amsseg);
@ -1684,8 +1685,10 @@ DEFINE_CLASS(AMSPoolClass, this)
this->fix = AMSFix;
this->fixEmergency = AMSFix;
this->reclaim = AMSReclaim;
this->walk = PoolNoWalk; /* TODO: job003738 */
this->freewalk = AMSFreeWalk;
this->describe = AMSDescribe;
AVERT(PoolClass, this);
}
@ -1713,6 +1716,7 @@ DEFINE_POOL_CLASS(AMSDebugPoolClass, this)
this->size = sizeof(AMSDebugStruct);
this->varargs = AMSDebugVarargs;
this->debugMixin = AMSDebugMixin;
AVERT(PoolClass, this);
}
@ -1721,7 +1725,7 @@ DEFINE_POOL_CLASS(AMSDebugPoolClass, this)
Bool AMSCheck(AMS ams)
{
CHECKS(AMS, ams);
CHECKL(PoolCheck(AMS2Pool(ams)));
CHECKD(Pool, AMS2Pool(ams));
CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet()));
CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift));
CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment);
@ -1729,7 +1733,7 @@ Bool AMSCheck(AMS ams)
CHECKD(PoolGen, &ams->pgen);
CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams)))));
CHECKL(FUNCHECK(ams->segSize));
CHECKL(RingCheck(&ams->segRing));
CHECKD_NOSIG(Ring, &ams->segRing);
CHECKL(FUNCHECK(ams->allocRing));
CHECKL(FUNCHECK(ams->segsDestroy));
CHECKL(FUNCHECK(ams->segClass));
@ -1740,7 +1744,7 @@ Bool AMSCheck(AMS ams)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolawl.c: AUTOMATIC WEAK LINKED POOL CLASS
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
*
* DESIGN
@ -187,7 +187,7 @@ static Res AWLSegInit(Seg seg, Pool pool, Addr base, Size size,
AVERT(Pool, pool);
arena = PoolArena(pool);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
ArgRequire(&arg, args, awlKeySegRankSet);
rankSet = arg.val.u;
AVERT(RankSet, rankSet);
@ -288,6 +288,7 @@ DEFINE_SEG_CLASS(AWLSegClass, class)
class->size = sizeof(AWLSegStruct);
class->init = AWLSegInit;
class->finish = AWLSegFinish;
AVERT(SegClass, class);
}
@ -450,10 +451,10 @@ static Res AWLSegCreate(AWLSeg *awlsegReturn,
Arena arena;
AVER(awlsegReturn != NULL);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
AVERT(Pool, pool);
AVER(size > 0);
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
awl = Pool2AWL(pool);
AVERT(AWL, awl);
@ -519,7 +520,7 @@ static void AWLVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[1].key = MPS_KEY_AWL_FIND_DEPENDENT;
args[1].val.addr_method = va_arg(varargs, mps_awl_find_dependent_t);
args[2].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -626,7 +627,7 @@ static Res AWLBufferFill(Addr *baseReturn, Addr *limitReturn,
AVERT(Pool, pool);
AVERT(Buffer, buffer);
AVER(size > 0);
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
awl = Pool2AWL(pool);
AVERT(AWL, awl);
@ -834,7 +835,7 @@ static void AWLBlacken(Pool pool, TraceSet traceSet, Seg seg)
AWLSeg awlseg;
AVERT(Pool, pool);
AVER(TraceSetCheck(traceSet));
AVERT(TraceSet, traceSet);
AVERT(Seg, seg);
awl = Pool2AWL(pool);
@ -1280,6 +1281,7 @@ DEFINE_POOL_CLASS(AWLPoolClass, this)
this->fixEmergency = AWLFix;
this->reclaim = AWLReclaim;
this->walk = AWLWalk;
AVERT(PoolClass, this);
}
@ -1307,7 +1309,7 @@ static Bool AWLCheck(AWL awl)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poollo.c: LEAF POOL CLASS
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* DESIGN
*
@ -73,6 +73,7 @@ DEFINE_SEG_CLASS(LOSegClass, class)
class->size = sizeof(LOSegStruct);
class->init = loSegInit;
class->finish = loSegFinish;
AVERT(SegClass, class);
}
@ -81,7 +82,7 @@ DEFINE_SEG_CLASS(LOSegClass, class)
static Bool LOSegCheck(LOSeg loseg)
{
CHECKS(LOSeg, loseg);
CHECKL(GCSegCheck(&loseg->gcSegStruct));
CHECKD(GCSeg, &loseg->gcSegStruct);
CHECKU(LO, loseg->lo);
CHECKL(loseg->mark != NULL);
CHECKL(loseg->alloc != NULL);
@ -112,7 +113,7 @@ static Res loSegInit(Seg seg, Pool pool, Addr base, Size size,
AVERT(Pool, pool);
arena = PoolArena(pool);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
lo = PoolPoolLO(pool);
AVERT(LO, lo);
@ -286,7 +287,7 @@ static Res loSegCreate(LOSeg *loSegReturn, Pool pool, Size size,
AVER(loSegReturn != NULL);
AVERT(Pool, pool);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
lo = PoolPoolLO(pool);
AVERT(LO, lo);
@ -460,7 +461,7 @@ static void LOVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[0].key = MPS_KEY_FORMAT;
args[0].val.format = va_arg(varargs, Format);
args[1].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -558,7 +559,7 @@ static Res LOBufferFill(Addr *baseReturn, Addr *limitReturn,
AVER(BufferRankSet(buffer) == RankSetEMPTY);
AVER(size > 0);
AVER(SizeIsAligned(size, PoolAlignment(pool)));
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* Try to find a segment with enough space already. */
RING_FOR(node, &pool->segRing, nextNode) {
@ -774,25 +775,23 @@ static void LOReclaim(Pool pool, Trace trace, Seg seg)
DEFINE_POOL_CLASS(LOPoolClass, this)
{
INHERIT_CLASS(this, AbstractCollectPoolClass);
INHERIT_CLASS(this, AbstractSegBufPoolClass);
PoolClassMixInFormat(this);
PoolClassMixInCollect(this);
this->name = "LO";
this->size = sizeof(LOStruct);
this->offset = offsetof(LOStruct, poolStruct);
this->attr &= ~(AttrSCAN | AttrINCR_RB);
this->varargs = LOVarargs;
this->init = LOInit;
this->finish = LOFinish;
this->bufferFill = LOBufferFill;
this->bufferEmpty = LOBufferEmpty;
this->whiten = LOWhiten;
this->grey = PoolNoGrey;
this->blacken = PoolNoBlacken;
this->scan = PoolNoScan;
this->fix = LOFix;
this->fixEmergency = LOFix;
this->reclaim = LOReclaim;
this->walk = LOWalk;
AVERT(PoolClass, this);
}
@ -821,7 +820,7 @@ static Bool LOCheck(LO lo)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolmfs.c: MANUAL FIXED SMALL UNIT POOL
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* This is the implementation of the MFS pool class.
*
@ -86,7 +86,7 @@ static void MFSVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[1].key = MPS_KEY_MFS_UNIT_SIZE;
args[1].val.size = va_arg(varargs, Size);
args[2].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
ARG_DEFINE_KEY(mfs_unit_size, Size);
@ -102,7 +102,7 @@ static Res MFSInit(Pool pool, ArgList args)
ArgStruct arg;
AVER(pool != NULL);
AVER(ArgListCheck(args));
AVERT(ArgList, args);
ArgRequire(&arg, args, MPS_KEY_MFS_UNIT_SIZE);
unitSize = arg.val.size;
@ -116,7 +116,7 @@ static Res MFSInit(Pool pool, ArgList args)
extendSelf = arg.val.b;
AVER(extendBy >= unitSize);
AVER(BoolCheck(extendSelf));
AVERT(Bool, extendSelf);
mfs = PoolPoolMFS(pool);
arena = PoolArena(pool);
@ -250,7 +250,7 @@ static Res MFSAlloc(Addr *pReturn, Pool pool, Size size,
AVER(pReturn != NULL);
AVER(size == mfs->unroundedUnitSize);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
f = mfs->freeList;
@ -347,6 +347,7 @@ DEFINE_POOL_CLASS(MFSPoolClass, this)
this->alloc = MFSAlloc;
this->free = MFSFree;
this->describe = MFSDescribe;
AVERT(PoolClass, this);
}
@ -369,7 +370,7 @@ Bool MFSCheck(MFS mfs)
CHECKS(MFS, mfs);
CHECKD(Pool, &mfs->poolStruct);
CHECKL(mfs->poolStruct.class == EnsureMFSPoolClass());
CHECKL(mfs->unroundedUnitSize >= UNIT_MIN);
CHECKL(mfs->unitSize >= UNIT_MIN);
CHECKL(mfs->extendBy >= UNIT_MIN);
CHECKL(BoolCheck(mfs->extendSelf));
arena = PoolArena(&mfs->poolStruct);
@ -377,7 +378,7 @@ Bool MFSCheck(MFS mfs)
CHECKL(SizeAlignUp(mfs->unroundedUnitSize, mfs->poolStruct.alignment) ==
mfs->unitSize);
if(mfs->tractList != NULL) {
CHECKL(TractCheck(mfs->tractList));
CHECKD_NOSIG(Tract, mfs->tractList);
}
return TRUE;
}
@ -385,7 +386,7 @@ Bool MFSCheck(MFS mfs)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolmrg.c: MANUAL RANK GUARDIAN POOL
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
*
@ -130,9 +130,9 @@ static Bool MRGCheck(MRG mrg)
CHECKS(MRG, mrg);
CHECKD(Pool, &mrg->poolStruct);
CHECKL(MRG2Pool(mrg)->class == PoolClassMRG());
CHECKL(RingCheck(&mrg->entryRing));
CHECKL(RingCheck(&mrg->freeRing));
CHECKL(RingCheck(&mrg->refRing));
CHECKD_NOSIG(Ring, &mrg->entryRing);
CHECKD_NOSIG(Ring, &mrg->freeRing);
CHECKD_NOSIG(Ring, &mrg->refRing);
CHECKL(mrg->extendBy == ArenaAlign(PoolArena(MRG2Pool(mrg))));
return TRUE;
}
@ -183,7 +183,7 @@ static Bool MRGLinkSegCheck(MRGLinkSeg linkseg)
Seg seg;
CHECKS(MRGLinkSeg, linkseg);
CHECKL(SegCheck(&linkseg->segStruct));
CHECKD(Seg, &linkseg->segStruct);
seg = LinkSeg2Seg(linkseg);
if (NULL != linkseg->refSeg) { /* see .link.nullref */
CHECKL(SegPool(seg) == SegPool(RefSeg2Seg(linkseg->refSeg)));
@ -198,10 +198,10 @@ static Bool MRGRefSegCheck(MRGRefSeg refseg)
Seg seg;
CHECKS(MRGRefSeg, refseg);
CHECKL(GCSegCheck(&refseg->gcSegStruct));
CHECKD(GCSeg, &refseg->gcSegStruct);
seg = RefSeg2Seg(refseg);
CHECKL(SegPool(seg) == SegPool(LinkSeg2Seg(refseg->linkSeg)));
CHECKL(RingCheck(&refseg->mrgRing));
CHECKD_NOSIG(Ring, &refseg->mrgRing);
CHECKD(MRGLinkSeg, refseg->linkSeg);
CHECKL(refseg->linkSeg->refSeg == refseg);
return TRUE;
@ -224,7 +224,7 @@ static Res MRGLinkSegInit(Seg seg, Pool pool, Addr base, Size size,
mrg = Pool2MRG(pool);
AVERT(MRG, mrg);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
/* Initialize the superclass fields first via next-method call */
super = SEG_SUPERCLASS(MRGLinkSegClass);
@ -267,7 +267,7 @@ static Res MRGRefSegInit(Seg seg, Pool pool, Addr base, Size size,
mrg = Pool2MRG(pool);
AVERT(MRG, mrg);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
AVERT(MRGLinkSeg, linkseg);
/* Initialize the superclass fields first via next-method call */
@ -302,6 +302,7 @@ DEFINE_SEG_CLASS(MRGLinkSegClass, class)
class->name = "MRGLSEG";
class->size = sizeof(MRGLinkSegStruct);
class->init = MRGLinkSegInit;
AVERT(SegClass, class);
}
@ -314,6 +315,7 @@ DEFINE_SEG_CLASS(MRGRefSegClass, class)
class->name = "MRGRSEG";
class->size = sizeof(MRGRefSegStruct);
class->init = MRGRefSegInit;
AVERT(SegClass, class);
}
@ -629,7 +631,7 @@ static Res MRGInit(Pool pool, ArgList args)
MRG mrg;
AVER(pool != NULL); /* Can't check more; see pool contract @@@@ */
AVER(ArgListCheck(args));
AVERT(ArgList, args);
UNUSED(args);
mrg = Pool2MRG(pool);
@ -855,13 +857,14 @@ DEFINE_POOL_CLASS(MRGPoolClass, this)
this->name = "MRG";
this->size = sizeof(MRGStruct);
this->offset = offsetof(MRGStruct, poolStruct);
this->attr |= (AttrSCAN | AttrFREE | AttrINCR_RB);
this->attr |= AttrSCAN;
this->init = MRGInit;
this->finish = MRGFinish;
this->grey = PoolTrivGrey;
this->blacken = PoolTrivBlacken;
this->scan = MRGScan;
this->describe = MRGDescribe;
AVERT(PoolClass, this);
}
@ -873,7 +876,7 @@ PoolClass PoolClassMRG(void)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolmv.c: MANUAL VARIABLE POOL
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* **** RESTRICTION: This pool may not allocate from the arena control
@ -138,11 +138,11 @@ static Bool MVSpanCheck(MVSpan span)
CHECKS(MVSpan, span);
CHECKL(RingCheck(&span->spans));
CHECKD_NOSIG(Ring, &span->spans);
CHECKU(MV, span->mv);
CHECKD_NOSIG(Tract, span->tract);
CHECKL(MVBlockCheck(&span->base));
CHECKL(MVBlockCheck(&span->limit));
CHECKD_NOSIG(MVBlock, &span->base);
CHECKD_NOSIG(MVBlock, &span->limit);
/* The block chain starts with the base sentinel. */
CHECKL(span->blocks == &span->base);
/* Since there is a limit sentinel, the chain can't end just after the */
@ -193,7 +193,7 @@ static void MVVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[2].key = MPS_KEY_MAX_SIZE;
args[2].val.size = va_arg(varargs, Size);
args[3].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
static void MVDebugVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
@ -570,7 +570,7 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size,
span->mv = mv;
/* Set the p field for each tract of the span */
TRACT_FOR(tract, addr, arena, base, limit) {
AVER(TractCheck(tract));
AVERT(Tract, tract);
AVER(TractP(tract) == NULL);
AVER(TractPool(tract) == pool);
TractSetP(tract, (void *)span);
@ -792,6 +792,7 @@ DEFINE_POOL_CLASS(MVPoolClass, this)
this->alloc = MVAlloc;
this->free = MVFree;
this->describe = MVDescribe;
AVERT(PoolClass, this);
}
@ -811,6 +812,7 @@ DEFINE_POOL_CLASS(MVDebugPoolClass, this)
this->size = sizeof(MVDebugStruct);
this->varargs = MVDebugVarargs;
this->debugMixin = MVDebugMixin;
AVERT(PoolClass, this);
}
@ -901,7 +903,7 @@ Bool MVCheck(MV mv)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolmv2.c: MANUAL VARIABLE-SIZED TEMPORAL POOL
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: A manual-variable pool designed to take advantage of
* placement according to predicted deathtime.
@ -145,6 +145,7 @@ DEFINE_POOL_CLASS(MVTPoolClass, this)
this->bufferFill = MVTBufferFill;
this->bufferEmpty = MVTBufferEmpty;
this->describe = MVTDescribe;
AVERT(PoolClass, this);
}
/* Macros */
@ -199,7 +200,7 @@ static void MVTVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[4].key = MPS_KEY_MVT_FRAG_LIMIT;
args[4].val.d = (double)va_arg(varargs, Count) / 100.0;
args[5].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -363,9 +364,7 @@ static Bool MVTCheck(MVT mvt)
CHECKD(Pool, &mvt->poolStruct);
CHECKL(mvt->poolStruct.class == MVTPoolClassGet());
CHECKD(CBS, &mvt->cbsStruct);
/* CHECKL(CBSCheck(MVTCBS(mvt))); */
CHECKD(ABQ, &mvt->abqStruct);
/* CHECKL(ABQCheck(MVTABQ(mvt))); */
CHECKD(Freelist, &mvt->flStruct);
CHECKL(mvt->reuseSize >= 2 * mvt->fillSize);
CHECKL(mvt->fillSize >= mvt->maxSize);
@ -379,8 +378,7 @@ static Bool MVTCheck(MVT mvt)
if (mvt->splinter) {
CHECKL(AddrOffset(mvt->splinterBase, mvt->splinterLimit) >=
mvt->minSize);
/* CHECKD(Seg, mvt->splinterSeg); */
CHECKL(SegCheck(mvt->splinterSeg));
CHECKD(Seg, mvt->splinterSeg);
CHECKL(mvt->splinterBase >= SegBase(mvt->splinterSeg));
CHECKL(mvt->splinterLimit <= SegLimit(mvt->splinterSeg));
}
@ -687,7 +685,7 @@ static Res MVTBufferFill(Addr *baseReturn, Addr *limitReturn,
AVER(BufferIsReset(buffer));
AVER(minSize > 0);
AVER(SizeIsAligned(minSize, pool->alignment));
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* Allocate oversize blocks exactly, directly from the arena.
<design/poolmvt/#arch.ap.no-fit.oversize> */
@ -1488,7 +1486,7 @@ CBS _mps_mvt_cbs(mps_pool_t mps_pool) {
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolmvff.c: First Fit Manual Variable Pool
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* .purpose: This is a pool class for manually managed objects of
@ -228,7 +228,7 @@ static Res MVFFAddSeg(Seg *segReturn,
AVERT(MVFF, mvff);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
pool = MVFF2Pool(mvff);
arena = PoolArena(pool);
@ -339,7 +339,7 @@ static Res MVFFAlloc(Addr *aReturn, Pool pool, Size size,
AVER(aReturn != NULL);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
size = SizeAlignUp(size, PoolAlignment(pool));
@ -510,7 +510,7 @@ static void MVFFVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[5].key = MPS_KEY_MVFF_FIRST_FIT;
args[5].val.b = va_arg(varargs, Bool);
args[6].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
static void MVFFDebugVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
@ -571,9 +571,9 @@ static Res MVFFInit(Pool pool, ArgList args)
AVER(avgSize > 0); /* .arg.check */
AVER(avgSize <= extendBy); /* .arg.check */
AVER(SizeIsAligned(align, MPS_PF_ALIGN));
AVER(BoolCheck(slotHigh));
AVER(BoolCheck(arenaHigh));
AVER(BoolCheck(firstFit));
AVERT(Bool, slotHigh);
AVERT(Bool, arenaHigh);
AVERT(Bool, firstFit);
mvff = Pool2MVFF(pool);
@ -720,6 +720,7 @@ DEFINE_POOL_CLASS(MVFFPoolClass, this)
this->bufferFill = MVFFBufferFill;
this->bufferEmpty = MVFFBufferEmpty;
this->describe = MVFFDescribe;
AVERT(PoolClass, this);
}
@ -739,6 +740,7 @@ DEFINE_POOL_CLASS(MVFFDebugPoolClass, this)
this->size = sizeof(MVFFDebugStruct);
this->varargs = MVFFDebugVarargs;
this->debugMixin = MVFFDebugMixin;
AVERT(PoolClass, this);
}
@ -828,7 +830,7 @@ CBS _mps_mvff_cbs(mps_pool_t mps_pool) {
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* pooln.c: NULL POOL CLASS
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*/
#include "pooln.h"
@ -71,7 +71,7 @@ static Res NAlloc(Addr *pReturn, Pool pool, Size size,
AVER(pReturn != NULL);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
return ResLIMIT; /* limit of nil blocks exceeded */
}
@ -110,7 +110,7 @@ static Res NBufferFill(Addr *baseReturn, Addr *limitReturn,
AVERT(Buffer, buffer);
AVER(BufferIsReset(buffer));
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
NOTREACHED; /* can't create buffers, so shouldn't fill them */
return ResUNIMPL;
@ -270,8 +270,7 @@ DEFINE_POOL_CLASS(NPoolClass, this)
this->name = "N";
this->size = sizeof(PoolNStruct);
this->offset = offsetof(PoolNStruct, poolStruct);
this->attr = AttrSCAN | AttrALLOC | AttrFREE | AttrBUF |
AttrBUF_RESERVE | AttrGC;
this->attr |= (AttrALLOC | AttrBUF | AttrFREE | AttrGC | AttrSCAN);
this->init = NInit;
this->finish = NFinish;
this->alloc = NAlloc;
@ -287,6 +286,7 @@ DEFINE_POOL_CLASS(NPoolClass, this)
this->reclaim = NReclaim;
this->traceEnd = NTraceEnd;
this->describe = NDescribe;
AVERT(PoolClass, this);
}
@ -313,7 +313,7 @@ Bool PoolNCheck(PoolN poolN)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* poolsnc.c: STACK NO CHECKING POOL CLASS
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* DESIGN
*
@ -90,9 +90,9 @@ static Bool SNCBufCheck(SNCBuf sncbuf)
CHECKS(SNCBuf, sncbuf);
segbuf = &sncbuf->segBufStruct;
CHECKL(SegBufCheck(segbuf));
CHECKD(SegBuf, segbuf);
if (sncbuf->topseg != NULL) {
CHECKL(SegCheck(sncbuf->topseg));
CHECKD(Seg, sncbuf->topseg);
}
return TRUE;
}
@ -185,6 +185,7 @@ DEFINE_BUFFER_CLASS(SNCBufClass, class)
class->size = sizeof(SNCBufStruct);
class->init = SNCBufInit;
class->finish = SNCBufFinish;
AVERT(BufferClass, class);
}
@ -216,7 +217,7 @@ typedef struct SNCSegStruct {
static Bool SNCSegCheck(SNCSeg sncseg)
{
CHECKS(SNCSeg, sncseg);
CHECKL(GCSegCheck(&sncseg->gcSegStruct));
CHECKD(GCSeg, &sncseg->gcSegStruct);
if (NULL != sncseg->next) {
CHECKS(SNCSeg, sncseg->next);
}
@ -237,7 +238,7 @@ static Res sncSegInit(Seg seg, Pool pool, Addr base, Size size,
sncseg = SegSNCSeg(seg);
AVERT(Pool, pool);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
/* Initialize the superclass fields first via next-method call */
super = SEG_SUPERCLASS(SNCSegClass);
@ -261,6 +262,7 @@ DEFINE_SEG_CLASS(SNCSegClass, class)
class->name = "SNCSEG";
class->size = sizeof(SNCSegStruct);
class->init = sncSegInit;
AVERT(SegClass, class);
}
@ -365,7 +367,7 @@ static void SNCVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs)
args[0].key = MPS_KEY_FORMAT;
args[0].val.format = va_arg(varargs, Format);
args[1].key = MPS_KEY_ARGS_END;
AVER(ArgListCheck(args));
AVERT(ArgList, args);
}
@ -431,7 +433,7 @@ static Res SNCBufferFill(Addr *baseReturn, Addr *limitReturn,
AVERT(Pool, pool);
AVERT(Buffer, buffer);
AVER(size > 0);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
AVER(BufferIsReset(buffer));
snc = Pool2SNC(pool);
@ -682,6 +684,7 @@ DEFINE_POOL_CLASS(SNCPoolClass, this)
this->framePopPending = SNCFramePopPending;
this->walk = SNCWalk;
this->bufferClass = SNCBufClassGet;
AVERT(PoolClass, this);
}
@ -699,7 +702,7 @@ static Bool SNCCheck(SNC snc)
CHECKD(Pool, &snc->poolStruct);
CHECKL(snc->poolStruct.class == SNCPoolClassGet());
if (snc->freeSegs != NULL) {
CHECKL(SegCheck(snc->freeSegs));
CHECKD(Seg, snc->freeSegs);
}
return TRUE;
}
@ -707,7 +710,7 @@ static Bool SNCCheck(SNC snc)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* prmci3li.c: PROTECTION MUTATOR CONTEXT INTEL 386 (LINUX)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This module implements the part of the protection module
* that decodes the MutatorFaultContext.
@ -57,9 +57,10 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
case 5: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EBP]);
case 6: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ESI]);
case 7: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EDI]);
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */
}
NOTREACHED;
return (MRef)NULL; /* Avoids compiler warning. */
}
@ -107,7 +108,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* prmci3w3.c: PROTECTION MUTATOR CONTEXT INTEL 386 (Win32)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* PURPOSE
*
@ -46,9 +46,10 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext context, unsigned int regnum)
case 5: return (MRef)&wincont->Ebp;
case 6: return (MRef)&wincont->Esi;
case 7: return (MRef)&wincont->Edi;
default:
NOTREACHED;
return NULL; /* suppress warning */
}
NOTREACHED;
return NULL; /* suppress warning */
}
@ -80,7 +81,7 @@ void Prmci3StepOverIns(MutatorFaultContext context, Size inslen)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* prmci3xc.c: PROTECTION MUTATOR CONTEXT INTEL 386 (MAC OS X)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This module implements the part of the protection module
* that decodes the MutatorFaultContext.
@ -55,9 +55,10 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
case 5: return (MRef)((char *)&mfc->threadState->__ebp);
case 6: return (MRef)((char *)&mfc->threadState->__esi);
case 7: return (MRef)((char *)&mfc->threadState->__edi);
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */
}
NOTREACHED;
return (MRef)NULL; /* Avoids compiler warning. */
}
@ -104,7 +105,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* prmci6li.c: PROTECTION MUTATOR CONTEXT x64 (LINUX)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This module implements the part of the protection module
* that decodes the MutatorFaultContext.
@ -61,9 +61,10 @@ MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
case 13: return &gregs[REG_R13];
case 14: return &gregs[REG_R14];
case 15: return &gregs[REG_R15];
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */
}
NOTREACHED;
return (MRef)NULL; /* Avoids compiler warning. */
}
@ -111,7 +112,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* prmci6w3.c: PROTECTION MUTATOR CONTEXT INTEL 386 (Win32)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* PURPOSE
*
@ -52,9 +52,10 @@ MRef Prmci6AddressHoldingReg(MutatorFaultContext context, unsigned int regnum)
case 13: return (MRef)&wincont->R13;
case 14: return (MRef)&wincont->R14;
case 15: return (MRef)&wincont->R15;
default:
NOTREACHED;
return NULL; /* suppress warning */
}
NOTREACHED;
return NULL; /* suppress warning */
}
@ -86,7 +87,7 @@ void Prmci6StepOverIns(MutatorFaultContext context, Size inslen)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* prmci6xc.c: PROTECTION MUTATOR CONTEXT x64 (MAC OS X)
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This module implements the part of the protection module
* that decodes the MutatorFaultContext.
@ -58,9 +58,10 @@ MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum)
case 13: return (MRef)((char *)&mfc->threadState->__r13);
case 14: return (MRef)((char *)&mfc->threadState->__r14);
case 15: return (MRef)((char *)&mfc->threadState->__r15);
default:
NOTREACHED;
return NULL; /* Avoids compiler warning. */
}
NOTREACHED;
return (MRef)NULL; /* Avoids compiler warning. */
}
@ -107,7 +108,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* pool.c: PROTOCOL IMPLEMENTATION
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* DESIGN
*
@ -18,7 +18,7 @@ SRCID(protocol, "$Id$");
Bool ProtocolClassCheck(ProtocolClass class)
{
CHECKS(ProtocolClass, class);
CHECKS(ProtocolClass, class->superclass);
CHECKU(ProtocolClass, class->superclass);
CHECKL(FUNCHECK(class->coerceInst));
CHECKL(FUNCHECK(class->coerceClass));
return TRUE;
@ -30,7 +30,7 @@ Bool ProtocolClassCheck(ProtocolClass class)
Bool ProtocolInstCheck(ProtocolInst inst)
{
CHECKS(ProtocolInst, inst);
CHECKL(ProtocolClassCheck(inst->class));
CHECKD(ProtocolClass, inst->class);
return TRUE;
}
@ -118,6 +118,7 @@ DEFINE_CLASS(ProtocolClass, theClass)
theClass->superclass = theClass;
theClass->coerceInst = ProtocolCoerceInst;
theClass->coerceClass = ProtocolCoerceClass;
AVERT(ProtocolClass, theClass);
}
@ -126,7 +127,7 @@ DEFINE_CLASS(ProtocolClass, theClass)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* pthreadext.c: POSIX THREAD EXTENSIONS
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: Provides extension to Pthreads.
*
@ -178,8 +178,8 @@ extern Bool PThreadextCheck(PThreadext pthreadext)
CHECKS(PThreadext, pthreadext);
/* can't check ID */
CHECKL(RingCheck(&pthreadext->threadRing));
CHECKL(RingCheck(&pthreadext->idRing));
CHECKD_NOSIG(Ring, &pthreadext->threadRing);
CHECKD_NOSIG(Ring, &pthreadext->idRing);
if (pthreadext->suspendedMFC == NULL) {
/* not suspended */
CHECKL(RingIsSingle(&pthreadext->threadRing));
@ -366,7 +366,7 @@ unlock:
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -334,7 +334,6 @@ static void *go(void *p, size_t s)
mps_fmt_t format;
mps_chain_t chain;
mps_addr_t base;
mps_addr_t *addr;
testlib_unused(p);
testlib_unused(s);
@ -357,9 +356,7 @@ static void *go(void *p, size_t s)
"RootCreateTable");
base = &activationStack;
addr = base;
die(mps_root_create_table(&actroot, arena, mps_rank_ambig(), 0,
addr, sizeof(QSCell)/sizeof(mps_addr_t)),
die(mps_root_create_table(&actroot, arena, mps_rank_ambig(), 0, base, 1),
"RootCreateTable");
/* makes a random list */

View file

@ -1,7 +1,7 @@
/* reserv.c: ARENA RESERVOIR
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* IMPROVEMENTS
*
@ -74,6 +74,7 @@ DEFINE_POOL_CLASS(ReservoirPoolClass, this)
this->offset = offsetof(ReservoirStruct, poolStruct);
this->init = ResPoolInit;
this->finish = ResPoolFinish;
AVERT(PoolClass, this);
}
@ -94,7 +95,7 @@ Bool ReservoirCheck(Reservoir reservoir)
/* could call ReservoirIsConsistent, but it's costly. */
tract = reservoir->reserve;
if (tract != NULL) {
CHECKL(TractCheck(tract));
CHECKD_NOSIG(Tract, tract);
CHECKL(TractPool(tract) == ReservoirPool(reservoir));
}
CHECKL(SizeIsAligned(reservoir->reservoirLimit, ArenaAlign(arena)));
@ -281,7 +282,7 @@ Bool ReservoirDeposit(Reservoir reservoir, Addr *baseIO, Size *sizeIO)
/* put as many pages as necessary into the reserve & free the rest */
TRACT_FOR(tract, addr, arena, base, limit) {
AVER(TractCheck(tract));
AVERT(Tract, tract);
if (reservoir->reservoirSize < reslimit) {
/* Reassign the tract to the reservoir pool */
TractFinish(tract);
@ -416,7 +417,7 @@ void ReservoirFinish (Reservoir reservoir)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* root.c: ROOT IMPLEMENTATION
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This is the implementation of the root datatype.
*
@ -98,7 +98,7 @@ Bool RootCheck(Root root)
CHECKS(Root, root);
CHECKU(Arena, root->arena);
CHECKL(root->serial < ArenaGlobals(root->arena)->rootSerial);
CHECKL(RingCheck(&root->arenaRing));
CHECKD_NOSIG(Ring, &root->arenaRing);
CHECKL(RankCheck(root->rank));
CHECKL(TraceSetCheck(root->grey));
/* Don't need to check var here, because of the switch below */
@ -121,7 +121,7 @@ Bool RootCheck(Root root)
case RootREG:
CHECKL(root->the.reg.scan != NULL);
CHECKL(ThreadCheck(root->the.reg.thread));
CHECKD_NOSIG(Thread, root->the.reg.thread); /* <design/check/#hidden-type> */
break;
case RootFMT:
@ -261,7 +261,7 @@ Res RootCreateTable(Root *rootReturn, Arena arena,
AVER(rootReturn != NULL);
AVERT(Arena, arena);
AVER(RankCheck(rank));
AVERT(Rank, rank);
AVER(base != 0);
AVER(base < limit);
@ -281,7 +281,7 @@ Res RootCreateTableMasked(Root *rootReturn, Arena arena,
AVER(rootReturn != NULL);
AVERT(Arena, arena);
AVER(RankCheck(rank));
AVERT(Rank, rank);
AVER(base != 0);
AVER(base < limit);
/* Can't check anything about mask. */
@ -302,7 +302,7 @@ Res RootCreateReg(Root *rootReturn, Arena arena,
AVER(rootReturn != NULL);
AVERT(Arena, arena);
AVER(RankCheck(rank));
AVERT(Rank, rank);
AVERT(Thread, thread);
AVER(scan != NULL);
@ -322,7 +322,7 @@ Res RootCreateFmt(Root *rootReturn, Arena arena,
AVER(rootReturn != NULL);
AVERT(Arena, arena);
AVER(RankCheck(rank));
AVERT(Rank, rank);
AVER(FUNCHECK(scan));
AVER(base != 0);
AVER(base < limit);
@ -342,7 +342,7 @@ Res RootCreateFun(Root *rootReturn, Arena arena, Rank rank,
AVER(rootReturn != NULL);
AVERT(Arena, arena);
AVER(RankCheck(rank));
AVERT(Rank, rank);
AVER(FUNCHECK(scan));
theUnion.fun.scan = scan;
@ -671,7 +671,7 @@ Res RootsDescribe(Globals arenaGlobals, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -48,13 +48,11 @@ Bool SparseArrayCheck(SparseArray sa)
CHECKS(SparseArray, sa);
CHECKL(sa->base != NULL);
CHECKL(sa->elementSize >= 1);
/* TODO: CHECKD(VM, sa->vm); once VMStruct becomes visible */
CHECKL(VMCheck(sa->vm));
CHECKD_NOSIG(VM, sa->vm); /* <design/check/#hidden-type> */
CHECKL(sa->elementSize <= VMAlign(sa->vm));
CHECKL(sa->length > 0);
/* TODO: Make BTCheck extern and use everywhere. */
/* CHECKL(BTCheck(sa->mapped)); */
/* CHECKL(BTCheck(sa->pages)); */
CHECKD_NOSIG(BT, sa->mapped);
CHECKD_NOSIG(BT, sa->pages);
CHECKL(sa->shift == SizeLog2(VMAlign(sa->vm)));
return TRUE;
}

View file

@ -1,7 +1,7 @@
/* sac.c: SEGREGATED ALLOCATION CACHES
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*/
#include "mpm.h"
@ -249,7 +249,7 @@ Res SACFill(Addr *p_o, SAC sac, Size size, Bool hasReservoirPermit)
AVER(p_o != NULL);
AVERT(SAC, sac);
AVER(size != 0);
AVER(BoolCheck(hasReservoirPermit));
AVERT(Bool, hasReservoirPermit);
esac = ExternalSACOfSAC(sac);
sacFind(&i, &blockSize, sac, size);
@ -384,7 +384,7 @@ void SACFlush(SAC sac)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -94,26 +94,26 @@ static mps_res_t stress(mps_class_t class,
/* upper half, as when allocating them again we want smaller objects */
/* see randomSize() */
switch (k % 2) {
case 0: {
case 0:
for (i=testSetSIZE/2; i<testSetSIZE; ++i)
MPS_SAC_FREE(sac, (mps_addr_t)ps[i], ss[i]);
} break;
case 1: {
break;
default:
for (i=testSetSIZE/2; i<testSetSIZE; ++i)
mps_sac_free(sac, (mps_addr_t)ps[i], ss[i]);
} break;
break;
}
/* allocate some new objects */
for (i=testSetSIZE/2; i<testSetSIZE; ++i) {
ss[i] = (*size)(i);
switch (k % 2) {
case 0: {
case 0:
res = make((mps_addr_t *)&ps[i], sac, ss[i]);
} break;
case 1: {
break;
default:
res = mps_sac_alloc((mps_addr_t *)&ps[i], sac, ss[i], FALSE);
} break;
}
break;
}
if (res != MPS_RES_OK) return res;
}
}
@ -185,7 +185,6 @@ int main(int argc, char *argv[])
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE);
MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE);
MPS_ARGS_DONE(args);
die(mps_arena_create_k(&arena, mps_arena_class_vm(), args),
"mps_arena_create");
} MPS_ARGS_END(args);

View file

@ -1,7 +1,7 @@
/* seg.c: SEGMENTS
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .design: The design for this module is <design/seg/>.
*
@ -68,7 +68,7 @@ Res SegAlloc(Seg *segReturn, SegClass class, SegPref pref,
AVERT(SegPref, pref);
AVER(size > (Size)0);
AVERT(Pool, pool);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
arena = PoolArena(pool);
AVERT(Arena, arena);
@ -152,7 +152,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size,
AVER(SizeIsAligned(size, align));
class = seg->class;
AVERT(SegClass, class);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
limit = AddrAdd(base, size);
seg->limit = limit;
@ -168,7 +168,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size,
seg->sig = SegSig; /* set sig now so tract checks will see it */
TRACT_FOR(tract, addr, arena, base, limit) {
AVER(TractCheck(tract)); /* <design/check/#type.no-sig> */
AVERT(Tract, tract);
AVER(TractP(tract) == NULL);
AVER(!TractHasSeg(tract));
AVER(TractPool(tract) == pool);
@ -196,7 +196,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size,
failInit:
RingFinish(SegPoolRing(seg));
TRACT_FOR(tract, addr, arena, base, limit) {
AVER(TractCheck(tract)); /* <design/check/#type.no-sig> */
AVERT(Tract, tract);
TRACT_UNSET_SEG(tract);
}
seg->sig = SigInvalid;
@ -233,7 +233,7 @@ static void SegFinish(Seg seg)
limit = SegLimit(seg);
TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) {
AVER(TractCheck(tract)); /* <design/check/#type.no-sig> */
AVERT(Tract, tract);
TractSetWhite(tract, TraceSetEMPTY);
TRACT_UNSET_SEG(tract);
}
@ -263,7 +263,7 @@ static void SegFinish(Seg seg)
void SegSetGrey(Seg seg, TraceSet grey)
{
AVERT(Seg, seg);
AVER(TraceSetCheck(grey));
AVERT(TraceSet, grey);
AVER(grey == TraceSetEMPTY || SegRankSet(seg) != RankSetEMPTY);
/* Don't dispatch to the class method if there's no actual change in
@ -281,7 +281,7 @@ void SegSetGrey(Seg seg, TraceSet grey)
void SegSetWhite(Seg seg, TraceSet white)
{
AVERT(Seg, seg);
AVER(TraceSetCheck(white));
AVERT(TraceSet, white);
seg->class->setWhite(seg, white);
}
@ -296,7 +296,7 @@ void SegSetWhite(Seg seg, TraceSet white)
void SegSetRankSet(Seg seg, RankSet rankSet)
{
AVERT(Seg, seg);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
AVER(rankSet != RankSetEMPTY || SegSummary(seg) == RefSetEMPTY);
seg->class->setRankSet(seg, rankSet);
}
@ -322,7 +322,7 @@ void SegSetSummary(Seg seg, RefSet summary)
void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary)
{
AVERT(Seg, seg);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
#ifdef PROTECTION_NONE
if (rankSet != RankSetEMPTY) {
@ -582,7 +582,7 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi,
mid = SegLimit(segLo);
limit = SegLimit(segHi);
AVER(SegBase(segHi) == SegLimit(segLo));
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
arena = PoolArena(SegPool(segLo));
ShieldFlush(arena); /* see <design/seg/#split-merge.shield> */
@ -634,7 +634,7 @@ Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at,
AVER(AddrIsAligned(at, arena->alignment));
AVER(at > base);
AVER(at < limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
ShieldFlush(arena); /* see <design/seg/#split-merge.shield> */
@ -690,7 +690,7 @@ Bool SegCheck(Seg seg)
/* can't assume nailed is subset of white - mightn't be during whiten */
/* CHECKL(TraceSetSub(seg->nailed, seg->white)); */
CHECKL(TraceSetCheck(seg->grey));
CHECKL(TractCheck(seg->firstTract)); /* <design/check/#type.no-sig> */
CHECKD_NOSIG(Tract, seg->firstTract);
pool = SegPool(seg);
CHECKU(Pool, pool);
arena = PoolArena(pool);
@ -704,7 +704,7 @@ Bool SegCheck(Seg seg)
TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, seg->limit) {
Seg trseg = NULL; /* suppress compiler warning */
CHECKL(TractCheck(tract)); /* <design/check/#type.no-sig> */
CHECKD_NOSIG(Tract, tract);
CHECKL(TRACT_SEG(&trseg, tract) && (trseg == seg));
CHECKL(TractWhite(tract) == seg->white);
CHECKL(TractPool(tract) == pool);
@ -716,7 +716,7 @@ Bool SegCheck(Seg seg)
/* the segment is initialized.) */
/* CHECKL(RingNext(&seg->poolRing) != &seg->poolRing); */
CHECKL(RingCheck(&seg->poolRing));
CHECKD_NOSIG(Ring, &seg->poolRing);
/* "pm", "sm", and "depth" not checked. See .check.shield. */
CHECKL(RankSetCheck(seg->rankSet));
@ -727,6 +727,8 @@ Bool SegCheck(Seg seg)
CHECKL(seg->sm == AccessSetEMPTY);
CHECKL(seg->pm == AccessSetEMPTY);
} else {
/* Segments with ranks may only belong to scannable pools. */
CHECKL(PoolHasAttr(pool, AttrSCAN));
/* <design/seg/#field.rankSet.single>: The Tracer only permits */
/* one rank per segment [ref?] so this field is either empty or a */
/* singleton. */
@ -760,8 +762,8 @@ static Res segTrivInit(Seg seg, Pool pool, Addr base, Size size,
AVER(SegBase(seg) == base);
AVER(SegSize(seg) == size);
AVER(SegPool(seg) == pool);
AVER(BoolCheck(reservoirPermit));
AVER(ArgListCheck(args));
AVERT(Bool, reservoirPermit);
AVERT(ArgList, args);
UNUSED(args);
return ResOK;
}
@ -781,7 +783,7 @@ static void segTrivFinish(Seg seg)
static void segNoSetGrey(Seg seg, TraceSet grey)
{
AVERT(Seg, seg);
AVER(TraceSetCheck(grey));
AVERT(TraceSet, grey);
AVER(seg->rankSet != RankSetEMPTY);
NOTREACHED;
}
@ -792,7 +794,7 @@ static void segNoSetGrey(Seg seg, TraceSet grey)
static void segNoSetWhite(Seg seg, TraceSet white)
{
AVERT(Seg, seg);
AVER(TraceSetCheck(white));
AVERT(TraceSet, white);
NOTREACHED;
}
@ -802,7 +804,7 @@ static void segNoSetWhite(Seg seg, TraceSet white)
static void segNoSetRankSet(Seg seg, RankSet rankSet)
{
AVERT(Seg, seg);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
NOTREACHED;
}
@ -822,7 +824,7 @@ static void segNoSetSummary(Seg seg, RefSet summary)
static void segNoSetRankSummary(Seg seg, RankSet rankSet, RefSet summary)
{
AVERT(Seg, seg);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
UNUSED(summary);
NOTREACHED;
}
@ -862,7 +864,7 @@ static Res segNoMerge(Seg seg, Seg segHi,
AVER(SegLimit(seg) == mid);
AVER(SegBase(segHi) == mid);
AVER(SegLimit(segHi) == limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
NOTREACHED;
return ResFAIL;
}
@ -898,7 +900,7 @@ static Res segTrivMerge(Seg seg, Seg segHi,
AVER(SegLimit(seg) == mid);
AVER(SegBase(segHi) == mid);
AVER(SegLimit(segHi) == limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* .similar. */
AVER(seg->rankSet == segHi->rankSet);
@ -916,7 +918,7 @@ static Res segTrivMerge(Seg seg, Seg segHi,
seg->limit = limit;
TRACT_FOR(tract, addr, arena, mid, limit) {
AVER(TractCheck(tract)); /* <design/check/#type.no-sig> */
AVERT(Tract, tract);
AVER(TractHasSeg(tract));
AVER(segHi == TractP(tract));
AVER(TractPool(tract) == pool);
@ -946,7 +948,7 @@ static Res segNoSplit(Seg seg, Seg segHi,
AVER(mid < limit);
AVER(SegBase(seg) == base);
AVER(SegLimit(seg) == limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
NOTREACHED;
return ResFAIL;
@ -977,7 +979,7 @@ static Res segTrivSplit(Seg seg, Seg segHi,
AVER(mid < limit);
AVER(SegBase(seg) == base);
AVER(SegLimit(seg) == limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* Segment may not be exposed, or in the shield cache */
/* See <design/seg/#split-merge.shield> & <code/shield.c#def.depth> */
@ -999,7 +1001,7 @@ static Res segTrivSplit(Seg seg, Seg segHi,
RingInit(SegPoolRing(segHi));
TRACT_FOR(tract, addr, arena, mid, limit) {
AVER(TractCheck(tract)); /* <design/check/#type.no-sig> */
AVERT(Tract, tract);
AVER(TractHasSeg(tract));
AVER(seg == TractP(tract));
AVER(TractPool(tract) == pool);
@ -1090,7 +1092,7 @@ Bool GCSegCheck(GCSeg gcseg)
Seg seg;
CHECKS(GCSeg, gcseg);
seg = &gcseg->segStruct;
CHECKL(SegCheck(seg));
CHECKD(Seg, seg);
if (gcseg->buffer != NULL) {
CHECKU(Buffer, gcseg->buffer);
@ -1100,7 +1102,7 @@ Bool GCSegCheck(GCSeg gcseg)
}
/* The segment should be on a grey ring if and only if it is grey. */
CHECKL(RingCheck(&gcseg->greyRing));
CHECKD_NOSIG(Ring, &gcseg->greyRing);
CHECKL((seg->grey == TraceSetEMPTY) ==
RingIsSingle(&gcseg->greyRing));
@ -1132,7 +1134,7 @@ static Res gcSegInit(Seg seg, Pool pool, Addr base, Size size,
AVER(SizeIsAligned(size, align));
gcseg = SegGCSeg(seg);
AVER(&gcseg->segStruct == seg);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
/* Initialize the superclass fields first via next-method call */
super = SEG_SUPERCLASS(GCSegClass);
@ -1309,7 +1311,7 @@ static void gcSegSetWhite(Seg seg, TraceSet white)
TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) {
Seg trseg = NULL; /* suppress compiler warning */
AVER_CRITICAL(TractCheck(tract)); /* <design/check/#type.no-sig> */
AVERT_CRITICAL(Tract, tract);
AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg));
TractSetWhite(tract, white);
}
@ -1497,7 +1499,7 @@ static Res gcSegMerge(Seg seg, Seg segHi,
AVER(SegLimit(seg) == mid);
AVER(SegBase(segHi) == mid);
AVER(SegLimit(segHi) == limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
buf = gcsegHi->buffer; /* any buffer on segHi must be reassigned */
AVER(buf == NULL || gcseg->buffer == NULL); /* See .buffer */
@ -1563,7 +1565,7 @@ static Res gcSegSplit(Seg seg, Seg segHi,
AVER(mid < limit);
AVER(SegBase(seg) == base);
AVER(SegLimit(seg) == limit);
AVER(BoolCheck(withReservoirPermit));
AVERT(Bool, withReservoirPermit);
grey = SegGrey(seg);
buf = gcseg->buffer; /* Look for buffer to reassign to segHi */
@ -1646,7 +1648,7 @@ static Res gcSegDescribe(Seg seg, mps_lib_FILE *stream)
Bool SegClassCheck(SegClass class)
{
CHECKL(ProtocolClassCheck(&class->protocol));
CHECKD(ProtocolClass, &class->protocol);
CHECKL(class->name != NULL); /* Should be <= 6 char C identifier */
CHECKL(class->size >= sizeof(SegStruct));
CHECKL(FUNCHECK(class->init));
@ -1683,6 +1685,7 @@ DEFINE_CLASS(SegClass, class)
class->split = segTrivSplit;
class->describe = segTrivDescribe;
class->sig = SegClassSig;
AVERT(SegClass, class);
}
@ -1707,6 +1710,7 @@ DEFINE_CLASS(GCSegClass, class)
class->merge = gcSegMerge;
class->split = gcSegSplit;
class->describe = gcSegDescribe;
AVERT(SegClass, class);
}
@ -1726,7 +1730,7 @@ void SegClassMixInNoSplitMerge(SegClass class)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -67,7 +67,7 @@ typedef struct AMSTStruct *AMST;
static Bool AMSTCheck(AMST amst)
{
CHECKS(AMST, amst);
CHECKL(AMSCheck(AMST2AMS(amst)));
CHECKD_NOSIG(AMS, AMST2AMS(amst)); /* <design/check/#hidden-type> */
return TRUE;
}
@ -104,7 +104,7 @@ typedef struct AMSTSegStruct {
static Bool AMSTSegCheck(AMSTSeg amstseg)
{
CHECKS(AMSTSeg, amstseg);
CHECKL(AMSSegCheck(&amstseg->amsSegStruct));
CHECKD_NOSIG(AMSSeg, &amstseg->amsSegStruct); /* <design/check/#hidden-type> */
/* don't bother to do other checks - this is a stress test */
return TRUE;
}
@ -129,7 +129,7 @@ static Res amstSegInit(Seg seg, Pool pool, Addr base, Size size,
amst = Pool2AMST(pool);
AVERT(AMST, amst);
/* no useful checks for base and size */
AVER(BoolCheck(reservoirPermit));
AVERT(Bool, reservoirPermit);
/* Initialize the superclass fields first via next-method call */
super = SEG_SUPERCLASS(AMSTSegClass);
@ -294,6 +294,7 @@ DEFINE_SEG_CLASS(AMSTSegClass, class)
class->finish = amstSegFinish;
class->split = amstSegSplit;
class->merge = amstSegMerge;
AVERT(SegClass, class);
}
@ -310,7 +311,7 @@ static Res AMSTSegSizePolicy(Size *sizeReturn,
AVER(sizeReturn != NULL);
AVERT(Pool, pool);
AVER(size > 0);
AVER(RankSetCheck(rankSet));
AVERT(RankSet, rankSet);
arena = PoolArena(pool);
@ -674,6 +675,7 @@ DEFINE_POOL_CLASS(AMSTPoolClass, this)
this->init = AMSTInit;
this->finish = AMSTFinish;
this->bufferFill = AMSTBufferFill;
AVERT(PoolClass, this);
}

View file

@ -48,6 +48,7 @@ Bool SplayTreeCheck(SplayTree splay)
CHECKL(FUNCHECK(splay->compare));
CHECKL(FUNCHECK(splay->nodeKey));
CHECKL(FUNCHECK(splay->updateNode));
/* Can't use CHECKD_NOSIG because TreeEMPTY is NULL. */
CHECKL(TreeCheck(splay->root));
return TRUE;
}

View file

@ -1,7 +1,7 @@
/* than.c: ANSI THREADS MANAGER
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* This is a single-threaded implementation of the threads manager.
* Has stubs for thread suspension.
@ -30,7 +30,7 @@ Bool ThreadCheck(Thread thread)
CHECKS(Thread, thread);
CHECKU(Arena, thread->arena);
CHECKL(thread->serial < thread->arena->threadSerial);
CHECKL(RingCheck(&thread->arenaRing));
CHECKD_NOSIG(Ring, &thread->arenaRing);
return TRUE;
}
@ -146,7 +146,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* thix.c: Threads Manager for Posix threads
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .purpose: This is a pthreads implementation of the threads manager.
* This implements <code/th.h>.
@ -61,7 +61,7 @@ Bool ThreadCheck(Thread thread)
CHECKS(Thread, thread);
CHECKU(Arena, thread->arena);
CHECKL(thread->serial < thread->arena->threadSerial);
CHECKL(RingCheck(&thread->arenaRing));
CHECKD_NOSIG(Ring, &thread->arenaRing);
CHECKD(PThreadext, &thread->thrextStruct);
return TRUE;
}
@ -292,7 +292,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* thw3i3.c: WIN32 THREAD MANAGER
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* Implements thread registration, suspension, and stack
* scanning. See <design/thread-manager/>.
@ -60,7 +60,7 @@ Bool ThreadCheck(Thread thread)
CHECKS(Thread, thread);
CHECKU(Arena, thread->arena);
CHECKL(thread->serial < thread->arena->threadSerial);
CHECKL(RingCheck(&thread->arenaRing));
CHECKD_NOSIG(Ring, &thread->arenaRing);
return TRUE;
}
@ -233,7 +233,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* thxc.c: OS X MACH THREADS MANAGER
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .design: See <design/thread-manager/>.
*
@ -45,7 +45,7 @@ Bool ThreadCheck(Thread thread)
CHECKS(Thread, thread);
CHECKU(Arena, thread->arena);
CHECKL(thread->serial < thread->arena->threadSerial);
CHECKL(RingCheck(&thread->arenaRing));
CHECKD_NOSIG(Ring, &thread->arenaRing);
CHECKL(MACH_PORT_VALID(thread->port));
return TRUE;
}
@ -267,7 +267,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -64,9 +64,9 @@ void ScanStateInit(ScanState ss, TraceSet ts, Arena arena,
TraceId ti;
Trace trace;
AVER(TraceSetCheck(ts));
AVERT(TraceSet, ts);
AVERT(Arena, arena);
AVER(RankCheck(rank));
AVERT(Rank, rank);
/* white is arbitrary and can't be checked */
/* NOTE: We can only currently support scanning for a set of traces with
@ -363,7 +363,7 @@ Res TraceAddWhite(Trace trace, Seg seg)
if(TraceSetIsMember(SegWhite(seg), trace)) {
trace->white = ZoneSetUnion(trace->white, ZoneSetOfSeg(trace->arena, seg));
/* if the pool is a moving GC, then condemned objects may move */
if(pool->class->attr & AttrMOVINGGC) {
if(PoolHasAttr(pool, AttrMOVINGGC)) {
trace->mayMove = ZoneSetUnion(trace->mayMove,
ZoneSetOfSeg(trace->arena, seg));
}
@ -410,8 +410,9 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet)
/* the requested zone set. Otherwise, we would bloat the */
/* foundation to no gain. Note that this doesn't exclude */
/* any segments from which the condemned set was derived, */
if((SegPool(seg)->class->attr & AttrGC) != 0
&& ZoneSetSuper(condemnedSet, ZoneSetOfSeg(arena, seg))) {
if(PoolHasAttr(SegPool(seg), AttrGC)
&& ZoneSetSuper(condemnedSet, ZoneSetOfSeg(arena, seg)))
{
res = TraceAddWhite(trace, seg);
if(res != ResOK)
return res;
@ -503,9 +504,9 @@ static Res rootFlip(Root root, void *p)
AVERT(Root, root);
AVER(p != NULL);
AVER(TraceSetCheck(rf->ts));
AVERT(TraceSet, rf->ts);
AVERT(Arena, rf->arena);
AVER(RankCheck(rf->rank));
AVERT(Rank, rf->rank);
AVER(RootRank(root) <= RankEXACT); /* see .root.rank */
@ -827,7 +828,7 @@ static void traceReclaim(Trace trace)
AVER_CRITICAL(!TraceSetIsMember(SegGrey(seg), trace));
if(TraceSetIsMember(SegWhite(seg), trace)) {
AVER_CRITICAL((pool->class->attr & AttrGC) != 0);
AVER_CRITICAL(PoolHasAttr(pool, AttrGC));
STATISTIC(++trace->reclaimCount);
PoolReclaim(pool, trace, seg);
@ -988,7 +989,7 @@ static Bool traceFindGrey(Seg *segReturn, Rank *rankReturn,
Ring node, nextNode;
AVER(segReturn != NULL);
AVER(TraceIdCheck(ti));
AVERT(TraceId, ti);
trace = ArenaTrace(arena, ti);
@ -1376,10 +1377,10 @@ void TraceScanSingleRef(TraceSet ts, Rank rank, Arena arena,
{
Res res;
AVER(TraceSetCheck(ts));
AVER(RankCheck(rank));
AVERT(TraceSet, ts);
AVERT(Rank, rank);
AVERT(Arena, arena);
AVER(SegCheck(seg));
AVERT(Seg, seg);
AVER(refIO != NULL);
res = traceScanSingleRefRes(ts, rank, arena, seg, refIO);
@ -1617,9 +1618,6 @@ Res TraceStart(Trace trace, double mortality, double finishingTime)
/* This is indicated by the rankSet begin non-empty. Such */
/* segments may only belong to scannable pools. */
if(SegRankSet(seg) != RankSetEMPTY) {
/* Segments with ranks may only belong to scannable pools. */
AVER((SegPool(seg)->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 */
@ -1634,8 +1632,9 @@ Res TraceStart(Trace trace, double mortality, double finishingTime)
}
}
if((SegPool(seg)->class->attr & AttrGC)
&& !TraceSetIsMember(SegWhite(seg), trace)) {
if(PoolHasAttr(SegPool(seg), AttrGC)
&& !TraceSetIsMember(SegWhite(seg), trace))
{
trace->notCondemned += size;
}
}
@ -1730,7 +1729,6 @@ void TraceQuantum(Trace trace)
if(traceFindGrey(&seg, &rank, arena, trace->ti)) {
Res res;
AVER((SegPool(seg)->class->attr & AttrSCAN) != 0);
res = traceScanSeg(TraceSetSingle(trace), rank, arena, seg);
/* Allocation failures should be handled by emergency mode, and we
don't expect any other error in a normal GC trace. */

View file

@ -1,7 +1,7 @@
/* tract.c: PAGE TABLES
*
* $Id$
* Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* .ullagepages: Pages whose page index is < allocBase are recorded as
* free but never allocated as alloc starts searching after the tables.
@ -113,7 +113,7 @@ Bool ChunkCheck(Chunk chunk)
CHECKS(Chunk, chunk);
CHECKU(Arena, chunk->arena);
CHECKL(chunk->serial < chunk->arena->chunkSerial);
CHECKL(RingCheck(&chunk->chunkRing));
CHECKD_NOSIG(Ring, &chunk->chunkRing);
CHECKL(ChunkPagesToSize(chunk, 1) == ChunkPageSize(chunk));
CHECKL(ShiftCheck(ChunkPageShift(chunk)));
@ -128,7 +128,7 @@ Bool ChunkCheck(Chunk chunk)
CHECKL(chunk->allocBase <= chunk->pages);
CHECKL(chunk->allocBase >= chunk->pageTablePages);
CHECKL(chunk->allocTable != NULL);
CHECKD_NOSIG(BT, chunk->allocTable);
/* check that allocTable is in the chunk overhead */
CHECKL((Addr)chunk->allocTable >= chunk->base);
CHECKL(AddrAdd((Addr)chunk->allocTable, BTSize(chunk->pages))
@ -671,7 +671,7 @@ void PageFree(Chunk chunk, Index pi)
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2013 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -1,7 +1,7 @@
/* walk.c: OBJECT WALKER
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*/
#include "mpm.h"
@ -77,7 +77,7 @@ static void ArenaFormattedObjectsWalk(Arena arena, FormattedObjectsStepMethod f,
do {
Pool pool;
pool = SegPool(seg);
if (pool->class->attr & AttrFMT) {
if (PoolHasAttr(pool, AttrFMT)) {
ShieldExpose(arena, seg);
PoolWalk(pool, seg, f, p, s);
ShieldCover(arena, seg);
@ -171,7 +171,7 @@ static Bool rootsStepClosureCheck(rootsStepClosure rsc)
CHECKL(FUNCHECK(rsc->f));
/* p and s fields are arbitrary closures which cannot be checked */
if (rsc->root != NULL) {
CHECKL(RootCheck(rsc->root));
CHECKD_NOSIG(Root, rsc->root); /* <design/check/#.hidden-type> */
}
return TRUE;
}
@ -243,7 +243,7 @@ static Res RootsWalkFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
/* If the segment isn't GCable then the ref is not to the heap and */
/* shouldn't be passed to the client. */
AVER((SegPool(seg)->class->attr & AttrGC) != 0);
AVER(PoolHasAttr(SegPool(seg), AttrGC));
/* Call the client closure - .assume.rootaddr */
rsc->f((mps_addr_t*)refIO, (mps_root_t)rsc->root, rsc->p, rsc->s);
@ -307,7 +307,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f,
/* NOTE: I'm not sure why this is. RB 2012-07-24 */
if (SegFirst(&seg, arena)) {
do {
if ((SegPool(seg)->class->attr & AttrGC) != 0) {
if (PoolHasAttr(SegPool(seg), AttrGC)) {
res = TraceAddWhite(trace, seg);
AVER(res == ResOK);
}
@ -363,7 +363,7 @@ void mps_arena_roots_walk(mps_arena_t mps_arena, mps_roots_stepper_t f,
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -11,6 +11,8 @@
#include "testlib.h"
#include "mpslib.h"
#include "mpscamc.h"
#include "mpscams.h"
#include "mpscawl.h"
#include "mpsavm.h"
#include "mpstd.h"
#ifdef MPS_OS_W3
@ -126,11 +128,16 @@ static void stepper(mps_addr_t object, mps_fmt_t format,
return;
}
static mps_addr_t test_awl_find_dependent(mps_addr_t addr)
{
testlib_unused(addr);
return NULL;
}
/* test -- the body of the test */
static void *test(void *arg, size_t s)
static void *test(mps_arena_t arena, mps_class_t pool_class)
{
mps_arena_t arena;
mps_chain_t chain;
mps_fmt_t format;
mps_pool_t pool;
@ -139,14 +146,15 @@ static void *test(void *arg, size_t s)
unsigned long objs;
struct stepper_data sdStruct, *sd;
arena = (mps_arena_t)arg;
(void)s; /* unused */
die(dylan_fmt(&format, arena), "fmt_create");
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain),
"pool_create(amc)");
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format);
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain);
MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent);
die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create");
} MPS_ARGS_END(args);
die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create");
@ -199,7 +207,6 @@ int main(int argc, char *argv[])
{
mps_arena_t arena;
mps_thr_t thread;
void *r;
testlib_init(argc, argv);
@ -207,7 +214,11 @@ int main(int argc, char *argv[])
testArenaSIZE),
"arena_create");
die(mps_thread_reg(&thread, arena), "thread_reg");
mps_tramp(&r, test, arena, 0);
test(arena, mps_class_amc());
test(arena, mps_class_awl());
/* TODO: test(arena, mps_class_ams()); -- see job003738 */
mps_thread_dereg(thread);
mps_arena_destroy(arena);

View file

@ -95,17 +95,30 @@ type structure pointer, possibly invoking ``<type>Check`` (depending
on level; see `.level`_). It should be called with the child type
and pointer.
_`.full-type`: ``CHECKS()``, ``CHECKD()``, ``CHECKU()``, all operate
only on fully fledged types. This means the type has to provide a
function ``Bool TypeCheck(Type type)`` where ``Type`` is substituted
for the name of the type (for example, ``PoolCheck()``), and the
expression ``obj->sig`` must be a valid value of type ``Sig`` whenever
``obj`` is a valid value of type ``Type``.
_`.full-type`: Use ``CHECKS()``, ``CHECKD()`` or ``CHECKU()`` on all
types that satisfy these three requirements:
_`.type.no-sig`: This tag is to be referenced in implementations
whenever the form ``CHECKL(ThingCheck(thing))`` is used instead of
``CHECK{U,D}(Thing, thing)`` because ``Thing`` is not a fully fledged
type (`.full-type`_).
_`.full-type.pointer`: The type is a pointer type.
_`.full-type.check`: The type provides a function ``Bool TypeCheck(Type
type)`` where ``Type`` is substituted for the name of the type (for
example, ``PoolCheck()``).
_`.full-type.sig`: The expression ``obj->sig`` is a valid value of
type ``Sig`` whenever ``obj`` is a valid value of type ``Type``.
_`.partial-type`: Where the type satisfies `.full-type.pointer`_ and
`.full-type.check`_ but not `.full-type.sig`_ because the type lacks a
signature in order to save space (this applies to small structures
that are embedded many times in other structures, for example
``Ring``), use ``CHECKD_NOSIG()``.
_`.hidden-type`: Where the type satisfies `.full-type.pointer`_ and
`.full-type.check`_ but not `.full-type.sig`_ because the structure
has a signature but the structure definition is not visible at point
of checking (for example ``Root``), use ``CHECKD_NOSIG()`` and
reference this tag. The structure could be considered for addition to
``mpmst.h``.
Document History

View file

@ -6,7 +6,7 @@ C interface design
:Tag: design.mps.interface.c
:Author: Richard Brooksby
:Date: 1996-07-29
:Status: incomplete document
:Status: complete design
:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: C interface; design
@ -29,7 +29,9 @@ Goals
_`.goal.c`: The file impl.h.mps is the C external interface to the
MPS. It is the default interface between client code written in C and
the MPS. _`.goal.cpp`: impl.h.mps is not specifically designed to be
the MPS.
_`.goal.cpp`: impl.h.mps is not specifically designed to be
an interface to C++, but should be usable from C++.
@ -38,36 +40,32 @@ Requirements
_`.req`: The interface must provide an interface from client code
written in C to the functionality of the MPS required by the product
(see req.product), Dylan (req.dylan), and the Core RIP (req.epcore).
(see req.product), and Open Dylan (req.dylan).
``mps.h`` may not include internal MPS header files (such as
``pool.h``).
_`.req.separation`: The external interface may not include internal
MPS header files (such as ``pool.h``).
It is essential that the interface cope well with change, in order to
avoid restricting possible future MPS developments. This means that
the interface must be "open ended" in its definitions. This accounts
for some of the apparently tortuous methods of doing things
(``mps_fmt_A_t``, for example). The requirement is that the MPS should
_`.req.flexibility`: It is essential that the interface cope well with
change, in order to avoid restricting possible future MPS
developments. This means that the interface must be "open ended" in
its definitions. This accounts for some of the apparently tortuous
methods of doing things (such as the keyword argument mechanism; see
design.mps.keyword-arguments_). The requirement is that the MPS should
be able to add new functionality, or alter the implementation of
existing functionality, without affecting existing client code. A
stronger requirement is that the MPS should be able to change without
*recompiling* client code. This is not always possible.
.. note::
.. _design.mps.keyword-arguments: keyword-arguments
`.naming.global` was presumably done in response to unwritten
requirements regarding the use of the name spaces in C, perhaps
these:
_`.req.name.iso`: The interface shall not conflict in terms of
naming with any interfaces specified by ISO C and all reasonable
future versions.
- _`.req.name.iso`: The interface shall not conflict in terms of
naming with any interfaces specified by ISO C and all reasonable
future versions.
- _`.req.name.general`: The interface shall use a documented and
reasonably small portion of the namespace so that clients can
interoperate easily.
David Jones, 1998-10-01.
_`.req.name.general`: The interface shall use a documented and
reasonably small portion of the namespace so that clients can use the
MPS C interface in combination with other interfaces without name
conflicts.
Architecture
@ -82,13 +80,18 @@ layer" which does the job of converting types and checking parameters
before calling through to the MPS proper, using internal MPS methods.
General conventions
-------------------
Naming conventions
------------------
_`.naming`: The external interface names should adhere to the
documented interface conventions; these are found in
doc.mps.ref-man.if-conv(0).naming. They are paraphrased/recreated
here.
documented interface conventions; these are found in the “`Interface
conventions`_” chapter of the Reference Manual. They are
paraphrased/recreated here.
.. _Interface conventions: ../topic/interface.html
_`.naming.file`: All files in the external interface have names
starting with ``mps``.
_`.naming.unixy`: The external interface does not follow the same
naming conventions as the internal code. The interface is designed to
@ -97,13 +100,13 @@ resemble a more conventional C, Unix, or Posix naming convention.
_`.naming.case`: Identifiers are in lower case, except
non-function-like macros, which are in upper case.
_`.naming.global`: All publicised identifiers are
prefixed ``mps_`` or ``MPS_``.
_`.naming.global`: All documented identifiers begin ``mps_`` or
``MPS_``.
_`.naming.all`: All identifiers defined by the MPS
should begin ``mps_`` or ``MPS_`` or ``_mps_``.
_`.naming.all`: All identifiers defined by the MPS begin ``mps_`` or
``MPS_`` or ``_mps_``.
_`.naming.type`: Types are suffixed ``_t``.
_`.naming.type`: Types are suffixed ``_t``, except for structure and union types.
_`.naming.struct`: Structure types and tags are suffixed ``_s``.
@ -117,15 +120,14 @@ structure and union members, macros, macro parameters, labels.
_`.naming.scope.labels`: labels (for ``goto`` statements) should be
rare, only in special block macros and probably not even then.
.. note::
This principle is not adhered to in the source code, which uses
``goto`` for handling error cases. Gareth Rees, 2013-05-27.
_`.naming.scope.other`: The naming convention would also extend to
enumeration types and parameters in functions prototypes but both of
those are prohibited from having names in an interface file.
Type conventions
----------------
_`.type.gen`: The interface defines memory addresses as ``void *`` and
sizes as ``size_t`` for compatibility with standard C (in particular,
with ``malloc()``). These types must be binary compatible with the
@ -139,13 +141,13 @@ which are never defined. These types are cast to the corresponding
internal types in ``mpsi.c``.
_`.type.trans`: Some transparent structures are defined. The client is
expected to read these, or poke about in them, under restrictions
which should be documented. The most important is probably the
allocation point (``mps_ap_s``) which is part of allocation buffers.
The transparent structures must be binary compatible with
corresponding internal structures. For example, the fields of
``mps_ap_s`` must correspond with ``APStruct`` internally. This is
checked by ``mpsi.c`` in ``mps_check()``.
expected to read these, or poke about in them, under documented
restrictions. The most important is the allocation point structure
(``mps_ap_s``) which is part of allocation buffers. The transparent
structures must be binary compatible with corresponding internal
structures. For example, the fields of ``mps_ap_s`` must correspond
with ``APStruct`` internally. This is checked by ``mpsi.c`` in
``mps_check()``.
_`.type.pseudo`: Some pseudo-opaque structures are defined. These only
exist so that code can be inlined using macros. The client code
@ -153,9 +155,9 @@ shouldn't mess with them. The most important case of this is the scan
state (``mps_ss_s``) which is accessed by the in-line scanning macros,
``MPS_SCAN_*`` and ``MPS_FIX*``.
_`.type.enum`: There should be no enumeration types in the interface.
Note that enum specifiers (to declare integer constants) are fine as
long as no type is declared. See guide.impl.c.misc.enum.type.
_`.type.enum`: There are no enumeration types in the interface. Note
that enum specifiers (to declare integer constants) are fine as long
as no type is declared. See guide.impl.c.misc.enum.type.
_`.type.fun`: Whenever function types or derived function types (such
as pointer to function) are declared a prototype should be used and
@ -184,39 +186,32 @@ See guide.impl.c.misc.prototype.parameters.
Checking
--------
_`.check.space`: When the arena needs to be recovered from a parameter
it is check using ``AVERT(Foo, foo)`` before any attempt to call
``FooArena(foo)``. The macro ``AVERT()`` in impl.h.assert performs
simple thread-safe checking of ``foo``, so it can be called outside of
``ArenaEnter()`` and ``ArenaLeave()``.
_`.check.avert`: Before any use of a function paramater ``FOO *foo``
it is checked using ``AVERT(Foo, foo)``. The macro ``AVERT()`` in
impl.h.check performs simple thread-safe checking of ``foo``, so it
can be called outside of ``ArenaEnter()`` and ``ArenaLeave()``.
_`.check.types`: We use definitions of types in both our external
interface and our internal code, and we want to make sure that they
are compatible. (The external interface changes less often and hides
more information.) At first, we were just checking their sizes, which
wasn't very good, but I've come up with some macros which check the
assignment compatibility of the types too. This is a sufficiently
useful trick that I thought I'd send it round. It may be useful in
other places where types and structures need to be checked for
compatibility at compile time.
These macros don't generate warnings on the compilers I've tried.
more information.) This checking uses the following macros.
``COMPATLVALUE(lvalue1, lvalue2)``
This macro checks the assignment compatibility of two lvalues. It uses
``sizeof()`` to ensure that the assignments have no effect. ::
_`.check.types.compat.lvalue`: This macro checks the assignment
compatibility of two lvalues. It uses ``sizeof()`` to ensure that the
assignments have no effect. ::
#define COMPATLVALUE(lv1, lv2) \
((void)sizeof((lv1) = (lv2)), (void)sizeof((lv2) = (lv1)), TRUE)
``COMPATTYPE(type1, type2)``
This macro checks that two types are assignment-compatible and equal
in size. The hack here is that it generates an lvalue for each type by
casting zero to a pointer to the type. The use of ``sizeof()`` avoids
the undefined behaviour that would otherwise result from dereferencing
a null pointer. ::
_`.check.types.compat.type`: This macro checks that two types are
assignment-compatible and equal in size. The hack here is that it
generates an lvalue for each type by casting zero to a pointer to the
type. The use of ``sizeof()`` avoids the undefined behaviour that
would otherwise result from dereferencing a null pointer. ::
#define COMPATTYPE(t1, t2) \
(sizeof(t1) == sizeof(t2) && \
@ -224,8 +219,8 @@ a null pointer. ::
``COMPATFIELDAPPROX(structure1, field1, structure2, field2)``
This macro checks that the offset and size of two fields in two
structure types are the same. ::
_`.check.types.compat.field.approx`: This macro checks that the offset
and size of two fields in two structure types are the same. ::
#define COMPATFIELDAPPROX(s1, f1, s2, f2) \
(sizeof(((s1 *)0)->f1) == sizeof(((s2 *)0)->f2) && \
@ -233,8 +228,8 @@ structure types are the same. ::
``COMPATFIELD(structure1, field1, structure2, field2)``
This macro checks the offset, size, and assignment-compatibility of
two fields in two structure types. ::
_`.check.types.compat.field`: This macro checks the offset, size, and
assignment-compatibility of two fields in two structure types. ::
#define COMPATFIELD(s1, f1, s2, f2) \
(COMPATFIELDAPPROX(s1, f1, s2, f2) && \
@ -247,21 +242,34 @@ Binary compatibility issues
As in, "Enumeration types are not allowed" (see
mail.richard.1995-09-08.09-28).
There are two main aspects to run-time compatibility: binary interface
and protocol. The binary interface is all the information needed to
correctly use the library, and includes external symbol linkage,
_`.compat`: There are two main aspects to run-time compatibility:
binary interface and protocol.
_`.compat.binary`: The binary interface is all the information needed
to correctly use the library, and includes external symbol linkage,
calling conventions, type representation compatibility, structure
layouts, etc. The protocol is how the library is actually used by the
client code -- whether this is called before that -- and determines
the semantic correctness of the client with respect to the library.
layouts, etc.
The binary interface is determined completely by the header file and
the target. The header file specifies the external names and the
types, and the target platform specifies calling conventions and type
representation. There is therefore a many-to-one mapping between the
header file version and the binary interface.
_`.compat.binary.unneeded`: Binary compatibility is not required by
the open source MPS: we expect (and indeed, recommend) that a client
program is compiled against the MPS sources. Nonetheless we try to
maintain binary compatibility in case the capability is required in
future.
The protocol is determined by the implementation of the library.
_`.compat.binary.dependencies`: The binary interface is determined
completely by the header file and the target. The header file
specifies the external names and the types, and the target platform
specifies calling conventions and type representation. There is
therefore a many-to-one mapping between the header file version and
the binary interface.
_`.compat.protocol`: The protocol is how the library is actually used
by the client code -- whether this is called before that -- and
determines the semantic correctness of the client with respect to the
library.
_`.compat.protocol.dependencies`: The protocol is determined by the
implementation of the library.
Constraints
@ -291,34 +299,59 @@ interface constrains ``Word`` to being the same size as C's generic
pointer type, ``void *``.
Implementation
--------------
_`.impl`: The external interface consists of the following header
files:
_`.impl.mps`: ``mps.h`` is the main external interface, containing of
type and function declarations needed by all clients of the MPS.
_`.impl.mpstd`: ``mpstd.h`` is the MPS target detection header. It
decodes preprocessor symbols which are predefined by build
environments in order to determine the target platform (see
design.mps.config_), and then defines uniform symbols, such as
``MPS_ARCH_I3``, for use externally and internally by the MPS.
``mpstd.h`` is not included by any of the other external headers, as
it relies on exact set of preprocessor constants defined by compilers.
.. _design.mps.config: config
_`.impl.mpsio`: ``mpsio.h`` is the interface to the MPS I/O subsystem,
part of the plinth. See design.mps.io_.
.. _design.mps.io: io
_`.impl.mpslib`: ``mpslib.h`` is the interface to the MPS Library
Interface, part of the plinth. See design.mps.lib_.
.. _design.mps.lib: lib
_`.impl.mpsa`: Interfaces to arena classes are in files with names
starting ``mpsa``: for example, the interface to the Virtual Memory
arena class is in ``mpsavm.h``.
_`.impl.mpsc`: Interfaces to pool classes are in files with names
starting ``mpsc``: for example, the interface to the MVFF pool class
is in ``mpscmvff.h``.
Notes
-----
The file ``mpstd.h`` is the MPS target detection header. It decodes
preprocessor symbols which are predefined by build environments in
order to determine the target platform, and then defines uniform
symbols, such as ``MPS_ARCH_I3``, for use internally by the MPS.
_`.fmt.extend`: ``mps_fmt_A_t`` is so called because new pool classes
might require new format methods, but these methods cannot be added to
the format structure without breaking binary compatibility. Therefore
these new pool classes would use new format structures named
``mps_fmt_B_t`` and so on.
There is a design document for the mps interface,
design.mps.interface, but it was written before we had the idea of
having a C interface layer. It is quite relevant, though, and could be
updated. We should use it during the review.
All exported identifiers and file names should begin with ``mps_`` or
``MPS_`` so that they don't clash with other systems.
We should probably have a specialized set of rules and a special
checklist for this interface.
_`.fmt.extend`: This paragraph should be an explanation of why
``mps_fmt_A_t`` is so called. The underlying reason is future
extensibility.
_`.thread-safety`: Most calls through this interface lock the space
_`.thread-safety`: Most calls through this interface lock the arena
and therefore make the MPM single-threaded. In order to do this they
must recover the space from their parameters. Methods such as
``ThreadSpace()`` must therefore be callable when the space is *not*
locked. These methods are tagged with the tag of this note.
must recover the arena from their parameters. Methods such as
``FormatArena()`` and ``ThreadArena()`` must therefore be callable
when the arena is *not* locked. These methods are tagged with the tag
of this note.
_`.lock-free`: Certain functions inside the MPM are thread-safe and do
not need to be serialized by using locks. They are marked with the tag

View file

@ -103,10 +103,10 @@ but ``arg.h`` provides a macro for this::
We define keys as static structures (rather than, say, an enum) because:
- The set of keys can be extended indefinitely.
- The set of keys can be extended by indepdently linked modules.
- The set of keys can be extended by independently linked modules.
- The structure contents allow strong checking of argument lists.
In the MPS Interface, we declare keys like this::
In the MPS C Interface, we declare keys like this::
extern const struct mps_key_s _mps_key_extend_by;
#define MPS_KEY_EXTEND_BY (&_mps_key_extend_by)

View file

@ -6,7 +6,7 @@ General MPS types
:Tag: design.mps.type
:Author: Richard Brooksby
:Date: 1996-10-23
:Status: incomplete document
:Status: complete document
:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: general types; design
@ -32,6 +32,87 @@ say ``Byte`` in your code if it's what you mean.
Concrete types
--------------
``typedef unsigned AccessSet``
_`.access-set`: An ``AccessSet`` is a bitset of ``Access`` modes,
which are ``AccessREAD`` and ``AccessWRITE``. ``AccessSetEMPTY`` is
the empty ``AccessSet``.
``typedef struct AddrStruct *Addr``
_`.addr`: ``Addr`` is the type used for "managed addresses", that is,
addresses of objects managed by the MPS.
_`.addr.def`: ``Addr`` is defined as ``struct AddrStruct *``, but
``AddrStruct`` is never defined. This means that ``Addr`` is always an
incomplete type, which prevents accidental dereferencing, arithmetic,
or assignment to other pointer types.
_`.addr.use`: ``Addr`` should be used whenever the code needs to deal
with addresses. It should not be used for the addresses of memory
manager data structures themselves, so that the memory manager remains
amenable to working in a separate address space. Be careful not to
confuse ``Addr`` with ``void *``.
_`.addr.ops`: Limited arithmetic is allowed on addresses using
``AddrAdd()`` and ``AddrOffset()`` (impl.c.mpm). Addresses may also be
compared using the relational operators ``==``, ``!=``, ``<``, ``<=``,
``>``, and ``>=``.
_`.addr.ops.mem`: We need efficient operators similar to ``memset()``,
``memcpy()``, and ``memcmp()`` on ``Addr``; these are called ``AddrSet()``,
``AddrCopy()``, and ``AddrComp()``. When ``Addr`` is compatible with
``void *``, these are implemented through the functions
``mps_lib_memset()``, ``mps_lib_memcpy()``, and ``mps_lib_memcmp()``
functions in the plinth (impl.h.mpm).
_`.addr.conv.c`: ``Addr`` is converted to ``mps_addr_t`` in the MPS C
Interface. ``mps_addr_t`` is defined to be the same as ``void *``, so
using the MPS C Interface confines the memory manager to the same
address space as the client data.
``typedef Word Align``
_`.align`: ``Align`` is an unsigned integral type which is used to
represent the alignment of managed addresses. All alignments are
positive powers of two. ``Align`` is large enough to hold the maximum
possible alignment.
_`.align.use`: ``Align`` should be used whenever the code needs to
deal with the alignment of a managed address.
_`.align.conv.c`: ``Align`` is converted to ``mps_align_t`` in the MPS
C Interface.
``typedef unsigned Attr``
_`.attr`: Pool attributes. A bitset of pool or pool class
attributes, which are:
=================== ===================================================
Attribute Description
=================== ===================================================
``AttrALLOC`` Supports the ``PoolAlloc`` interface.
``AttrBUF`` Supports the buffer interface.
``AttrFMT`` Contains formatted objects.
Used to decide which pools to walk.
``AttrFREE`` Supports the ``PoolFree`` interface.
``AttrGC`` Is garbage collecting, that is, parts may be
reclaimed. Used to decide which segments are
condemned.
``AttrMOVINGGC`` Is moving, that is, objects may move in memory.
Used to update the set of zones that might have
moved and so implement location dependency.
``AttrSCAN`` Contains references and must be scanned.
=================== ===================================================
There is an attribute field in the pool class (``PoolClassStruct``)
which declares the attributes of that class.
``typedef int Bool``
_`.bool`: The ``Bool`` type is mostly defined so that the intention of
@ -71,63 +152,135 @@ for ``BoolCheck`` on the PC Aaron. "With" ran in 97.7% of the time
(averaged over 3 runs).
``typedef int Res``
``typedef unsigned BufferMode``
_`.res`: ``Res`` is the type of result codes. A result code indicates
the success or failure of an operation, along with the reason for
failure. Like Unix error codes, the meaning of the code depends on the
call that returned it. These codes are just broad categories with
mnemonic names for various sorts of problems.
_`.buffermode`: ``BufferMode`` is a bitset of buffer attributes. See
design.mps.buffer_. It is a sum of the following:
=================== =======================================================
Result code Description
=================== =======================================================
``ResOK`` The operation succeeded. Return parameters may only be
updated if OK is returned, otherwise they must be left
untouched.
------------------- -------------------------------------------------------
``ResFAIL`` Something went wrong which doesn't fall into any of the
other categories. The exact meaning depends on the
call. See documentation.
------------------- -------------------------------------------------------
``ResRESOURCE`` A needed resource could not be obtained. Which resource
depends on the call. See also ``ResMEMORY``, which is a
special case of this.
------------------- -------------------------------------------------------
``ResMEMORY`` Needed memory (committed memory, not address space)
could not be obtained.
------------------- -------------------------------------------------------
``ResLIMIT`` An internal limitation was reached. For example, the
maximum number of somethings was reached. We should
avoid returning this by not including static
limitations in our code, as far as possible. (See
rule.impl.constrain and
rule.impl.limits.)
------------------- -------------------------------------------------------
``ResUNIMPL`` The operation, or some vital part of it, is
unimplemented. This might be returned by functions
which are no longer supported, or by operations which
are included for future expansion, but not yet
supported.
------------------- -------------------------------------------------------
``ResIO`` An I/O error occurred. Exactly what depends on the
function.
------------------- -------------------------------------------------------
``ResCOMMIT_LIMIT`` The arena's commit limit would have been exceeded
as a result of allocation.
------------------- -------------------------------------------------------
``ResPARAM`` An invalid parameter was passed. Normally reserved for
parameters passed from the client.
=================== =======================================================
.. _design.mps.buffer: buffer
_`.res.use`: ``Res`` should be returned from any function which might
fail. Any other results of the function should be passed back in
"return" parameters (pointers to locations to fill in with the
results).
======================== ==============================================
Mode Description
======================== ==============================================
``BufferModeATTACHED`` Buffer is attached to a region of memory.
``BufferModeFLIPPED`` Buffer has been flipped.
``BufferModeLOGGED`` Buffer emits the events ``BufferReserve`` and
``BufferCommit``.
``BufferModeTRANSITION`` Buffer is in the process of being detached.
======================== ==============================================
.. note:: This is documented elsewhere, I think -- richard
_`.res.use.spec`: The most specific code should be returned.
``typedef unsigned char Byte``
_`.byte`: ``Byte`` is an unsigned integral type corresponding to the
unit in which most sizes are measured, and also the units of
``sizeof``.
_`.byte.use`: ``Byte`` should be used in preference to ``char`` or
``unsigned char`` wherever it is necessary to deal with bytes
directly.
_`.byte.source`: ``Byte`` is a just pedagogic version of ``unsigned
char``, since ``char`` is the unit of ``sizeof``.
``typedef Word Clock``
_`.clock`: ``Clock`` is an unsigned integral type representing clock
time since some epoch.
_`.clock.use`: A ``Clock`` value is returned by the plinth function
``mps_clock``. It is used to make collection scheduling decisions and
to calibrate the time stamps on events in the telemetry stream.
_`.clock.units`: The plinth function ``mps_clocks_per_sec`` defines
the units of a ``Clock`` value.
_`.clock.conv.c`: ``Clock`` is converted to ``mps_clock_t`` in the MPS
C Interface.
``typedef unsigned Compare``
_`.compare`: ``Compare`` is the type of tri-state comparison
values.
================== ====================================================
Value Description
================== ====================================================
``CompareLESS`` A value compares less than another value.
``CompareEQUAL`` Two values compare the same.
``CompareGREATER`` A value compares greater than another value.
================== ====================================================
``typedef Word Count``
_`.count`: ``Count`` is an unsigned integral type which is large
enough to hold the size of any collection of objects in the MPS.
_`.count.use`: ``Count`` should be used for a number of objects
(control or managed) where the maximum number of objects cannot be
statically determined. If the maximum number can be statically
determined then the smallest unsigned integer with a large enough
range may be used instead (although ``Count`` may be preferable for
clarity).
_`.count.use.other`: ``Count`` may also be used to count things that
aren't represented by objects (for example, levels), but only where it
can be determined that the maximum count is less than the number of
objects.
``typedef Size Epoch``
_`.epoch`: An ``Epoch`` is a count of the number of flips that have
occurred. It is used in the implementation of location dependencies.
``Epoch`` is converted to ``mps_word_t`` in the MPS C Interface, as a
field of ``mps_ld_s``.
``typedef unsigned FindDelete``
_`.finddelete`: ``FindDelete`` represents an instruction to one of the
*find* methods of a ``Land`` as to what it should do if it finds a
suitable block. See design.mps.land_. It takes one of the following
values:
.. _design.mps.land: land
==================== ==================================================
Value Description
==================== ==================================================
``FindDeleteNONE`` Don't delete after finding.
``FindDeleteLOW`` Delete from low end of block.
``FindDeleteHIGH`` Delete from high end of block.
``FindDeleteENTIRE`` Delete entire block.
==================== ==================================================
``typedef unsigned FrameState``
_`.framestate`: ``FrameState`` represents the current state in a
buffer frame's lifecycle. See design.mps.alloc-frame_. It takes one of
the following values:
.. _design.mps.alloc-frame: alloc-frame
========================== ============================================
State Description
========================== ============================================
``BufferFrameVALID`` Indicates that ``PushFrame()`` can be a
lightweight operation and need not be
synchronized.
``BufferFramePOP_PENDING`` Indicates that there has been a
``PopFrame()`` operation that the pool
must respond to.
``BufferFrameDISABLED`` Indicates that the pool has disabled
support for lightweight operations for
this buffer.
========================== ============================================
``typedef void (*Fun)(void)``
@ -142,6 +295,328 @@ through to a third function ``h``, where ``h`` knows the real type of
``f`` but ``g`` doesn't.
``typedef Word Index``
_`.index`: ``Index`` is an unsigned integral type which is large
enough to hold any array index.
_`.index.use`: ``Index`` should be used where the maximum size of the
array cannot be statically determined. If the maximum size can be
determined then the smallest unsigned integer with a large enough
range may be used instead.
``typedef unsigned MessageType``
_`.messagetype`: ``MessageType`` is the type of a message. See
design.mps.message_. It takes one of the following values:
.. _design.mps.message: message
=========================== ===========================================
Message type Description
=========================== ===========================================
``MessageTypeFINALIZATION`` A block is finalizable.
``MessageTypeGC`` A garbage collection finished.
``MessageTypeGCSTART`` A garbage collection started.
=========================== ===========================================
``typedef unsigned Rank``
_`.rank`: ``Rank`` is an enumeration which represents the rank of a
reference. The ranks are:
============= ===== ==================================================
Rank Index Description
============= ===== ==================================================
``RankAMBIG`` 0 The reference is ambiguous. That is, it must be
assumed to be a reference, but not updated in
case it isn't.
``RankEXACT`` 1 The reference is exact, and refers to an object.
``RankFINAL`` 2 The reference is exact and final, so special
action is required if only final or weak
references remain to the object.
``RankWEAK`` 3 The reference is exact and weak, so should
be deleted if only weak references remain to the
object.
============= ===== ==================================================
``Rank`` is stored with segments and roots, and passed around.
``Rank`` is converted to ``mps_rank_t`` in the MPS C Interface.
The ordering of the ranks is important. It is the order in which the
references must be scanned in order to respect the properties of
references of the ranks. Therefore they are declared explicitly with
their integer values.
.. note:: Could ``Rank`` be a ``short``?
.. note::
This documentation should be expanded and moved to its own
document, then referenced from the implementation more thoroughly.
``typedef unsigned RankSet``
_`.rankset`: ``RankSet`` is a set of ranks, represented as a bitset.
``typedef Addr Ref``
_`.ref`: ``Ref`` is a reference to a managed object (as opposed to any
old managed address). ``Ref`` should be used where a reference is
intended.
.. note:: This isn't too clear -- richard
``typedef Word RefSet``
_`.refset`: ``RefSet`` is a conservative approximation to a set of
references. See design.mps.refset_.
.. _design.mps.refset: refset
``typedef int Res``
_`.res`: ``Res`` is the type of result codes. A result code indicates
the success or failure of an operation, along with the reason for
failure. Like Unix error codes, the meaning of the code depends on the
call that returned it. These codes are just broad categories with
mnemonic names for various sorts of problems.
=================== ===================================================
Result code Description
=================== ===================================================
``ResOK`` The operation succeeded. Return parameters may only
be updated if OK is returned, otherwise they must
be left untouched.
``ResCOMMIT_LIMIT`` The arena's commit limit would have been exceeded
as a result of allocation.
``ResFAIL`` Something went wrong which doesn't fall into any of
the other categories. The exact meaning depends
on the call. See documentation.
``ResIO`` An I/O error occurred. Exactly what depends on the
function.
``ResLIMIT`` An internal limitation was reached. For example,
the maximum number of somethings was reached. We
should avoid returning this by not including
static limitations in our code, as far as
possible. (See rule.impl.constrain and
rule.impl.limits.)
``ResMEMORY`` Needed memory (committed memory, not address space)
could not be obtained.
``ResPARAM`` An invalid parameter was passed. Normally reserved
for parameters passed from the client.
``ResRESOURCE`` A needed resource could not be obtained. Which
resource depends on the call. See also
``ResMEMORY``, which is a special case of this.
``ResUNIMPL`` The operation, or some vital part of it, is
unimplemented. This might be returned by
functions which are no longer supported, or by
operations which are included for future
expansion, but not yet supported.
=================== ===================================================
_`.res.use`: ``Res`` should be returned from any function which might
fail. Any other results of the function should be passed back in
"return" parameters (pointers to locations to fill in with the
results).
.. note:: This is documented elsewhere, I think -- richard
_`.res.use.spec`: The most specific code should be returned.
``typedef unsigned RootMode``
_`.rootmode`: ``RootMode`` is an unsigned integral type which is used
to represent an attribute of a root:
============================= =========================================
Root mode Description
============================= =========================================
``RootModeCONSTANT`` Client program will not change the root
after it is registered.
``RootModePROTECTABLE`` Root is protectable: the MPS may place
a barrier on any page containing any
part of the root.
``RootModePROTECTABLE_INNER`` Root is protectable: the MPS may place
a barrier on any page completely covered
by part of the root.
============================= =========================================
_`.rootmode.const.unused`: ``RootModeCONSTANT`` has no effect. This
mode was introduced in the hope of being able to maintain a
:term:`remembered set` for the root without needing a :term:`write
barrier`, but it can't work as described, since you can't reliably
create a valid registered constant root that contains any references.
(If you add the references before registering the root, they may have
become invalid; but you can't add them afterwards because the root is
supposed to be constant.)
_`.rootmode.conv.c`: ``RootMode`` is converted to ``mps_rm_t`` in the MPS C
Interface.
``typedef int RootVar``
_`.rootvar`: The type ``RootVar`` is the type of the
discriminator for the union within ``RootStruct``.
``typedef int SegPrefKind``
_`.segprefkind`: The type ``SegPrefKind`` expresses a preference about
where the arena should place a segment. It takes one of the following
values:
================== ====================================================
Kind Description
================== ====================================================
``SegPrefHigh`` Place the segment high in the address space.
``SegPrefLow`` Place the segment low in the address space.
``SegPrefZoneSet`` Place the segment in specified zones.
================== ====================================================
``typedef unsigned Serial``
_`.serial`: A ``Serial`` is a number which is assigned to a structure
when it is initialized. The serial number is taken from a field in the
parent structure, which is incremented. Thus, every instance of a
structure has a unique "name" which is a path of structures from the
global root. For example::
space[3].pool[5].buffer[2]
Why? Consistency checking, debugging, and logging. Not well thought
out.
``typedef unsigned Shift``
_`.shift`: ``Shift`` is an unsigned integral type which can hold the
amount by which a ``Word`` can be shifted. It is therefore large
enough to hold the word width (in bits).
_`.shift.use`: ``Shift`` should be used whenever a shift value (the
right-hand operand of the ``<<`` or ``>>`` operators) is intended, to
make the code clear. It should also be used for structure fields which
have this use.
``typedef unsigned long Sig``
_`.sig`: ``Sig`` is the type of signatures, which are written into
structures when they are created, and invalidated when they are
destroyed. They provide a limited form of run-time type checking and
dynamic scope checking. See design.mps.sig_.
.. _design.mps.sig: sig
``typedef Word Size``
_`.size`: ``Size`` is an unsigned integral type large enough to
hold the size of any object which the MPS might manage.
_`.size.byte`: ``Size`` should hold a size calculated in bytes.
.. warning::
This is violated by ``GenParams.capacity`` (which is measured in
kilobytes).
_`.size.use`: ``Size`` should be used whenever the code needs to deal
with the size of managed memory or client objects. It should not be
used for the sizes of the memory manager's own data structures, so
that the memory manager is amenable to working in a separate address
space. Be careful not to confuse it with ``size_t``.
_`.size.ops`: ``SizeIsAligned()``, ``SizeAlignUp()``,
``SizeAlignDown()`` and ``SizeRoundUp()``.
_`.size.conv.c`: ``Size`` is converted to ``size_t`` in the MPS C
Interface. This constrains the memory manager to the same address
space as the client data.
``typedef unsigned TraceId``
_`.traceid`: A ``TraceId`` is an unsigned integer which is less than
``TRACE_MAX``. Each running trace has a different ``TraceId`` which is
used to index into tables and bitfields used to remember the state of
that trace.
``typedef unsigned TraceSet``
_`.traceset`: A ``TraceSet`` is a bitset of ``TraceId``,
represented in the obvious way::
member(ti, ts) ⇔ ((1<<ti) & ts) != 0
``TraceSet`` is used to represent colour in the Tracer. See
design.mps.trace_.
.. _design.mps.trace: trace
``typedef unsigned TraceStartWhy``
_`.tracestartwhy`: ``TraceStartWhy`` represents the reason that a
trace was started. It takes one of the following values:
======================================= ===============================
Reason Description
======================================= ===============================
``TraceStartWhyCHAIN_GEN0CAP`` Generation zero of a chain
reached capacity.
``TraceStartWhyDYNAMICCRITERION`` Need to start full collection
now, or there won't be enough
memory to complete it.
``TraceStartWhyOPPORTUNISM`` Client had idle time available.
``TraceStartWhyCLIENTFULL_INCREMENTAL`` Client requested incremental
collection.
``TraceStartWhyCLIENTFULL_BLOCK`` Client requested full
collection.
``TraceStartWhyWALK`` Walking references.
``TraceStartWhyEXTENSION`` Request by MPS extension.
======================================= ===============================
``typedef unsigned TraceState``
_`.tracestate`: ``TraceState`` represents the current state in a
trace's lifecycle. See design.mps.trace_. It takes one of the
following values:
================== ====================================================
State Description
================== ====================================================
``TraceINIT`` Nothing happened yet.
``TraceUNFLIPPED`` Segments condemned (made white); initial grey set
created; scanning rate calculated.
``TraceFLIPPED`` Buffers flipped; roots scanned; location
dependencies made stale; grey segments protected.
``TraceRECLAIM`` There are no outstanding grey segments.
``TraceFINISHED`` All segments reclaimed.
================== ====================================================
``typedef MPS_T_ULONGEST ULongest``
_`.ulongest`: ``ULongest`` is the longest unsigned integer on the
platform. (We used to use ``unsigned long`` but this assumption is
violated by 64-bit Windows.) This type should be used for calculations
where any integer might be passed. Notably, it is used in ``WriteF()``
to print any integer.
``typedef MPS_T_WORD Word``
_`.word`: ``Word`` is an unsigned integral type which matches the size
@ -162,348 +637,10 @@ _`.word.ops`: ``WordIsAligned()``, ``WordAlignUp()``,
``WordAlignDown()`` and ``WordRoundUp()``.
``typedef unsigned char Byte``
``typedef Word ZoneSet``
_`.byte`: ``Byte`` is an unsigned integral type corresponding to the
unit in which most sizes are measured, and also the units of
``sizeof``.
_`.byte.use`: ``Byte`` should be used in preference to ``char`` or
``unsigned char`` wherever it is necessary to deal with bytes
directly.
_`.byte.source`: ``Byte`` is a just pedagogic version of ``unsigned
char``, since ``char`` is the unit of ``sizeof``.
``typedef Word Index``
_`.index`: ``Index`` is an unsigned integral type which is large
enough to hold any array index.
_`.index.use`: ``Index`` should be used where the maximum size of the
array cannot be statically determined. If the maximum size can be
determined then the smallest unsigned integer with a large enough
range may be used instead.
``typedef Word Count``
_`.count`: ``Count`` is an unsigned integral type which is large
enough to hold the size of any collection of objects in the MPS.
_`.count.use`: ``Count`` should be used for a number of objects
(control or managed) where the maximum number of objects cannot be
statically determined. If the maximum number can be statically
determined then the smallest unsigned integer with a large enough
range may be used instead (although ``Count`` may be preferable for
clarity).
.. note::
Should ``Count`` be used to count things that aren't represented
by objects (for example, a level)? I would say yes. gavinm
1998-07-21
.. note::
Only where it can be determined that the maximum count is less
than the number of objects. pekka 1998-07-21
``typedef Word Accumulation``
_`.accumulation`: ``Accumulation`` is an arithmetic type which is
large enough to hold accumulated totals of objects of bytes (for
example, total number of objects allocated, total number of bytes
allocated).
_`.accumulation.type`: Currently it is ``double``, but the reason for
the interface is so that we can more easily change it if we want to
(if we decide we need more accuracy for example).
_`.accumulation.use`: Currently the only way to use an
``Accumulation`` is to reset it (by calling ``AccumulatorReset``) and
accumulate amounts into it (by calling ``Accumulate``). There is no
way to read it at the moment, but that's okay, because no one seems to
want to.
_`.accumulation.future`: Probably we should have methods which return
the accumulation into an ``unsigned long``, and also a ``double``;
these functions should return ``Bool`` to indicate whether the
accumulation can fit in the requested type. Possibly we could have
functions which returned scaled accumulations. For example,
``AccumulatorScale(a, d)`` would divide the ``Accumulation a`` by
``double d`` and return the ``double`` result if it fitted into a
``double``.
``typedef struct AddrStruct *Addr``
_`.addr`: ``Addr`` is the type used for "managed addresses", that is,
addresses of objects managed by the MPS.
_`.addr.def`: ``Addr`` is defined as ``struct AddrStruct *``, but
``AddrStruct`` is never defined. This means that ``Addr`` is always an
incomplete type, which prevents accidental dereferencing, arithmetic,
or assignment to other pointer types.
_`.addr.use`: ``Addr`` should be used whenever the code needs to deal
with addresses. It should not be used for the addresses of memory
manager data structures themselves, so that the memory manager remains
amenable to working in a separate address space. Be careful not to
confuse ``Addr`` with ``void *``.
_`.addr.ops`: Limited arithmetic is allowed on addresses using
``AddrAdd()`` and ``AddrOffset()`` (impl.c.mpm). Addresses may also be
compared using the relational operators ``==``, ``!=``, ``<``, ``<=``,
``>``, and ``>=``.
_`.addr.ops.mem`: We need efficient operators similar to ``memset()``,
``memcpy()``, and ``memcmp()`` on ``Addr``; these are called ``AddrSet()``,
``AddrCopy()``, and ``AddrComp()``. When ``Addr`` is compatible with
``void *``, these are implemented through the functions
``mps_lib_memset()``, ``mps_lib_memcpy()``, and ``mps_lib_memcmp()``
functions in the plinth (impl.h.mpm).
.. note::
No other implementation exists at present. pekka 1998-09-07
_`.addr.conv.c`: ``Addr`` is converted to ``mps_addr_t`` in the MPS C
Interface. ``mps_addr_t`` is defined to be the same as ``void *``, so
using the MPS C Interface confines the memory manager to the same
address space as the client data.
``typedef Word Size``
_`.size`: ``Size`` is an unsigned integral type large enough to
hold the size of any object which the MPS might manage.
_`.size.byte`: ``Size`` should hold a size calculated in bytes.
.. warning:: This may not be true for all existing code.
_`.size.use`: ``Size`` should be used whenever the code needs to deal
with the size of managed memory or client objects. It should not be
used for the sizes of the memory manager's own data structures, so
that the memory manager is amenable to working in a separate address
space. Be careful not to confuse it with ``size_t``.
_`.size.ops`: ``SizeIsAligned()``, ``SizeAlignUp()``,
``SizeAlignDown()`` and ``SizeRoundUp()``.
_`.size.conv.c`: ``Size`` is converted to ``size_t`` in the MPS C
Interface. This constrains the memory manager to the same address
space as the client data.
``typedef Word Align``
_`.align`: ``Align`` is an unsigned integral type which is used to
represent the alignment of managed addresses. All alignments are
positive powers of two. ``Align`` is large enough to hold the maximum
possible alignment.
_`.align.use`: ``Align`` should be used whenever the code needs to
deal with the alignment of a managed address.
_`.align.conv.c`: ``Align`` is converted to ``mps_align_t`` in the MPS
C Interface.
``typedef unsigned Shift``
_`.shift`: ``Shift`` is an unsigned integral type which can hold the
amount by which a ``Word`` can be shifted. It is therefore large
enough to hold the word width (in bits).
_`.shift.use`: ``Shift`` should be used whenever a shift value (the
right-hand operand of the ``<<`` or ``>>`` operators) is intended, to
make the code clear. It should also be used for structure fields which
have this use.
_`.shift.conv.c`: ``Shift`` is converted to ``mps_shift_t`` in the MPS
C Interface.
``typedef Addr Ref``
_`.ref`: ``Ref`` is a reference to a managed object (as opposed to any
old managed address). ``Ref`` should be used where a reference is
intended.
.. note:: This isn't too clear -- richard
``typedef Word RefSet``
_`.refset`: ``RefSet`` is a conservative approximation to a set of
references. See design.mps.refset.
``typedef unsigned Rank``
_`.rank`: ``Rank`` is an enumeration which represents the rank of a
reference. The ranks are:
============= ===== =====================================================
Rank Index Description
============= ===== =====================================================
``RankAMBIG`` 0 The reference is ambiguous. That is, it must be
assumed to be a reference, but not updated in case it
isn't.
------------- ----- -----------------------------------------------------
``RankEXACT`` 1 The reference is exact, and refers to an object.
------------- ----- -----------------------------------------------------
``RankFINAL`` 2 The reference is exact and final, so special action
is required if only final or weak references remain
to the object.
------------- ----- -----------------------------------------------------
``RankWEAK`` 3 The reference is exact and weak, so should be deleted
if only weak references remain to the object.
============= ===== =====================================================
``Rank`` is stored with segments and roots, and passed around.
``Rank`` is converted to ``mps_rank_t`` in the MPS C Interface.
The ordering of the ranks is important. It is the order in which the
references must be scanned in order to respect the properties of
references of the ranks. Therefore they are declared explicitly with
their integer values.
.. note:: Could ``Rank`` be a ``short``?
.. note::
This documentation should be expanded and moved to its own
document, then referenced from the implementation more thoroughly.
``typedef Size Epoch``
_`.epoch`: An ``Epoch`` is a count of the number of flips that have
occurred. It is used in the implementation of location dependencies.
``Epoch`` is converted to ``mps_word_t`` in the MPS C Interface, as a
field of ``mps_ld_s``.
``typedef unsigned TraceId``
_`.traceid`: A ``TraceId`` is an unsigned integer which is less than
``TRACE_MAX``. Each running trace has a different ``TraceId`` which is
used to index into tables and bitfields used to remember the state of
that trace.
``typedef unsigned TraceSet``
_`.traceset`: A ``TraceSet`` is a bitset of ``TraceId``,
represented in the obvious way::
member(ti, ts) ⇔ ((1<<ti) & ts) != 0
``TraceSet`` is used to represent colour in the Tracer.
.. note:: Expand on this.
``typedef unsigned AccessSet``
_`.access-set`: An ``AccessSet`` is a bitset of ``Access``
modes, which are ``AccessREAD`` and ``AccessWRITE``. ``AccessNONE`` is
the empty ``AccessSet``.
``typedef unsigned Attr``
_`.attr`: Pool attributes. A bitset of pool or pool class
attributes, which are:
=================== ===========================================================
Attribute Description
=================== ===========================================================
``AttrFMT`` Contains formatted objects.
------------------- -----------------------------------------------------------
``AttrSCAN`` Contains references and must be scanned.
------------------- -----------------------------------------------------------
``AttrPM_NO_READ`` May not be read protected.
------------------- -----------------------------------------------------------
``AttrPM_NO_WRITE`` May not be write protected.
------------------- -----------------------------------------------------------
``AttrALLOC`` Supports the ``PoolAlloc`` interface.
------------------- -----------------------------------------------------------
``AttrFREE`` Supports the ``PoolFree`` interface.
------------------- -----------------------------------------------------------
``AttrBUF`` Supports the allocation buffer interface.
------------------- -----------------------------------------------------------
``AttrBUF_RESERVE`` Supports the reserve/commit protocol on allocation buffers.
------------------- -----------------------------------------------------------
``AttrBUF_ALLOC`` Supports the alloc protocol on allocation buffers.
------------------- -----------------------------------------------------------
``AttrGC`` Is garbage collecting, that is, parts may be reclaimed.
------------------- -----------------------------------------------------------
``AttrINCR_RB`` Is incremental, requiring a read barrier.
------------------- -----------------------------------------------------------
``AttrINCR_WB`` Is incremental, requiring a write barrier.
=================== ===========================================================
There is an attribute field in the pool class (``PoolClassStruct``)
which declares the attributes of that class. These attributes are only
used for consistency checking at the moment.
.. note::
It's no longer true that they are only used for consistency
checking -- drj 1998-05-07
``typedef int RootVar``
_`.rootvar`: The type ``RootVar`` is the type of the
discriminator for the union within ``RootStruct``.
``typedef unsigned Serial``
_`.serial`: A ``Serial`` is a number which is assigned to a structure
when it is initialized. The serial number is taken from a field in the
parent structure, which is incremented. Thus, every instance of a
structure has a unique "name" which is a path of structures from the
global root. For example::
space[3].pool[5].buffer[2]
Why? Consistency checking, debugging, and logging. Not well thought
out.
``typedef unsigned Compare``
_`.compare`: ``Compare`` is the type of tri-state comparison
values.
================== ===========================================
Value Description
================== ===========================================
``CompareLESS`` A value compares less than another value.
------------------ -------------------------------------------
``CompareEQUAL`` Two values compare the same.
------------------ -------------------------------------------
``CompareGREATER`` A value compares greater than another value.
================== ===========================================
``typedef MPS_T_ULONGEST ULongest``
_`.ulongest`: ``ULongest`` is the longest unsigned integer on the
platform. (We used to use ``unsigned long`` but this assumption is
violated by 64-bit Windows.) This type should be used for calculations
where any integer might be passed. Notably, it is used in ``WriteF()``
to print any integer.
_`.zoneset`: ``ZoneSet`` is a conservative approximation to a set of
zone. See design.mps.refset_.
Abstract types
@ -513,7 +650,12 @@ _`.adts`: The following types are abstract data types, implemented as
pointers to structures. For example, ``Ring`` is a pointer to a
``RingStruct``. They are described elsewhere.
``AP``, ``Arena``, ``Buffer``, ``Format``, ``LD``, ``Lock``, ``PoolClass``, ``Pool``, ``Ring``, ``Root``, ``ScanState``, ``Seg``, ``Space``, ``Thread``, ``Trace``, ``VM``.
``AllocFrame``, ``AllocPattern``, ``AP``, ``Arena``, ``BootBlock``,
``Buffer``, ``Chain``, ``Chunk``, ``Format``, ``Globals``, ``Land``,
``LD``, ``Lock``, ``MutatorFaultContext``, ``PoolClass``, ``Page``,
``Pool``, ``PoolDebugMixin``, ``Range``, ``Reservoir``, ``Ring``,
``Root``, ``ScanState``, ``Seg``, ``SegBuf``, ``SegPref``,
``StackContext``, ``Thread``, ``Trace``, ``VM``.
``typedef void *Pointer``

View file

@ -13,8 +13,10 @@ Design
freelist
guide.hex.trans
guide.impl.c.format
interface-c
keyword-arguments
nailboard
range
ring
sig
type

View file

@ -25,7 +25,6 @@ Old design
diag
finalize
fix
interface-c
io
lib
lock
@ -62,7 +61,6 @@ Old design
thread-manager
thread-safety
trace
type
version-library
version
vm

View file

@ -905,6 +905,10 @@ changes size::
3. The order of operations at the end is important: the old root
must be de-registered before its memory is freed.
4. When calling :c:func:`mps_root_create_table`, take care to
avoid undefined behaviour due to :term:`type punning`. See the
:ref:`warning <topic-root-type-pun>`.
.. topics::
:ref:`topic-root`.

View file

@ -168,3 +168,86 @@ Other changes
exception while the MPS is holding the arena lock. See job003640_.
.. _job003640: https://www.ravenbrook.com/project/mps/issue/job003640/
.. _release-notes-1.111:
Release 1.111.0
---------------
New features
............
#. Reporting features have been removed from the :ref:`mpseventcnv
<telemetry-mpseventcnv>` utility. Instead, the telemetry system
comes with two new utility programs to assist with reporting and
analysis: :ref:`mpseventtxt <telemetry-mpseventtxt>` converts an
event stream into human-readable form, and :ref:`mpseventsql
<telemetry-mpseventsql>` loads an event stream into a SQLite
database for further analysis. See :ref:`topic-telemetry`.
#. The new pool class MFS provide manually managed allocation of
fixed-size objects. See :ref:`pool-mfs`.
#. The new pool class MVT provide manually managed allocation of
variable-size objects using a *temporal fit* allocation policy
(that is, objects that are allocated togther are expected to be
freed together). See :ref:`pool-mvt`.
Interface changes
.................
#. It is no longer necessary for client programs to use
:c:func:`mps_tramp` to ensure that exceptions due to barrier hits
are caught. This function is now deprecated.
#. You can set the environment variable
:envvar:`MPS_TELEMETRY_CONTROL` to ``all`` to make the telemetry
system output all events. See :ref:`topic-telemetry`.
#. New functions :c:func:`mps_telemetry_get`,
:c:func:`mps_telemetry_set` and :c:func:`mps_telemetry_reset`
provide a more convenient interface to telemetry control than
:c:func:`mps_telemetry_control`, which is now deprecated. See
:ref:`topic-telemetry`.
#. The pool classes :ref:`pool-mv` and :ref:`pool-snc` are now
deprecated.
#. Allocation frames are now deprecated. See :ref:`topic-frame`.
#. Additionally, the functions :c:func:`mps_arena_expose`,
:c:func:`mps_arena_unsafe_expose_remember_protection`,
:c:func:`mps_arena_unsafe_restore_protection`,
:c:func:`mps_arena_roots_walk`, and :c:func:`mps_fix` are now
deprecated.
Other changes
.............
#. :c:func:`mps_arena_step` no longer unclamps the arena as a side
effect. If the arena is clamped or parked before calling
:c:func:`mps_arena_step`, it is clamped afterwards. See job003320_.
.. _job003320: https://www.ravenbrook.com/project/mps/issue/job003320/
#. The ambiguous stack scanner, :c:func:`mps_stack_scan_ambig`, no
longer asserts on Linux when there are multiple threads. See
job003412_.
.. _job003412: https://www.ravenbrook.com/project/mps/issue/job003412/
#. It is no longer possible for the "ramp" allocation pattern,
:c:func:`mps_alloc_pattern_ramp()`, to get stuck. Now
:c:func:`mps_ap_alloc_pattern_end` reliably clears this pattern.
See job003454_.
.. _job003454: https://www.ravenbrook.com/project/mps/issue/job003454/
#. The build system now correctly detects the FreeBSD operating system
running on the x86-64 architecture, for FreeBSD version 9.1 or
later. See job003473_.
.. _job003473: https://www.ravenbrook.com/project/mps/issue/job003473/

View file

@ -157,7 +157,7 @@ Cautions
prompt release of scarce resources. For example, Scheme provides
the ``(with-input-from-file)`` procedure which specifies that the
created port has :term:`dynamic extent` (and so can be closed as
soon as the procedure exits).
soon as the procedure exits, even if it is still reachable).
#. The MPS does not finalize objects in the context of
:c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`.
@ -185,8 +185,8 @@ Cautions
described under :c:func:`mps_pool_destroy`, but the objects do
not get finalized.
The only reliable way to ensure that all finalizable object
gets finalized is to maintain a table of :term:`weak
The only reliable way to ensure that all finalizable objects
are finalized is to maintain a table of :term:`weak
references (1)` to all such objects. The weak references don't
prevent the objects from being finalized, but you can iterate
over the list at an appropriate point and finalize any

View file

@ -205,11 +205,11 @@ Instead, we recommend this approach::
struct foo *fp;
res = mps_alloc(&p, pool, sizeof(struct foo));
if(res) /* handle error case */;
fp = (struct foo *)p;
fp = p;
This is portable because conversion from ``void *`` to any other
:term:`object pointer` type is defined by :ref:`ISO/IEC 9899:1990
<ISO90>` §6.3.2.3.1.
This has defined behaviour because conversion from ``void *`` to any
other :term:`object pointer` type is defined by :ref:`ISO/IEC
9899:1990 <ISO90>` §6.3.2.3.1.
.. index::

View file

@ -271,7 +271,7 @@ allowing the MPS to detect whether they have changed.
The :term:`root mode` for :term:`protectable roots`. This tells
the MPS that it may place a :term:`barrier (1)` on any
:term:`page` which any part of the :term:`root` covers. No
:term:`page` containing any part of the :term:`root`. No
:term:`format method` or :term:`scan method` (except for the one
for this root) may write data in this root. They may read it.
@ -514,6 +514,28 @@ Root interface
The registered root description persists until it is destroyed by
calling :c:func:`mps_root_destroy`.
.. _topic-root-type-pun:
.. warning::
The ``base`` argument has type ``mps_addr_t *`` (a typedef for
``void **``) but the table of references most likely has some
other pointer type, ``my_object *`` say. It is tempting to
write::
mps_root_create_table(..., (mps_addr_t *)my_table, ...)
but this is :term:`type punning`, and its behaviour is not
defined in ANSI/ISO Standard C. (GCC and Clang have a warning
flag ``-Wstrict-aliasing`` which detects some errors of this
form.)
To ensure well-defined behaviour, the pointer must be
converted via ``void *`` (or via :c:type:`mps_addr_t`, which
is a typedef for ``void *``), like this::
mps_addr_t base = my_table;
mps_root_create_table(..., base, ...)
.. c:function:: mps_res_t mps_root_create_table_masked(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_addr_t *base, size_t count, mps_word_t mask)
@ -558,13 +580,17 @@ Root interface
mps_res_t res;
mps_root_t root;
mps_addr_t base = symtab;
res = mps_root_create_table_masked(&root, arena,
mps_rank_exact(),
(mps_rm_t)0,
symtab, symtab_size * 2,
base, symtab_size * 2,
(mps_word_t)TAG_MASK);
if (res != MPS_RES_OK) errror("can't create symtab root");
.. warning::
See the warning for :c:func:`mps_root_create_table` above.
.. c:function:: void mps_root_destroy(mps_root_t root)

View file

@ -56,7 +56,7 @@ region to be scanned. They must carry out the following steps:
a pointer to a location containing the reference.
#. If :c:func:`MPS_FIX2` returns a :term:`result code` other than
:c:func:`MPS_RES_OK`, return this result code from the scanning
:c:macro:`MPS_RES_OK`, return this result code from the scanning
function as soon as practicable.
#. If :c:func:`MPS_FIX2` returns :c:macro:`MPS_RES_OK`, it may have

View file

@ -169,6 +169,6 @@ int main(void)
stackpointer=&m; /* hack to get stack pointer */
easy_tramp(test);
report("result", "unknown");
pass();
return 0;
}

View file

@ -61,7 +61,7 @@ static void test(void)
for (j = 1; j < 100; j++) {
comment("%i of 100", j);
p = allocdumb(ap, sizeof(mps_ld_s));
p = allocdumb(ap, sizeof(mycell));
ld = (mps_ld_t) getdata(p);
b = a;

View file

@ -7,7 +7,7 @@ function/1.c
% function/3.c -- interactive test, can't run unattended
% function/4.c -- interactive test, can't run unattended
function/5.c
% function/6.c -- job003494
function/6.c
function/7.c
% function/8.c -- tries to exhaust memory by mps_arena_create
function/9.c
@ -48,12 +48,12 @@ function/42.c
function/43.c
function/44.c
function/45.c
% function/46.c -- report("result", "unknown"); @@@@
function/46.c
function/47.c
function/48.c
function/49.c
function/50.c
% function/51.c -- would pass if we allowed iter = 4 @@@@
% function/51.c -- job003739
function/52.c
function/53.c
function/55.c