*/
ReservoirSetLimit(ArenaReservoir(arena), 0);
- arena->poolReady = FALSE;
ControlFinish(arena);
- /* We must tear down the freeLand before the chunks, because pages
- containing CBS blocks might be allocated in those chunks. */
- AVER(arena->hasFreeLand);
- arena->hasFreeLand = FALSE;
- LandFinish(ArenaFreeLand(arena));
-
- /* The CBS block pool can't free its own memory via ArenaFree because
- that would use the freeLand. */
- MFSFinishTracts(ArenaCBSBlockPool(arena), arenaMFSPageFreeVisitor,
- UNUSED_POINTER, UNUSED_SIZE);
+ /* We must tear down the free land before the chunks, because pages
+ * containing CBS blocks might be allocated in those chunks. */
+ arenaFreeLandFinish(arena);
/* Call class-specific finishing. This will call ArenaFinish. */
(*arena->class->finish)(arena);
@@ -427,6 +455,7 @@ Res ControlInit(Arena arena)
Res res;
AVERT(Arena, arena);
+ AVER(!arena->poolReady);
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, CONTROL_EXTEND_BY);
res = PoolInit(MVPool(&arena->controlPoolStruct), arena,
@@ -444,6 +473,7 @@ Res ControlInit(Arena arena)
void ControlFinish(Arena arena)
{
AVERT(Arena, arena);
+ AVER(arena->poolReady);
arena->poolReady = FALSE;
PoolFinish(MVPool(&arena->controlPoolStruct));
}
@@ -454,7 +484,6 @@ void ControlFinish(Arena arena)
Res ArenaDescribe(Arena arena, mps_lib_FILE *stream, Count depth)
{
Res res;
- Size reserved;
if (!TESTT(Arena, arena))
return ResFAIL;
@@ -476,20 +505,9 @@ Res ArenaDescribe(Arena arena, mps_lib_FILE *stream, Count depth)
return res;
}
- /* Note: this Describe clause calls a function */
- reserved = ArenaReserved(arena);
res = WriteF(stream, depth + 2,
- "reserved $W <-- "
- "total size of address-space reserved\n",
- (WriteFW)reserved,
- NULL);
- if (res != ResOK)
- return res;
-
- res = WriteF(stream, depth + 2,
- "committed $W <-- "
- "total bytes currently stored (in RAM or swap)\n",
- (WriteFW)arena->committed,
+ "reserved $W\n", (WriteFW)arena->reserved,
+ "committed $W\n", (WriteFW)arena->committed,
"commitLimit $W\n", (WriteFW)arena->commitLimit,
"spareCommitted $W\n", (WriteFW)arena->spareCommitted,
"spareCommitLimit $W\n", (WriteFW)arena->spareCommitLimit,
@@ -669,7 +687,10 @@ Res ControlDescribe(Arena arena, mps_lib_FILE *stream, Count depth)
}
-/* ArenaChunkInsert -- insert chunk into arena's chunk tree and ring */
+/* ArenaChunkInsert -- insert chunk into arena's chunk tree and ring,
+ * update the total reserved address space, and set the primary chunk
+ * if not already set.
+ */
void ArenaChunkInsert(Arena arena, Chunk chunk) {
Bool inserted;
@@ -687,6 +708,8 @@ void ArenaChunkInsert(Arena arena, Chunk chunk) {
arena->chunkTree = updatedTree;
RingAppend(&arena->chunkRing, &chunk->arenaRing);
+ arena->reserved += ChunkReserved(chunk);
+
/* As part of the bootstrap, the first created chunk becomes the primary
chunk. This step allows ArenaFreeLandInsert to allocate pages. */
if (arena->primary == NULL)
@@ -694,6 +717,31 @@ void ArenaChunkInsert(Arena arena, Chunk chunk) {
}
+/* ArenaChunkRemoved -- chunk was removed from the arena and is being
+ * finished, so update the total reserved address space, and unset the
+ * primary chunk if necessary.
+ */
+
+void ArenaChunkRemoved(Arena arena, Chunk chunk)
+{
+ Size size;
+
+ AVERT(Arena, arena);
+ AVERT(Chunk, chunk);
+
+ size = ChunkReserved(chunk);
+ AVER(arena->reserved >= size);
+ arena->reserved -= size;
+
+ if (chunk == arena->primary) {
+ /* The primary chunk must be the last chunk to be removed. */
+ AVER(RingIsSingle(&arena->chunkRing));
+ AVER(arena->reserved == 0);
+ arena->primary = NULL;
+ }
+}
+
+
/* arenaAllocPage -- allocate one page from the arena
*
* This is a primitive allocator used to allocate pages for the arena
@@ -781,7 +829,7 @@ static Res arenaExtendCBSBlockPool(Range pageRangeReturn, Arena arena)
return res;
MFSExtend(ArenaCBSBlockPool(arena), pageBase, ArenaGrainSize(arena));
- RangeInit(pageRangeReturn, pageBase, AddrAdd(pageBase, ArenaGrainSize(arena)));
+ RangeInitSize(pageRangeReturn, pageBase, ArenaGrainSize(arena));
return ResOK;
}
@@ -801,15 +849,19 @@ static void arenaExcludePage(Arena arena, Range pageRange)
}
-/* arenaLandInsert -- add range to arena's land, maybe extending block pool
+/* arenaFreeLandInsertExtend -- add range to arena's free land, maybe
+ * extending block pool
*
- * The arena's land can't get memory in the usual way because it is
- * used in the basic allocator, so we allocate pages specially.
+ * The arena's free land can't get memory for its block pool in the
+ * usual way (via ArenaAlloc), because it is the mechanism behind
+ * ArenaAlloc! So we extend the block pool via a back door (see
+ * arenaExtendCBSBlockPool).
*
* Only fails if it can't get a page for the block pool.
*/
-static Res arenaLandInsert(Range rangeReturn, Arena arena, Range range)
+static Res arenaFreeLandInsertExtend(Range rangeReturn, Arena arena,
+ Range range)
{
Res res;
@@ -835,16 +887,18 @@ static Res arenaLandInsert(Range rangeReturn, Arena arena, Range range)
}
-/* ArenaFreeLandInsert -- add range to arena's land, maybe stealing memory
+/* arenaFreeLandInsertSteal -- add range to arena's free land, maybe
+ * stealing memory
*
- * See arenaLandInsert. This function may only be applied to mapped
- * pages and may steal them to store Land nodes if it's unable to
- * allocate space for CBS blocks.
+ * See arenaFreeLandInsertExtend. This function may only be applied to
+ * mapped pages and may steal them to store Land nodes if it's unable
+ * to allocate space for CBS blocks.
*
* IMPORTANT: May update rangeIO.
*/
-static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO)
+static void arenaFreeLandInsertSteal(Range rangeReturn, Arena arena,
+ Range rangeIO)
{
Res res;
@@ -852,7 +906,7 @@ static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO)
AVERT(Arena, arena);
AVERT(Range, rangeIO);
- res = arenaLandInsert(rangeReturn, arena, rangeIO);
+ res = arenaFreeLandInsertExtend(rangeReturn, arena, rangeIO);
if (res != ResOK) {
Addr pageBase;
@@ -881,7 +935,8 @@ static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO)
}
-/* ArenaFreeLandInsert -- add range to arena's land, maybe extending block pool
+/* ArenaFreeLandInsert -- add range to arena's free land, maybe extending
+ * block pool
*
* The inserted block of address space may not abut any existing block.
* This restriction ensures that we don't coalesce chunks and allocate
@@ -896,7 +951,7 @@ Res ArenaFreeLandInsert(Arena arena, Addr base, Addr limit)
AVERT(Arena, arena);
RangeInit(&range, base, limit);
- res = arenaLandInsert(&oldRange, arena, &range);
+ res = arenaFreeLandInsertExtend(&oldRange, arena, &range);
if (res != ResOK)
return res;
@@ -911,7 +966,8 @@ Res ArenaFreeLandInsert(Arena arena, Addr base, Addr limit)
}
-/* ArenaFreeLandDelete -- remove range from arena's land, maybe extending block pool
+/* ArenaFreeLandDelete -- remove range from arena's free land, maybe
+ * extending block pool
*
* This is called from ChunkFinish in order to remove address space from
* the arena.
@@ -1003,7 +1059,7 @@ static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high,
failMark:
{
- Res insertRes = arenaLandInsert(&oldRange, arena, &range);
+ Res insertRes = arenaFreeLandInsertExtend(&oldRange, arena, &range);
AVER(insertRes == ResOK); /* We only just deleted it. */
/* If the insert does fail, we lose some address space permanently. */
}
@@ -1215,7 +1271,7 @@ void ArenaFree(Addr base, Size size, Pool pool)
RangeInit(&range, base, limit);
- arenaLandInsertSteal(&oldRange, arena, &range); /* may update range */
+ arenaFreeLandInsertSteal(&oldRange, arena, &range); /* may update range */
(*arena->class->free)(RangeBase(&range), RangeSize(&range), pool);
@@ -1231,7 +1287,7 @@ void ArenaFree(Addr base, Size size, Pool pool)
Size ArenaReserved(Arena arena)
{
AVERT(Arena, arena);
- return (*arena->class->reserved)(arena);
+ return arena->reserved;
}
Size ArenaCommitted(Arena arena)
diff --git a/mps/code/arenacl.c b/mps/code/arenacl.c
index 857c4608e11..cd5c24fe46a 100644
--- a/mps/code/arenacl.c
+++ b/mps/code/arenacl.c
@@ -81,8 +81,15 @@ static Bool ClientChunkCheck(ClientChunk clChunk)
ATTRIBUTE_UNUSED
static Bool ClientArenaCheck(ClientArena clientArena)
{
+ Arena arena;
+
CHECKS(ClientArena, clientArena);
- CHECKD(Arena, ClientArena2Arena(clientArena));
+ arena = ClientArena2Arena(clientArena);
+ CHECKD(Arena, arena);
+ /* See */
+ CHECKL(arena->committed <= arena->reserved);
+ CHECKL(arena->spareCommitted == 0);
+
return TRUE;
}
@@ -125,12 +132,13 @@ static Res clientChunkCreate(Chunk *chunkReturn, ClientArena clientArena,
chunk = ClientChunk2Chunk(clChunk);
res = ChunkInit(chunk, arena, alignedBase,
- AddrAlignDown(limit, ArenaGrainSize(arena)), boot);
+ AddrAlignDown(limit, ArenaGrainSize(arena)),
+ AddrOffset(base, limit), boot);
if (res != ResOK)
goto failChunkInit;
- ClientArena2Arena(clientArena)->committed +=
- AddrOffset(base, PageIndexBase(chunk, chunk->allocBase));
+ arena->committed += ChunkPagesToSize(chunk, chunk->allocBase);
+
BootBlockFinish(boot);
clChunk->sig = ClientChunkSig;
@@ -176,8 +184,10 @@ static Res ClientChunkInit(Chunk chunk, BootBlock boot)
static Bool clientChunkDestroy(Tree tree, void *closureP, Size closureS)
{
+ Arena arena;
Chunk chunk;
ClientChunk clChunk;
+ Size size;
AVERT(Tree, tree);
AVER(closureP == UNUSED_POINTER);
@@ -187,8 +197,15 @@ static Bool clientChunkDestroy(Tree tree, void *closureP, Size closureS)
chunk = ChunkOfTree(tree);
AVERT(Chunk, chunk);
+ arena = ChunkArena(chunk);
+ AVERT(Arena, arena);
clChunk = Chunk2ClientChunk(chunk);
AVERT(ClientChunk, clChunk);
+ AVER(chunk->pages == clChunk->freePages);
+
+ size = ChunkPagesToSize(chunk, chunk->allocBase);
+ AVER(arena->committed >= size);
+ arena->committed -= size;
clChunk->sig = SigInvalid;
ChunkFinish(chunk);
@@ -257,7 +274,7 @@ static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
AVER(base != (Addr)0);
AVERT(ArenaGrainSize, grainSize);
- if (size < grainSize * MPS_WORD_SHIFT)
+ if (size < grainSize * MPS_WORD_WIDTH)
/* Not enough room for a full complement of zones. */
return ResMEMORY;
@@ -324,6 +341,10 @@ static void ClientArenaFinish(Arena arena)
clientArena->sig = SigInvalid;
+ /* Destroying the chunks should leave nothing behind. */
+ AVER(arena->reserved == 0);
+ AVER(arena->committed == 0);
+
ArenaFinish(arena); /* */
}
@@ -348,27 +369,6 @@ static Res ClientArenaExtend(Arena arena, Addr base, Size size)
}
-/* ClientArenaReserved -- return the amount of reserved address space */
-
-static Size ClientArenaReserved(Arena arena)
-{
- Size size;
- Ring node, nextNode;
-
- AVERT(Arena, arena);
-
- size = 0;
- /* .req.extend.slow */
- RING_FOR(node, &arena->chunkRing, nextNode) {
- Chunk chunk = RING_ELT(Chunk, arenaRing, node);
- AVERT(Chunk, chunk);
- size += ChunkSize(chunk);
- }
-
- return size;
-}
-
-
/* ClientArenaPagesMarkAllocated -- Mark the pages allocated */
static Res ClientArenaPagesMarkAllocated(Arena arena, Chunk chunk,
@@ -376,9 +376,12 @@ static Res ClientArenaPagesMarkAllocated(Arena arena, Chunk chunk,
Pool pool)
{
Index i;
+ ClientChunk clChunk;
AVERT(Arena, arena);
AVERT(Chunk, chunk);
+ clChunk = Chunk2ClientChunk(chunk);
+ AVERT(ClientChunk, clChunk);
AVER(chunk->allocBase <= baseIndex);
AVER(pages > 0);
AVER(baseIndex + pages <= chunk->pages);
@@ -387,15 +390,17 @@ static Res ClientArenaPagesMarkAllocated(Arena arena, Chunk chunk,
for (i = 0; i < pages; ++i)
PageAlloc(chunk, baseIndex + i, pool);
- Chunk2ClientChunk(chunk)->freePages -= pages;
+ arena->committed += ChunkPagesToSize(chunk, pages);
+ AVER(clChunk->freePages >= pages);
+ clChunk->freePages -= pages;
return ResOK;
}
-/* ClientFree - free a region in the arena */
+/* ClientArenaFree - free a region in the arena */
-static void ClientFree(Addr base, Size size, Pool pool)
+static void ClientArenaFree(Addr base, Size size, Pool pool)
{
Arena arena;
Chunk chunk = NULL; /* suppress "may be used uninitialized" */
@@ -436,6 +441,8 @@ static void ClientFree(Addr base, Size size, Pool pool)
AVER(BTIsSetRange(chunk->allocTable, baseIndex, limitIndex));
BTResRange(chunk->allocTable, baseIndex, limitIndex);
+ AVER(arena->committed >= size);
+ arena->committed -= size;
clChunk->freePages += pages;
}
@@ -451,10 +458,9 @@ DEFINE_ARENA_CLASS(ClientArenaClass, this)
this->varargs = ClientArenaVarargs;
this->init = ClientArenaInit;
this->finish = ClientArenaFinish;
- this->reserved = ClientArenaReserved;
this->extend = ClientArenaExtend;
this->pagesMarkAllocated = ClientArenaPagesMarkAllocated;
- this->free = ClientFree;
+ this->free = ClientArenaFree;
this->chunkInit = ClientChunkInit;
this->chunkFinish = ClientChunkFinish;
AVERT(ArenaClass, this);
diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c
index 54b7ef7ba25..ba34a7c70ef 100644
--- a/mps/code/arenavm.c
+++ b/mps/code/arenavm.c
@@ -323,7 +323,8 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size)
/* Copy VM descriptor into its place in the chunk. */
VMCopy(VMChunkVM(vmChunk), vm);
- res = ChunkInit(VMChunk2Chunk(vmChunk), arena, base, limit, boot);
+ res = ChunkInit(VMChunk2Chunk(vmChunk), arena, base, limit,
+ VMReserved(VMChunkVM(vmChunk)), boot);
if (res != ResOK)
goto failChunkInit;
@@ -560,6 +561,7 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
res = ArenaInit(arena, class, grainSize, args);
if (res != ResOK)
goto failArenaInit;
+ arena->reserved = VMReserved(vm);
arena->committed = VMMapped(vm);
/* Copy VM descriptor into its place in the arena. */
@@ -640,6 +642,7 @@ static void VMArenaFinish(Arena arena)
RingFinish(&vmArena->spareRing);
/* Destroying the chunks should leave only the arena's own VM. */
+ AVER(arena->reserved == VMReserved(VMArenaVM(vmArena)));
AVER(arena->committed == VMMapped(VMArenaVM(vmArena)));
vmArena->sig = SigInvalid;
@@ -654,25 +657,6 @@ static void VMArenaFinish(Arena arena)
}
-/* VMArenaReserved -- return the amount of reserved address space
- *
- * Add up the reserved space from all the chunks.
- */
-
-static Size VMArenaReserved(Arena arena)
-{
- Size reserved;
- Ring node, next;
-
- reserved = 0;
- RING_FOR(node, &arena->chunkRing, next) {
- VMChunk vmChunk = Chunk2VMChunk(RING_ELT(Chunk, arenaRing, node));
- reserved += VMReserved(VMChunkVM(vmChunk));
- }
- return reserved;
-}
-
-
/* vmArenaChunkSize -- choose chunk size for arena extension
*
* .vmchunk.overhead: This code still lacks a proper estimate of
@@ -723,7 +707,7 @@ static Res VMArenaGrow(Arena arena, LocusPref pref, Size size)
chunkSize = vmArenaChunkSize(vmArena, size);
EVENT3(vmArenaExtendStart, size, chunkSize,
- VMArenaReserved(VMArena2Arena(vmArena)));
+ ArenaReserved(VMArena2Arena(vmArena)));
/* .chunk-create.fail: If we fail, try again with a smaller size */
{
@@ -737,17 +721,17 @@ static Res VMArenaGrow(Arena arena, LocusPref pref, Size size)
if (chunkSize < chunkMin)
chunkSize = chunkMin;
+ res = ResRESOURCE;
for(;; chunkSize = chunkHalf) {
chunkHalf = chunkSize / 2;
sliceSize = chunkHalf / fidelity;
AVER(sliceSize > 0);
/* remove slices, down to chunkHalf but no further */
- res = ResRESOURCE;
for(; chunkSize > chunkHalf; chunkSize -= sliceSize) {
if(chunkSize < chunkMin) {
EVENT2(vmArenaExtendFail, chunkMin,
- VMArenaReserved(VMArena2Arena(vmArena)));
+ ArenaReserved(VMArena2Arena(vmArena)));
return res;
}
res = VMChunkCreate(&newChunk, vmArena, chunkSize);
@@ -758,7 +742,7 @@ static Res VMArenaGrow(Arena arena, LocusPref pref, Size size)
}
vmArenaGrow_Done:
- EVENT2(vmArenaExtendDone, chunkSize, VMArenaReserved(VMArena2Arena(vmArena)));
+ EVENT2(vmArenaExtendDone, chunkSize, ArenaReserved(VMArena2Arena(vmArena)));
vmArena->extended(VMArena2Arena(vmArena),
newChunk->base,
AddrOffset(newChunk->base, newChunk->limit));
@@ -806,16 +790,23 @@ static Res pageDescMap(VMChunk vmChunk, Index basePI, Index limitPI)
Size before = VMMapped(VMChunkVM(vmChunk));
Arena arena = VMArena2Arena(VMChunkVMArena(vmChunk));
Res res = SparseArrayMap(&vmChunk->pages, basePI, limitPI);
- arena->committed += VMMapped(VMChunkVM(vmChunk)) - before;
+ Size after = VMMapped(VMChunkVM(vmChunk));
+ AVER(before <= after);
+ arena->committed += after - before;
return res;
}
static void pageDescUnmap(VMChunk vmChunk, Index basePI, Index limitPI)
{
+ Size size, after;
Size before = VMMapped(VMChunkVM(vmChunk));
Arena arena = VMArena2Arena(VMChunkVMArena(vmChunk));
SparseArrayUnmap(&vmChunk->pages, basePI, limitPI);
- arena->committed += VMMapped(VMChunkVM(vmChunk)) - before;
+ after = VMMapped(VMChunkVM(vmChunk));
+ AVER(after <= before);
+ size = before - after;
+ AVER(arena->committed >= size);
+ arena->committed -= size;
}
@@ -1144,7 +1135,7 @@ static void VMCompact(Arena arena, Trace trace)
AVERT(VMArena, vmArena);
AVERT(Trace, trace);
- vmem1 = VMArenaReserved(arena);
+ vmem1 = ArenaReserved(arena);
/* Destroy chunks that are completely free, but not the primary
* chunk. See
@@ -1154,7 +1145,7 @@ static void VMCompact(Arena arena, Trace trace)
{
Size vmem0 = trace->preTraceArenaReserved;
- Size vmem2 = VMArenaReserved(arena);
+ Size vmem2 = ArenaReserved(arena);
/* VMCompact event: emit for all client-requested collections, */
/* plus any others where chunks were gained or lost during the */
@@ -1204,7 +1195,6 @@ DEFINE_ARENA_CLASS(VMArenaClass, this)
this->varargs = VMArenaVarargs;
this->init = VMArenaInit;
this->finish = VMArenaFinish;
- this->reserved = VMArenaReserved;
this->purgeSpare = VMPurgeSpare;
this->grow = VMArenaGrow;
this->free = VMFree;
diff --git a/mps/code/buffer.c b/mps/code/buffer.c
index 4c30ed3d8a7..edef611c217 100644
--- a/mps/code/buffer.c
+++ b/mps/code/buffer.c
@@ -19,10 +19,8 @@
*
* TRANSGRESSIONS
*
- * .trans.mod: There are several instances where pool structures are
- * directly accessed by this module because does not provide
- * an adequate (or adequately documented) interface. They bear this
- * tag.
+ * .trans.mod: pool->bufferSerial is directly accessed by this module
+ * because does not provide an interface.
*/
#include "mpm.h"
@@ -221,7 +219,7 @@ static Res BufferInit(Buffer buffer, BufferClass class,
}
buffer->fillSize = 0.0;
buffer->emptySize = 0.0;
- buffer->alignment = pool->alignment; /* .trans.mod */
+ buffer->alignment = PoolAlignment(pool);
buffer->base = (Addr)0;
buffer->initAtFlip = (Addr)0;
/* In the next three assignments we really mean zero, not NULL, because
diff --git a/mps/code/cbs.c b/mps/code/cbs.c
index d98a92cb8c4..0b30b68acb1 100644
--- a/mps/code/cbs.c
+++ b/mps/code/cbs.c
@@ -1,7 +1,7 @@
/* cbs.c: COALESCING BLOCK STRUCTURE IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* .intro: This is a portable implementation of coalescing block
* structures.
@@ -1069,7 +1069,7 @@ static Res cbsFindInZones(Bool *foundReturn, Range rangeReturn,
AVERT(CBS, cbs);
AVER(IsLandSubclass(CBSLand(cbs), CBSZonedLandClass));
/* AVERT(ZoneSet, zoneSet); */
- AVER(BoolCheck(high));
+ AVERT(Bool, high);
landFind = high ? cbsFindLast : cbsFindFirst;
splayFind = high ? SplayFindLast : SplayFindFirst;
@@ -1208,7 +1208,7 @@ DEFINE_LAND_CLASS(CBSZonedLandClass, class)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk
index 2eb68381a3f..c82caa4576e 100644
--- a/mps/code/comm.gmk
+++ b/mps/code/comm.gmk
@@ -36,7 +36,6 @@
# NOISY if defined and non-empty, causes commands to be emitted
# MPMPF platform-dependent C sources for the "mpm" part
# MPMS assembler sources for the "mpm" part (.s files)
-# MPMPS pre-processor assembler sources for the "mpm" part (.S files)
#
# %%PART: When adding a new part, add a new parameter above for the
# files included in the part.
@@ -309,12 +308,12 @@ all: $(ALL_TARGETS)
# testci = continuous integration tests, must be known good
# testall = all test cases, for ensuring quality of a release
# testansi = tests that run on the generic ("ANSI") platform
-# testpoll = tests that run on the generic platform with CONFIG_POLL_NONE
+# testpollnone = tests that run on the generic platform with CONFIG_POLL_NONE
-TEST_SUITES=testrun testci testall testansi testpoll
+TEST_SUITES=testrun testci testall testansi testpollnone
$(addprefix $(PFM)/$(VARIETY)/,$(TEST_SUITES)): $(TEST_TARGETS)
- ../tool/testrun.sh "$(PFM)/$(VARIETY)" "$(notdir $@)"
+ ../tool/testrun.sh -s "$(notdir $@)" "$(PFM)/$(VARIETY)"
# These convenience targets allow one to type "make foo" to build target
diff --git a/mps/code/commpost.nmk b/mps/code/comm.nmk
similarity index 64%
rename from mps/code/commpost.nmk
rename to mps/code/comm.nmk
index 1d2783a7bbb..a59132ff354 100644
--- a/mps/code/commpost.nmk
+++ b/mps/code/comm.nmk
@@ -1,11 +1,330 @@
-# commpost.nmk: SECOND COMMON FRAGMENT FOR PLATFORMS USING NMAKE -*- makefile -*-
+# -*- makefile -*-
+#
+# comm.nmk: COMMON NMAKE FRAGMENT
#
# $Id$
# Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
#
# DESCRIPTION
#
-# Second common makefile fragment for w3*mv.nmk. See commpre.nmk
+# This makefile fragment is included in more specific makefiles for
+# platforms which use nmake.
+#
+# %%PART: When adding a new part, add a new parameter for the files included
+# in the part
+# Parameters:
+# PFM platform code, e.g. "w3i3mv"
+# PFMDEFS /D options to define platforms preprocessor symbols
+# to the compiler. Avoid using this if possible, as it
+# prevents the MPS being built with a simple command like
+# "cl mps.c".
+# MPMCOMMON list of sources which make up the "mpm" part for all
+# platforms. Each source is stripped of its .c extension
+# and surrounded with [brackets].
+# MPMPF as above for the current platform.
+# PLINTH as above for the "plinth" part
+# AMC as above for the "amc" part
+# AMS as above for the "ams" part
+# LO as above for the "lo" part
+# POOLN as above for the "pooln" part
+# SNC as above for the "snc" part
+# POOLS as above for all pools included in the target
+# MPM as above for the MPMCOMMON + MPMPF + PLINTH + POOLS
+# DW as above for the "dw" part
+# FMTTEST as above for the "fmttest" part
+# FMTSCHEME as above for the "fmtscheme" part
+# TESTLIB as above for the "testlib" part
+# TESTTHR as above for the "testthr" part
+# NOISY if defined, causes command to be emitted
+#
+#
+# EDITING
+#
+# To add new targets. varieties, and parts:
+# Search for the string "%%TARGET", "%%VARIETY", or "%%PART" in this makefile
+# and follow the instructions.
+#
+
+
+# TARGETS
+#
+#
+# %%TARGET: When adding a new target, add it to one of the variables
+# in this section. Library components go in LIB_TARGETS.
+
+LIB_TARGETS=mps.lib
+
+# Test cases go in TEST_TARGETS.
+
+TEST_TARGETS=\
+ abqtest.exe \
+ airtest.exe \
+ amcss.exe \
+ amcsshe.exe \
+ amcssth.exe \
+ amsss.exe \
+ amssshe.exe \
+ apss.exe \
+ arenacv.exe \
+ awlut.exe \
+ awluthe.exe \
+ awlutth.exe \
+ btcv.exe \
+ bttest.exe \
+ djbench.exe \
+ exposet0.exe \
+ expt825.exe \
+ finalcv.exe \
+ finaltest.exe \
+ fotest.exe \
+ gcbench.exe \
+ landtest.exe \
+ locbwcss.exe \
+ lockcov.exe \
+ lockut.exe \
+ locusss.exe \
+ locv.exe \
+ messtest.exe \
+ mpmss.exe \
+ mpsicv.exe \
+ mv2test.exe \
+ nailboardtest.exe \
+ poolncv.exe \
+ qs.exe \
+ sacss.exe \
+ segsmss.exe \
+ steptest.exe \
+ teletest.exe \
+ walkt0.exe \
+ zcoll.exe \
+ zmess.exe
+
+# Stand-alone programs go in EXTRA_TARGETS if they should always be
+# built, or in OPTIONAL_TARGETS if they should only be built if
+
+EXTRA_TARGETS=mpseventcnv.exe mpseventtxt.exe
+OPTIONAL_TARGETS=mpseventsql.exe
+
+# This target records programs that we were once able to build but
+# can't at the moment:
+#
+# replay -- depends on the EPVM pool.
+
+UNBUILDABLE_TARGETS=replay.exe
+
+ALL_TARGETS=$(LIB_TARGETS) $(TEST_TARGETS) $(EXTRA_TARGETS)
+
+
+# PARAMETERS
+#
+#
+# %%PART: When adding a new part, add the sources for the new part here.
+
+MPMCOMMON=\
+ [abq] \
+ [arena] \
+ [arenacl] \
+ [arenavm] \
+ [arg] \
+ [boot] \
+ [bt] \
+ [buffer] \
+ [cbs] \
+ [dbgpool] \
+ [dbgpooli] \
+ [event] \
+ [failover] \
+ [format] \
+ [freelist] \
+ [global] \
+ [land] \
+ [ld] \
+ [locus] \
+ [message] \
+ [meter] \
+ [mpm] \
+ [mpsi] \
+ [nailboard] \
+ [pool] \
+ [poolabs] \
+ [poolmfs] \
+ [poolmrg] \
+ [poolmv2] \
+ [poolmv] \
+ [protocol] \
+ [range] \
+ [ref] \
+ [reserv] \
+ [ring] \
+ [root] \
+ [sa] \
+ [sac] \
+ [seg] \
+ [shield] \
+ [splay] \
+ [ss] \
+ [table] \
+ [trace] \
+ [traceanc] \
+ [tract] \
+ [tree] \
+ [version] \
+ [vm] \
+ [walk]
+PLINTH = [mpsliban] [mpsioan]
+AMC = [poolamc]
+AMS = [poolams] [poolamsi]
+AWL = [poolawl]
+LO = [poollo]
+MVFF = [poolmvff]
+POOLN = [pooln]
+SNC = [poolsnc]
+FMTDY = [fmtdy] [fmtno]
+FMTTEST = [fmthe] [fmtdy] [fmtno] [fmtdytst]
+FMTSCHEME = [fmtscheme]
+TESTLIB = [testlib] [getoptl]
+TESTTHR = [testthrw3]
+POOLS = $(AMC) $(AMS) $(AWL) $(LO) $(MV2) $(MVFF) $(SNC)
+MPM = $(MPMCOMMON) $(MPMPF) $(POOLS) $(PLINTH)
+
+
+# CHECK PARAMETERS
+#
+#
+# %%PART: When adding a new part, add checks for the parameter with the
+# sources for the new part.
+
+!IFNDEF PFM
+!ERROR comm.nmk: PFM not defined
+!ENDIF
+!IFNDEF MPM
+!ERROR comm.nmk: MPM not defined
+!ENDIF
+!IFNDEF MPMCOMMON
+!ERROR comm.nmk: MPMCOMMON not defined
+!ENDIF
+!IFNDEF MPMPF
+!ERROR comm.nmk: MPMPF not defined
+!ENDIF
+!IFNDEF PLINTH
+!ERROR comm.nmk: PLINTH not defined
+!ENDIF
+!IFNDEF LO
+!ERROR comm.nmk: LO not defined
+!ENDIF
+!IFNDEF AMC
+!ERROR comm.nmk: AMC not defined
+!ENDIF
+!IFNDEF AMS
+!ERROR comm.nmk: AMS not defined
+!ENDIF
+!IFNDEF POOLN
+!ERROR comm.nmk: POOLN not defined
+!ENDIF
+!IFNDEF SNC
+!ERROR comm.nmk: SNC not defined
+!ENDIF
+!IFNDEF FMTDY
+!ERROR comm.nmk: FMTDY not defined
+!ENDIF
+!IFNDEF FMTTEST
+!ERROR comm.nmk: FMTTEST not defined
+!ENDIF
+!IFNDEF FMTSCHEME
+!ERROR comm.nmk: FMTSCHEME not defined
+!ENDIF
+!IFNDEF TESTLIB
+!ERROR comm.nmk: TESTLIB not defined
+!ENDIF
+!IFNDEF TESTTHR
+!ERROR comm.nmk: TESTTHR not defined
+!ENDIF
+
+
+# DECLARATIONS
+
+
+!IFDEF NOISY
+ECHO = rem
+!ELSE
+.SILENT:
+ECHO = echo
+!ENDIF
+
+
+# C FLAGS
+
+CFLAGSTARGETPRE =
+CFLAGSTARGETPOST =
+CRTFLAGSHOT =
+CRTFLAGSCOOL =
+LINKFLAGSHOT =
+LINKFLAGSCOOL =
+
+CFLAGSSQLPRE = /nologo $(PFMDEFS)
+CFLAGSCOMMONPRE = /nologo $(PFMDEFS) $(CFLAGSTARGETPRE)
+CFLAGSSQLPOST =
+CFLAGSCOMMONPOST = $(CFLAGSTARGETPOST)
+
+# Flags for use in the variety combinations
+CFLAGSHOT = /O2
+# (above /O2 (maximise speed) used to be set to /Ox
+# (maximise optimisations) in for tool versions before VS 9)
+# We used to have /GZ here (stack probe).
+# Note that GZ is specific to version 12 of the cl tool. drj 2003-11-04
+# It is ignored on earlier versions of the cl tool.
+# /GZ here generates a dependency on the C library and when we are
+# building a DLL, mpsdy.dll, the linker step will fail (error LNK2001:
+# unresolved external symbol __chkesp). See
+# http://support.microsoft.com/kb/q191669/
+CFLAGSCOOL =
+CFLAGSINTERNAL = /Zi
+CFLAGSEXTERNAL =
+
+# The combinations of variety
+# %%VARIETY: When adding a new variety, define a macro containing the set
+# of flags for the new variety.
+CFRASH = /DCONFIG_VAR_RASH $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL)
+CFHOT = /DCONFIG_VAR_HOT $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL)
+CFCOOL = /DCONFIG_VAR_COOL $(CRTFLAGSCOOL) $(CFLAGSCOOL) $(CFLAGSINTERNAL)
+
+# Microsoft documentation is not very clear on the point of using both
+# optimization and debug information
+
+# LINKER FLAGS
+# %%VARIETY: When adding a new variety, define a macro containing the flags
+# for the new variety
+LINKER = link
+LINKFLAGSCOMMON = /nologo /LARGEADDRESSAWARE
+LINKFLAGSINTERNAL = /DEBUG
+# ( Internal flags used to be set to /DEBUG:full )
+LINKFLAGSEXTERNAL = /RELEASE
+
+LFRASH = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL)
+LFHOT = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL)
+LFCOOL = $(LINKFLAGSCOOL) $(LINKFLAGSINTERNAL)
+
+#LFCV = /PROFILE /DEBUG:full /DEBUGTYPE:cv
+
+# Library manager
+# %%VARIETY: When adding a new variety, define a macro containing the flags
+# for the new variety
+LIBMAN = lib # can't call this LIB - it screws the environment
+LIBFLAGSCOMMON =
+
+LIBFLAGSRASH =
+LIBFLAGSHOT =
+LIBFLAGSCOOL =
+
+# Browser database manager [not used at present]
+#BSC = bscmake
+#BSCFLAGS = /nologo /n
+
+
+# == Common definitions ==
+# %%PART: When adding a new part, add it here, unless it's platform-specific
+# [It is not possible use a macro, like $(PFM), in a substitution,
+# hence all parts end up being platform-specific.]
# == Pseudo-targets ==
@@ -56,10 +375,10 @@ variety: $(PFM)\$(VARIETY)\$(TARGET)
!ENDIF
!ENDIF
-# testrun testci testall testansi testpoll
+# testrun testci testall testansi testpollnone
# Runs automated test cases.
-testrun testci testall testansi testpoll: $(TEST_TARGETS)
+testrun testci testall testansi testpollnone: $(TEST_TARGETS)
!IFDEF VARIETY
..\tool\testrun.bat $(PFM) $(VARIETY) $@
!ELSE
@@ -382,18 +701,18 @@ $(PFM)\$(VARIETY)\sqlite3.obj:
# Copyright (C) 2001-2014 Ravenbrook Limited .
# All rights reserved. This is an open source license. Contact
# Ravenbrook for commercial licensing options.
-#
+#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
-#
+#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
-#
+#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
-#
+#
# 3. Redistributions in any form must be accompanied by information on how
# to obtain complete source code for this software and any accompanying
# software that uses this software. The source code must either be
@@ -404,7 +723,7 @@ $(PFM)\$(VARIETY)\sqlite3.obj:
# include source code for modules or files that typically accompany the
# major components of the operating system on which the executable file
# runs.
-#
+#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
diff --git a/mps/code/commpre.nmk b/mps/code/commpre.nmk
deleted file mode 100644
index b622ff25741..00000000000
--- a/mps/code/commpre.nmk
+++ /dev/null
@@ -1,369 +0,0 @@
-# commpre.nmk: FIRST COMMON FRAGMENT FOR PLATFORMS USING NMAKE -*- makefile -*-1
-#
-# $Id$
-# Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
-#
-# DESCRIPTION
-#
-# .description: This makefile fragment is included in more specific
-# makefiles for platforms which use the "mv" builder. This is
-# the first of two common makefile fragements (the other is commpost.nmk).
-# Alas, due to shortcomings in nmake, it is not possible to use only one
-# common fragment.
-#
-# %%PART: When adding a new part, add a new parameter for the files included
-# in the part
-# Parameters:
-# PFM platform code, e.g. "w3i3mv"
-# PFMDEFS /D options to define platforms preprocessor symbols
-# to the compiler. Eg "/DOS_NT /DARCH_386 /DBUILD_MVC"
-# MPMCOMMON list of sources which make up the "mpm" part for all
-# platforms. Each source is stripped of its .c extension
-# and surrounded with [brackets].
-# MPM as above, plus sources for the "mpm" part for the current
-# platform.
-# PLINTH as above for the "plinth" part
-# AMC as above for the "amc" part
-# AMS as above for the "ams" part
-# LO as above for the "lo" part
-# POOLN as above for the "pooln" part
-# SNC as above for the "snc" part
-# DW as above for the "dw" part
-# FMTTEST as above for the "fmttest" part
-# FMTSCHEME as above for the "fmtscheme" part
-# TESTLIB as above for the "testlib" part
-# TESTTHR as above for the "testthr" part
-# NOISY if defined, causes command to be emitted
-#
-#
-# EDITING
-#
-# To add new targets. varieties, and parts:
-# Search for the string "%%TARGET", "%%VARIETY", or "%%PART" in this makefile
-# and follow the instructions.
-#
-
-
-# TARGETS
-#
-#
-# %%TARGET: When adding a new target, add it to one of the variables
-# in this section. Library components go in LIB_TARGETS.
-
-LIB_TARGETS=mps.lib
-
-# Test cases go in TEST_TARGETS.
-
-TEST_TARGETS=\
- abqtest.exe \
- airtest.exe \
- amcss.exe \
- amcsshe.exe \
- amcssth.exe \
- amsss.exe \
- amssshe.exe \
- apss.exe \
- arenacv.exe \
- awlut.exe \
- awluthe.exe \
- awlutth.exe \
- btcv.exe \
- bttest.exe \
- djbench.exe \
- exposet0.exe \
- expt825.exe \
- finalcv.exe \
- finaltest.exe \
- fotest.exe \
- gcbench.exe \
- landtest.exe \
- locbwcss.exe \
- lockcov.exe \
- lockut.exe \
- locusss.exe \
- locv.exe \
- messtest.exe \
- mpmss.exe \
- mpsicv.exe \
- mv2test.exe \
- nailboardtest.exe \
- poolncv.exe \
- qs.exe \
- sacss.exe \
- segsmss.exe \
- steptest.exe \
- teletest.exe \
- walkt0.exe \
- zcoll.exe \
- zmess.exe
-
-# Stand-alone programs go in EXTRA_TARGETS if they should always be
-# built, or in OPTIONAL_TARGETS if they should only be built if
-
-EXTRA_TARGETS=mpseventcnv.exe mpseventtxt.exe
-OPTIONAL_TARGETS=mpseventsql.exe
-
-# This target records programs that we were once able to build but
-# can't at the moment:
-#
-# replay -- depends on the EPVM pool.
-
-UNBUILDABLE_TARGETS=replay.exe
-
-ALL_TARGETS=$(LIB_TARGETS) $(TEST_TARGETS) $(EXTRA_TARGETS)
-
-
-# PARAMETERS
-#
-#
-# %%PART: When adding a new part, add the sources for the new part here.
-
-MPMCOMMON=\
- [abq] \
- [arena] \
- [arenacl] \
- [arenavm] \
- [arg] \
- [boot] \
- [bt] \
- [buffer] \
- [cbs] \
- [dbgpool] \
- [dbgpooli] \
- [event] \
- [failover] \
- [format] \
- [freelist] \
- [global] \
- [land] \
- [ld] \
- [locus] \
- [message] \
- [meter] \
- [mpm] \
- [mpsi] \
- [nailboard] \
- [pool] \
- [poolabs] \
- [poolmfs] \
- [poolmrg] \
- [poolmv2] \
- [poolmv] \
- [protocol] \
- [range] \
- [ref] \
- [reserv] \
- [ring] \
- [root] \
- [sa] \
- [sac] \
- [seg] \
- [shield] \
- [splay] \
- [ss] \
- [table] \
- [trace] \
- [traceanc] \
- [tract] \
- [tree] \
- [version] \
- [vm] \
- [walk]
-PLINTH = [mpsliban] [mpsioan]
-AMC = [poolamc]
-AMS = [poolams] [poolamsi]
-AWL = [poolawl]
-LO = [poollo]
-MVFF = [poolmvff]
-POOLN = [pooln]
-SNC = [poolsnc]
-FMTDY = [fmtdy] [fmtno]
-FMTTEST = [fmthe] [fmtdy] [fmtno] [fmtdytst]
-FMTSCHEME = [fmtscheme]
-TESTLIB = [testlib] [getoptl]
-TESTTHR = [testthrw3]
-POOLS = $(AMC) $(AMS) $(AWL) $(LO) $(MV2) $(MVFF) $(SNC)
-MPM = $(MPMCOMMON) $(MPMPF) $(POOLS) $(PLINTH)
-
-
-# CHECK PARAMETERS
-#
-#
-# %%PART: When adding a new part, add checks for the parameter with the
-# sources for the new part.
-
-!IFNDEF PFM
-!ERROR commpre.nmk: PFM not defined
-!ENDIF
-!IFNDEF PFMDEFS
-!ERROR commpre.nmk: PFMDEFS not defined
-!ENDIF
-!IFNDEF MPM
-!ERROR commpre.nmk: MPM not defined
-!ENDIF
-!IFNDEF MPMCOMMON
-!ERROR commpre.nmk: MPMCOMMON not defined
-!ENDIF
-!IFNDEF MPMPF
-!ERROR commpre.nmk: MPMPF not defined
-!ENDIF
-!IFNDEF PLINTH
-!ERROR commpre.nmk: PLINTH not defined
-!ENDIF
-!IFNDEF LO
-!ERROR commpre.nmk: LO not defined
-!ENDIF
-!IFNDEF AMC
-!ERROR commpre.nmk: AMC not defined
-!ENDIF
-!IFNDEF AMS
-!ERROR commpre.nmk: AMS not defined
-!ENDIF
-!IFNDEF POOLN
-!ERROR commpre.nmk: POOLN not defined
-!ENDIF
-!IFNDEF SNC
-!ERROR commpre.nmk: SNC not defined
-!ENDIF
-!IFNDEF FMTDY
-!ERROR commpre.nmk: FMTDY not defined
-!ENDIF
-!IFNDEF FMTTEST
-!ERROR commpre.nmk: FMTTEST not defined
-!ENDIF
-!IFNDEF FMTSCHEME
-!ERROR commpre.nmk: FMTSCHEME not defined
-!ENDIF
-!IFNDEF TESTLIB
-!ERROR commpre.nmk: TESTLIB not defined
-!ENDIF
-!IFNDEF TESTTHR
-!ERROR commpre.nmk: TESTTHR not defined
-!ENDIF
-
-
-# DECLARATIONS
-
-
-!IFDEF NOISY
-ECHO = rem
-!ELSE
-.SILENT:
-ECHO = echo
-!ENDIF
-
-
-# C FLAGS
-
-CFLAGSTARGETPRE =
-CFLAGSTARGETPOST =
-CRTFLAGSHOT =
-CRTFLAGSCOOL =
-LINKFLAGSHOT =
-LINKFLAGSCOOL =
-
-CFLAGSSQLPRE = /nologo $(PFMDEFS)
-CFLAGSCOMMONPRE = /nologo $(PFMDEFS) $(CFLAGSTARGETPRE)
-CFLAGSSQLPOST =
-CFLAGSCOMMONPOST = $(CFLAGSTARGETPOST)
-
-# Flags for use in the variety combinations
-CFLAGSHOT = /O2
-# (above /O2 (maximise speed) used to be set to /Ox
-# (maximise optimisations) in for tool versions before VS 9)
-# We used to have /GZ here (stack probe).
-# Note that GZ is specific to version 12 of the cl tool. drj 2003-11-04
-# It is ignored on earlier versions of the cl tool.
-# /GZ here generates a dependency on the C library and when we are
-# building a DLL, mpsdy.dll, the linker step will fail (error LNK2001:
-# unresolved external symbol __chkesp). See
-# http://support.microsoft.com/kb/q191669/
-CFLAGSCOOL =
-CFLAGSINTERNAL = /Zi
-CFLAGSEXTERNAL =
-
-# The combinations of variety
-# %%VARIETY: When adding a new variety, define a macro containing the set
-# of flags for the new variety.
-CFRASH = /DCONFIG_VAR_RASH $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL)
-CFHOT = /DCONFIG_VAR_HOT $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL)
-CFCOOL = /DCONFIG_VAR_COOL $(CRTFLAGSCOOL) $(CFLAGSCOOL) $(CFLAGSINTERNAL)
-
-# Microsoft documentation is not very clear on the point of using both
-# optimization and debug information
-
-# LINKER FLAGS
-# %%VARIETY: When adding a new variety, define a macro containing the flags
-# for the new variety
-LINKER = link
-LINKFLAGSCOMMON = /nologo /LARGEADDRESSAWARE
-LINKFLAGSINTERNAL = /DEBUG
-# ( Internal flags used to be set to /DEBUG:full )
-LINKFLAGSEXTERNAL = /RELEASE
-
-LFRASH = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL)
-LFHOT = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL)
-LFCOOL = $(LINKFLAGSCOOL) $(LINKFLAGSINTERNAL)
-
-#LFCV = /PROFILE /DEBUG:full /DEBUGTYPE:cv
-
-# Library manager
-# %%VARIETY: When adding a new variety, define a macro containing the flags
-# for the new variety
-LIBMAN = lib # can't call this LIB - it screws the environment
-LIBFLAGSCOMMON =
-
-LIBFLAGSRASH =
-LIBFLAGSHOT =
-LIBFLAGSCOOL =
-
-# Browser database manager [not used at present]
-#BSC = bscmake
-#BSCFLAGS = /nologo /n
-
-
-# == Common definitions ==
-# %%PART: When adding a new part, add it here, unless it's platform-specific
-# [It is not possible use a macro, like $(PFM), in a substitution,
-# hence all parts end up being platform-specific.]
-
-
-# C. COPYRIGHT AND LICENSE
-#
-# Copyright (C) 2001-2014 Ravenbrook Limited .
-# All rights reserved. This is an open source license. Contact
-# Ravenbrook for commercial licensing options.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# 3. Redistributions in any form must be accompanied by information on how
-# to obtain complete source code for this software and any accompanying
-# software that uses this software. The source code must either be
-# included in the distribution or be available for no more than the cost
-# of distribution plus a nominal fee, and must be freely redistributable
-# under reasonable conditions. For an executable file, complete source
-# code means the source code for all modules it contains. It does not
-# include source code for modules or files that typically accompany the
-# major components of the operating system on which the executable file
-# runs.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-# PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
-# COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/mps/code/djbench.c b/mps/code/djbench.c
index 33cf1d4bdb9..fbc6dcabc1c 100644
--- a/mps/code/djbench.c
+++ b/mps/code/djbench.c
@@ -13,10 +13,15 @@
#include "mps.c"
-#include "getopt.h"
#include "testlib.h"
#include "testthr.h"
+#ifdef MPS_OS_W3
+#include "getopt.h"
+#else
+#include
+#endif
+
#include /* fprintf, stderr */
#include /* alloca, exit, EXIT_SUCCESS, EXIT_FAILURE */
#include /* CLOCKS_PER_SEC, clock */
diff --git a/mps/code/freelist.c b/mps/code/freelist.c
index a9e482550f3..6eddc3dff83 100644
--- a/mps/code/freelist.c
+++ b/mps/code/freelist.c
@@ -1,7 +1,7 @@
/* freelist.c: FREE LIST ALLOCATOR IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2013-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2013-2015 Ravenbrook Limited. See end of file for license.
*
* .sources: .
*/
@@ -18,11 +18,11 @@ SRCID(freelist, "$Id$");
typedef union FreelistBlockUnion {
- struct {
+ struct FreelistBlockSmall {
FreelistBlock next; /* tagged with low bit 1 */
/* limit is (char *)this + freelistAlignment(fl) */
} small;
- struct {
+ struct FreelistBlockLarge {
FreelistBlock next; /* not tagged (low bit 0) */
Addr limit;
} large;
@@ -101,6 +101,9 @@ static Bool FreelistBlockCheck(FreelistBlock block)
CHECKL(freelistBlockNext(block) == freelistEND
|| block < freelistBlockNext(block));
CHECKL(freelistBlockIsSmall(block) || (Addr)block < block->large.limit);
+ /* Would like to CHECKL(!freelistBlockIsSmall(block) ||
+ * freelistBlockSize(fl, block) == freelistAlignment(fl)) but we
+ * don't have 'fl' here. This is checked in freelistBlockSetLimit. */
return TRUE;
}
@@ -139,6 +142,7 @@ static void freelistBlockSetLimit(Freelist fl, FreelistBlock block, Addr limit)
} else {
AVER(size >= sizeof(block->small));
block->small.next = freelistTagSet(block->small.next);
+ AVER(freelistBlockSize(fl, block) == freelistAlignment(fl));
}
AVER(freelistBlockLimit(fl, block) == limit);
}
@@ -170,6 +174,9 @@ Bool FreelistCheck(Freelist fl)
CHECKS(Freelist, fl);
land = FreelistLand(fl);
CHECKD(Land, land);
+ CHECKL(AlignCheck(FreelistMinimumAlignment));
+ CHECKL(sizeof(struct FreelistBlockSmall) < sizeof(struct FreelistBlockLarge));
+ CHECKL(sizeof(struct FreelistBlockSmall) <= freelistAlignment(fl));
/* See */
CHECKL(AlignIsAligned(freelistAlignment(fl), FreelistMinimumAlignment));
CHECKL((fl->list == freelistEND) == (fl->listSize == 0));
@@ -236,12 +243,14 @@ static Size freelistSize(Land land)
* Otherwise, if next is freelistEND, make prev the last block in the list.
* Otherwise, make next follow prev in the list.
* Update the count of blocks by 'delta'.
-
+ *
* It is tempting to try to simplify this code by putting a
* FreelistBlockUnion into the FreelistStruct and so avoiding the
* special case on prev. But the problem with that idea is that we
* can't guarantee that such a sentinel would respect the isolated
- * range invariant, and so it would still have to be special-cases.
+ * range invariant (it would have to be at a lower address than the
+ * first block in the free list, which the MPS has no mechanism to
+ * enforce), and so it would still have to be special-cased.
*/
static void freelistBlockSetPrevNext(Freelist fl, FreelistBlock prev,
@@ -781,6 +790,7 @@ static Res freelistDescribe(Land land, mps_lib_FILE *stream, Count depth)
res = WriteF(stream, depth,
"Freelist $P {\n", (WriteFP)fl,
" listSize = $U\n", (WriteFU)fl->listSize,
+ " size = $U\n", (WriteFU)fl->size,
NULL);
b = LandIterate(land, freelistDescribeVisitor, stream, depth + 2);
@@ -815,7 +825,7 @@ DEFINE_LAND_CLASS(FreelistLandClass, class)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2013-2014 Ravenbrook Limited .
+ * Copyright (C) 2013-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/gcbench.c b/mps/code/gcbench.c
index 2ae97104930..6d7f3339667 100644
--- a/mps/code/gcbench.c
+++ b/mps/code/gcbench.c
@@ -7,13 +7,18 @@
*/
#include "mps.c"
-#include "getopt.h"
#include "testlib.h"
#include "testthr.h"
#include "fmtdy.h"
#include "fmtdytst.h"
#include "mpm.h"
+#ifdef MPS_OS_W3
+#include "getopt.h"
+#else
+#include
+#endif
+
#include /* fprintf, printf, putchars, sscanf, stderr, stdout */
#include /* alloca, exit, EXIT_FAILURE, EXIT_SUCCESS, strtoul */
#include /* clock, CLOCKS_PER_SEC */
diff --git a/mps/code/global.c b/mps/code/global.c
index d60e925fdb3..164798d9695 100644
--- a/mps/code/global.c
+++ b/mps/code/global.c
@@ -657,7 +657,8 @@ Bool ArenaAccess(Addr addr, AccessSet mode, MutatorFaultContext context)
res = PoolAccess(SegPool(seg), seg, addr, mode, context);
AVER(res == ResOK); /* Mutator can't continue unless this succeeds */
} else {
- /* Protection was already cleared: nothing to do now. */
+ /* Protection was already cleared, for example by another thread
+ or a fault in a nested exception handler: nothing to do now. */
}
EVENT4(ArenaAccess, arena, count, addr, mode);
ArenaLeave(arena);
diff --git a/mps/code/land.c b/mps/code/land.c
index 7dbc7845b5b..18d446288f8 100644
--- a/mps/code/land.c
+++ b/mps/code/land.c
@@ -1,7 +1,7 @@
/* land.c: LAND (COLLECTION OF ADDRESS RANGES) IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2014-2015 Ravenbrook Limited. See end of file for license.
*
* .design:
*/
@@ -282,7 +282,7 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
AVER(SizeIsAligned(size, land->alignment));
- AVER(FindDeleteCheck(findDelete));
+ AVERT(FindDelete, findDelete);
landEnter(land);
b = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size,
@@ -306,7 +306,7 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size,
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
AVER(SizeIsAligned(size, land->alignment));
- AVER(FindDeleteCheck(findDelete));
+ AVERT(FindDelete, findDelete);
landEnter(land);
b = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size,
@@ -330,7 +330,7 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
AVER(SizeIsAligned(size, land->alignment));
- AVER(FindDeleteCheck(findDelete));
+ AVERT(FindDelete, findDelete);
landEnter(land);
b = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size,
@@ -470,7 +470,7 @@ Bool LandClassCheck(LandClass class)
static Res landTrivInit(Land land, ArgList args)
{
AVERT(Land, land);
- AVER(ArgListCheck(args));
+ AVERT(ArgList, args);
UNUSED(args);
return ResOK;
}
@@ -555,7 +555,7 @@ static Bool landNoFind(Range rangeReturn, Range oldRangeReturn, Land land, Size
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
UNUSED(size);
- AVER(FindDeleteCheck(findDelete));
+ AVERT(FindDelete, findDelete);
return ResUNIMPL;
}
@@ -567,7 +567,7 @@ static Res landNoFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRang
AVERT(Land, land);
UNUSED(size);
UNUSED(zoneSet);
- AVER(BoolCheck(high));
+ AVERT(Bool, high);
return ResUNIMPL;
}
@@ -606,7 +606,7 @@ DEFINE_CLASS(LandClass, class)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2014 Ravenbrook Limited .
+ * Copyright (C) 2014-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/ld.c b/mps/code/ld.c
index 3c55c27fccd..c9e79f8a762 100644
--- a/mps/code/ld.c
+++ b/mps/code/ld.c
@@ -1,7 +1,7 @@
/* ld.c: LOCATION DEPENDENCY IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* .def: A location dependency records the fact that the bit-patterns
* of some references will be used directly (most likely for
@@ -92,6 +92,15 @@ void LDReset(mps_ld_t ld, Arena arena)
* occured since the epoch recorded in the dependency. If the location
* were used first only the new location of the reference would end up
* in the set.
+ *
+ * .add.no-arena-check: Add does not check that the address belongs to
+ * the arena because this would require taking the arena lock. We
+ * would rather that this function be lock-free even if some errors
+ * are not detected.
+ *
+ * .add.no-align-check: Add does not check that the address is
+ * aligned, for the same reason as .add.check: it can't find out which
+ * pool the address belongs to without taking the lock.
*/
void LDAdd(mps_ld_t ld, Arena arena, Addr addr)
{
@@ -153,6 +162,10 @@ Bool LDIsStaleAny(mps_ld_t ld, Arena arena)
* .stale.conservative: In fact we just ignore the address and test if
* any dependency is stale. This is conservatively correct (no false
* negatives) but provides a hook for future improvement.
+ *
+ * .stale.no-arena-check: See .add.no-arena-check.
+ *
+ * .stale.no-align-check: See .add.no-align-check.
*/
Bool LDIsStale(mps_ld_t ld, Arena arena, Addr addr)
{
@@ -225,7 +238,7 @@ void LDMerge(mps_ld_t ld, Arena arena, mps_ld_t from)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/mpm.c b/mps/code/mpm.c
index d3c32a66daf..aba1ac2f5cb 100644
--- a/mps/code/mpm.c
+++ b/mps/code/mpm.c
@@ -1,7 +1,7 @@
/* mpm.c: GENERAL MPM SUPPORT
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* .purpose: Miscellaneous support for the implementation of the MPM
* and pool classes.
@@ -137,6 +137,16 @@ Bool AlignCheck(Align align)
}
+/* AccessSetCheck -- check that an access set is valid */
+
+Bool AccessSetCheck(AccessSet mode)
+{
+ CHECKL(mode < ((ULongest)1 << AccessLIMIT));
+ UNUSED(mode); /* see .check.unused */
+ return TRUE;
+}
+
+
#endif /* defined(AVER_AND_CHECK) */
@@ -638,7 +648,7 @@ Bool StringEqual(const char *s1, const char *s2)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index a3c5a8bbf6c..af2cde97ff1 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -1,7 +1,7 @@
/* mpm.h: MEMORY POOL MANAGER DEFINITIONS
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* .trans.bufferinit: The Buffer data structure has an Init field and
@@ -46,6 +46,7 @@ extern Bool FunCheck(Fun f);
extern Bool ShiftCheck(Shift shift);
extern Bool AttrCheck(Attr attr);
extern Bool RootVarCheck(RootVar rootVar);
+extern Bool AccessSetCheck(AccessSet mode);
/* Address/Size Interface -- see */
@@ -562,13 +563,14 @@ extern Bool (ArenaStep)(Globals globals, double interval, double multiplier);
extern void ArenaClamp(Globals globals);
extern void ArenaRelease(Globals globals);
extern void ArenaPark(Globals globals);
-extern void ArenaExposeRemember(Globals globals, int remember);
+extern void ArenaExposeRemember(Globals globals, Bool remember);
extern void ArenaRestoreProtection(Globals globals);
extern Res ArenaStartCollect(Globals globals, int why);
extern Res ArenaCollect(Globals globals, int why);
extern Bool ArenaHasAddr(Arena arena, Addr addr);
extern Res ArenaAddrObject(Addr *pReturn, Arena arena, Addr addr);
extern void ArenaChunkInsert(Arena arena, Chunk chunk);
+extern void ArenaChunkRemoved(Arena arena, Chunk chunk);
extern void ArenaSetEmergency(Arena arena, Bool emergency);
extern Bool ArenaEmergency(Arena arean);
@@ -1052,7 +1054,7 @@ extern LandClass LandClassGet(void);
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h
index 01dbf16b732..a798cc71fc4 100644
--- a/mps/code/mpmst.h
+++ b/mps/code/mpmst.h
@@ -526,7 +526,6 @@ typedef struct mps_arena_class_s {
ArenaVarargsMethod varargs;
ArenaInitMethod init;
ArenaFinishMethod finish;
- ArenaReservedMethod reserved;
ArenaPurgeSpareMethod purgeSpare;
ArenaExtendMethod extend;
ArenaGrowMethod grow;
@@ -714,7 +713,8 @@ typedef struct mps_arena_s {
ReservoirStruct reservoirStruct; /* */
- Size committed; /* amount of committed RAM */
+ Size reserved; /* total reserved address space */
+ Size committed; /* total committed memory */
Size commitLimit; /* client-configurable commit limit */
Size spareCommitted; /* Amount of memory in hysteresis fund */
diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h
index a69b2b79ebe..a6030e4c1e5 100644
--- a/mps/code/mpmtypes.h
+++ b/mps/code/mpmtypes.h
@@ -120,7 +120,6 @@ typedef void (*ArenaVarargsMethod)(ArgStruct args[], va_list varargs);
typedef Res (*ArenaInitMethod)(Arena *arenaReturn,
ArenaClass class, ArgList args);
typedef void (*ArenaFinishMethod)(Arena arena);
-typedef Size (*ArenaReservedMethod)(Arena arena);
typedef Size (*ArenaPurgeSpareMethod)(Arena arena, Size size);
typedef Res (*ArenaExtendMethod)(Arena arena, Addr base, Size size);
typedef Res (*ArenaGrowMethod)(Arena arena, LocusPref pref, Size size);
diff --git a/mps/code/mps.c b/mps/code/mps.c
index d31a1f60a0a..95919d9680c 100644
--- a/mps/code/mps.c
+++ b/mps/code/mps.c
@@ -214,7 +214,6 @@
#include "mpsiw3.c" /* Windows interface layer extras */
/* Windows on 64-bit Intel with Microsoft Visual Studio */
-/* ssw3i6.asm is also required, but can't be included here */
#elif defined(MPS_PF_W3I6MV)
diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj
index c83a1026d6e..30aad557d3b 100644
--- a/mps/code/mps.xcodeproj/project.pbxproj
+++ b/mps/code/mps.xcodeproj/project.pbxproj
@@ -43,16 +43,16 @@
name = testall;
productName = testrun;
};
- 2215A9C1192A47D500E9E2CE /* testpoll */ = {
+ 2215A9C1192A47D500E9E2CE /* testpollnone */ = {
isa = PBXAggregateTarget;
- buildConfigurationList = 2215A9C5192A47D500E9E2CE /* Build configuration list for PBXAggregateTarget "testpoll" */;
+ buildConfigurationList = 2215A9C5192A47D500E9E2CE /* Build configuration list for PBXAggregateTarget "testpollnone" */;
buildPhases = (
2215A9C4192A47D500E9E2CE /* ShellScript */,
);
dependencies = (
2215A9C2192A47D500E9E2CE /* PBXTargetDependency */,
);
- name = testpoll;
+ name = testpollnone;
productName = testrun;
};
22CDE8EF16E9E97D00366D0A /* testrun */ = {
@@ -285,7 +285,6 @@
3124CAFB156BE82000753214 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
3124CAFC156BE82900753214 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
3150AE53156ABA2500A6E22A /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
- 318DA8D21892B13B0089718C /* getoptl.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8D11892B13B0089718C /* getoptl.c */; };
318DA8D31892B27E0089718C /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
31A47BA4156C1E130039B1C2 /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; };
31D60007156D3C6200337B26 /* segsmss.c in Sources */ = {isa = PBXBuildFile; fileRef = 31D60006156D3C5F00337B26 /* segsmss.c */; };
@@ -327,7 +326,6 @@
31FCAE161769244F008C034C /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; };
31FCAE19176924D4008C034C /* scheme.c in Sources */ = {isa = PBXBuildFile; fileRef = 31FCAE18176924D4008C034C /* scheme.c */; };
6313D46918A400B200EB03EF /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
- 6313D46A18A400B200EB03EF /* getoptl.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8D11892B13B0089718C /* getoptl.c */; };
6313D47318A4028E00EB03EF /* djbench.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8CE1892B1210089718C /* djbench.c */; };
6313D47418A4029200EB03EF /* gcbench.c in Sources */ = {isa = PBXBuildFile; fileRef = 6313D46618A3FDC900EB03EF /* gcbench.c */; };
6313D47518A40C6300EB03EF /* fmtdytst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC7156BE48D00753214 /* fmtdytst.c */; };
@@ -1635,8 +1633,6 @@
317B3C2A1731830100F9A469 /* arg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arg.c; sourceTree = ""; };
318DA8CD1892B0F30089718C /* djbench */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = djbench; sourceTree = BUILT_PRODUCTS_DIR; };
318DA8CE1892B1210089718C /* djbench.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = djbench.c; sourceTree = ""; };
- 318DA8D01892B13B0089718C /* getopt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getopt.h; sourceTree = ""; };
- 318DA8D11892B13B0089718C /* getoptl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getoptl.c; sourceTree = ""; };
31A47BA3156C1E130039B1C2 /* mps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mps.c; sourceTree = ""; };
31A47BA5156C1E5E0039B1C2 /* ssixi3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ssixi3.c; sourceTree = ""; };
31C83ADD1786281C0031A0DB /* protxc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = protxc.h; sourceTree = ""; };
@@ -2267,8 +2263,6 @@
318DA8C21892B0B20089718C /* Benchmarks */ = {
isa = PBXGroup;
children = (
- 318DA8D01892B13B0089718C /* getopt.h */,
- 318DA8D11892B13B0089718C /* getoptl.c */,
318DA8CE1892B1210089718C /* djbench.c */,
6313D46618A3FDC900EB03EF /* gcbench.c */,
);
@@ -3403,7 +3397,7 @@
2215A9B9192A47CE00E9E2CE /* testall */,
2215A9B1192A47C500E9E2CE /* testansi */,
2215A9A9192A47BB00E9E2CE /* testci */,
- 2215A9C1192A47D500E9E2CE /* testpoll */,
+ 2215A9C1192A47D500E9E2CE /* testpollnone */,
22CDE8EF16E9E97D00366D0A /* testrun */,
31EEABFA156AAF9D00714D05 /* mps */,
3114A632156E94DB001E0AA3 /* abqtest */,
@@ -3468,7 +3462,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
+ shellScript = "../tool/testrun.sh -s \"$TARGET_NAME\" \"$TARGET_BUILD_DIR\"\n";
showEnvVarsInLog = 0;
};
2215A9B4192A47C500E9E2CE /* ShellScript */ = {
@@ -3482,7 +3476,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
+ shellScript = "../tool/testrun.sh -s \"$TARGET_NAME\" \"$TARGET_BUILD_DIR\"\n";
showEnvVarsInLog = 0;
};
2215A9BC192A47CE00E9E2CE /* ShellScript */ = {
@@ -3496,7 +3490,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
+ shellScript = "../tool/testrun.sh -s \"$TARGET_NAME\" \"$TARGET_BUILD_DIR\"\n";
showEnvVarsInLog = 0;
};
2215A9C4192A47D500E9E2CE /* ShellScript */ = {
@@ -3510,7 +3504,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
+ shellScript = "../tool/testrun.sh -s \"$TARGET_NAME\" \"$TARGET_BUILD_DIR\"\n";
showEnvVarsInLog = 0;
};
22CDE8F416E9E9D400366D0A /* ShellScript */ = {
@@ -3524,7 +3518,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "../tool/testrun.sh \"$TARGET_BUILD_DIR\" \"$TARGET_NAME\"\n";
+ shellScript = "../tool/testrun.sh -s \"$TARGET_NAME\" \"$TARGET_BUILD_DIR\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -3909,7 +3903,6 @@
files = (
318DA8D31892B27E0089718C /* testlib.c in Sources */,
6313D47318A4028E00EB03EF /* djbench.c in Sources */,
- 318DA8D21892B13B0089718C /* getoptl.c in Sources */,
22561A9A18F426BB00372C66 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -4018,7 +4011,6 @@
6313D47418A4029200EB03EF /* gcbench.c in Sources */,
6313D47518A40C6300EB03EF /* fmtdytst.c in Sources */,
6313D47618A40C7B00EB03EF /* fmtdy.c in Sources */,
- 6313D46A18A400B200EB03EF /* getoptl.c in Sources */,
22561A9B18F426F300372C66 /* testthrix.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -5810,7 +5802,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 2215A9C5192A47D500E9E2CE /* Build configuration list for PBXAggregateTarget "testpoll" */ = {
+ 2215A9C5192A47D500E9E2CE /* Build configuration list for PBXAggregateTarget "testpollnone" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2215A9C6192A47D500E9E2CE /* Debug */,
diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c
index c00da18c201..283fbc6123e 100644
--- a/mps/code/mpsi.c
+++ b/mps/code/mpsi.c
@@ -1,14 +1,14 @@
/* mpsi.c: MEMORY POOL SYSTEM C INTERFACE LAYER
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 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,
* , and the internal MPM interfaces, as defined by
* . .purpose.check: It performs checking of the C client's
* usage of the MPS Interface. .purpose.thread: It excludes multiple
- * threads from the MPM by locking the Arena (see .thread-safety).
+ * threads from the MPM by locking the Arena (see ).
*
* .design:
*
@@ -248,7 +248,7 @@ void mps_arena_park(mps_arena_t arena)
void mps_arena_expose(mps_arena_t arena)
{
ArenaEnter(arena);
- ArenaExposeRemember(ArenaGlobals(arena), 0);
+ ArenaExposeRemember(ArenaGlobals(arena), FALSE);
ArenaLeave(arena);
}
@@ -256,7 +256,7 @@ void mps_arena_expose(mps_arena_t arena)
void mps_arena_unsafe_expose_remember_protection(mps_arena_t arena)
{
ArenaEnter(arena);
- ArenaExposeRemember(ArenaGlobals(arena), 1);
+ ArenaExposeRemember(ArenaGlobals(arena), TRUE);
ArenaLeave(arena);
}
@@ -1384,6 +1384,7 @@ mps_res_t mps_root_create_reg(mps_root_t *mps_root_o, mps_arena_t arena,
AVER(mps_reg_scan != NULL);
AVER(mps_reg_scan == mps_stack_scan_ambig); /* .reg.scan */
AVER(reg_scan_p != NULL); /* stackBot */
+ AVER(AddrIsAligned(reg_scan_p, sizeof(Word)));
AVER(rank == mps_rank_ambig());
AVER(mps_rm == (mps_rm_t)0);
@@ -2005,7 +2006,7 @@ void _mps_args_set_key(mps_arg_s args[MPS_ARGS_MAX], unsigned i,
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/mv.nmk b/mps/code/mv.nmk
index d0759bad532..6abd37d810e 100644
--- a/mps/code/mv.nmk
+++ b/mps/code/mv.nmk
@@ -7,7 +7,7 @@
#
# This file is included by platform nmake files that use the Microsoft
# Visual C/C+ compiler. It defines the compiler-specific variables
-# that the common nmake file fragment () requires.
+# that the common nmake fragment (comm.nmk) requires.
CC = cl
LIBMAN = lib
diff --git a/mps/code/pc.nmk b/mps/code/pc.nmk
index e52addfba4c..fdcf1235d37 100644
--- a/mps/code/pc.nmk
+++ b/mps/code/pc.nmk
@@ -7,7 +7,7 @@
#
# This file is included by platform nmake files that use the Pelles C
# compiler. It defines the compiler-specific variables that the common
-# nmake file fragment () requires.
+# nmake fragment (comm.nmk) requires.
CC = pocc
LIBMAN = polib
diff --git a/mps/code/pool.c b/mps/code/pool.c
index 945a846edcb..f939bca84e9 100644
--- a/mps/code/pool.c
+++ b/mps/code/pool.c
@@ -1,7 +1,7 @@
/* pool.c: POOL IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2001 Global Graphics Software.
*
* DESIGN
@@ -328,7 +328,7 @@ Res PoolAccess(Pool pool, Seg seg, Addr addr,
AVERT(Seg, seg);
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
- /* Can't check mode as there is no check method */
+ AVERT(AccessSet, mode);
/* Can't check MutatorFaultContext as there is no check method */
return (*pool->class->access)(pool, seg, addr, mode, context);
@@ -694,7 +694,7 @@ Bool PoolHasRange(Pool pool, Addr base, Addr limit)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/poolabs.c b/mps/code/poolabs.c
index 712f24152e5..30f5d0f999e 100644
--- a/mps/code/poolabs.c
+++ b/mps/code/poolabs.c
@@ -1,7 +1,7 @@
/* poolabs.c: ABSTRACT POOL CLASSES
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
* PURPOSE
@@ -334,7 +334,7 @@ Res PoolNoAccess(Pool pool, Seg seg, Addr addr,
AVERT(Seg, seg);
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
- /* can't check AccessSet as there is no Check method */
+ AVERT(AccessSet, mode);
/* can't check context as there is no Check method */
UNUSED(mode);
UNUSED(context);
@@ -360,7 +360,7 @@ Res PoolSegAccess(Pool pool, Seg seg, Addr addr,
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
AVER(SegPool(seg) == pool);
- /* can't check AccessSet as there is no Check method */
+ AVERT(AccessSet, mode);
/* can't check context as there is no Check method */
UNUSED(addr);
@@ -396,7 +396,7 @@ Res PoolSingleAccess(Pool pool, Seg seg, Addr addr,
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
AVER(SegPool(seg) == pool);
- /* can't check AccessSet as there is no Check method */
+ AVERT(AccessSet, mode);
/* can't check context as there is no Check method */
arena = PoolArena(pool);
@@ -691,7 +691,7 @@ Size PoolNoSize(Pool pool)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c
index 01ca12ea46f..5bb0e6b9025 100644
--- a/mps/code/poolawl.c
+++ b/mps/code/poolawl.c
@@ -1,7 +1,7 @@
/* poolawl.c: AUTOMATIC WEAK LINKED POOL CLASS
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
*
* DESIGN
@@ -1206,6 +1206,7 @@ static Res AWLAccess(Pool pool, Seg seg, Addr addr,
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
AVER(SegPool(seg) == pool);
+ AVERT(AccessSet, mode);
/* Attempt scanning a single reference if permitted */
if(AWLCanTrySingleAccess(PoolArena(pool), awl, seg, addr)) {
@@ -1375,7 +1376,7 @@ static Bool AWLCheck(AWL awl)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/poolmv.c b/mps/code/poolmv.c
index 709dfb6bf7b..19b3c2bb443 100644
--- a/mps/code/poolmv.c
+++ b/mps/code/poolmv.c
@@ -1,7 +1,7 @@
/* poolmv.c: MANUAL VARIABLE POOL
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 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
@@ -260,7 +260,7 @@ static Res MVInit(Pool pool, ArgList args)
res = PoolInit(mvBlockPool(mv), arena, PoolClassMFS(), piArgs);
} MPS_ARGS_END(piArgs);
if(res != ResOK)
- return res;
+ goto failBlockPoolInit;
spanExtendBy = sizeof(MVSpanStruct) * (maxSize/extendBy);
@@ -270,7 +270,7 @@ static Res MVInit(Pool pool, ArgList args)
res = PoolInit(mvSpanPool(mv), arena, PoolClassMFS(), piArgs);
} MPS_ARGS_END(piArgs);
if(res != ResOK)
- return res;
+ goto failSpanPoolInit;
mv->extendBy = extendBy;
mv->avgSize = avgSize;
@@ -284,6 +284,11 @@ static Res MVInit(Pool pool, ArgList args)
AVERT(MV, mv);
EVENT5(PoolInitMV, pool, arena, extendBy, avgSize, maxSize);
return ResOK;
+
+failSpanPoolInit:
+ PoolFinish(mvBlockPool(mv));
+failBlockPoolInit:
+ return res;
}
@@ -913,7 +918,7 @@ Bool MVCheck(MV mv)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/protan.c b/mps/code/protan.c
index 1959e42395b..0e4771f18da 100644
--- a/mps/code/protan.c
+++ b/mps/code/protan.c
@@ -1,7 +1,7 @@
/* protan.c: ANSI MEMORY PROTECTION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
*
* DESIGN
@@ -36,8 +36,7 @@ Size ProtGranularity(void)
void ProtSet(Addr base, Addr limit, AccessSet pm)
{
AVER(base < limit);
- /* .improve.protset.check: There is nor AccessSetCheck, so we */
- /* don't check it. */
+ AVERT(AccessSet, pm);
UNUSED(pm);
NOOP;
}
@@ -74,7 +73,7 @@ void ProtSync(Arena arena)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/protix.c b/mps/code/protix.c
index ea674ae53d5..a243b009491 100644
--- a/mps/code/protix.c
+++ b/mps/code/protix.c
@@ -1,7 +1,7 @@
/* protix.c: PROTECTION FOR UNIX
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* Somewhat generic across different Unix systems. Shared between
* OS X, FreeBSD, and Linux.
@@ -66,6 +66,7 @@ void ProtSet(Addr base, Addr limit, AccessSet mode)
AVER(base < limit);
AVER(base != 0);
AVER(AddrOffset(base, limit) <= INT_MAX); /* should be redundant */
+ AVERT(AccessSet, mode);
/* Convert between MPS AccessSet and UNIX PROT thingies.
In this function, AccessREAD means protect against read accesses
@@ -122,7 +123,7 @@ Size ProtGranularity(void)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/protw3.c b/mps/code/protw3.c
index 30c3edc0975..a8dddd74fe2 100644
--- a/mps/code/protw3.c
+++ b/mps/code/protw3.c
@@ -1,7 +1,7 @@
/* protw3.c: PROTECTION FOR WIN32
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*/
#include "mpm.h"
@@ -26,6 +26,7 @@ void ProtSet(Addr base, Addr limit, AccessSet mode)
AVER(base < limit);
AVER(base != 0);
+ AVERT(AccessSet, mode);
newProtect = PAGE_EXECUTE_READWRITE;
if((mode & AccessWRITE) != 0)
@@ -140,7 +141,7 @@ void ProtSync(Arena arena)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/reserv.c b/mps/code/reserv.c
index b0d431c3f9c..91a2fd52559 100644
--- a/mps/code/reserv.c
+++ b/mps/code/reserv.c
@@ -100,6 +100,7 @@ Bool ReservoirCheck(Reservoir reservoir)
}
CHECKL(SizeIsArenaGrains(reservoir->reservoirLimit, arena));
CHECKL(SizeIsArenaGrains(reservoir->reservoirSize, arena));
+ CHECKL(reservoir->reservoirSize <= reservoir->reservoirLimit);
return TRUE;
}
diff --git a/mps/code/root.c b/mps/code/root.c
index bd9afec57d4..7a3e1205be2 100644
--- a/mps/code/root.c
+++ b/mps/code/root.c
@@ -1,7 +1,7 @@
/* root.c: ROOT IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* .purpose: This is the implementation of the root datatype.
*
@@ -139,7 +139,7 @@ Bool RootCheck(Root root)
CHECKL(root->protBase != (Addr)0);
CHECKL(root->protLimit != (Addr)0);
CHECKL(root->protBase < root->protLimit);
- /* there is no AccessSetCheck */
+ CHECKL(AccessSetCheck(root->pm));
} else {
CHECKL(root->protBase == (Addr)0);
CHECKL(root->protLimit == (Addr)0);
@@ -263,7 +263,9 @@ Res RootCreateTable(Root *rootReturn, Arena arena,
AVERT(Arena, arena);
AVERT(Rank, rank);
AVER(base != 0);
- AVER(base < limit);
+ AVER(AddrIsAligned(base, sizeof(Word)));
+ AVER(base < limit);
+ AVER(AddrIsAligned(limit, sizeof(Word)));
theUnion.table.base = base;
theUnion.table.limit = limit;
@@ -315,6 +317,13 @@ Res RootCreateReg(Root *rootReturn, Arena arena,
return rootCreate(rootReturn, arena, rank, (RootMode)0, RootREG, &theUnion);
}
+/* RootCreateFmt -- create root from block of formatted objects
+ *
+ * .fmt.no-align-check: Note that we don't check the alignment of base
+ * and limit. That's because we're only given the scan function, so we
+ * don't know the format's alignment requirements.
+ */
+
Res RootCreateFmt(Root *rootReturn, Arena arena,
Rank rank, RootMode mode, mps_fmt_scan_t scan,
Addr base, Addr limit)
@@ -549,7 +558,7 @@ Bool RootOfAddr(Root *rootReturn, Arena arena, Addr addr)
void RootAccess(Root root, AccessSet mode)
{
AVERT(Root, root);
- /* Can't AVERT mode. */
+ AVERT(AccessSet, mode);
AVER((root->pm & mode) != AccessSetEMPTY);
AVER(mode == AccessWRITE); /* only write protection supported */
@@ -698,7 +707,7 @@ Res RootsDescribe(Globals arenaGlobals, mps_lib_FILE *stream, Count depth)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/seg.c b/mps/code/seg.c
index ab7414eaf4a..7007bca62b7 100644
--- a/mps/code/seg.c
+++ b/mps/code/seg.c
@@ -1,7 +1,7 @@
/* seg.c: SEGMENTS
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* .design: The design for this module is .
*
@@ -529,7 +529,7 @@ Bool SegNextOfRing(Seg *segReturn, Arena arena, Pool pool, Ring next)
AVER_CRITICAL(segReturn != NULL); /* .seg.critical */
AVERT_CRITICAL(Arena, arena);
AVERT_CRITICAL(Pool, pool);
- AVER_CRITICAL(RingCheck(next));
+ AVERT_CRITICAL(Ring, next);
if (next == PoolSegRing(pool)) {
if (!PoolNext(&pool, arena, pool) ||
@@ -1224,7 +1224,7 @@ static void gcSegSetGrey(Seg seg, TraceSet grey)
Arena arena;
AVERT_CRITICAL(Seg, seg); /* .seg.method.check */
- AVER_CRITICAL(TraceSetCheck(grey)); /* .seg.method.check */
+ AVERT_CRITICAL(TraceSet, grey); /* .seg.method.check */
AVER(seg->rankSet != RankSetEMPTY);
gcseg = SegGCSeg(seg);
AVERT_CRITICAL(GCSeg, gcseg);
@@ -1264,7 +1264,7 @@ static void gcSegSetWhite(Seg seg, TraceSet white)
Addr addr, limit;
AVERT_CRITICAL(Seg, seg); /* .seg.method.check */
- AVER_CRITICAL(TraceSetCheck(white)); /* .seg.method.check */
+ AVERT_CRITICAL(TraceSet, white); /* .seg.method.check */
gcseg = SegGCSeg(seg);
AVERT_CRITICAL(GCSeg, gcseg);
AVER_CRITICAL(&gcseg->segStruct == seg);
@@ -1307,7 +1307,7 @@ static void gcSegSetRankSet(Seg seg, RankSet rankSet)
Arena arena;
AVERT_CRITICAL(Seg, seg); /* .seg.method.check */
- AVER_CRITICAL(RankSetCheck(rankSet)); /* .seg.method.check */
+ AVERT_CRITICAL(RankSet, rankSet); /* .seg.method.check */
AVER_CRITICAL(rankSet == RankSetEMPTY
|| RankSetIsSingle(rankSet)); /* .seg.method.check */
gcseg = SegGCSeg(seg);
@@ -1378,7 +1378,7 @@ static void gcSegSetRankSummary(Seg seg, RankSet rankSet, RefSet summary)
Arena arena;
AVERT_CRITICAL(Seg, seg); /* .seg.method.check */
- AVER_CRITICAL(RankSetCheck(rankSet)); /* .seg.method.check */
+ AVERT_CRITICAL(RankSet, rankSet); /* .seg.method.check */
AVER_CRITICAL(rankSet == RankSetEMPTY
|| RankSetIsSingle(rankSet)); /* .seg.method.check */
gcseg = SegGCSeg(seg);
@@ -1701,7 +1701,7 @@ void SegClassMixInNoSplitMerge(SegClass class)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/shield.c b/mps/code/shield.c
index 88ee8751331..0dfc1945db6 100644
--- a/mps/code/shield.c
+++ b/mps/code/shield.c
@@ -1,7 +1,7 @@
/* shield.c: SHIELD IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* See: idea.shield, design.mps.shield.
*
@@ -105,6 +105,7 @@ static void protLower(Arena arena, Seg seg, AccessSet mode)
AVERT_CRITICAL(Arena, arena);
UNUSED(arena);
AVERT_CRITICAL(Seg, seg);
+ AVERT_CRITICAL(AccessSet, mode);
if (SegPM(seg) & mode) {
SegSetPM(seg, SegPM(seg) & ~mode);
@@ -191,6 +192,7 @@ void (ShieldRaise) (Arena arena, Seg seg, AccessSet mode)
/* can't check seg. Nor can we check arena as that checks the */
/* segs in the cache. */
+ AVERT(AccessSet, mode);
AVER((SegSM(seg) & mode) == AccessSetEMPTY);
SegSetSM(seg, SegSM(seg) | mode); /* inv.prot.shield preserved */
@@ -204,6 +206,7 @@ void (ShieldRaise) (Arena arena, Seg seg, AccessSet mode)
void (ShieldLower)(Arena arena, Seg seg, AccessSet mode)
{
/* Don't check seg or arena, see .seg.broken */
+ AVERT(AccessSet, mode);
AVER((SegSM(seg) & mode) == mode);
/* synced(seg) is not changed by the following
* preserving inv.unsynced.suspended
@@ -336,7 +339,7 @@ void (ShieldCover)(Arena arena, Seg seg)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/splay.c b/mps/code/splay.c
index 658faa7dd25..ed46c7a4ba4 100644
--- a/mps/code/splay.c
+++ b/mps/code/splay.c
@@ -1,7 +1,7 @@
/* splay.c: SPLAY TREE IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (c) 2001-2015 Ravenbrook Limited. See end of file for license.
*
* .purpose: Splay trees are used to manage potentially unbounded
* collections of ordered things. In the MPS these are usually
@@ -9,10 +9,9 @@
*
* .source:
*
- * .note.stack: It's important that the MPS have a bounded stack
- * size, and this is a problem for tree algorithms. Basically,
- * we have to avoid recursion. TODO: Design documentation for this
- * requirement, meanwhile see job003651 and job003640.
+ * .note.stack: It's important that the MPS have a bounded stack size,
+ * and this is a problem for tree algorithms. Basically, we have to
+ * avoid recursion. See design.mps.sp.sol.depth.no-recursion.
*/
@@ -1402,7 +1401,7 @@ Res SplayTreeDescribe(SplayTree splay, mps_lib_FILE *stream, Count depth,
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited .
+ * Copyright (C) 2001-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/trace.c b/mps/code/trace.c
index 7aeb70305c7..7e918513279 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.c
@@ -1,7 +1,7 @@
/* trace.c: GENERIC TRACER IMPLEMENTATION
*
* $Id$
- * Copyright (c) 2001-2014 Ravenbrook Limited.
+ * Copyright (c) 2001-2015 Ravenbrook Limited.
* See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
@@ -1188,6 +1188,7 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode)
AVERT(Arena, arena);
AVERT(Seg, seg);
+ AVERT(AccessSet, mode);
/* If it's a read access, then the segment must be grey for a trace */
/* which is flipped. */
@@ -1962,7 +1963,7 @@ Res TraceDescribe(Trace trace, mps_lib_FILE *stream, Count depth)
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2001-2014 Ravenbrook Limited
+ * Copyright (C) 2001-2015 Ravenbrook Limited
* .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
diff --git a/mps/code/traceanc.c b/mps/code/traceanc.c
index 77fe772d587..ede8d012fe8 100644
--- a/mps/code/traceanc.c
+++ b/mps/code/traceanc.c
@@ -674,7 +674,7 @@ static Res arenaRememberSummaryOne(Globals global, Addr base, RefSet summary)
RememberedSummaryBlock newBlock;
int res;
- res = ControlAlloc(&p, arena, sizeof *newBlock, 0);
+ res = ControlAlloc(&p, arena, sizeof *newBlock, FALSE);
if(res != ResOK) {
return res;
}
@@ -704,12 +704,13 @@ static Res arenaRememberSummaryOne(Globals global, Addr base, RefSet summary)
protection state or not (for later restoration with
ArenaRestoreProtection).
*/
-void ArenaExposeRemember(Globals globals, int remember)
+void ArenaExposeRemember(Globals globals, Bool remember)
{
Seg seg;
Arena arena;
AVERT(Globals, globals);
+ AVERT(Bool, remember);
ArenaPark(globals);
diff --git a/mps/code/tract.c b/mps/code/tract.c
index 5d3bffe9721..9aa815f47ba 100644
--- a/mps/code/tract.c
+++ b/mps/code/tract.c
@@ -167,7 +167,8 @@ Bool ChunkCheck(Chunk chunk)
/* ChunkInit -- initialize generic part of chunk */
-Res ChunkInit(Chunk chunk, Arena arena, Addr base, Addr limit, BootBlock boot)
+Res ChunkInit(Chunk chunk, Arena arena, Addr base, Addr limit, Size reserved,
+ BootBlock boot)
{
Size size;
Count pages;
@@ -192,6 +193,7 @@ Res ChunkInit(Chunk chunk, Arena arena, Addr base, Addr limit, BootBlock boot)
chunk->pageShift = pageShift = SizeLog2(chunk->pageSize);
chunk->base = base;
chunk->limit = limit;
+ chunk->reserved = reserved;
size = ChunkSize(chunk);
chunk->pages = pages = size >> pageShift;
@@ -262,17 +264,16 @@ void ChunkFinish(Chunk chunk)
PageIndexBase(chunk, chunk->allocBase),
chunk->limit);
+ ArenaChunkRemoved(arena, chunk);
+
chunk->sig = SigInvalid;
TreeFinish(&chunk->chunkTree);
RingRemove(&chunk->arenaRing);
- if (chunk->arena->primary == chunk)
- chunk->arena->primary = NULL;
-
/* Finish all other fields before class finish, because they might be */
/* unmapped there. */
- (chunk->arena->class->chunkFinish)(chunk);
+ (*arena->class->chunkFinish)(chunk);
}
diff --git a/mps/code/tract.h b/mps/code/tract.h
index 07906ad5756..ce7c602a176 100644
--- a/mps/code/tract.h
+++ b/mps/code/tract.h
@@ -148,6 +148,9 @@ typedef struct ChunkStruct {
BT allocTable; /* page allocation table */
Page pageTable; /* the page table */
Count pageTablePages; /* number of pages occupied by page table */
+ Size reserved; /* reserved address space for chunk (including overhead
+ such as losses due to alignment): must not change
+ (or arena reserved calculation will break) */
} ChunkStruct;
@@ -159,10 +162,11 @@ typedef struct ChunkStruct {
#define ChunkSizeToPages(chunk, size) ((Count)((size) >> (chunk)->pageShift))
#define ChunkPage(chunk, pi) (&(chunk)->pageTable[pi])
#define ChunkOfTree(tree) PARENT(ChunkStruct, chunkTree, tree)
+#define ChunkReserved(chunk) RVALUE((chunk)->reserved)
extern Bool ChunkCheck(Chunk chunk);
extern Res ChunkInit(Chunk chunk, Arena arena, Addr base, Addr limit,
- BootBlock boot);
+ Size reserved, BootBlock boot);
extern void ChunkFinish(Chunk chunk);
extern Compare ChunkCompare(Tree tree, TreeKey key);
extern TreeKey ChunkKey(Tree tree);
diff --git a/mps/code/tree.c b/mps/code/tree.c
index fb651ed5919..f87e8364ea7 100644
--- a/mps/code/tree.c
+++ b/mps/code/tree.c
@@ -1,7 +1,7 @@
/* tree.c: BINARY TREE IMPLEMENTATION
*
* $Id$
- * Copyright (C) 2014 Ravenbrook Limited. See end of file for license.
+ * Copyright (C) 2014-2015 Ravenbrook Limited. See end of file for license.
*
* Simple binary trees with utilities, for use as building blocks.
* Keep it simple, like Rings (see ring.h).
@@ -9,10 +9,9 @@
* The performance requirements on tree implementation will depend on
* how each individual function is applied in the MPS.
*
- * .note.stack: It's important that the MPS have a bounded stack
- * size, and this is a problem for tree algorithms. Basically,
- * we have to avoid recursion. TODO: Design documentation for this
- * requirement, meanwhile see job003651 and job003640.
+ * .note.stack: It's important that the MPS have a bounded stack size,
+ * and this is a problem for tree algorithms. Basically, we have to
+ * avoid recursion. See design.mps.sp.sol.depth.no-recursion.
*/
#include "tree.h"
@@ -569,7 +568,7 @@ void TreeTraverseAndDelete(Tree *treeIO, TreeVisitor visitor,
/* C. COPYRIGHT AND LICENSE
*
- * Copyright (C) 2014 Ravenbrook Limited .
+ * Copyright (C) 2014-2015 Ravenbrook Limited .
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
diff --git a/mps/code/w3i3mv.nmk b/mps/code/w3i3mv.nmk
index ff84851b1de..92e609b5f2f 100644
--- a/mps/code/w3i3mv.nmk
+++ b/mps/code/w3i3mv.nmk
@@ -5,9 +5,6 @@
PFM = w3i3mv
-PFMDEFS = /DCONFIG_PF_STRING="w3i3mv" /DCONFIG_PF_W3I3MV /DWIN32 /D_WINDOWS
-
-# MPM platform-specific sources.
MPMPF = \
[lockw3] \
[mpsiw3] \
@@ -20,9 +17,8 @@ MPMPF = \
[thw3i3] \
[vmw3]
-!INCLUDE commpre.nmk
!INCLUDE mv.nmk
-!INCLUDE commpost.nmk
+!INCLUDE comm.nmk
# C. COPYRIGHT AND LICENSE
diff --git a/mps/code/w3i3pc.nmk b/mps/code/w3i3pc.nmk
index da76ee4d338..5ffe8892ebb 100644
--- a/mps/code/w3i3pc.nmk
+++ b/mps/code/w3i3pc.nmk
@@ -5,9 +5,6 @@
PFM = w3i3pc
-PFMDEFS = /DCONFIG_PF_STRING="w3i3pc" /DCONFIG_PF_W3I3PC /DWIN32 /D_WINDOWS
-
-# MPM platform-specific sources.
MPMPF = \
[lockw3] \
[mpsiw3] \
@@ -20,9 +17,8 @@ MPMPF = \
[thw3i3] \
[vmw3]
-!INCLUDE commpre.nmk
!INCLUDE pc.nmk
-!INCLUDE commpost.nmk
+!INCLUDE comm.nmk
# C. COPYRIGHT AND LICENSE
diff --git a/mps/code/w3i6mv.nmk b/mps/code/w3i6mv.nmk
index 26f4329bc0e..eb36bc200d2 100644
--- a/mps/code/w3i6mv.nmk
+++ b/mps/code/w3i6mv.nmk
@@ -5,10 +5,6 @@
PFM = w3i6mv
-PFMDEFS = /DCONFIG_PF_STRING="w3i6mv" /DCONFIG_PF_W3I6MV /DWIN32 /D_WINDOWS
-MASM = ml64
-
-# MPM platform-specific sources.
MPMPF = \
[lockw3] \
[mpsiw3] \
@@ -21,9 +17,8 @@ MPMPF = \
[thw3i6] \
[vmw3]
-!INCLUDE commpre.nmk
!INCLUDE mv.nmk
-!INCLUDE commpost.nmk
+!INCLUDE comm.nmk
# C. COPYRIGHT AND LICENSE
diff --git a/mps/code/w3i6pc.nmk b/mps/code/w3i6pc.nmk
index 9870f697e4b..31b86a82fc0 100644
--- a/mps/code/w3i6pc.nmk
+++ b/mps/code/w3i6pc.nmk
@@ -7,11 +7,8 @@
PFM = w3i6pc
-PFMDEFS = /DCONFIG_PF_STRING="w3i6pc" /DCONFIG_PF_W3I6PC /DWIN32 /D_WINDOWS
+CFLAGSTARGETPRE = /Tamd64-coff
-CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /Tamd64-coff
-
-# MPM platform-specific sources.
MPMPF = \
[lockw3] \
[mpsiw3] \
@@ -24,9 +21,8 @@ MPMPF = \
[thw3i6] \
[vmw3]
-!INCLUDE commpre.nmk
!INCLUDE pc.nmk
-!INCLUDE commpost.nmk
+!INCLUDE comm.nmk
# C. COPYRIGHT AND LICENSE
diff --git a/mps/design/an.txt b/mps/design/an.txt
new file mode 100644
index 00000000000..7d6cc117407
--- /dev/null
+++ b/mps/design/an.txt
@@ -0,0 +1,216 @@
+.. mode: -*- rst -*-
+
+Generic modules
+===============
+
+:Tag: design.mps.an
+:Author: Gareth Rees
+:Date: 2014-11-02
+:Status: complete design
+:Revision: $Id$
+:Copyright: See `Copyright and License`_.
+:Index terms: pair: generic modules; design
+
+
+Introduction
+------------
+
+_`.intro`: This is the design of generic modules in the MPS.
+
+_`.readership`: Any MPS developer; anyone porting the MPS to a new
+platform.
+
+_`.overview`: Generic modules provide implementations of functional
+modules using only the features of the Standard C Library. These
+implementations are partially functional or non-functional, but
+provide a basis for ports of the MPS to new platforms.
+
+_`.name`: The name "ANSI" for the generic modules is historical: the C
+language was originally standardized by the American National
+Standards Institute, and so Standard C used to be known as "ANSI C".
+
+
+Requirements
+------------
+
+_`.req.port`: The MPS must be portable to new platforms. (Otherwise we
+can't meet the needs of customers using new platforms.)
+
+_`.req.port.rapid`: The MPS should be portable to new platforms
+rapidly.
+
+_`.req.port.rapid.expert`: An expert MPS developer (who may be a
+novice on the new platform) should be able to get a minimally useful
+implementation of the MPS running on a new platform within a few
+hours.
+
+_`.req.port.rapid.novice`: A novice MPS developer (who is an expert on
+the new platform) should be able to get the MPS running on a new
+platform within a few days.
+
+
+Design
+------
+
+_`.sol.modules`: Features of the MPS which can benefit from
+platform-specific implementations are divided into *functional
+modules*, with clean interfaces to the MPS and to each other. See
+`.mod`_ for a list of these modules. (This helps meet `.req.port`_ by
+isolating the platform dependencies, and it helps meet
+`.req.port.rapid`_ because a porter can mix and match implementations,
+using existing implementations where possible.)
+
+_`.sol.generic`: Each functional module has a generic implementation
+using only features of the Standard C Library. (This helps meet
+`.req.port.rapid`_ because the MPS can be ported in stages, starting
+with the generic modules and porting the modules needed to meet the
+most urgent requirements. The generic implementations help meet
+`.req.port.rapid.novice`_ by providing clear and illustrative
+examples.)
+
+_`.sol.fallback`: The interfaces to the modules are designed to make
+it possible to implement `.sol.generic`_. When a platform-specific
+feature is needed to meet performance (or other attribute)
+requirements, the interface also makes it possible to meet the
+functional requirements while missing the attribute requirements. See
+`.sol.fallback.example`_ for an example. (This helps meet
+`.req.port.rapid`_ by allowing the generic implementations to meet
+many or most of the functional requirements.)
+
+_`.sol.fallback.example`: The MPS normally uses incremental collection
+to meet requirements on pause times, but this requires barriers. The
+interface to the protection module is designed to make it possible to
+write an implementation without barriers, via the function
+``ProtSync()`` that synchronizes the mutator with the collector.
+
+_`.sol.test`: There are makefiles for the pseudo-platforms ``anangc``,
+``ananll`` and ``ananmv`` that compile and test the generic
+implementations. See design.mps.config.opt_ for the configuration
+options used to implement these platforms. (This supports
+`.req.port.rapid`_ by making sure that the generic implementations are
+working when it is time to use them.)
+
+.. _design.mps.config.opt: config#opt
+
+
+Modules
+-------
+
+_`.mod`: This section lists the functional modules in the MPS.
+
+_`.mod.lock`: Locks. See design.mps.lock_.
+
+_`.mod.prmc`: Protection mutator context. See design.mps.prmc_.
+
+_`.mod.prot`: Memory protection. See design.mps.prot_.
+
+_`.mod.ss`: Stack and register scanning. See design.mps.ss_.
+
+_`.mod.sp`: Stack probe. See design.mps.sp_.
+
+_`.mod.th`: Thread manager. See design.mps.thread-manager_.
+
+_`.mod.vm`: Virtual mapping. See design.mps.vm_.
+
+.. _design.mps.lock: lock
+.. _design.mps.prot: prot
+.. _design.mps.prmc: prmc
+.. _design.mps.sp: sp
+.. _design.mps.ss: ss
+.. _design.mps.thread-manager: thread-manager
+.. _design.mps.vm: vm
+
+
+Limitations of generic implementations
+--------------------------------------
+
+_`.lim`: This section summarizes the limitations of the generic
+implementations of the function modules.
+
+_`.lim.lock`: Requires a single-threaded mutator (see
+design.mps.lock.impl.an_).
+
+_`.lim.prmc`: Does not support single-stepping of accesses (see
+design.mps.prmc.impl.an.fault_) and requires a single-threaded mutator
+(see design.mps.prmc.impl.an.suspend_).
+
+_`.lim.prot`: Does not support incremental collection (see
+design.mps.prot.impl.an.sync_) and is not compatible with
+implementations of the protection mutator context module that support
+single-stepping of accesses (see design.mps.prot.impl.an.sync.issue_).
+
+_`.lim.sp`: Only suitable for use with programs that do not handle
+stack overflow faults, or do not call into the MPS from the handler
+(see design.mps.sp.issue.an_).
+
+_`.lim.ss`: Overscans compared to a platform-specific implementation
+(see design.mps.ss.impl.an_).
+
+_`.lim.th`: Requires a single-threaded mutator (see
+design.mps.thread-manager.impl.an.single_).
+
+_`.lim.vm`: Maps all reserved addresses into main memory (see
+design.mps.vm.impl.an.reserve_), thus using more main memory than a
+platform-specific implementation.
+
+.. _design.mps.lock.impl.an: lock#impl.an
+.. _design.mps.prmc.impl.an.fault: prmc#impl.an.fault
+.. _design.mps.prmc.impl.an.suspend: prmc#impl.an.suspend
+.. _design.mps.prot.impl.an.sync: prot#impl.an.sync
+.. _design.mps.prot.impl.an.sync.issue: prot#impl.an.sync.issue
+.. _design.mps.sp.issue.an: sp#issue.an
+.. _design.mps.ss.impl.an: ss#impl.an
+.. _design.mps.thread-manager.impl.an.single: thread-manager#impl.an.single
+.. _design.mps.vm.impl.an.reserve: vm#impl.an.reserve
+
+
+
+Document History
+----------------
+
+- 2014-11-02 GDR_ Initial draft based on design.mps.protan.
+
+.. _GDR: http://www.ravenbrook.com/consultants/gdr/
+
+
+Copyright and License
+---------------------
+
+Copyright © 2014 Ravenbrook Limited. All rights reserved.
+ . This is an open source license. Contact
+Ravenbrook for commercial licensing options.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+#. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+#. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+#. Redistributions in any form must be accompanied by information on how
+ to obtain complete source code for this software and any
+ accompanying software that uses this software. The source code must
+ either be included in the distribution or be available for no more than
+ the cost of distribution plus a nominal fee, and must be freely
+ redistributable under reasonable conditions. For an executable file,
+ complete source code means the source code for all modules it contains.
+ It does not include source code for modules or files that typically
+ accompany the major components of the operating system on which the
+ executable file runs.
+
+**This software is provided by the copyright holders and contributors
+"as is" and any express or implied warranties, including, but not
+limited to, the implied warranties of merchantability, fitness for a
+particular purpose, or non-infringement, are disclaimed. In no event
+shall the copyright holders and contributors be liable for any direct,
+indirect, incidental, special, exemplary, or consequential damages
+(including, but not limited to, procurement of substitute goods or
+services; loss of use, data, or profits; or business interruption)
+however caused and on any theory of liability, whether in contract,
+strict liability, or tort (including negligence or otherwise) arising in
+any way out of the use of this software, even if advised of the
+possibility of such damage.**
diff --git a/mps/design/bootstrap.txt b/mps/design/bootstrap.txt
new file mode 100644
index 00000000000..7eb79df1475
--- /dev/null
+++ b/mps/design/bootstrap.txt
@@ -0,0 +1,127 @@
+.. mode: -*- rst -*-
+
+Bootstrapping
+=============
+
+:Tag: design.mps.bootstrap
+:Author: Gareth Rees
+:Date: 2015-09-01
+:Status: incomplete design
+:Revision: $Id$
+:Copyright: See section `Copyright and License`_.
+:Index terms: pair: bootsrap; design
+
+
+Introduction
+------------
+
+_`.intro`: This explains how the MPS gets started.
+
+_`.readership`: Any MPS developer.
+
+_`.overview`: The job of the MPS is to allocate memory to a program.
+Before it can allocate memory, the MPS needs to create data structures
+to represent its internal state. But before it can create those data
+structures, it needs to allocate memory to store them in. This
+bootstrapping problem affects the MPS at several points, which are
+listed here, together with their solutions.
+
+
+Bootstrapping problems
+----------------------
+
+Virtual memory descriptor
+.........................
+
+_`.vm`: Before address space can be mapped into main memory, the
+virtual memory descriptor must be initialized. But before the virtual
+memory descriptor can be initialized, some address space must be
+mapped into main memory in order to store it. See
+`design.vm.req.bootstrap`_.
+
+_`.vm.sol`: The virtual memory descriptor is allocated initially on
+the stack, and then copied into its place in the chunk after the
+memory for it has been mapped. See `design.vm.sol.bootstrap`_.
+
+.. _design.vm.req.bootstrap: vm#req.bootstrap
+.. _design.vm.sol.bootstrap: vm#sol.bootstrap
+
+
+Arena descriptor
+................
+
+_`.arena`: Before chunks of address space can be reserved and mapped,
+the virtual memory arena descriptor must be initialized (so that the
+chunks can be added to the arena's chunk tree). But before a virtual
+memory arena descriptor can be initialized, address space must be
+reserved and mapped in order to store it.
+
+_`.arena.sol`: A small amount of address space is reserved and mapped
+directly via ``VMInit()`` and ``VMMap()`` (not via the chunk system)
+in order to provide enough memory for the arena descriptor.
+
+
+Arena's free land
+.................
+
+_`.land`: Before the arena can allocate memory, a range of addresses
+must be inserted into the arena's free land (so that the free land can
+hand out memory from this range). But before addresses can be inserted
+into the arena's free land, the arena must be able to allocate memory
+(to store the nodes in the tree representing those addresses).
+
+_`.land.sol`: The arena has two "back door" mechanisms and uses them
+in combination. First, there is a mechanism for allocating a block of
+memory directly from a chunk, bypassing the free land; second, the MFS
+pool class has a mechanism for extending it with a block of memory.
+
+
+Document History
+----------------
+
+- 2015-09-01 GDR_ Initial draft.
+
+.. _GDR: http://www.ravenbrook.com/consultants/gdr/
+
+
+Copyright and License
+---------------------
+
+Copyright © 2015 Ravenbrook Limited. All rights reserved.
+ . This is an open source license. Contact
+Ravenbrook for commercial licensing options.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+#. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+#. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+#. Redistributions in any form must be accompanied by information on how
+ to obtain complete source code for this software and any
+ accompanying software that uses this software. The source code must
+ either be included in the distribution or be available for no more than
+ the cost of distribution plus a nominal fee, and must be freely
+ redistributable under reasonable conditions. For an executable file,
+ complete source code means the source code for all modules it contains.
+ It does not include source code for modules or files that typically
+ accompany the major components of the operating system on which the
+ executable file runs.
+
+**This software is provided by the copyright holders and contributors
+"as is" and any express or implied warranties, including, but not
+limited to, the implied warranties of merchantability, fitness for a
+particular purpose, or non-infringement, are disclaimed. In no event
+shall the copyright holders and contributors be liable for any direct,
+indirect, incidental, special, exemplary, or consequential damages
+(including, but not limited to, procurement of substitute goods or
+services; loss of use, data, or profits; or business interruption)
+however caused and on any theory of liability, whether in contract,
+strict liability, or tort (including negligence or otherwise) arising in
+any way out of the use of this software, even if advised of the
+possibility of such damage.**
diff --git a/mps/design/cbs.txt b/mps/design/cbs.txt
index 629ffee08fe..34c2eedd4cd 100644
--- a/mps/design/cbs.txt
+++ b/mps/design/cbs.txt
@@ -76,14 +76,14 @@ class, a subclass of ``LandClass`` suitable for passing to
``LandClass CBSFastLandClassGet(void)``
-_`.function.class`: Returns a subclass of ``CBSLandClass`` that
+_`.function.class.fast`: Returns a subclass of ``CBSLandClass`` that
maintains, for each subtree, the size of the largest block in that
subtree. This enables the ``LandFindFirst()``, ``LandFindLast()``, and
``LandFindLargest()`` generic functions.
``LandClass CBSZonedLandClassGet(void)``
-_`.function.class`: Returns a subclass of ``CBSFastLandClass`` that
+_`.function.class.zoned`: Returns a subclass of ``CBSFastLandClass`` that
maintains, for each subtree, the union of the zone sets of all ranges
in that subtree. This enables the ``LandFindInZones()`` generic
function.
diff --git a/mps/design/exec-env.txt b/mps/design/exec-env.txt
new file mode 100644
index 00000000000..65de1dd228f
--- /dev/null
+++ b/mps/design/exec-env.txt
@@ -0,0 +1,189 @@
+.. mode: -*- rst -*-
+
+Execution environment
+=====================
+
+:Tag: design.mps.exec-env
+:Author: Richard Brooksby
+:Date: 1996-08-30
+:Status: incomplete design
+:Revision: $Id$
+:Copyright: See section `Copyright and License`_.
+:Index terms: pair: execution; environment
+
+
+Introduction
+------------
+
+_`.intro`: This document describes how the MPS is designed to work in
+different execution environments (see standard.ansic section 5.1.2).
+
+
+Discussion
+----------
+
+_`.std`: These are the relevant statements from the International
+Standard ISO/IEC 9899:1990 "Programming languages — C", with tags
+added:
+
+ 4. Compliance
+
+ […]
+
+ _`.std.com.hosted`: A "conforming hosted implementation" shall
+ accept any strictly conforming program. _`.std.com.free`: A
+ "conforming freestanding implementation" shall accept any strictly
+ conforming program in which the use of the features specified in
+ the library clause (clause 7) is confined to the contents of the
+ standard headers ````, ````, ````,
+ and ````. A conforming implementation may have
+ extensions (including additional library functions), provided they
+ do not alter the behaviour of any strictly conforming program.
+
+ […]
+
+ 5.1.2 Execution environments
+
+ _`.std.def`: Two execution environments are defined:
+ "freestanding" and "hosted". […]
+
+ _`.std.init`: All objects in static storage shall be "initialized"
+ (set to their initial values) before program startup. The manner
+ and timing of such initialization are otherwise unspecified. […]
+
+ _`.std.term`: "Program termination" returns control to the execution
+ environment. […]
+
+ 5.1.2.1 Freestanding environment
+
+ _`.std.free.lib`: Any library facilities available to a
+ freestanding environment are implementation-defined.
+
+ _`.std.free.term`: The effect of program termination in a
+ free-standing environment is implementation-defined.
+
+
+Interpretation
+--------------
+
+_`.int.free`: We interpret the "freestanding environment" as being the
+sort of environment you'd expect in an embedded system. The classic
+example is a washing machine. There are no library facilities
+available, only language facilities.
+
+_`.int.free.lib`: We assume that the headers ````,
+````, ```` and ```` are available in the
+freestanding environment, because they define only language features
+and not library calls. We assume that we may not make use of
+definitions in any other headers in freestanding parts of the system.
+
+_`.int.free.term`: We may not terminate the program in a freestanding
+environment, and therefore we may not call :c:func:`abort`. We can't
+call :c:func:`abort` anyway, because it's not defined in the headers
+listed above (`.int.free.lib`_).
+
+_`.int.free.term.own`: We can add an interface for asserting, that is,
+reporting an error and not returning, for use in debugging builds
+only. This is because the environment can implement this in a way that
+does not return to the MPS, but doesn't terminate, either. We need
+this if debugging builds are to run in a (possibly simulated or
+emulated) freestanding environment at all.
+
+
+Requirements
+------------
+
+_`.req`: It should be possible to make use of the MPS in a
+freestanding environment such as an embedded controller.
+
+_`.req.conf`: There can be configurations of the MPS that are not
+freestanding (such as using a VM arena).
+
+
+Architecture
+------------
+
+_`.arch`: Like Gaul, the MPS is divided into three parts: the *core*,
+the *platform*, and the *plinth*.
+
+_`.arch.core`: The *core* consists of the Memory Pool Manager (the
+core data structures and algorithms) and the built-in Pool Classes.
+The core must be freestanding.
+
+_`.arch.platform`: The *platform* provides the core with interfaces to
+features of the operating system and processor (locks, memory
+protection, protection mutator context, stack probing, stack and
+register scanning, thread management, and virtual memory). The
+platform is specialized to a particular environment and so can safely
+use whatever features are available in that environment.
+
+_`.arch.plinth`: The *plinth* provides the core with interfaces to
+features of the user environment (time, assertions, and logging). See
+design.mps.io_ and design.mps.lib_.
+
+.. _design.mps.io: io
+.. _design.mps.lib: lib
+
+_`.arch.distinction`: The distinction between *plinth* and *platform*
+is that end users will need to customize the features provided by the
+plinth for most programs that use the MPS (and so the interface needs
+to be simple, documented and supported), whereas implementing the
+platform interface is a specialized task that will typically be done
+once for each platform and then maintained alongside the core.
+
+
+Document History
+----------------
+
+- 1996-08-30 RB_ Created to clarify concepts needed for
+ design.mps.io_.
+
+- 2015-02-06 GDR_ Converted to reStructuredText; bring the
+ architecture description up to date by describing the platform
+ interface.
+
+.. _RB: http://www.ravenbrook.com/consultants/rb/
+.. _GDR: http://www.ravenbrook.com/consultants/gdr/
+
+
+Copyright and License
+---------------------
+
+Copyright © 1996-2015 Ravenbrook Limited. All rights reserved.
+ . This is an open source license. Contact
+Ravenbrook for commercial licensing options.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+#. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+#. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+#. Redistributions in any form must be accompanied by information on how
+ to obtain complete source code for this software and any
+ accompanying software that uses this software. The source code must
+ either be included in the distribution or be available for no more than
+ the cost of distribution plus a nominal fee, and must be freely
+ redistributable under reasonable conditions. For an executable file,
+ complete source code means the source code for all modules it contains.
+ It does not include source code for modules or files that typically
+ accompany the major components of the operating system on which the
+ executable file runs.
+
+**This software is provided by the copyright holders and contributors
+"as is" and any express or implied warranties, including, but not
+limited to, the implied warranties of merchantability, fitness for a
+particular purpose, or non-infringement, are disclaimed. In no event
+shall the copyright holders and contributors be liable for any direct,
+indirect, incidental, special, exemplary, or consequential damages
+(including, but not limited to, procurement of substitute goods or
+services; loss of use, data, or profits; or business interruption)
+however caused and on any theory of liability, whether in contract,
+strict liability, or tort (including negligence or otherwise) arising in
+any way out of the use of this software, even if advised of the
+possibility of such damage.**
diff --git a/mps/design/guide.hex.trans.txt b/mps/design/guide.hex.trans.txt
index 95c533f6bc8..8120f6e53e5 100644
--- a/mps/design/guide.hex.trans.txt
+++ b/mps/design/guide.hex.trans.txt
@@ -22,10 +22,11 @@ hexadecimal digits.
_`.readership`: This document is intended for anyone devising
arbitrary constants which may appear in hex-dumps.
-_`.sources`: This transliteration was supplied by RHSK in
-`mail.richardk.1997-04-07.13-44`_.
-
-.. _mail.richardk.1997-04-07.13-44: https://info.ravenbrook.com/project/mps/mail/1997/04/07/13-44/0.txt
+_`.sources`: This transliteration was supplied by Richard Kistruck
+[RHSK-1997-04-07]_ based on magic number encodings for object signatures
+used by Richard Brooksby [RB-1996-02-12]_, the existence of which was
+inspired by the structure marking used in the Multics operating system
+[THVV-1995]_.
Transliteration
@@ -78,8 +79,8 @@ _`.trans.t`: T is an exception to `.numbers`_, but is such a common
letter that it deserves it.
-4. Notes
---------
+Notes
+-----
_`.change`: This transliteration differs from the old transliteration
used for signatures (see design.mps.sig_), as follows: J:6->1;
@@ -106,6 +107,33 @@ selected (by capitalisation), e.g.::
#define SpaceSig ((Sig)0x5195BACE) /* SIGnature SPACE */
+References
+----------
+
+.. [RB-1996-02-12]
+ "Signature magic numbers" (e-mail message);
+ `Richard Brooksby`_;
+ Harlequin;
+ 1996-12-02 12:05:30Z.
+
+.. _`Richard Brooksby`: mailto:rb@ravenbrook.com
+
+.. [RHSK-1997-04-07]
+ "Alpha-to-Hex v1.0 beta";
+ Richard Kistruck;
+ Ravenbrook;
+ 1997-04-07 14:42:02+0100;
+ .
+
+.. [THVV-1995]
+ "Structure Marking";
+ Tom Van Vleck;
+ multicians.org_;
+ .
+
+.. _multicians.org: http://www.multicians.org/
+
+
Document History
----------------
2013-05-10 RB_ Converted to reStructuredText and imported to MPS design.
diff --git a/mps/design/guide.review.txt b/mps/design/guide.review.txt
new file mode 100644
index 00000000000..b1298b26b90
--- /dev/null
+++ b/mps/design/guide.review.txt
@@ -0,0 +1,96 @@
+.. mode: -*- rst -*-
+
+Review checklist
+================
+
+:Tag: guide.review
+:Status: incomplete documentation
+:Author: Gareth Rees
+:Organization: Ravenbrook Limited
+:Date: 2015-08-10
+:Revision: $Id$
+:Copyright: See section `Copyright and License`_.
+:Index terms: pair: review; checklist
+
+
+Introduction
+------------
+
+_`.scope`: This document contains a list of checks to apply when
+reviewing code or other documents in the Memory Pool System.
+
+_`.readership`: This document is intended for reviewers.
+
+_`.example`: The "example" links are issues caused by a failure to
+apply the checklist item.
+
+_`.diff`: Some items in the checklist are particularly susceptible to
+being ignored if one reviews only via the version control diff. These
+items refer to this tag.
+
+
+Checklist
+---------
+
+_`.test`: If a new feature has been added to the code, is there a test
+case? Example: job003923_.
+
+.. _job003923: http://www.ravenbrook.com/project/mps/issue/job003923/
+
+_`.unwind`: If code has been updated in a function that unwinds its
+state in failure cases, have the failure cases been updated to
+correspond? Example: job003922_. See `.diff`_.
+
+.. _job003922: http://www.ravenbrook.com/project/mps/issue/job003922/
+
+
+
+Document History
+----------------
+
+2015-08-10 GDR_ Created.
+
+.. _GDR: http://www.ravenbrook.com/consultants/gdr/
+
+
+Copyright and License
+---------------------
+
+Copyright © 2015 Ravenbrook Limited. All rights reserved.
+ . This is an open source license. Contact
+Ravenbrook for commercial licensing options.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+#. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+#. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+#. Redistributions in any form must be accompanied by information on how
+ to obtain complete source code for this software and any
+ accompanying software that uses this software. The source code must
+ either be included in the distribution or be available for no more than
+ the cost of distribution plus a nominal fee, and must be freely
+ redistributable under reasonable conditions. For an executable file,
+ complete source code means the source code for all modules it contains.
+ It does not include source code for modules or files that typically
+ accompany the major components of the operating system on which the
+ executable file runs.
+
+**This software is provided by the copyright holders and contributors
+"as is" and any express or implied warranties, including, but not
+limited to, the implied warranties of merchantability, fitness for a
+particular purpose, or non-infringement, are disclaimed. In no event
+shall the copyright holders and contributors be liable for any direct,
+indirect, incidental, special, exemplary, or consequential damages
+(including, but not limited to, procurement of substitute goods or
+services; loss of use, data, or profits; or business interruption)
+however caused and on any theory of liability, whether in contract,
+strict liability, or tort (including negligence or otherwise) arising in
+any way out of the use of this software, even if advised of the
+possibility of such damage.**
diff --git a/mps/design/index.txt b/mps/design/index.txt
index d2a1e06024f..7e48b625319 100644
--- a/mps/design/index.txt
+++ b/mps/design/index.txt
@@ -41,8 +41,10 @@ Designs
====================== ================================================
abq_ Fixed-length queues
alloc-frame_ Allocation frame protocol
+an_ Generic modules
arena_ Arena
arenavm_ Virtual memory arena
+bootstrap_ Bootstrapping
bt_ Bit tables
buffer_ Allocation buffers and allocation points
cbs_ Coalescing block structures
@@ -52,6 +54,7 @@ collection_ Collection framework
config_ MPS configuration
critical-path_ The critical path through the MPS
diag_ Diagnostic feedback
+exec-env_ Execution environment
failover_ Fail-over allocator
finalize_ Finalization
fix_ The generic fix function
@@ -59,6 +62,7 @@ freelist_ Free list allocator
guide.hex.trans_ Transliterating the alphabet into hexadecimal
guide.impl.c.format_ Coding standard: conventions for the general format of C source code in the MPS
guide.impl.c.naming_ Coding standard: conventions for internal names
+guide.review_ Review checklist
interface-c_ C interface
io_ I/O subsystem
keyword-arguments_ Keyword arguments
@@ -82,7 +86,6 @@ poolmvt_ Manual Variable Temporal pool class
poolmvff_ Manual Variable First-Fit pool class
prmc_ Protection mutator context
prot_ Memory protection
-protan_ ANSI implementation of protection module
protli_ Linux implementation of protection module
protocol_ Protocol inheritance
protsu_ SunOS 4 implementation of protection module
@@ -117,8 +120,10 @@ writef_ The WriteF function
.. _abq: abq
.. _alloc-frame: alloc-frame
+.. _an: an
.. _arena: arena
.. _arenavm: arenavm
+.. _bootstrap: bootstrap
.. _bt: bt
.. _buffer: buffer
.. _cbs: cbs
@@ -128,6 +133,7 @@ writef_ The WriteF function
.. _config: config
.. _critical-path: critical-path
.. _diag: diag
+.. _exec-env: exec-env
.. _failover: failover
.. _finalize: finalize
.. _fix: fix
@@ -135,6 +141,7 @@ writef_ The WriteF function
.. _guide.hex.trans: guide.hex.trans
.. _guide.impl.c.format: guide.impl.c.format
.. _guide.impl.c.naming: guide.impl.c.naming
+.. _guide.review: guide.review
.. _interface-c: interface-c
.. _io: io
.. _keyword-arguments: keyword-arguments
@@ -158,7 +165,6 @@ writef_ The WriteF function
.. _poolmvff: poolmvff
.. _prmc: prmc
.. _prot: prot
-.. _protan: protan
.. _protli: protli
.. _protocol: protocol
.. _protsu: protsu
@@ -231,7 +237,7 @@ Document History
Copyright and License
---------------------
-Copyright © 2002-2014 Ravenbrook Limited. All rights reserved.
+Copyright © 2002-2015 Ravenbrook Limited. All rights reserved.
. This is an open source license. Contact
Ravenbrook for commercial licensing options.
diff --git a/mps/design/io.txt b/mps/design/io.txt
index 655eea8caf2..27ab9d7802a 100644
--- a/mps/design/io.txt
+++ b/mps/design/io.txt
@@ -95,17 +95,19 @@ which the MPM sends and receives "messages" to and from the hosted I/O
module.
_`.arch.module`: The modules are part of the MPS but not part of the
-freestanding core system (see design.mps.exec-env). The I/O module is
+freestanding core system (see design.mps.exec-env_). The I/O module is
responsible for transmitting those messages to the external tools, and
for receiving messages from external tools and passing them to the
MPM.
+.. _design.mps.exec-env: exec-env
+
_`.arch.module.example`: For example, the "file implementation" might
just send/write telemetry messages into a file so that they can be
received/read later by an off-line measurement tool.
_`.arch.external`: The I/O Interface is part of interface to the
-freestanding core system (see design.mps.exec-env). This is so that
+freestanding core system (see design.mps.exec-env_). This is so that
the MPS can be deployed in a freestanding environment, with a special
I/O module. For example, if the MPS is used in a washing machine the
I/O module could communicate by writing output to the seven-segment
@@ -429,7 +431,7 @@ Document History
Copyright and License
---------------------
-Copyright © 2013-2014 Ravenbrook Limited. All rights reserved.
+Copyright © 2013-2015 Ravenbrook Limited. All rights reserved.
. This is an open source license. Contact
Ravenbrook for commercial licensing options.
diff --git a/mps/design/land.txt b/mps/design/land.txt
index f99ff95baba..df16fc922b9 100644
--- a/mps/design/land.txt
+++ b/mps/design/land.txt
@@ -86,7 +86,7 @@ indicating whether to continue with the iteration.
``typedef Bool (*LandDeleteVisitor)(Bool *deleteReturn, Land land, Range range, void *closureP, Size closureS)``
-_`.type.visitor`: Type ``LandDeleteVisitor`` is a callback function that may
+_`.type.deletevisitor`: Type ``LandDeleteVisitor`` is a callback function that may
be passed to ``LandIterateAndDelete()``. It is called for every isolated
contiguous range in address order. The function must return a ``Bool``
indicating whether to continue with the iteration. It may additionally
@@ -187,6 +187,16 @@ _`.function.iterate.and.delete`: As ``LandIterate()``, but the visitor
function additionally returns a Boolean indicating whether the range
should be deleted from the land.
+_`.function.iterate.and.delete.justify`: The reason for having both
+``LandIterate()`` and ``LandIterateAndDelete()`` is that it may be
+possible to use a more efficient algorithm, or to preserve more
+properties of the data structure, when it is known that the land willl
+not be modified during the iteration. For example, in the CBS
+implementation, ``LandIterate()`` uses ``TreeTraverse()`` which
+preserves the tree structure, whereas ``LandIterateAndDelete()`` uses
+``TreeTraverseAndDelete()`` which flattens the tree structure, losing
+information about recently accessed nodes.
+
``Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
_`.function.find.first`: Locate the first block (in address order)
@@ -311,7 +321,7 @@ Document History
Copyright and License
---------------------
-Copyright © 2014 Ravenbrook Limited. All rights reserved.
+Copyright © 2014-2015 Ravenbrook Limited. All rights reserved.
. This is an open source license. Contact
Ravenbrook for commercial licensing options.
diff --git a/mps/design/lib.txt b/mps/design/lib.txt
index 962b6328cb2..1dd7efe6964 100644
--- a/mps/design/lib.txt
+++ b/mps/design/lib.txt
@@ -29,11 +29,13 @@ _`.goal`: The goals of the MPS library interface are:
_`.goal.host`: To control the dependency of the MPS on the hosted ISO
C library so that the core MPS remains freestanding (see
-design.mps.exec-env).
+design.mps.exec-env_).
+
+.. _design.mps.exec-env: exec-env
_`.goal.free`: To allow the core MPS convenient access to ISO C
functionality that is provided on freestanding platforms (see
-design.mps.exec-env.std.com.free).
+design.mps.exec-env_).
Description
@@ -46,7 +48,7 @@ _`.overview.access`: The core MPS needs to access functionality that
could be provided by an ISO C hosted environment.
_`.overview.hosted`: The core MPS must not make direct use of any
-facilities in the hosted environment (design.mps.exec-env). However,
+facilities in the hosted environment (design.mps.exec-env_). However,
it is sensible to make use of them when the MPS is deployed in a
hosted environment.
@@ -93,7 +95,7 @@ Document History
Copyright and License
---------------------
-Copyright © 2013-2014 Ravenbrook Limited. All rights reserved.
+Copyright © 2013-2015 Ravenbrook Limited. All rights reserved.
. This is an open source license. Contact
Ravenbrook for commercial licensing options.
diff --git a/mps/design/lock.txt b/mps/design/lock.txt
index 2c744cedb64..069474ae428 100644
--- a/mps/design/lock.txt
+++ b/mps/design/lock.txt
@@ -166,7 +166,7 @@ implemented using the same mechanism as normal locks. (But an
operating system-specific mechanism is used, if possible, to ensure
that the global locks are initialized just once.)
-_`.impl.ansi`: Single-threaded generic implementation ``lockan.c``:
+_`.impl.an`: Single-threaded generic implementation ``lockan.c``:
- single-threaded;
- no need for locking;
@@ -174,7 +174,7 @@ _`.impl.ansi`: Single-threaded generic implementation ``lockan.c``:
- provides checking in debug version;
- otherwise does nothing except keep count of claims.
-_`.impl.win`: Windows implementation ``lockw3.c``:
+_`.impl.w3`: Windows implementation ``lockw3.c``:
- supports Windows threads;
- uses critical section objects [cso]_;
@@ -182,7 +182,7 @@ _`.impl.win`: Windows implementation ``lockw3.c``:
- recursive and non-recursive calls use the same Windows function;
- also performs checking.
-_`.impl.posix`: POSIX implementation ``lockix.c``:
+_`.impl.ix`: POSIX implementation ``lockix.c``:
- supports [POSIXThreads]_;
- locking structure contains a mutex, initialized to check for
@@ -194,7 +194,7 @@ _`.impl.posix`: POSIX implementation ``lockix.c``:
success or ``EDEADLK`` (indicating a recursive claim);
- also performs checking.
-_`.impl.linux`: Linux implementation ``lockli.c``:
+_`.impl.li`: Linux implementation ``lockli.c``:
- supports [POSIXThreads]_;
- also supports [LinuxThreads]_, a partial implementation of POSIX Threads
diff --git a/mps/design/prmc.txt b/mps/design/prmc.txt
index 8d13d831420..0822e709527 100644
--- a/mps/design/prmc.txt
+++ b/mps/design/prmc.txt
@@ -7,7 +7,7 @@ Protection mutator context
:Author: Gareth Rees
:Date: 2014-10-23
:Status: complete design
-:Revision: $Id: //info.ravenbrook.com/project/mps/master/design/tests.txt#2 $
+:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: protection mutator context; design
diff --git a/mps/design/prot.txt b/mps/design/prot.txt
index 89635435ede..fb06b78b328 100644
--- a/mps/design/prot.txt
+++ b/mps/design/prot.txt
@@ -116,9 +116,22 @@ _`.if.sync.noop`: ``ProtSync()`` is permitted to be a no-op if
Implementations
---------------
-_`.impl.an`: Generic implementation. See design.mps.protan_.
+_`.impl.an`: Generic implementation in ``protan.c``.
-.. _design.mps.protan: protan
+_`.impl.an.set`: ``ProtSet()`` does nothing.
+
+_`.impl.an.sync`: ``ProtSync()`` has no way of changing the protection
+of a segment, so it simulates faults on all segments that are supposed
+to be protected, by calling ``TraceSegAccess()``, until it determines
+that no segments require protection any more. This forces the trace to
+proceed until it is completed, preventing incremental collection.
+
+_`.impl.an.sync.issue`: This relies on the pool actually removing the
+protection, otherwise there is an infinite loop here. This is
+therefore not compatible with implementations of the protection
+mutator context module that support single-stepping of accesses (see design.mps.prmc.req.fault.step_).
+
+.. _design.mps.prmc.req.fault.step: prmc#req.fault.step
_`.impl.ix`: POSIX implementation.
diff --git a/mps/design/protan.txt b/mps/design/protan.txt
deleted file mode 100644
index 4ab046d7e47..00000000000
--- a/mps/design/protan.txt
+++ /dev/null
@@ -1,135 +0,0 @@
-.. mode: -*- rst -*-
-
-ANSI implementation of protection module
-========================================
-
-:Tag: design.mps.protan
-:Author: David Jones
-:Date: 1997-03-19
-:Status: incomplete document
-:Revision: $Id$
-:Copyright: See `Copyright and License`_.
-:Index terms:
- pair: ANSI; protection interface design
- pair: ANSI protection interface; design
-
-
-Introduction
-------------
-
-_`.readership`: Any MPS developer.
-
-_`.intro`: This is the design for the ANSI implementation of the
-protection module.
-
-
-Requirements
-------------
-
-_`.req.test`: This module is required for testing. Particularly on
-platforms where no real implementation of the protection module
-exists.
-
-_`.req.rapid-port`: This module is required for rapid porting. It
-should enable a developer to port a minimally useful configuration of
-the MPS to new platforms very quickly.
-
-
-Overview
---------
-
-_`.overview`: Most of the functions in the module do nothing. The
-exception is ``ProtSync()`` which traverses over all segments in the
-arena and simulates an access to each segment that has any protection
-on it. This means that this module depends on certain fields in the
-segment structure.
-
-_`.overview.noos`: No operating system specific (or even ANSI hosted
-specific) code is in this module. It can therefore be used on any
-platform, particularly where no real implementation of the module
-exists. It satisfies `.req.test`_ and `.req.rapid-port`_ in this way.
-
-
-Functions
----------
-
-_`.fun.protsetup`: ``ProtSetup()`` does nothing as there is nothing to
-do (under UNIX we might expect the protection module to install one or
-more signal handlers at this pointer, but that is not appropriate for
-the ANSI implementation). Of course, we can't have an empty function
-body, so there is a ``NOOP;`` here.
-
-_`.fun.sync`: ``ProtSync()`` is called to ensure that the actual
-protection of each segment (as determined by the OS) is in accordance
-with the segments's pm field. In the ANSI implementation we have no
-way of changing the protection of a segment, so instead we generate
-faults on all protected segments in the assumption that that will
-remove the protection on segments.
-
-_`.fun.sync.how`: Continually loops over all the segments until it
-finds that all segments have no protection.
-
-_`.fun.sync.seg`: If it finds a segment that is protected then
-``PoolAccess()`` is called on that segment's pool and with that
-segment. The call to ``PoolAccess()`` is wrapped with a
-``ShieldEnter()`` and ``ShieldLeave()`` thereby giving the pool the
-illusion that the fault was generated outside the MM. This depends on
-being able to determine the protection of a segment (using the ``pm``
-field), on being able to call ``ShieldEnter()`` and ``ShieldLeave()``,
-and on being able to call ``PoolAccess()``.
-
-
-Document History
-----------------
-
-- 1997-03-19 David Jones. Incomplete document.
-
-- 2002-06-07 RB_ Converted from MMInfo database design document.
-
-- 2013-05-23 GDR_ Converted to reStructuredText.
-
-.. _RB: http://www.ravenbrook.com/consultants/rb/
-.. _GDR: http://www.ravenbrook.com/consultants/gdr/
-
-
-Copyright and License
----------------------
-
-Copyright © 2013-2014 Ravenbrook Limited. All rights reserved.
- . This is an open source license. Contact
-Ravenbrook for commercial licensing options.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-#. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-#. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-#. Redistributions in any form must be accompanied by information on how
- to obtain complete source code for this software and any
- accompanying software that uses this software. The source code must
- either be included in the distribution or be available for no more than
- the cost of distribution plus a nominal fee, and must be freely
- redistributable under reasonable conditions. For an executable file,
- complete source code means the source code for all modules it contains.
- It does not include source code for modules or files that typically
- accompany the major components of the operating system on which the
- executable file runs.
-
-**This software is provided by the copyright holders and contributors
-"as is" and any express or implied warranties, including, but not
-limited to, the implied warranties of merchantability, fitness for a
-particular purpose, or non-infringement, are disclaimed. In no event
-shall the copyright holders and contributors be liable for any direct,
-indirect, incidental, special, exemplary, or consequential damages
-(including, but not limited to, procurement of substitute goods or
-services; loss of use, data, or profits; or business interruption)
-however caused and on any theory of liability, whether in contract,
-strict liability, or tort (including negligence or otherwise) arising in
-any way out of the use of this software, even if advised of the
-possibility of such damage.**
diff --git a/mps/design/sp.txt b/mps/design/sp.txt
index 235e00f82ac..47dab436b4e 100644
--- a/mps/design/sp.txt
+++ b/mps/design/sp.txt
@@ -7,7 +7,7 @@ Stack probe
:Author: Gareth Rees
:Date: 2014-10-23
:Status: complete design
-:Revision: $Id: //info.ravenbrook.com/project/mps/master/design/thread-manager.txt#7 $
+:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: stack probe; design
@@ -143,7 +143,7 @@ that it is only suitable for use with programs that do not handle
stack overflow faults, or do not call into the MPS from the handler.
This is because our customers have only required `.req.overflow`_ on
Windows so far. If this becomes a requirement on other platforms, the
-following Standard C implementation is likely to work::
+following Standard C implementation might work::
void StackProbe(Size depth) {
volatile Word w;
@@ -151,8 +151,9 @@ following Standard C implementation is likely to work::
w = *p;
}
-(The use of ``volatile`` is to prevent compilers from warning about
-the variable ``w`` being written but never read.)
+The use of ``volatile`` here is to prevent compilers from warning
+about the variable ``w`` being written but never read, or worse,
+optimizing away the whole statement under the "as if" rule.
Implementations
diff --git a/mps/design/splay-rotate-left.svg b/mps/design/splay-rotate-left.svg
index f5e50922aa8..00ae646a735 100644
--- a/mps/design/splay-rotate-left.svg
+++ b/mps/design/splay-rotate-left.svg
@@ -388,7 +388,7 @@
id="tspan4371"
x="388"
y="96.362183"
- style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana">x
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana">y
y
+ sodipodi:role="line">x
diff --git a/mps/design/splay-rotate-right.svg b/mps/design/splay-rotate-right.svg
index 39fea1b2a20..d2a02bc48bb 100644
--- a/mps/design/splay-rotate-right.svg
+++ b/mps/design/splay-rotate-right.svg
@@ -374,7 +374,7 @@
id="tspan4371"
x="388"
y="96.362183"
- style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana">x
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana">y
y
+ sodipodi:role="line">x
diff --git a/mps/design/ss.txt b/mps/design/ss.txt
index 01dd2caf268..60b5c2817fa 100644
--- a/mps/design/ss.txt
+++ b/mps/design/ss.txt
@@ -7,7 +7,7 @@ Stack and register scanning
:Author: Gareth Rees
:Date: 2014-10-22
:Status: complete design
-:Revision: $Id: //info.ravenbrook.com/project/mps/master/design/thread-manager.txt#7 $
+:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: stack and register scanning; design
diff --git a/mps/design/testthr.txt b/mps/design/testthr.txt
index e00ccd8b317..a1bf99bb247 100644
--- a/mps/design/testthr.txt
+++ b/mps/design/testthr.txt
@@ -7,7 +7,7 @@ Multi-threaded testing
:Author: Gareth Rees
:Date: 2014-10-21
:Status: complete design
-:Revision: $Id: //info.ravenbrook.com/project/mps/master/design/nailboard.txt#3 $
+:Revision: $Id$
:Copyright: See section `Copyright and License`_.
:Index terms: pair: threads; testing
diff --git a/mps/design/type.txt b/mps/design/type.txt
index 708693ad1db..25943f41a4b 100644
--- a/mps/design/type.txt
+++ b/mps/design/type.txt
@@ -180,8 +180,8 @@ Mode Description
======================== ==============================================
``BufferModeATTACHED`` Buffer is attached to a region of memory.
``BufferModeFLIPPED`` Buffer has been flipped.
-``BufferModeLOGGED`` Buffer emits the events ``BufferReserve`` and
- ``BufferCommit``.
+``BufferModeLOGGED`` Buffer remains permanently trapped, so that
+ all reserve and commit events can be logged.
``BufferModeTRANSITION`` Buffer is in the process of being detached.
======================== ==============================================
diff --git a/mps/design/vm.txt b/mps/design/vm.txt
index 85c5506043f..fb1be6eb5da 100644
--- a/mps/design/vm.txt
+++ b/mps/design/vm.txt
@@ -133,8 +133,8 @@ the function ``VMCopy()``. This allows the initialization of a
temporary VM descriptor on the stack. Second, call ``VMInit()`` to
reserve address space and initialize the temporary VM descriptor.
Third, call ``VMMap()`` on the new VM to map enough memory to store a
-``VMChunkStruct``. Fourth, call ``VMCopy()`` to copy the temporary VM
-descriptor into its place in the ``VMChunkStruct``.
+``VMChunk``. Fourth, call ``VMCopy()`` to copy the temporary VM
+descriptor into its place in the ``VMChunk``.
_`.sol.params`: To meet `.req.params`_, the interface provides the
function ``VMParamFromArgs()``, which decodes relevant keyword
diff --git a/mps/design/writef.txt b/mps/design/writef.txt
index bb8547d6616..2a0277990e0 100644
--- a/mps/design/writef.txt
+++ b/mps/design/writef.txt
@@ -6,7 +6,7 @@ The WriteF function
:Tag: design.mps.writef
:Author: Richard Brooksby
:Date: 1996-10-18
-:Status: incomplete design
+:Status: complete design
:Revision: $Id$
:Copyright: See `Copyright and License`_.
:Index terms: pair: WriteF function; design
@@ -16,11 +16,13 @@ Introduction
------------
_`.intro`: This document describes the ``WriteF()`` function, which
-allows formatted output in a manner similar to ANSI C ``printf``, but
-allows the MPM to operate in a freestanding environment (see
-design.mps.exec-env).
+allows formatted output in a manner similar to ``printf()`` from the
+Standard C library, but allows the Memory Pool Manager (MPM) to
+operate in a freestanding environment (see design.mps.exec-env_).
-_`.background`: The documents design.mps.exec-env and design.mps.lib_
+.. _design.mps.exec-env: exec-env
+
+_`.background`: The documents design.mps.exec-env_ and design.mps.lib_
describe the design of the library interface and the reason that it
exists.
@@ -31,10 +33,10 @@ Design
------
_`.no-printf`: There is no dependency on ``printf()``. The MPM only
-depends on ``fputc()`` and ``fputs()``, via the Library Interface
-(design.mps.lib_). This makes it much easier to deploy the MPS in a
-freestanding environment. This is achieved by implementing our own
-internal output routines in mpm.c.
+depends on ``mps_io_fputc()`` and ``mps_io_fputs()``, via the library
+interface (design.mps.lib_), part of the *plinth*. This makes it much
+easier to deploy the MPS in a freestanding environment. This is
+achieved by implementing our own output routines.
_`.writef`: Our output requirements are few, so the code is short. The
only output function which should be used in the rest of the MPM is
@@ -42,9 +44,9 @@ only output function which should be used in the rest of the MPM is
``Res WriteF(mps_lib_FILE *stream, Count depth, ...)``
-If ``depth`` is greater than zero, then the first format character,
-and each format character after a newline, is preceded by ``depth``
-spaces.
+If ``depth`` is greater than zero, then the first output character,
+and each output character after a newline in a format string, is
+preceded by ``depth`` spaces.
``WriteF()`` expects a format string followed by zero or more items to
insert into the output, followed by another format string, more items,
@@ -54,7 +56,8 @@ and so on, and finally a ``NULL`` format string. For example::
"Hello: $A\n", (WriteFA)address,
"Spong: $U ($S)\n", (WriteFU)number, (WriteFS)string,
NULL);
- if (res != ResOK) return res;
+ if (res != ResOK)
+ return res;
This makes ``Describe()`` methods much easier to write. For example, ``BufferDescribe()`` contains the following code::
@@ -83,14 +86,15 @@ This makes ``Describe()`` methods much easier to write. For example, ``BufferDes
" alignment $W\n", (WriteFW)buffer->alignment,
" rampCount $U\n", (WriteFU)buffer->rampCount,
NULL);
- if (res != ResOK) return res;
+ if (res != ResOK)
+ return res;
-_`.types`: For each format ``$X`` that ``WriteF()`` supports, there is a
-type defined in impl.h.mpmtypes ``WriteFX()`` which is the promoted
-version of that type. These are provided both to ensure promotion and
-to avoid any confusion about what type should be used in a cast. It is
-easy to check the casts against the formats to ensure that they
-correspond.
+_`.types`: For each format ``$X`` that ``WriteF()`` supports, there is
+a type ``WriteFX`` defined in mpmtypes.h, which is the promoted
+version of that type. These types are provided both to ensure
+promotion and to avoid any confusion about what type should be used in
+a cast. It is easy to check the casts against the formats to ensure
+that they correspond.
_`.types.cast`: Every argument to ``WriteF()`` must be cast, because
in variable-length argument lists the "default argument promotion"
@@ -154,7 +158,7 @@ Document History
Copyright and License
---------------------
-Copyright © 2013-2014 Ravenbrook Limited. All rights reserved.
+Copyright © 2013-2015 Ravenbrook Limited. All rights reserved.
. This is an open source license. Contact
Ravenbrook for commercial licensing options.
diff --git a/mps/manual/build.txt b/mps/manual/build.txt
index 5403d7ffc44..7b8e17c51b9 100644
--- a/mps/manual/build.txt
+++ b/mps/manual/build.txt
@@ -96,8 +96,7 @@ Building the MPS for development
If you're making modifications to the MPS itself, want to build MPS
libraries for linking, or want to build MPS tests and tools, you should
-use the MPS build. This uses makefiles or Xcode projects. [Coming
-soon, Microsoft Visual Studio solutions.]
+use the MPS build. This uses makefiles or Xcode projects.
Prerequisites
diff --git a/mps/manual/source/_templates/links.html b/mps/manual/source/_templates/links.html
index b62c13d7813..b7263205f3e 100644
--- a/mps/manual/source/_templates/links.html
+++ b/mps/manual/source/_templates/links.html
@@ -1,13 +1,11 @@
Downloads
-MPS Kit release {{ release }}
All MPS Kit releases
Issues
-Known issues
-Issues fixed in release {{ release }}
+All open issues
diff --git a/mps/manual/source/design/index.rst b/mps/manual/source/design/index.rst
index 2dd8d9d4207..b8da67a4333 100644
--- a/mps/manual/source/design/index.rst
+++ b/mps/manual/source/design/index.rst
@@ -7,14 +7,18 @@ Design
:numbered:
abq
+ an
+ bootstrap
cbs
config
critical-path
+ exec-env
failover
freelist
guide.hex.trans
guide.impl.c.format
guide.impl.c.naming
+ guide.review
interface-c
keyword-arguments
land
@@ -32,3 +36,4 @@ Design
thread-manager
type
vm
+ writef
diff --git a/mps/manual/source/design/old.rst b/mps/manual/source/design/old.rst
index ee43ba7ae7c..8a8e71be1a6 100644
--- a/mps/manual/source/design/old.rst
+++ b/mps/manual/source/design/old.rst
@@ -41,7 +41,6 @@ Old design
poolmv
poolmvt
poolmvff
- protan
protli
protsu
protocol
@@ -61,4 +60,3 @@ Old design
version
vmo1
vmso
- writef
diff --git a/mps/manual/source/glossary/b.rst b/mps/manual/source/glossary/b.rst
index 8356404267c..12d4838e466 100644
--- a/mps/manual/source/glossary/b.rst
+++ b/mps/manual/source/glossary/b.rst
@@ -182,9 +182,22 @@ Memory Management Glossary: B
.. relevance::
Bitmaps are sometimes used to represent the marks in a
- :term:`mark-sweep` collector, or the used memory in a
- :term:`bitmapped fits` :term:`allocator`.
+ :term:`mark-sweep` collector (see :term:`bitmap marking`),
+ or the used memory in a :term:`bitmapped fits`
+ :term:`allocator`.
+ bitmap marking
+
+ In :term:`mark-sweep` collectors, bitmap marking is a
+ technique for :term:`marking` objects that stores the mark
+ bits for the objects in a contiguous range of memory in a
+ separate :term:`bitmap`. This improves the collector's
+ :term:`locality of reference` and cache performance, because
+ it avoids setting the :term:`dirty bit` on the :term:`pages`
+ containing the marked objects.
+
+ .. bibref:: :ref:`Zorn (1989) `.
+
bitmapped fit
A class of :term:`allocation mechanisms` that use a
diff --git a/mps/manual/source/glossary/index.rst b/mps/manual/source/glossary/index.rst
index a0484b3c5ee..6c15cbd4e84 100644
--- a/mps/manual/source/glossary/index.rst
+++ b/mps/manual/source/glossary/index.rst
@@ -84,6 +84,7 @@ All
:term:`bit table `
:term:`bit vector `
:term:`bitmap`
+:term:`bitmap marking`
:term:`bitmapped fit`
:term:`bitmask`
:term:`bitset `
diff --git a/mps/manual/source/glossary/m.rst b/mps/manual/source/glossary/m.rst
index db4d8b88a59..92abdcf2740 100644
--- a/mps/manual/source/glossary/m.rst
+++ b/mps/manual/source/glossary/m.rst
@@ -207,7 +207,11 @@ Memory Management Glossary: M
though any conservative representation of a predicate on the
:term:`memory location` of the object can be used. In
particular, storing the mark bit within the object can lead to
- poor :term:`locality of reference`.
+ poor :term:`locality of reference` and to poor cache
+ performance, because the marking phases ends up setting the
+ :term:`dirty bit` on all :term:`pages` in the :term:`working
+ set`. An alternative is to store the mark bits separately:
+ see :term:`bitmap marking`.
.. seealso:: :term:`sweep `, :term:`compact `.
diff --git a/mps/manual/source/glossary/r.rst b/mps/manual/source/glossary/r.rst
index 9f4449a930e..cbab9a255fe 100644
--- a/mps/manual/source/glossary/r.rst
+++ b/mps/manual/source/glossary/r.rst
@@ -39,7 +39,7 @@ Memory Management Glossary: R
.. mps:specific::
A value of :c:type:`mps_rank_t` indicating whether a
- :term:`root` is :term:`ambiguous `
+ :term:`reference` is :term:`ambiguous `
(:c:func:`mps_rank_ambig`), :term:`exact `
(:c:func:`mps_rank_exact`) or :term:`weak `
(:c:func:`mps_rank_weak`).
diff --git a/mps/manual/source/guide/index.rst b/mps/manual/source/guide/index.rst
index a7218dd2ba5..fd98e0481e5 100644
--- a/mps/manual/source/guide/index.rst
+++ b/mps/manual/source/guide/index.rst
@@ -13,4 +13,4 @@ Guide
debug
perf
advanced
-
+ malloc
diff --git a/mps/manual/source/guide/lang.rst b/mps/manual/source/guide/lang.rst
index 68473613ba2..88c7ec93eb5 100644
--- a/mps/manual/source/guide/lang.rst
+++ b/mps/manual/source/guide/lang.rst
@@ -266,6 +266,25 @@ code for creating the object format for the toy Scheme interpreter::
} MPS_ARGS_END(args);
if (res != MPS_RES_OK) error("Couldn't create obj format");
+The keyword arguments specify the :term:`alignment` and the
+:term:`format methods` required by the AMC pool class. These are
+described in the following sections.
+
+.. topics::
+
+ :ref:`topic-format`.
+
+
+.. index::
+ single: alignment
+ single: alignment; object
+ single: Scheme; object alignment
+
+.. _guide-lang-alignment:
+
+Alignment
+^^^^^^^^^
+
The argument for the keyword :c:macro:`MPS_KEY_FMT_ALIGN` is the
:term:`alignment` of objects belonging to this format. Determining the
alignment is hard to do portably, because it depends on the target
@@ -294,13 +313,19 @@ memory. Here are some things you might try:
#define ALIGNMENT sizeof(mps_word_t)
-The other keyword arguments specify the :term:`format methods`
-required by the AMC pool class, which are described in the following
-sections.
+#. The MPS interface provides the type :c:type:`MPS_PF_ALIGN`, which
+ is the :term:`natural alignment` of the platform: the largest
+ alignment that might be required. So as a last resort, you can
+ use::
-.. topics::
+ #define ALIGNMENT MPS_PF_ALIGN
- :ref:`topic-format`.
+ But this may be larger than necessary and so waste space. For
+ example, on Windows on x86-64, :c:type:`MPS_PF_ALIGN` is 16 bytes,
+ but this is only necessary for SSE_ types; ordinary types on this
+ platform require no more than 8-byte alignment.
+
+ .. _SSE: http://msdn.microsoft.com/en-us/library/t467de55.aspx
.. index::
diff --git a/mps/manual/source/guide/malloc.rst b/mps/manual/source/guide/malloc.rst
new file mode 100644
index 00000000000..843fc2371ed
--- /dev/null
+++ b/mps/manual/source/guide/malloc.rst
@@ -0,0 +1,70 @@
+.. index::
+ single: malloc; implementing
+ single: free; implementing
+
+.. _guide-malloc:
+
+Implementing malloc and free
+============================
+
+The MPS function :c:func:`mps_free` is unlike the Standard C Library
+function :c:func:`free` in that it takes a ``size`` argument. That's
+because it's nearly always the case that either the size of a block is
+known statically based on its type (for example, a structure), or else
+the size of the block is easily computed from information that needs
+to be stored anyway (for example, a vector), and so memory can be
+saved by not storing the size separately. It's also better for virtual
+memory performance, as a block does not have to be touched in order
+to free it.
+
+But sometimes you need to interact with :term:`foreign code` which
+requires :c:func:`malloc` and :c:func:`free` (or a pair of functions
+with the same interface). In this situation you can implement this
+interface using a global pool variable, and putting the size of each
+block into its header, like this::
+
+ #include "mps.h"
+
+ static mps_pool_t malloc_pool;
+
+ typedef union {
+ size_t size;
+ char alignment[MPS_PF_ALIGN]; /* see note below */
+ } header_u;
+
+ void *malloc(size_t size) {
+ mps_res_t res;
+ mps_addr_t p;
+ header_u *header;
+ size += sizeof *header;
+ res = mps_alloc(&p, malloc_pool, size);
+ if (res != MPS_RES_OK)
+ return NULL;
+ header = p;
+ header->size = size;
+ return header + 1;
+ }
+
+ void free(void *p) {
+ if (p) {
+ header_u *header = ((header_u *)p) - 1;
+ mps_free(malloc_pool, header, header->size);
+ }
+ }
+
+The ``alignment`` member of ``union header_u`` ensures that
+allocations are aligned to the platform's :term:`natural alignment`
+(see :ref:`guide-lang-alignment`).
+
+The pool needs to belong to a :term:`manually managed ` pool class, for example :ref:`pool-mvff` (or its
+:ref:`debugging counterpart `)::
+
+ #include "mpscmvff.h"
+
+ void malloc_pool_init(mps_arena_t arena) {
+ mps_res_t res;
+ res = mps_pool_create_k(&malloc_pool, arena, mps_class_mvff(), mps_args_none);
+ if (res != RES_OK)
+ abort();
+ }
diff --git a/mps/manual/source/pool/amc.rst b/mps/manual/source/pool/amc.rst
index 0562b9bce5a..a21594202c6 100644
--- a/mps/manual/source/pool/amc.rst
+++ b/mps/manual/source/pool/amc.rst
@@ -115,7 +115,7 @@ AMC interface
method`, a :term:`forward method`, an :term:`is-forwarded
method` and a :term:`padding method`.
- It accepts four optional keyword arguments:
+ It accepts three optional keyword arguments:
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
the :term:`generation chain` for the pool. If not specified, the
@@ -128,8 +128,10 @@ AMC interface
pointers` keep objects alive.
* :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`,
- default 4096) is the default :term:`size` of block that the pool
- will request from the :term:`arena`.
+ default 4096) is the minimum :term:`size` of the memory segments
+ that the pool requests from the :term:`arena`. Larger segments
+ reduce the per-segment overhead, but increase
+ :term:`fragmentation` and :term:`retention`.
For example::
@@ -138,20 +140,12 @@ AMC interface
res = mps_pool_create_k(&pool, arena, mps_class_amc(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the format and
- chain like this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_amc(),
- mps_fmt_t fmt,
- mps_chain_t chain)
-
.. index::
pair: AMC; introspection
+.. _pool-amc-introspection:
+
AMC introspection
-----------------
diff --git a/mps/manual/source/pool/amcz.rst b/mps/manual/source/pool/amcz.rst
index 9993647d0db..4f65d205d1b 100644
--- a/mps/manual/source/pool/amcz.rst
+++ b/mps/manual/source/pool/amcz.rst
@@ -87,12 +87,11 @@ AMCZ interface
res = mps_pool_create_k(&pool, arena, mps_class_amcz(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
+
+.. index::
+ pair: AMCZ; introspection
- When using :c:func:`mps_pool_create`, pass the format and
- chain like this::
+AMCZ introspection
+------------------
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_amcz(),
- mps_fmt_t fmt,
- mps_chain_t chain)
+See :ref:`pool-amc-introspection`.
diff --git a/mps/manual/source/pool/ams.rst b/mps/manual/source/pool/ams.rst
index 98da5eda587..4d66fdc0fc3 100644
--- a/mps/manual/source/pool/ams.rst
+++ b/mps/manual/source/pool/ams.rst
@@ -41,7 +41,8 @@ AMS properties
* Supports allocation via :term:`allocation points`. If an allocation
point is created in an AMS pool, the call to
- :c:func:`mps_ap_create_k` takes no keyword arguments.
+ :c:func:`mps_ap_create_k` takes one optional keyword argument,
+ :c:macro:`MPS_KEY_RANK`.
* Supports :term:`allocation frames` but does not use them to improve
the efficiency of stack-like allocation.
@@ -137,19 +138,8 @@ AMS interface
res = mps_pool_create_k(&pool, arena, mps_class_ams(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the format,
- chain, and ambiguous flag like this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_ams(),
- mps_fmt_t fmt,
- mps_chain_t chain,
- mps_bool_t support_ambiguous)
-
When creating an :term:`allocation point` on an AMS pool,
- :c:func:`mps_ap_create_k` accepts one keyword argument:
+ :c:func:`mps_ap_create_k` accepts one optional keyword argument:
* :c:macro:`MPS_KEY_RANK` (type :c:type:`mps_rank_t`, default
:c:func:`mps_rank_exact`) specifies the :term:`rank` of references
@@ -166,13 +156,6 @@ AMS interface
res = mps_ap_create_k(&ap, ams_pool, args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_ap_create`, pass the rank like this::
-
- mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
- mps_rank_t rank)
-
.. c:function:: mps_pool_class_t mps_class_ams_debug(void)
@@ -186,15 +169,3 @@ AMS interface
:c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` are as described above,
and :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
options. See :c:type:`mps_pool_debug_option_s`.
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the arguments like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_ams_debug(),
- mps_pool_debug_option_s debug_option,
- mps_fmt_t fmt,
- mps_chain_t chain,
- mps_bool_t support_ambiguous)
diff --git a/mps/manual/source/pool/awl.rst b/mps/manual/source/pool/awl.rst
index e4437ebe5ee..63eca08635e 100644
--- a/mps/manual/source/pool/awl.rst
+++ b/mps/manual/source/pool/awl.rst
@@ -59,7 +59,7 @@ AWL properties
* Supports allocation via :term:`allocation points`. If an allocation
point is created in an AWL pool, the call to
- :c:func:`mps_ap_create_k` accepts one keyword argument,
+ :c:func:`mps_ap_create_k` accepts one optional keyword argument,
:c:macro:`MPS_KEY_RANK`.
* Supports :term:`allocation frames` but does not use them to improve
@@ -350,18 +350,8 @@ AWL interface
res = mps_pool_create_k(&pool, arena, mps_class_awl(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the format and
- find-dependent function like this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_awl(),
- mps_fmt_t fmt,
- mps_awl_find_dependent_t find_dependent)
-
When creating an :term:`allocation point` on an AWL pool,
- :c:func:`mps_ap_create_k` accepts one keyword argument:
+ :c:func:`mps_ap_create_k` accepts one optional keyword argument:
* :c:macro:`MPS_KEY_RANK` (type :c:type:`mps_rank_t`, default
:c:func:`mps_rank_exact`) specifies the :term:`rank` of
@@ -378,13 +368,6 @@ AWL interface
res = mps_ap_create_k(&ap, awl_pool, args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_ap_create`, pass the rank like this::
-
- mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
- mps_rank_t rank)
-
.. c:type:: mps_addr_t (*mps_awl_find_dependent_t)(mps_addr_t addr)
diff --git a/mps/manual/source/pool/lo.rst b/mps/manual/source/pool/lo.rst
index edd784c1fe5..197e8b57138 100644
--- a/mps/manual/source/pool/lo.rst
+++ b/mps/manual/source/pool/lo.rst
@@ -136,12 +136,3 @@ LO interface
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
res = mps_pool_create_k(&pool, arena, mps_class_lo(), args);
} MPS_ARGS_END(args);
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the format like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_lo(),
- mps_fmt_t fmt)
diff --git a/mps/manual/source/pool/mfs.rst b/mps/manual/source/pool/mfs.rst
index c4501d05c54..c1e13a5479d 100644
--- a/mps/manual/source/pool/mfs.rst
+++ b/mps/manual/source/pool/mfs.rst
@@ -87,7 +87,8 @@ MFS interface
:term:`size` of blocks that will be allocated from this pool, in
:term:`bytes (1)`. It must be at least one :term:`word`.
- In addition, :c:func:`mps_pool_create_k` may take:
+ In addition, :c:func:`mps_pool_create_k` accepts one optional
+ keyword argument:
* :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`,
default 65536) is the :term:`size` of block that the pool will
@@ -103,13 +104,3 @@ MFS interface
MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, 1024 * 1024);
res = mps_pool_create_k(&pool, arena, mps_class_mfs(), args);
} MPS_ARGS_END(args);
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the block size and
- unit size like this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_mfs(),
- size_t extend_size,
- size_t unit_size)
diff --git a/mps/manual/source/pool/mv.rst b/mps/manual/source/pool/mv.rst
index 8561e96d7d1..27e691ed3af 100644
--- a/mps/manual/source/pool/mv.rst
+++ b/mps/manual/source/pool/mv.rst
@@ -7,10 +7,6 @@
MV (Manual Variable)
====================
-.. deprecated:: starting with version 1.111.
-
- :ref:`pool-mvff` or :ref:`pool-mvt` should be used instead.
-
**MV** is a general-purpose :term:`manually managed ` :term:`pool class` that manages :term:`blocks` of
variable size.
@@ -70,8 +66,8 @@ MV interface
Return the :term:`pool class` for an MV (Manual Variable)
:term:`pool`.
- When creating an MV pool, :c:func:`mps_pool_create_k` may take
- the following :term:`keyword arguments`:
+ When creating an MV pool, :c:func:`mps_pool_create_k` takes four
+ optional :term:`keyword arguments`:
* :c:macro:`MPS_KEY_ALIGN` (type :c:type:`mps_align_t`, default is
:c:macro:`MPS_PF_ALIGN`) is the
@@ -105,17 +101,6 @@ MV interface
res = mps_pool_create_k(&pool, arena, mps_class_mfs(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the block size,
- mean size, and maximum size like this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_mv(),
- size_t extend_size,
- size_t average_size,
- mps_size_t maximum_size)
-
.. c:function:: mps_pool_class_t mps_class_mv_debug(void)
@@ -123,49 +108,8 @@ MV interface
class.
When creating a debugging MV pool, :c:func:`mps_pool_create_k`
- takes the following keyword arguments: :c:macro:`MPS_KEY_ALIGN`,
+ takes five optional keyword arguments: :c:macro:`MPS_KEY_ALIGN`,
:c:macro:`MPS_KEY_EXTEND_SIZE`, :c:macro:`MPS_KEY_MEAN_SIZE`,
:c:macro:`MPS_KEY_MAX_SIZE` are as described above, and
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
- options. See :c:type:`mps_debug_option_s`.
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the arguments like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_mv_debug(),
- mps_pool_debug_option_s debug_option,
- mps_size_t extend_size,
- mps_size_t average_size,
- mps_size_t maximum_size)
-
-
-.. index::
- pair: MV; introspection
-
-MV introspection
-----------------
-
-::
-
- #include "mpscmv.h"
-
-.. c:function:: size_t mps_mv_free_size(mps_pool_t pool)
-
- Return the total amount of free space in an MV pool.
-
- ``pool`` is the MV pool.
-
- Returns the total free space in the pool, in :term:`bytes (1)`.
-
-
-.. c:function:: size_t mps_mv_size(mps_pool_t pool)
-
- Return the total size of an MV pool.
-
- ``pool`` is the MV pool.
-
- Returns the total size of the pool, in :term:`bytes (1)`. This
- is the sum of allocated space and free space.
+ options. See :c:type:`mps_pool_debug_option_s`.
diff --git a/mps/manual/source/pool/mvff.rst b/mps/manual/source/pool/mvff.rst
index 51252208719..04a7d48603d 100644
--- a/mps/manual/source/pool/mvff.rst
+++ b/mps/manual/source/pool/mvff.rst
@@ -102,8 +102,8 @@ MVFF interface
Return the :term:`pool class` for an MVFF (Manual Variable First
Fit) :term:`pool`.
- When creating an MVFF pool, :c:func:`mps_pool_create_k` may take
- the following :term:`keyword arguments`:
+ When creating an MVFF pool, :c:func:`mps_pool_create_k` accepts
+ seven optional :term:`keyword arguments`:
* :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`, default
65536) is the :term:`size` of block that the pool will request
@@ -132,15 +132,15 @@ MVFF interface
default false) determines whether new blocks are acquired at high
addresses (if true), or at low addresses (if false).
- * :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` [#not-ap]_ (type :c:type:`mps_bool_t`,
- default false) determines whether to search for the highest
- addressed free area (if true) or lowest (if false) when allocating
- using :c:func:`mps_alloc`.
+ * :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` [#not-ap]_ (type
+ :c:type:`mps_bool_t`, default false) determines whether to
+ search for the highest addressed free area (if true) or lowest
+ (if false) when allocating using :c:func:`mps_alloc`.
- * :c:macro:`MPS_KEY_MVFF_FIRST_FIT` [#not-ap]_ (type :c:type:`mps_bool_t`, default
- true) determines whether to allocate from the highest address in a
- found free area (if true) or lowest (if false) when allocating
- using :c:func:`mps_alloc`.
+ * :c:macro:`MPS_KEY_MVFF_FIRST_FIT` [#not-ap]_ (type
+ :c:type:`mps_bool_t`, default true) determines whether to
+ allocate from the highest address in a found free area (if true)
+ or lowest (if false) when allocating using :c:func:`mps_alloc`.
.. [#not-ap]
@@ -150,12 +150,12 @@ MVFF interface
They use a worst-fit policy in order to maximise the number of
in-line allocations.
- The defaults yield a a simple first-fit allocator. Specify
+ The defaults yield a a simple first-fit allocator. Specify
:c:macro:`MPS_KEY_MVFF_ARENA_HIGH` and
:c:macro:`MPS_KEY_MVFF_SLOT_HIGH` true, and
:c:macro:`MPS_KEY_MVFF_FIRST_FIT` false to get a first-fit
- allocator that works from the top of memory downwards.
- Other combinations may be useful in special circumstances.
+ allocator that works from the top of memory downwards. Other
+ combinations may be useful in special circumstances.
For example::
@@ -169,20 +169,6 @@ MVFF interface
res = mps_pool_create_k(&pool, arena, mps_class_mvff(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the arguments like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_mvff(),
- size_t extend_size,
- size_t average_size,
- mps_align_t alignment,
- mps_bool_t slot_high,
- mps_bool_t arena_high,
- mps_bool_t first_fit)
-
.. c:function:: mps_pool_class_t mps_class_mvff_debug(void)
@@ -190,55 +176,11 @@ MVFF interface
class.
When creating a debugging MVFF pool, :c:func:`mps_pool_create_k`
- takes seven :term:`keyword arguments`.
-
- * :c:macro:`MPS_KEY_EXTEND_BY`, :c:macro:`MPS_KEY_MEAN_SIZE`,
- :c:macro:`MPS_KEY_ALIGN`, :c:macro:`MPS_KEY_MVFF_ARENA_HIGH`,
- :c:macro:`MPS_KEY_MVFF_SLOT_HIGH`, and
- :c:macro:`MPS_KEY_MVFF_FIRST_FIT` are as described above, and
- :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
- options. See :c:type:`mps_pool_debug_option_s`.
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the arguments like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_mvff_debug(),
- mps_pool_debug_option_s debug_option,
- size_t extend_size,
- size_t average_size,
- mps_align_t alignment,
- mps_bool_t slot_high,
- mps_bool_t arena_high,
- mps_bool_t first_fit)
-
-
-.. index::
- pair: MVFF; introspection
-
-MVFF introspection
-------------------
-
-::
-
- #include "mpscmvff.h"
-
-.. c:function:: size_t mps_mvff_free_size(mps_pool_t pool)
-
- Return the total amount of free space in an MVFF pool.
-
- ``pool`` is the MVFF pool.
-
- Returns the total free space in the pool, in :term:`bytes (1)`.
-
-
-.. c:function:: size_t mps_mvff_size(mps_pool_t pool)
-
- Return the total size of an MVFF pool.
-
- ``pool`` is the MVFF pool.
-
- Returns the total size of the pool, in :term:`bytes (1)`. This
- is the sum of allocated space and free space.
+ accepts eight optional :term:`keyword arguments`:
+ :c:macro:`MPS_KEY_EXTEND_BY`, :c:macro:`MPS_KEY_MEAN_SIZE`,
+ :c:macro:`MPS_KEY_ALIGN`, :c:macro:`MPS_KEY_SPARE`,
+ :c:macro:`MPS_KEY_MVFF_ARENA_HIGH`,
+ :c:macro:`MPS_KEY_MVFF_SLOT_HIGH`, and
+ :c:macro:`MPS_KEY_MVFF_FIRST_FIT` are as described above, and
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
+ options. See :c:type:`mps_pool_debug_option_s`.
diff --git a/mps/manual/source/pool/mvt.rst b/mps/manual/source/pool/mvt.rst
index 18e738413b9..da2ce024baa 100644
--- a/mps/manual/source/pool/mvt.rst
+++ b/mps/manual/source/pool/mvt.rst
@@ -111,8 +111,8 @@ MVT interface
Return the :term:`pool class` for an MVT (Manual Variable
Temporal) :term:`pool`.
- When creating an MVT pool, :c:func:`mps_pool_create_k` may take
- six :term:`keyword arguments`:
+ When creating an MVT pool, :c:func:`mps_pool_create_k` accepts six
+ optional :term:`keyword arguments`:
* :c:macro:`MPS_KEY_ALIGN` (type :c:type:`mps_align_t`, default is
:c:macro:`MPS_PF_ALIGN`) is the
@@ -196,51 +196,3 @@ MVT interface
MPS_ARGS_ADD(args, MPS_KEY_MVT_FRAG_LIMIT, 0.5);
res = mps_pool_create_k(&pool, arena, mps_class_mvt(), args);
} MPS_ARGS_END(args);
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the arguments like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_mvt(),
- size_t minimum_size,
- size_t mean_size,
- size_t maximum_size,
- mps_word_t reserve_depth,
- mps_word_t fragmentation_limit)
-
- .. note::
-
- The fragmentation_limit is a percentage from 0 to 100
- inclusive when passed to :c:func:`mps_pool_create`, not a
- double from 0.0 to 1.0 as in :c:func:`mps_pool_create_k`.
-
-
-.. index::
- pair: MVT; introspection
-
-MVT introspection
------------------
-
-::
-
- #include "mpscmvt.h"
-
-.. c:function:: size_t mps_mvt_free_size(mps_pool_t pool)
-
- Return the total amount of free space in an MVT pool.
-
- ``pool`` is the MVT pool.
-
- Returns the total free space in the pool, in :term:`bytes (1)`.
-
-
-.. c:function:: size_t mps_mvt_size(mps_pool_t pool)
-
- Return the total size of an MVT pool.
-
- ``pool`` is the MVT pool.
-
- Returns the total size of the pool, in :term:`bytes (1)`. This
- is the sum of allocated space and free space.
diff --git a/mps/manual/source/pool/snc.rst b/mps/manual/source/pool/snc.rst
index 2e82d055e7c..d39a392c614 100644
--- a/mps/manual/source/pool/snc.rst
+++ b/mps/manual/source/pool/snc.rst
@@ -39,7 +39,7 @@ SNC properties
* Supports allocation via :term:`allocation points` only. If an
allocation point is created in an SNC pool, the call to
- :c:func:`mps_ap_create_k` requires one keyword argument,
+ :c:func:`mps_ap_create_k` accepts one optional keyword argument,
:c:macro:`MPS_KEY_RANK`.
* Does not support deallocation via :c:func:`mps_free`.
@@ -83,8 +83,8 @@ SNC properties
.. index::
single: SNC; interface
-SNC introspection
------------------
+SNC interface
+-------------
::
@@ -111,21 +111,12 @@ SNC introspection
res = mps_pool_create_k(&pool, arena, mps_class_snc(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_pool_create`, pass the format like
- this::
-
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_pool_class_t mps_class_snc(),
- mps_fmt_t fmt)
-
When creating an :term:`allocation point` on an SNC pool,
- :c:func:`mps_ap_create_k` requires one keyword argument:
+ :c:func:`mps_ap_create_k` accepts one optional keyword argument:
- * :c:macro:`MPS_KEY_RANK` (type :c:type:`mps_rank_t`) specifies
- the :term:`rank` of references in objects allocated on this
- allocation point. It must be :c:func:`mps_rank_exact`.
+ * :c:macro:`MPS_KEY_RANK` (type :c:type:`mps_rank_t`, default
+ :c:func:`mps_rank_exact`) specifies the :term:`rank` of references
+ in objects allocated on this allocation point.
For example::
@@ -133,10 +124,3 @@ SNC introspection
MPS_ARGS_ADD(args, MPS_KEY_RANK, mps_rank_exact());
res = mps_ap_create_k(&ap, awl_pool, args);
} MPS_ARGS_END(args);
-
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_ap_create`, pass the rank like this::
-
- mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
- mps_rank_t rank)
diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst
index fc9cc438c55..cb820397281 100644
--- a/mps/manual/source/release.rst
+++ b/mps/manual/source/release.rst
@@ -9,6 +9,15 @@ Release notes
Release 1.115.0
---------------
+New features
+............
+
+#. When creating an :ref:`pool-amc` pool, :c:func:`mps_pool_create_k`
+ accepts the new keyword argument :c:macro:`MPS_KEY_EXTEND_BY`,
+ specifying the minimum size of the memory segments that the pool
+ requests from the :term:`arena`.
+
+
Interface changes
.................
@@ -16,6 +25,46 @@ Interface changes
name :c:type:`mps_class_t` is still available via a ``typedef``,
but is deprecated.
+#. The functions :c:func:`mps_mv_free_size`, :c:func:`mps_mv_size`,
+ :c:func:`mps_mvff_free_size`, :c:func:`mps_mvff_size`,
+ :c:func:`mps_mvt_free_size` and :c:func:`mps_mvt_size` are now
+ deprecated in favour of the generic functions
+ :c:func:`mps_pool_free_size` and :c:func:`mps_pool_total_size`.
+
+
+Other changes
+.............
+
+#. :c:func:`mps_arena_committed` now returns a meaningful value (the
+ amount of memory marked as in use in the page tables) for
+ :term:`client arenas`. See job001887_.
+
+ .. _job001887: https://www.ravenbrook.com/project/mps/issue/job001887/
+
+#. :ref:`pool-amc` pools now assert that exact references into the
+ pool are aligned to the pool's alignment. See job002175_.
+
+ .. _job002175: https://www.ravenbrook.com/project/mps/issue/job002175/
+
+#. Internal calculation of the address space available to the MPS no
+ longer takes time proportional to the number of times the arena has
+ been extended, speeding up allocation when memory is tight. See
+ job003814_.
+
+ .. _job003814: https://www.ravenbrook.com/project/mps/issue/job003814/
+
+#. Setting :c:macro:`MPS_KEY_SPARE` for a :ref:`pool-mvff` pool now
+ works. See job003870_.
+
+ .. _job003870: https://www.ravenbrook.com/project/mps/issue/job003870/
+
+#. When the arena is out of memory and cannot be extended without
+ hitting the :term:`commit limit`, the MPS now returns
+ :c:macro:`MPS_RES_COMMIT_LIMIT` rather than substituting
+ :c:macro:`MPS_RES_RESOURCE`. See job003899_.
+
+ .. _job003899: https://www.ravenbrook.com/project/mps/issue/job003899/
+
.. _release-notes-1.114:
@@ -57,8 +106,8 @@ New features
generation sizes. (This is not necessary, but may improve
performance.)
-#. New pool introspection functions :c:func:`mps_pool_total_size` and
- :c:func:`mps_pool_free_size`.
+#. New pool introspection functions :c:func:`mps_pool_free_size` and
+ :c:func:`mps_pool_total_size`.
Interface changes
@@ -147,8 +196,8 @@ Other changes
#. Allocation into :ref:`pool-awl` pools again reliably provokes
garbage collections of the generation that the pool belongs to. (In
- release 1.113.0, the generation would only be collected if a pool
- of some other class allocated into it.) See job003772_.
+ version 1.113, the generation would only be collected if a pool of
+ some other class allocated into it.) See job003772_.
.. _job003772: https://www.ravenbrook.com/project/mps/issue/job003772/
@@ -160,13 +209,21 @@ Other changes
.. _job003773: https://www.ravenbrook.com/project/mps/issue/job003773/
#. The :ref:`pool-mvt` and :ref:`pool-mvff` pool classes are now
- around 25% faster (in our benchmarks) than they were in release
- 1.113.0.
+ around 25% faster (in our benchmarks) than they were in version
+ 1.113.
-#. The default assertion handler in the ANSI plinth now flushes the
- telemetry stream before aborting. See
+#. The default assertion handler in the default :term:`plinth` now
+ flushes the telemetry stream before aborting. See
:c:func:`mps_lib_assert_fail`.
+#. Garbage collection performance is substantially improved in the
+ situation where the arena has been extended many times. Critical
+ operations now take time logarithmic in the number of times the
+ arena has been extended (rather than linear, as in version 1.113
+ and earlier). See job003554_.
+
+ .. _job003554: https://www.ravenbrook.com/project/mps/issue/job003554/
+
.. _release-notes-1.113:
@@ -278,8 +335,8 @@ Interface changes
along indefinitely. See :ref:`topic-error-assertion-handling`.
#. The behaviour when an assertion is triggered is now configurable in
- the standard ANSI :term:`plinth` by installing an assertion
- handler. See :c:func:`mps_lib_assert_fail_install`.
+ the default :term:`plinth` by installing an assertion handler. See
+ :c:func:`mps_lib_assert_fail_install`.
#. Functions that take a variable number of arguments
(:c:func:`mps_arena_create`, :c:func:`mps_pool_create`,
@@ -437,3 +494,74 @@ Other changes
later. See job003473_.
.. _job003473: https://www.ravenbrook.com/project/mps/issue/job003473/
+
+
+.. _release-notes-1.110:
+
+Release 1.110.0
+---------------
+
+New features
+............
+
+#. New supported platforms:
+
+ * ``fri6gc`` (FreeBSD, x86-64, GCC)
+ * ``lii6gc`` (Linux, x86-64, GCC)
+ * ``w3i6mv`` (Windows, x86-64, Microsoft Visual C)
+ * ``xci3ll`` (OS X, IA-32, Clang/LLVM)
+ * ``xci6gc`` (OS X, x86-64, GCC)
+ * ``xci6ll`` (OS X, x86-64, Clang/LLVM)
+
+#. Support removed for platforms:
+
+ * ``iam4cc`` (Irix 6, MIPS R4000, MIPSpro C)
+ * ``lii3eg`` (Linux, IA-32, EGCS)
+ * ``lippgc`` (Linux, PowerPC, GCC)
+ * ``o1alcc`` (OSF/1, Alpha, Digital C)
+ * ``o1algc`` (OSF/1, Alpha, GCC)
+ * ``s7ppmw`` (System 7, PowerPC, MetroWerks C)
+ * ``sos8gc`` (Solaris, SPARC 8, GCC)
+ * ``sos9sc`` (Solaris, SPARC 9, SunPro C)
+ * ``sus8gc`` (SunOS, SPARC 8, GCC)
+ * ``xcppgc`` (OS X, PowerPC, GCC)
+
+#. On Unix platforms, the MPS can now be built and installed by
+ running ``./configure && make install``. See :ref:`guide-build`.
+
+#. The MPS can be compiled in a single step via the new source file
+ ``mps.c``. This also allows you to compile the MPS in the same
+ compilation unit as your object format, allowing the compiler to
+ perform global optimizations between the two. See
+ :ref:`guide-build`.
+
+#. The set of build varieties has been reduced to three: the
+ :term:`cool` variety for development and debugging, the :term:`hot`
+ variety for production, and the :term:`rash` variety for people who
+ like to live dangerously. See :ref:`topic-error-variety`.
+
+#. The environment variable :envvar:`MPS_TELEMETRY_CONTROL` can now be
+ set to a space-separated list of event kinds. See
+ :ref:`topic-telemetry`.
+
+#. Telemetry output is now emitted to the file named by the
+ environment variable :envvar:`MPS_TELEMETRY_FILENAME`, if it is
+ set. See :ref:`topic-telemetry`.
+
+
+Interface changes
+.................
+
+#. Deprecated constants ``MPS_MESSAGE_TYPE_FINALIZATION``,
+ ``MPS_MESSAGE_TYPE_GC`` and ``MPS_MESSAGE_TYPE_GC_START`` have been
+ removed. Use :c:func:`mps_message_type_finalization`,
+ :c:func:`mps_message_type_gc` and
+ :c:func:`mps_message_type_gc_start` instead.
+
+#. Deprecated constants ``MPS_RANK_AMBIG``, ``MPS_RANK_EXACT`` and
+ ``MPS_RANK_WEAK`` have been removed. Use :c:func:`mps_rank_ambig`,
+ :c:func:`mps_rank_exact` and :c:func:`mps_rank_weak` instead.
+
+#. Deprecated functions with names starting ``mps_space_`` have been
+ removed. Use the functions with names starting ``mps_arena_``
+ instead.
diff --git a/mps/manual/source/topic/allocation.rst b/mps/manual/source/topic/allocation.rst
index 57e9c0d6548..4075cfe006a 100644
--- a/mps/manual/source/topic/allocation.rst
+++ b/mps/manual/source/topic/allocation.rst
@@ -120,31 +120,6 @@ many small objects. They must be used according to the
point or points.
-.. c:function:: mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool, ...)
-
- .. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_ap_create_k` instead: the :term:`keyword
- arguments` interface is more reliable and produces better
- error messages.
-
- An alternative to :c:func:`mps_ap_create_k` that takes its extra
- arguments using the standard :term:`C` variable argument list
- mechanism.
-
-
-.. c:function:: mps_res_t mps_ap_create_v(mps_ap_t *ap_o, mps_pool_t pool, va_list args)
-
- .. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_ap_create_k` instead: the :term:`keyword
- arguments` interface is more reliable and produces better
- error messages.
-
- An alternative to :c:func:`mps_ap_create_k` that takes its extra
- arguments using the standard :term:`C` ``va_list`` mechanism.
-
-
.. c:function:: void mps_ap_destroy(mps_ap_t ap)
Destroy an :term:`allocation point`.
@@ -240,7 +215,8 @@ is thus::
size_t aligned_size = ALIGN(size); /* see note 1 */
do {
mps_res_t res = mps_reserve(&p, ap, aligned_size);
- if (res != MPS_RES_OK) /* handle the error */;
+ if (res != MPS_RES_OK)
+ /* handle the error */;
/* p is now an ambiguous reference to the reserved block */
obj = p;
/* initialize obj */
diff --git a/mps/manual/source/topic/arena.rst b/mps/manual/source/topic/arena.rst
index 04c537a79de..d33242e279d 100644
--- a/mps/manual/source/topic/arena.rst
+++ b/mps/manual/source/topic/arena.rst
@@ -92,32 +92,6 @@ the way that they acquire the memory to be managed.
:c:func:`mps_arena_destroy`.
-.. c:function:: mps_res_t mps_arena_create(mps_arena_t *arena_o, mps_arena_class_t arena_class, ...)
-
- .. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_arena_create_k` instead: the :term:`keyword
- arguments` interface is more reliable and produces better
- error messages.
-
- An alternative to :c:func:`mps_arena_create_k` that takes its
- extra arguments using the standard :term:`C` variable argument
- list mechanism.
-
-
-.. c:function:: mps_res_t mps_arena_create_v(mps_arena_t *arena_o, mps_arena_class_t arena_class, va_list args)
-
- .. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_arena_create_k` instead: the :term:`keyword
- arguments` interface is more reliable and produces better
- error messages.
-
- An alternative to :c:func:`mps_arena_create_k` that takes its
- extra arguments using the standard :term:`C` ``va_list``
- mechanism.
-
-
.. c:function:: void mps_arena_destroy(mps_arena_t arena)
Destroy an :term:`arena`.
@@ -192,15 +166,6 @@ Client arenas
Client arenas have no mechanism for returning unused memory.
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_arena_create`, pass the size and base
- address like this::
-
- mps_res_t mps_arena_create(mps_arena_t *arena_o,
- mps_arena_class_t mps_arena_class_cl,
- size_t size, mps_addr_t base)
-
.. c:function:: mps_res_t mps_arena_extend(mps_arena_t arena, mps_addr_t base, size_t size)
@@ -311,15 +276,6 @@ Virtual memory arenas
res = mps_arena_create_k(&arena, mps_arena_class_vm(), args);
} MPS_ARGS_END(args);
- .. deprecated:: starting with version 1.112.
-
- When using :c:func:`mps_arena_create`, pass the size like
- this::
-
- mps_res_t mps_arena_create(mps_arena_t *arena_o,
- mps_arena_class_t arena_class_vm(),
- size_t size)
-
.. index::
single: arena; properties
@@ -391,9 +347,18 @@ Arena properties
``arena`` is the arena.
- Returns the total amount of memory that has been committed to RAM
+ Returns the total amount of memory that has been committed for use
by the MPS, in :term:`bytes (1)`.
+ For a :term:`virtual memory arena`, this is the amount of memory
+ mapped to RAM by the operating system's virtual memory interface.
+
+ For a :term:`client arena`, this is the amount of memory marked as
+ in use in the arena's page tables. This is not particularly
+ meaningful by itself, but it corresponds to the amount of mapped
+ memory that the MPS would use if switched to a virtual memory
+ arena.
+
The committed memory is generally larger than the sum of the sizes
of the allocated :term:`blocks`. The reasons for this are:
@@ -420,10 +385,10 @@ Arena properties
state>`). If it is called when the arena is in the unclamped state
then the value may change after this function returns. A possible
use might be to call it just after :c:func:`mps_arena_collect` to
- (over-)estimate the size of the heap.
+ estimate the size of the heap.
If you want to know how much memory the MPS is using then you're
- probably interested in the value :c:func:`mps_arena_committed()` −
+ probably interested in the value :c:func:`mps_arena_committed` −
:c:func:`mps_arena_spare_committed`.
The amount of committed memory can be limited with the function
@@ -447,12 +412,12 @@ Arena properties
.. note::
- For a client arena, the reserved address may be lower than the
- sum of the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument
- passed to :c:func:`mps_arena_create_k` and the ``size``
- arguments passed to :c:func:`mps_arena_extend`, because the
- arena may be unable to use the whole of each chunk for reasons
- of alignment.
+ For a :term:`client arena`, the reserved address space may be
+ lower than the sum of the :c:macro:`MPS_KEY_ARENA_SIZE`
+ keyword argument passed to :c:func:`mps_arena_create_k` and
+ the ``size`` arguments passed to :c:func:`mps_arena_extend`,
+ because the arena may be unable to use the whole of each chunk
+ for reasons of alignment.
.. c:function:: size_t mps_arena_spare_commit_limit(mps_arena_t arena)
@@ -517,6 +482,11 @@ Arena properties
functions for limiting the amount of :term:`committed `
memory.
+ .. note::
+
+ :term:`Client arenas` do not use spare committed memory, and
+ so this function always returns 0.
+
.. index::
single: arena; states
@@ -839,114 +809,3 @@ Arena introspection
return storage to the operating system). For reliable results
call this function and interpret the result while the arena is
in the :term:`parked state`.
-
-
-.. index::
- pair: arena; protection
-
-Protection interface
---------------------
-
-.. c:function:: void mps_arena_expose(mps_arena_t arena)
-
- .. deprecated:: starting with version 1.111.
-
- Ensure that the MPS is not protecting any :term:`page` in the
- :term:`arena` with a :term:`read barrier` or :term:`write
- barrier`.
-
- ``mps_arena`` is the arena to expose.
-
- This is expected to only be useful for debugging. The arena is
- left in the :term:`clamped state`.
-
- Since barriers are used during a collection, calling this function
- has the same effect as calling :c:func:`mps_arena_park`: all
- collections are run to completion, and the arena is clamped so
- that no new collections begin. The MPS also uses barriers to
- maintain :term:`remembered sets`, so calling this
- function will effectively destroy the remembered sets and any
- optimization gains from them.
-
- Calling this function is time-consuming: any active collections
- will be run to completion; and the next collection will have to
- recompute all the remembered sets by scanning the entire arena.
-
- The recomputation of the remembered sets can be avoided by calling
- :c:func:`mps_arena_unsafe_expose_remember_protection` instead of
- :c:func:`mps_arena_expose`, and by calling
- :c:func:`mps_arena_unsafe_restore_protection` before calling
- :c:func:`mps_arena_release`. Those functions have unsafe aspects
- and place restrictions on what the :term:`client program` can do
- (basically no exposed data can be changed).
-
-
-.. c:function:: void mps_arena_unsafe_expose_remember_protection(mps_arena_t arena)
-
- .. deprecated:: starting with version 1.111.
-
- Ensure that the MPS is not protecting any :term:`page` in the
- :term:`arena` with a :term:`read barrier` or :term:`write
- barrier`. In addition, request the MPS to remember some parts of its
- internal state so that they can be restored later.
-
- ``mps_arena`` is the arena to expose.
-
- This function is the same as :c:func:`mps_arena_expose`, but
- additionally causes the MPS to remember its protection state. The
- remembered protection state can optionally be restored later by
- calling the :c:func:`mps_arena_unsafe_restore_protection` function.
- This is an optimization that avoids the MPS having to recompute
- all the remembered sets by scanning the entire arena.
-
- However, restoring the remembered protections is only safe if the
- contents of the exposed pages have not been changed; therefore
- this function should only be used if you do not intend to change
- the pages, and the remembered protection must only be restored if
- the pages have not been changed.
-
- The MPS will only remember the protection state if resources
- (memory) are available. If memory is low then only some or
- possibly none of the protection state will be remembered, with a
- corresponding necessity to recompute it later. The MPS provides no
- mechanism for the :term:`client program` to determine whether the
- MPS has in fact remembered the protection state.
-
- The remembered protection state, if any, is discarded after
- calling :c:func:`mps_arena_unsafe_restore_protection`, or as soon
- as the arena leaves the :term:`clamped state` by calling
- :c:func:`mps_arena_release`.
-
-
-.. c:function:: void mps_arena_unsafe_restore_protection(mps_arena_t arena)
-
- .. deprecated:: starting with version 1.111.
-
- Restore the remembered protection state for an :term:`arena`.
-
- ``mps_arena`` is the arena to restore the protection state for.
-
- This function restores the protection state that the MPS has
- remembered when the :term:`client program` called
- :c:func:`mps_arena_unsafe_expose_remember_protection`. The purpose
- of remembering and restoring the protection state is to avoid the
- need for the MPS to recompute all the :term:`remembered sets` by scanning the entire arena, that occurs when
- :c:func:`mps_arena_expose` is used, and which causes the next
- :term:`garbage collection` to be slow.
-
- The client program must not change the exposed data between the
- call to :c:func:`mps_arena_unsafe_expose_remember_protection` and
- :c:func:`mps_arena_unsafe_restore_protection`. If the client
- program has changed the exposed data then
- :c:func:`mps_arena_unsafe_restore_protection` must not be called:
- in this case simply call :c:func:`mps_arena_release`.
-
- Calling this function does not release the arena from the clamped
- state: :c:func:`mps_arena_release` must be called to continue
- normal collections.
-
- Calling this function causes the MPS to forget the remember
- protection state; as a consequence the same remembered state
- cannot be restored more than once.
-
-
diff --git a/mps/manual/source/topic/deprecated.rst b/mps/manual/source/topic/deprecated.rst
new file mode 100644
index 00000000000..dfd4d8d74cb
--- /dev/null
+++ b/mps/manual/source/topic/deprecated.rst
@@ -0,0 +1,745 @@
+.. index::
+ single: deprecated interfaces
+
+.. _topic-deprecated:
+
+Deprecated interfaces
+=====================
+
+This chapter documents the public symbols in the MPS interface that
+are now deprecated. These symbols may be removed in any future release
+(see :ref:`topic-interface-support` for details). If you are using one
+of these symbols, then you should update your code to use the
+supported interface.
+
+.. note::
+
+ If you are relying on a deprecated interface, and there is no
+ supported alternative, please :ref:`contact us `. It
+ makes a difference if we know that someone is using a feature.
+
+
+.. index::
+ single: deprecated interfaces; in version 1.115
+
+Deprecated in version 1.115
+...........................
+
+.. c:type:: typedef mps_pool_class_t mps_class_t
+
+ .. deprecated::
+
+ The former name for :c:type:`mps_pool_class_t`, chosen when
+ pools were the only objects in the MPS that belonged to
+ classes.
+
+
+.. c:function:: size_t mps_mv_free_size(mps_pool_t pool)
+
+ .. deprecated::
+
+ Use the generic function :c:func:`mps_pool_free_size` instead.
+
+ Return the total amount of free space in an MV pool.
+
+ ``pool`` is the MV pool.
+
+ Returns the total free space in the pool, in :term:`bytes (1)`.
+
+
+.. c:function:: size_t mps_mv_size(mps_pool_t pool)
+
+ .. deprecated::
+
+ Use the generic function :c:func:`mps_pool_total_size`
+ instead.
+
+ Return the total size of an MV pool.
+
+ ``pool`` is the MV pool.
+
+ Returns the total size of the pool, in :term:`bytes (1)`. This
+ is the sum of allocated space and free space.
+
+
+.. c:function:: size_t mps_mvff_free_size(mps_pool_t pool)
+
+ .. deprecated::
+
+ Use the generic function :c:func:`mps_pool_free_size` instead.
+
+ Return the total amount of free space in an MVFF pool.
+
+ ``pool`` is the MVFF pool.
+
+ Returns the total free space in the pool, in :term:`bytes (1)`.
+
+
+.. c:function:: size_t mps_mvff_size(mps_pool_t pool)
+
+ .. deprecated::
+
+ Use the generic function :c:func:`mps_pool_total_size`
+ instead.
+
+ Return the total size of an MVFF pool.
+
+ ``pool`` is the MVFF pool.
+
+ Returns the total size of the pool, in :term:`bytes (1)`. This
+ is the sum of allocated space and free space.
+
+
+.. c:function:: size_t mps_mvt_free_size(mps_pool_t pool)
+
+ .. deprecated::
+
+ Use the generic function :c:func:`mps_pool_free_size` instead.
+
+ Return the total amount of free space in an MVT pool.
+
+ ``pool`` is the MVT pool.
+
+ Returns the total free space in the pool, in :term:`bytes (1)`.
+
+
+.. c:function:: size_t mps_mvt_size(mps_pool_t pool)
+
+ .. deprecated::
+
+ Use the generic function :c:func:`mps_pool_total_size`
+ instead.
+
+ Return the total size of an MVT pool.
+
+ ``pool`` is the MVT pool.
+
+ Returns the total size of the pool, in :term:`bytes (1)`. This
+ is the sum of allocated space and free space.
+
+
+.. index::
+ single: deprecated interfaces; in version 1.113
+
+Deprecated in version 1.113
+...........................
+
+.. c:function:: MPS_ARGS_DONE(args)
+
+ .. deprecated::
+
+ Formerly this was used to finalize a list of :term:`keyword
+ arguments` before passing it to a function. It is no longer
+ needed.
+
+
+.. index::
+ single: deprecated interfaces; in version 1.112
+
+Deprecated in version 1.112
+...........................
+
+.. c:function:: mps_res_t mps_arena_create(mps_arena_t *arena_o, mps_arena_class_t arena_class, ...)
+
+ .. deprecated::
+
+ Use :c:func:`mps_arena_create_k` instead.
+
+ An alternative to :c:func:`mps_arena_create_k` that takes its
+ extra arguments using the standard :term:`C` variable argument
+ list mechanism.
+
+ When creating an arena of class :c:func:`mps_arena_class_cl`, pass
+ the values for the keyword arguments :c:macro:`MPS_KEY_ARENA_SIZE`
+ and :c:macro:`MPS_KEY_ARENA_CL_BASE` like this::
+
+ mps_res_t mps_arena_create(mps_arena_t *arena_o,
+ mps_arena_class_t mps_arena_class_cl(),
+ size_t arena_size,
+ mps_addr_t cl_base)
+
+ When creating an arena of class :c:func:`mps_arena_class_vm`, pass
+ the value for the keyword argument :c:macro:`MPS_KEY_ARENA_SIZE`
+ like this::
+
+ mps_res_t mps_arena_create(mps_arena_t *arena_o,
+ mps_arena_class_t mps_arena_class_vm(),
+ size_t arena_size)
+
+
+.. c:function:: mps_res_t mps_arena_create_v(mps_arena_t *arena_o, mps_arena_class_t arena_class, va_list args)
+
+ .. deprecated::
+
+ Use :c:func:`mps_arena_create_k` instead.
+
+ An alternative to :c:func:`mps_arena_create_k` that takes its
+ extra arguments using the standard :term:`C` ``va_list``
+ mechanism. See :c:func:`mps_arena_create` for details of which
+ arguments to pass for the different arena classes.
+
+
+.. c:function:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, mps_pool_class_t pool_class, ...)
+
+ .. deprecated::
+
+ Use :c:func:`mps_pool_create_k` instead.
+
+ An alternative to :c:func:`mps_pool_create_k` that takes its
+ extra arguments using the standard :term:`C` variable argument
+ list mechanism.
+
+ When creating a pool of class :c:func:`mps_class_amc` or
+ :c:func:`mps_class_amcz`, pass the values for the keyword
+ arguments :c:macro:`MPS_KEY_FORMAT` and :c:macro:`MPS_KEY_CHAIN`
+ like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_amc(),
+ mps_fmt_t format,
+ mps_chain_t chain)
+
+ When creating a pool of class :c:func:`mps_class_ams`, pass the
+ values for the keyword arguments :c:macro:`MPS_KEY_FORMAT`,
+ :c:macro:`MPS_KEY_CHAIN` and ambiguous flag
+ :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_ams(),
+ mps_fmt_t format,
+ mps_chain_t chain,
+ mps_bool_t ams_support_ambiguous)
+
+ When creating a pool of class :c:func:`mps_class_ams_debug`, pass
+ the values for the keyword arguments
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS`, :c:macro:`MPS_KEY_FORMAT`,
+ :c:macro:`MPS_KEY_CHAIN` and
+ :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_ams_debug(),
+ mps_pool_debug_option_s *pool_debug_options,
+ mps_fmt_t format,
+ mps_chain_t chain,
+ mps_bool_t ams_support_ambiguous)
+
+ When creating a pool of class :c:func:`mps_class_awl`, pass the
+ values for the keyword arguments :c:macro:`MPS_KEY_FORMAT` and
+ :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_awl(),
+ mps_fmt_t format,
+ mps_awl_find_dependent_t awl_find_dependent)
+
+ When creating a pool of class :c:func:`mps_class_lo`, pass the
+ value for the keyword argument :c:macro:`MPS_KEY_FORMAT` like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_lo(),
+ mps_fmt_t format)
+
+ When creating a pool of class :c:func:`mps_class_mfs`, pass the
+ values for the keyword arguments :c:macro:`MPS_KEY_EXTEND_BY` and
+ :c:macro:`MPS_KEY_MFS_UNIT_SIZE` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_mfs(),
+ size_t extend_by,
+ size_t unit_size)
+
+ When creating a pool of class :c:func:`mps_class_mv`, pass the
+ values for the keyword arguments :c:macro:`MPS_KEY_EXTEND_BY`,
+ :c:macro:`MPS_KEY_MEAN_SIZE`, and :c:macro:`MPS_KEY_MAX_SIZE` like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_mv(),
+ size_t extend_by,
+ size_t mean_size,
+ size_t max_size)
+
+ When creating a pool of class :c:func:`mps_class_mv_debug`, pass
+ the values for the keyword arguments
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS`,
+ :c:macro:`MPS_KEY_EXTEND_BY`, :c:macro:`MPS_KEY_MEAN_SIZE` and
+ :c:macro:`MPS_KEY_MAX_SIZE` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_mv_debug(),
+ mps_pool_debug_option_s *pool_debug_options,
+ size_t extend_by,
+ size_t mean_size,
+ size_t max_size)
+
+ When creating a pool of class :c:func:`mps_class_mvff`, pass the
+ values for the keyword arguments :c:macro:`MPS_KEY_EXTEND_BY`,
+ :c:macro:`MPS_KEY_MEAN_SIZE`, :c:macro:`MPS_KEY_ALIGN`,
+ :c:macro:`MPS_KEY_MVFF_SLOT_HIGH`,
+ :c:macro:`MPS_KEY_MVFF_ARENA_HIGH` and
+ :c:macro:`MPS_KEY_MVFF_FIRST_FIT` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_mvff(),
+ size_t extend_by,
+ size_t mean_size,
+ mps_align_t align,
+ mps_bool_t mvff_slot_high,
+ mps_bool_t mvff_arena_high,
+ mps_bool_t mvff_first_fit)
+
+ When creating a pool of class :c:func:`mps_class_mvff_debug`, pass
+ the values for the keyword arguments
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS`,
+ :c:macro:`MPS_KEY_EXTEND_BY`, :c:macro:`MPS_KEY_MEAN_SIZE`,
+ :c:macro:`MPS_KEY_ALIGN`, :c:macro:`MPS_KEY_MVFF_SLOT_HIGH`,
+ :c:macro:`MPS_KEY_MVFF_ARENA_HIGH`, and
+ :c:macro:`MPS_KEY_MVFF_FIRST_FIT` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_mvff_debug(),
+ mps_pool_debug_option_s *pool_debug_options,
+ size_t extend_by,
+ size_t mean_size,
+ mps_align_t align,
+ mps_bool_t mvff_slot_high,
+ mps_bool_t mvff_arena_high,
+ mps_bool_t mvff_first_fit)
+
+ When creating a pool of class :c:func:`mps_class_mvt`, pass the
+ values for the keyword arguments :c:macro:`MPS_KEY_MIN_SIZE`,
+ :c:macro:`MPS_KEY_MEAN_SIZE`, :c:macro:`MPS_KEY_MAX_SIZE`,
+ :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` and
+ :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_mvt(),
+ size_t min_size,
+ size_t mean_size,
+ size_t max_size,
+ mps_word_t mvt_reserve_depth,
+ mps_word_t mvt_frag_limit)
+
+ .. note::
+
+ The ``mvt_frag_limit`` is a percentage from 0 to 100
+ inclusive when passed to :c:func:`mps_pool_create`, not a
+ double from 0.0 to 1.0 as in :c:func:`mps_pool_create_k`.
+
+ When creating a pool of class :c:func:`mps_class_snc`, pass the
+ value for the keyword argument :c:macro:`MPS_KEY_FORMAT` like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_pool_class_t mps_class_snc(),
+ mps_fmt_t format)
+
+
+.. c:function:: mps_res_t mps_pool_create_v(mps_pool_t *pool_o, mps_arena_t arena, mps_pool_class_t pool_class, va_list args)
+
+ .. deprecated::
+
+ Use :c:func:`mps_pool_create_k` instead.
+
+ An alternative to :c:func:`mps_pool_create_k` that takes its extra
+ arguments using the standard :term:`C` ``va_list`` mechanism. See
+ :c:func:`mps_pool_create` for details of which arguments to pass
+ for the different pool classes.
+
+
+.. c:function:: mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool, ...)
+
+ .. deprecated::
+
+ Use :c:func:`mps_ap_create_k` instead.
+
+ An alternative to :c:func:`mps_ap_create_k` that takes its extra
+ arguments using the standard :term:`C` variable argument list
+ mechanism.
+
+ When creating an allocation point on a pool of class
+ :c:func:`mps_class_ams`, :c:func:`mps_class_ams_debug`,
+ :c:func:`mps_class_awl` or :c:func:`mps_class_snc`, pass the
+ keyword argument :c:macro:`MPS_KEY_RANK` like this::
+
+ mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
+ mps_rank_t rank)
+
+
+.. c:function:: mps_res_t mps_ap_create_v(mps_ap_t *ap_o, mps_pool_t pool, va_list args)
+
+ .. deprecated::
+
+ Use :c:func:`mps_ap_create_k` instead.
+
+ An alternative to :c:func:`mps_ap_create_k` that takes its extra
+ arguments using the standard :term:`C` ``va_list`` mechanism. See
+ :c:func:`mps_ap_create` for details of which arguments to pass
+ for the different pool classes.
+
+
+.. c:type:: mps_fmt_A_s
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ The type of the structure used to create an :term:`object format`
+ of variant A. ::
+
+ typedef struct mps_fmt_A_s {
+ mps_align_t align;
+ mps_fmt_scan_t scan;
+ mps_fmt_skip_t skip;
+ mps_fmt_copy_t copy;
+ mps_fmt_fwd_t fwd;
+ mps_fmt_isfwd_t isfwd;
+ mps_fmt_pad_t pad;
+ } mps_fmt_A_s;
+
+ The fields of this structure correspond to the keyword arguments
+ to :c:func:`mps_fmt_create_k`, except for ``copy``, which is not
+ used. In older versions of the MPS this was a *copy method*
+ that copied objects belonging to this format.
+
+
+.. c:function:: mps_res_t mps_fmt_create_A(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_A_s *fmt_A)
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ Create an :term:`object format` based on a description of an
+ object format of variant A.
+
+
+.. c:type:: mps_fmt_B_s
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ The type of the structure used to create an :term:`object format`
+ of variant B. ::
+
+ typedef struct mps_fmt_B_s {
+ mps_align_t align;
+ mps_fmt_scan_t scan;
+ mps_fmt_skip_t skip;
+ mps_fmt_copy_t copy;
+ mps_fmt_fwd_t fwd;
+ mps_fmt_isfwd_t isfwd;
+ mps_fmt_pad_t pad;
+ mps_fmt_class_t mps_class;
+ } mps_fmt_B_s;
+
+ Variant B is the same as variant A except for the addition of the
+ ``mps_class`` method. See :c:type:`mps_fmt_A_s`.
+
+
+.. c:function:: mps_res_t mps_fmt_create_B(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_B_s *fmt_B)
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ Create an :term:`object format` based on a description of an
+ object format of variant B.
+
+
+.. c:type:: mps_fmt_auto_header_s
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ The type of the structure used to create an :term:`object format`
+ of variant auto-header. ::
+
+ typedef struct mps_fmt_auto_header_s {
+ mps_align_t align;
+ mps_fmt_scan_t scan;
+ mps_fmt_skip_t skip;
+ mps_fmt_fwd_t fwd;
+ mps_fmt_isfwd_t isfwd;
+ mps_fmt_pad_t pad;
+ size_t mps_headerSize;
+ } mps_fmt_auto_header_s;
+
+ Variant auto-header is the same as variant A except for the
+ removal of the unused ``copy`` method, and the addition of the
+ ``mps_headerSize`` field. See :c:type:`mps_fmt_A_s`.
+
+
+.. c:function:: mps_res_t mps_fmt_create_auto_header(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_auto_header_s *fmt_ah)
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ Create an :term:`object format` based on a description of an
+ object format of variant auto-header.
+
+
+.. c:type:: mps_fmt_fixed_s
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ The type of the structure used to create an :term:`object format`
+ of variant fixed. ::
+
+ typedef struct mps_fmt_fixed_s {
+ mps_align_t align;
+ mps_fmt_scan_t scan;
+ mps_fmt_fwd_t fwd;
+ mps_fmt_isfwd_t isfwd;
+ mps_fmt_pad_t pad;
+ } mps_fmt_fixed_s;
+
+ Variant fixed is the same as variant A except for the removal of
+ the unused ``copy`` method, and the lack of a ``skip`` method
+ (this is not needed because the objects are fixed in size). See
+ :c:type:`mps_fmt_A_s`.
+
+
+.. c:function:: mps_res_t mps_fmt_create_fixed(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_fixed_s *fmt_fixed)
+
+ .. deprecated::
+
+ Use :c:func:`mps_fmt_create_k` instead.
+
+ Create an :term:`object format` based on a description of an
+ object format of variant fixed.
+
+
+.. index::
+ single: deprecated interfaces; in version 1.111
+
+Deprecated in version 1.111
+...........................
+
+.. c:function:: mps_res_t mps_fix(mps_ss_t ss, mps_addr_t *ref_io)
+
+ .. deprecated::
+
+ Use :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2` instead.
+
+ :term:`Fix` a :term:`reference`.
+
+ This is a function equivalent to::
+
+ MPS_SCAN_BEGIN(ss);
+ res = MPS_FIX12(ss, ref_io);
+ MPS_SCAN_END(ss);
+ return res;
+
+ Because :term:`scanning ` is an operation on the
+ :term:`critical path`, we recommend that you use
+ :c:func:`MPS_FIX12` (or :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2`)
+ to ensure that the "stage 1 fix" is inlined.
+
+ .. note::
+
+ If you call this between :c:func:`MPS_SCAN_BEGIN` and
+ :c:func:`MPS_SCAN_END`, you must use :c:func:`MPS_FIX_CALL` to
+ ensure that the scan state is passed correctly.
+
+
+.. c:function:: mps_word_t mps_telemetry_control(mps_word_t reset_mask, mps_word_t flip_mask)
+
+ .. deprecated::
+
+ Use :c:func:`mps_telemetry_get`,
+ :c:func:`mps_telemetry_reset`, and :c:func:`mps_telemetry_set`
+ instead.
+
+ Update and return the :term:`telemetry filter`.
+
+ ``reset_mask`` is a :term:`bitmask` indicating the bits in the
+ telemetry filter that should be reset.
+
+ ``flip_mask`` is a bitmask indicating the bits in the telemetry
+ filter whose value should be flipped after the resetting.
+
+ Returns the previous value of the telemetry filter, prior to the
+ reset and the flip.
+
+ The parameters ``reset_mask`` and ``flip_mask`` allow the
+ specification of any binary operation on the filter control. For
+ typical operations, the parameters should be set as follows:
+
+ ============ ============== =============
+ Operation ``reset_mask`` ``flip_mask``
+ ============ ============== =============
+ ``set(M)`` ``M`` ``M``
+ ------------ -------------- -------------
+ ``reset(M)`` ``M`` ``0``
+ ------------ -------------- -------------
+ ``flip(M)`` ``0`` ``M``
+ ------------ -------------- -------------
+ ``read()`` ``0`` ``0``
+ ============ ============== =============
+
+
+.. c:function:: void mps_tramp(void **r_o, mps_tramp_t f, void *p, size_t s)
+
+ .. deprecated::
+
+ The MPS trampoline is no longer required on any operating
+ system supported by the MPS.
+
+ Call a function via the MPS trampoline.
+
+ ``r_o`` points to a location that will store the result of calling
+ ``f``.
+
+ ``f`` is the function to call.
+
+ ``p`` and ``s`` are arguments that will be passed to ``f`` each
+ time it is called. This is intended to make it easy to pass, for
+ example, an array and its size as parameters.
+
+ The MPS relies on :term:`barriers (1)` to protect memory
+ that is in an inconsistent state. On some operating systems,
+ barrier hits generate exceptions that have to be caught by a
+ handler that is on the stack. On these operating systems, any code
+ that uses memory managed by the MPS must be called from inside
+ such an exception handler, that is, inside a call to
+ :c:func:`mps_tramp`.
+
+ If you have multiple threads that run code that uses memory
+ managed by the MPS, each thread must execute such code inside a
+ call to :c:func:`mps_tramp`.
+
+
+.. index::
+ single: trampoline
+
+.. c:type:: void *(*mps_tramp_t)(void *p, size_t s)
+
+ .. deprecated::
+
+ The MPS trampoline is no longer required on any operating
+ system supported by the MPS.
+
+ The type of a function called by :c:func:`mps_tramp`.
+
+ ``p`` and ``s`` are the corresponding arguments that were passed
+ to :c:func:`mps_tramp`.
+
+
+.. c:function:: void mps_arena_expose(mps_arena_t arena)
+
+ .. deprecated::
+
+ If you need access to protected memory for debugging,
+ :ref:`contact us `.
+
+ Ensure that the MPS is not protecting any :term:`page` in the
+ :term:`arena` with a :term:`read barrier` or :term:`write
+ barrier`.
+
+ ``arena`` is the arena to expose.
+
+ This is expected to only be useful for debugging. The arena is
+ left in the :term:`clamped state`.
+
+ Since barriers are used during a collection, calling this function
+ has the same effect as calling :c:func:`mps_arena_park`: all
+ collections are run to completion, and the arena is clamped so
+ that no new collections begin. The MPS also uses barriers to
+ maintain :term:`remembered sets`, so calling this
+ function will effectively destroy the remembered sets and any
+ optimization gains from them.
+
+ Calling this function is time-consuming: any active collections
+ will be run to completion; and the next collection will have to
+ recompute all the remembered sets by scanning the entire arena.
+
+ The recomputation of the remembered sets can be avoided by calling
+ :c:func:`mps_arena_unsafe_expose_remember_protection` instead of
+ :c:func:`mps_arena_expose`, and by calling
+ :c:func:`mps_arena_unsafe_restore_protection` before calling
+ :c:func:`mps_arena_release`. Those functions have unsafe aspects
+ and place restrictions on what the :term:`client program` can do
+ (basically no exposed data can be changed).
+
+
+.. c:function:: void mps_arena_unsafe_expose_remember_protection(mps_arena_t arena)
+
+ .. deprecated::
+
+ If you need access to protected memory for debugging,
+ :ref:`contact us `.
+
+ Ensure that the MPS is not protecting any :term:`page` in the
+ :term:`arena` with a :term:`read barrier` or :term:`write
+ barrier`. In addition, request the MPS to remember some parts of its
+ internal state so that they can be restored later.
+
+ ``arena`` is the arena to expose.
+
+ This function is the same as :c:func:`mps_arena_expose`, but
+ additionally causes the MPS to remember its protection state. The
+ remembered protection state can optionally be restored later by
+ calling the :c:func:`mps_arena_unsafe_restore_protection` function.
+ This is an optimization that avoids the MPS having to recompute
+ all the remembered sets by scanning the entire arena.
+
+ However, restoring the remembered protections is only safe if the
+ contents of the exposed pages have not been changed; therefore
+ this function should only be used if you do not intend to change
+ the pages, and the remembered protection must only be restored if
+ the pages have not been changed.
+
+ The MPS will only remember the protection state if resources
+ (memory) are available. If memory is low then only some or
+ possibly none of the protection state will be remembered, with a
+ corresponding necessity to recompute it later. The MPS provides no
+ mechanism for the :term:`client program` to determine whether the
+ MPS has in fact remembered the protection state.
+
+ The remembered protection state, if any, is discarded after
+ calling :c:func:`mps_arena_unsafe_restore_protection`, or as soon
+ as the arena leaves the :term:`clamped state` by calling
+ :c:func:`mps_arena_release`.
+
+
+.. c:function:: void mps_arena_unsafe_restore_protection(mps_arena_t arena)
+
+ .. deprecated::
+
+ If you need access to protected memory for debugging,
+ :ref:`contact us `.
+
+ Restore the remembered protection state for an :term:`arena`.
+
+ ``arena`` is the arena to restore the protection state for.
+
+ This function restores the protection state that the MPS has
+ remembered when the :term:`client program` called
+ :c:func:`mps_arena_unsafe_expose_remember_protection`. The purpose
+ of remembering and restoring the protection state is to avoid the
+ need for the MPS to recompute all the :term:`remembered sets` by
+ scanning the entire arena, that occurs when
+ :c:func:`mps_arena_expose` is used, and which causes the next
+ :term:`garbage collection` to be slow.
+
+ The client program must not change the exposed data between the
+ call to :c:func:`mps_arena_unsafe_expose_remember_protection` and
+ :c:func:`mps_arena_unsafe_restore_protection`. If the client
+ program has changed the exposed data then
+ :c:func:`mps_arena_unsafe_restore_protection` must not be called:
+ in this case simply call :c:func:`mps_arena_release`.
+
+ Calling this function does not release the arena from the clamped
+ state: :c:func:`mps_arena_release` must be called to continue
+ normal collections.
+
+ Calling this function causes the MPS to forget the remembered
+ protection state; as a consequence the same remembered state
+ cannot be restored more than once.
+
diff --git a/mps/manual/source/topic/error.rst b/mps/manual/source/topic/error.rst
index 82efa2e5e3c..1120b868897 100644
--- a/mps/manual/source/topic/error.rst
+++ b/mps/manual/source/topic/error.rst
@@ -76,31 +76,28 @@ Result codes
A :term:`result code` indicating that an operation could not be
completed as requested without exceeding the :term:`commit limit`.
- You need to deallocate something to make more space, or increase
+ You need to deallocate something or allow the :term:`garbage
+ collector` to reclaim something to make more space, or increase
the commit limit by calling :c:func:`mps_arena_commit_limit_set`.
.. c:macro:: MPS_RES_FAIL
A :term:`result code` indicating that something went wrong that
- does not fall under the description of any other result code. The
- exact meaning depends on the function that returned this result
- code.
+ does not fall under the description of any other result code.
.. c:macro:: MPS_RES_IO
A :term:`result code` indicating that an input/output error
- occurred. The exact meaning depends on the function that returned
- this result code.
+ occurred in the :term:`telemetry` system.
.. c:macro:: MPS_RES_LIMIT
A :term:`result code` indicating that an operation could not be
completed as requested because of an internal limitation of the
- MPS. The exact meaning depends on the function that returned this
- result code.
+ MPS.
.. c:macro:: MPS_RES_MEMORY
@@ -109,7 +106,7 @@ Result codes
completed because there wasn't enough memory available.
You need to deallocate something or allow the :term:`garbage
- collector` to reclaim something to free enough memory, or expand
+ collector` to reclaim something to free enough memory, or extend
the :term:`arena` (if you're using an arena for which that does
not happen automatically).
@@ -140,27 +137,23 @@ Result codes
A :term:`result code` indicating that an operation could not be
completed as requested because an invalid parameter was passed to
- the operation. The exact meaning depends on the function that
- returned this result code.
+ the operation.
.. c:macro:: MPS_RES_RESOURCE
A :term:`result code` indicating that an operation could not be
completed as requested because the MPS could not obtain a needed
- resource. The resource in question depends on the operation.
+ resource. It can be returned when the MPS runs out of
+ :term:`address space`. If this happens, you need to reclaim memory
+ within your process (as for the result code
+ :c:macro:`MPS_RES_MEMORY`).
Two special cases have their own result codes: when the MPS runs
out of committed memory, it returns :c:macro:`MPS_RES_MEMORY`, and
when it cannot proceed without exceeding the :term:`commit limit`,
it returns :c:macro:`MPS_RES_COMMIT_LIMIT`.
- This result code can be returned when the MPS runs out of
- :term:`virtual memory`. If this happens, you need to reclaim
- memory within your process (as for the result code
- :c:macro:`MPS_RES_MEMORY`), or terminate other processes running
- on the same machine.
-
.. c:macro:: MPS_RES_UNIMPL
@@ -272,13 +265,49 @@ this documentation.
:c:type:`mps_fmt_t` for this argument.
+``global.c: RingIsSingle(&arena->chainRing)``
+
+ The client program called :c:func:`mps_arena_destroy` without
+ destroying all the :term:`generation chains` belonging to the
+ arena. It is necessary to call :c:func:`mps_chain_destroy` first.
+
+
+``global.c: RingIsSingle(&arena->formatRing)``
+
+ The client program called :c:func:`mps_arena_destroy` without
+ destroying all the :term:`object formats` belonging to the arena.
+ It is necessary to call :c:func:`mps_fmt_destroy` first.
+
+
+``global.c: RingIsSingle(&arena->rootRing)``
+
+ The client program called :c:func:`mps_arena_destroy` without
+ destroying all the :term:`roots` belonging to the arena.
+ It is necessary to call :c:func:`mps_root_destroy` first.
+
+
+``global.c: RingIsSingle(&arena->threadRing)``
+
+ The client program called :c:func:`mps_arena_destroy` without
+ deregistering all the :term:`threads` belonging to the arena.
+ It is necessary to call :c:func:`mps_thread_dereg` first.
+
+
+``global.c: RingLength(&arenaGlobals->poolRing) == 5``
+
+ The client program called :c:func:`mps_arena_destroy` without
+ destroying all the :term:`pools` belonging to the arena.
+ It is necessary to call :c:func:`mps_pool_destroy` first.
+
+
``lockix.c: res == 0``
``lockw3.c: lock->claims == 0``
The client program has made a re-entrant call into the MPS. Look
- at the backtrace to see what it was. Common culprits are
- :term:`format methods` and :term:`stepper functions`.
+ at the backtrace to see what it was. Common culprits are signal
+ handlers, assertion handlers, :term:`format methods`, and
+ :term:`stepper functions`.
``locus.c: chain->activeTraces == TraceSetEMPTY``
@@ -305,13 +334,19 @@ this documentation.
condition?
-``ring.c: ring->next == ring``
+``poolsnc.c: foundSeg``
- The client program destroyed an object without having destroyed
- all the objects that it owns first. For example, it destroyed an
- arena without first destroying all pools in that arena, or it
- destroyed a pool without first destroying all allocation points
- created on that pool.
+ The client program passed an incorrect ``frame`` argument to
+ :c:func:`mps_ap_frame_pop`. This argument must be the result from
+ a previous call to :c:func:`mps_ap_frame_push` on the same
+ allocation point.
+
+
+``seg.c: gcseg->buffer == NULL``
+
+ The client program destroyed pool without first destroying all the
+ allocation points created on that pool. The allocation points must
+ be destroyed first.
``trace.c: ss->rank < RankEXACT``
@@ -320,7 +355,7 @@ this documentation.
for finalization, and then continued to run the garbage collector.
See :ref:`topic-finalization-cautions` under
:ref:`topic-finalization`, which says, "You must destroy these
- pools by following the “safe tear-down” procedure described under
+ pools by following the ‘safe tear-down’ procedure described under
:c:func:`mps_pool_destroy`."
@@ -330,22 +365,24 @@ this documentation.
reference to an object that moved. See
:ref:`topic-scanning-protocol`, which says, "If :c:func:`MPS_FIX2`
returns :c:macro:`MPS_RES_OK`, it may have updated the reference.
- If necessary, make sure that the updated reference is stored back
- to the region being scanned."
+ Make sure that the updated reference is stored back to the region
+ being scanned."
.. index::
single: error handling; varieties
single: variety
+.. _topic-error-variety:
+
Varieties
---------
-The MPS has three behaviours with respect to internal checking and
-:ref:`telemetry `, which need to be selected at
-compile time, by defining one of the following preprocessor
-constants. If none is specified then :c:macro:`CONFIG_VAR_HOT` is the
-default.
+The MPS has three *varieties* which have different levels of internal
+checking and :ref:`telemetry `. The variety can be
+selected at compile time, by defining one of the following
+preprocessor constants. If none is specified then
+:c:macro:`CONFIG_VAR_HOT` is the default.
.. index::
@@ -354,7 +391,7 @@ default.
.. c:macro:: CONFIG_VAR_COOL
- The cool variety is intended for development and testing.
+ The *cool variety* is intended for development and testing.
All functions check the consistency of their data structures and may
assert, including functions on the :term:`critical path`.
@@ -372,7 +409,7 @@ default.
.. c:macro:: CONFIG_VAR_HOT
- The hot variety is intended for production and deployment.
+ The *hot variety* is intended for production and deployment.
Some functions check the consistency of their data structures and
may assert, namely those not on the :term:`critical path`. However,
@@ -389,7 +426,7 @@ default.
.. c:macro:: CONFIG_VAR_RASH
- The rash variety is intended for mature integrations, or for
+ The *rash variety* is intended for mature integrations, or for
developers who like living dangerously.
No functions check the consistency of their data structures and
diff --git a/mps/manual/source/topic/format.rst b/mps/manual/source/topic/format.rst
index 9ed826b2ac2..7db5c8a1178 100644
--- a/mps/manual/source/topic/format.rst
+++ b/mps/manual/source/topic/format.rst
@@ -179,6 +179,20 @@ There are some cautions to be observed when using in-band headers:
#. Not all :term:`pool classes` support objects with in-band headers.
See the documentation for the pool class.
+.. note::
+
+ A :term:`client program` that allocates objects with
+ :term:`in-band headers` has to make a choice about how to
+ represent references to those objects. It can represent them using
+ :term:`base pointers` (which is convenient for allocation, since
+ :c:func:`mps_reserve` returns a base pointer, but requires
+ decoding when scanning) or using :term:`client pointers` (which is
+ convenient for scanning, since the :term:`scan method` takes a
+ client pointer, but requires encoding on allocation). Either
+ approach will work, but :term:`client pointers` are normally the
+ better choice, since scanning is normally more
+ performance-critical than allocation.
+
.. index::
pair: object format; cautions
@@ -221,9 +235,9 @@ Cautions
#. Format methods must use no more than 64 words of stack space.
This restriction is necessary to avoid stack overflow in the MPS;
- see :mps:ref:`design.mps.sp` for details. If your application has
- format methods that need more stack space than this, :ref:`contact
- us `.
+ see :ref:`design-sp` for details. If your application has format
+ methods that need more stack space than this, :ref:`contact us
+ `.
#. Format methods must not:
@@ -535,137 +549,3 @@ Object format introspection
c. memory not managed by the MPS;
It must not access other memory managed by the MPS.
-
-
-Obsolete interface
-------------------
-
-.. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_ap_create_k` instead: the :term:`keyword
- arguments` interface is more flexible and easier to understand.
-
-Formerly the only way to create object formats was to describe the
-format in the form of a *format variant structure*.
-
-There are four format variants.
-
-* Variant A (:c:type:`mps_fmt_A_s`): for objects without
- :term:`in-band headers`.
-
-* Variant B (:c:type:`mps_fmt_B_s`): as variant A, but with the
- addition of a class method.
-
-* Variant auto-header (:c:type:`mps_fmt_auto_header_s`): for objects
- with :term:`in-band headers`.
-
-* Variant fixed (:c:type:`mps_fmt_fixed_s`): for fixed-size objects.
-
-The client program creates an object format by construct a format
-variant structure and then calling the appropriate ``mps_fmt_create_``
-function for the variant. The variant structure can then be disposed
-of.
-
-
-.. c:type:: mps_fmt_A_s
-
- The type of the structure used to create an :term:`object format`
- of variant A. ::
-
- typedef struct mps_fmt_A_s {
- mps_align_t align;
- mps_fmt_scan_t scan;
- mps_fmt_skip_t skip;
- mps_fmt_copy_t copy;
- mps_fmt_fwd_t fwd;
- mps_fmt_isfwd_t isfwd;
- mps_fmt_pad_t pad;
- } mps_fmt_A_s;
-
- The fields of this structure correspond to the keyword arguments
- to :c:func:`mps_fmt_create_k`, except for ``copy``, which is not
- used. In older versions of the MPS this was a *copy method*
- that copied objects belonging to this format.
-
-
-.. c:function:: mps_res_t mps_fmt_create_A(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_A_s *fmt_A)
-
- Create an :term:`object format` based on a description of an
- object format of variant A.
-
-
-.. c:type:: mps_fmt_B_s
-
- The type of the structure used to create an :term:`object format`
- of variant B. ::
-
- typedef struct mps_fmt_B_s {
- mps_align_t align;
- mps_fmt_scan_t scan;
- mps_fmt_skip_t skip;
- mps_fmt_copy_t copy;
- mps_fmt_fwd_t fwd;
- mps_fmt_isfwd_t isfwd;
- mps_fmt_pad_t pad;
- mps_fmt_class_t mps_class;
- } mps_fmt_B_s;
-
- Variant B is the same as variant A except for the addition of the
- ``mps_class`` method. See :c:type:`mps_fmt_A_s`.
-
-
-.. c:function:: mps_res_t mps_fmt_create_B(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_B_s *fmt_B)
-
- Create an :term:`object format` based on a description of an
- object format of variant B.
-
-
-.. c:type:: mps_fmt_auto_header_s
-
- The type of the structure used to create an :term:`object format`
- of variant auto-header. ::
-
- typedef struct mps_fmt_auto_header_s {
- mps_align_t align;
- mps_fmt_scan_t scan;
- mps_fmt_skip_t skip;
- mps_fmt_fwd_t fwd;
- mps_fmt_isfwd_t isfwd;
- mps_fmt_pad_t pad;
- size_t mps_headerSize;
- } mps_fmt_auto_header_s;
-
- Variant auto-header is the same as variant A except for the
- removal of the unused ``copy`` method, and the addition of the
- ``mps_headerSize`` field. See :c:type:`mps_fmt_A_s`.
-
-
-.. c:function:: mps_res_t mps_fmt_create_auto_header(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_auto_header_s *fmt_ah)
-
- Create an :term:`object format` based on a description of an
- object format of variant auto-header.
-
-
-.. c:type:: mps_fmt_fixed_s
-
- The type of the structure used to create an :term:`object format`
- of variant fixed. ::
-
- typedef struct mps_fmt_fixed_s {
- mps_align_t align;
- mps_fmt_scan_t scan;
- mps_fmt_fwd_t fwd;
- mps_fmt_isfwd_t isfwd;
- mps_fmt_pad_t pad;
- } mps_fmt_fixed_s;
-
- Variant fixed is the same as variant A except for the removal of
- the unused ``copy`` method, and the lack of a ``skip`` method
- (this is not needed because the objects are fixed in size). See
- :c:type:`mps_fmt_A_s`.
-
-
-.. c:function:: mps_res_t mps_fmt_create_fixed(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_fixed_s *fmt_fixed)
-
- Create an :term:`object format` based on a description of an
- object format of variant fixed.
diff --git a/mps/manual/source/topic/index.rst b/mps/manual/source/topic/index.rst
index 32f4a6bb494..3f2cb2863bf 100644
--- a/mps/manual/source/topic/index.rst
+++ b/mps/manual/source/topic/index.rst
@@ -29,3 +29,5 @@ Reference
plinth
platform
porting
+ deprecated
+
diff --git a/mps/manual/source/topic/interface.rst b/mps/manual/source/topic/interface.rst
index 54637557f60..e7715181836 100644
--- a/mps/manual/source/topic/interface.rst
+++ b/mps/manual/source/topic/interface.rst
@@ -35,6 +35,10 @@ Support policy
a version in which the symbol (or reliance on some of its
behaviour) is deprecated.
+ Symbols may be deprecated in their old place in the reference
+ manual, or they may be moved to the :ref:`topic-deprecated`
+ chapter.
+
.. note::
If you are relying on a feature and you see that it's
@@ -204,7 +208,8 @@ Instead, we recommend this approach::
mps_addr_t p;
struct foo *fp;
res = mps_alloc(&p, pool, sizeof(struct foo));
- if(res) /* handle error case */;
+ if (res != MPS_RES_OK)
+ /* handle error case */;
fp = p;
This has defined behaviour because conversion from ``void *`` to any
diff --git a/mps/manual/source/topic/keyword.rst b/mps/manual/source/topic/keyword.rst
index 25e18f2de4d..ac80333ba36 100644
--- a/mps/manual/source/topic/keyword.rst
+++ b/mps/manual/source/topic/keyword.rst
@@ -82,43 +82,43 @@ now :c:macro:`MPS_KEY_ARGS_END`.
The type of :term:`keyword argument` keys. Must take one of the
following values:
- ======================================== ====================================================== ==========================================================
- Keyword Type & field in ``arg.val`` See
- ======================================== ====================================================== ==========================================================
- :c:macro:`MPS_KEY_ARGS_END` *none* *see above*
- :c:macro:`MPS_KEY_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`, :c:func:`mps_class_mvt`
- :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_ams`
- :c:macro:`MPS_KEY_ARENA_CL_BASE` :c:type:`mps_addr_t` ``addr`` :c:func:`mps_arena_class_cl`
- :c:macro:`MPS_KEY_ARENA_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
- :c:macro:`MPS_KEY_ARENA_GRAIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
- :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``void *(*)(void *)`` ``addr_method`` :c:func:`mps_class_awl`
- :c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
- :c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`
- :c:macro:`MPS_KEY_FMT_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_CLASS` :c:type:`mps_fmt_class_t` ``fmt_class`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_FWD` :c:type:`mps_fmt_fwd_t` ``fmt_fwd`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_HEADER_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_ISFWD` :c:type:`mps_fmt_isfwd_t` ``fmt_isfwd`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_PAD` :c:type:`mps_fmt_pad_t` ``fmt_pad`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_SCAN` :c:type:`mps_fmt_scan_t` ``fmt_scan`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FMT_SKIP` :c:type:`mps_fmt_skip_t` ``fmt_skip`` :c:func:`mps_fmt_create_k`
- :c:macro:`MPS_KEY_FORMAT` :c:type:`mps_fmt_t` ``format`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` , :c:func:`mps_class_snc`
- :c:macro:`MPS_KEY_GEN` :c:type:`unsigned` ``u`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
- :c:macro:`MPS_KEY_INTERIOR` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`
- :c:macro:`MPS_KEY_MAX_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`
- :c:macro:`MPS_KEY_MEAN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`, :c:func:`mps_class_mvt`, :c:func:`mps_class_mvff`
- :c:macro:`MPS_KEY_MFS_UNIT_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs`
- :c:macro:`MPS_KEY_MIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mvt`
- :c:macro:`MPS_KEY_MVFF_ARENA_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
- :c:macro:`MPS_KEY_MVFF_FIRST_FIT` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
- :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
- :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt`
- :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt`
- :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` ``mps_pool_debug_options_s *`` ``pool_debug_options`` :c:func:`mps_class_ams_debug`, :c:func:`mps_class_mv_debug`, :c:func:`mps_class_mvff_debug`
- :c:macro:`MPS_KEY_RANK` :c:type:`mps_rank_t` ``rank`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_snc`
- :c:macro:`MPS_KEY_SPARE` :c:type:`double` ``d`` :c:func:`mps_class_mvff`
- :c:macro:`MPS_KEY_VMW3_TOP_DOWN` :c:type:`mps_bool_t` ``b`` :c:func:`mps_arena_class_vm`
- ======================================== ====================================================== ==========================================================
+ ======================================== ========================================================= ==========================================================
+ Keyword Type & field in ``arg.val`` See
+ ======================================== ========================================================= ==========================================================
+ :c:macro:`MPS_KEY_ARGS_END` *none* *see above*
+ :c:macro:`MPS_KEY_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`, :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_ams`
+ :c:macro:`MPS_KEY_ARENA_CL_BASE` :c:type:`mps_addr_t` ``addr`` :c:func:`mps_arena_class_cl`
+ :c:macro:`MPS_KEY_ARENA_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
+ :c:macro:`MPS_KEY_ARENA_GRAIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
+ :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``void *(*)(void *)`` ``addr_method`` :c:func:`mps_class_awl`
+ :c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
+ :c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_FMT_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_CLASS` :c:type:`mps_fmt_class_t` ``fmt_class`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_FWD` :c:type:`mps_fmt_fwd_t` ``fmt_fwd`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_HEADER_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_ISFWD` :c:type:`mps_fmt_isfwd_t` ``fmt_isfwd`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_PAD` :c:type:`mps_fmt_pad_t` ``fmt_pad`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_SCAN` :c:type:`mps_fmt_scan_t` ``fmt_scan`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FMT_SKIP` :c:type:`mps_fmt_skip_t` ``fmt_skip`` :c:func:`mps_fmt_create_k`
+ :c:macro:`MPS_KEY_FORMAT` :c:type:`mps_fmt_t` ``format`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` , :c:func:`mps_class_snc`
+ :c:macro:`MPS_KEY_GEN` :c:type:`unsigned` ``u`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
+ :c:macro:`MPS_KEY_INTERIOR` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`
+ :c:macro:`MPS_KEY_MAX_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`
+ :c:macro:`MPS_KEY_MEAN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`, :c:func:`mps_class_mvt`, :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MFS_UNIT_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs`
+ :c:macro:`MPS_KEY_MIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_MVFF_ARENA_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MVFF_FIRST_FIT` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` :c:type:`mps_pool_debug_option_s` ``*pool_debug_options`` :c:func:`mps_class_ams_debug`, :c:func:`mps_class_mv_debug`, :c:func:`mps_class_mvff_debug`
+ :c:macro:`MPS_KEY_RANK` :c:type:`mps_rank_t` ``rank`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_snc`
+ :c:macro:`MPS_KEY_SPARE` :c:type:`double` ``d`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_VMW3_TOP_DOWN` :c:type:`mps_bool_t` ``b`` :c:func:`mps_arena_class_vm`
+ ======================================== ========================================================= ==========================================================
.. c:function:: MPS_ARGS_BEGIN(args)
@@ -192,11 +192,3 @@ now :c:macro:`MPS_KEY_ARGS_END`.
``args`` is the name of array that contains the keyword arguments.
It must match the argument to the preceding call to
:c:func:`MPS_ARGS_BEGIN`.
-
-
-.. c:function:: MPS_ARGS_DONE(args)
-
- .. deprecated:: starting with version 1.113.
-
- Formerly this was used to finalize a list of keyword arguments
- before passing it to a function. It is no longer needed.
diff --git a/mps/manual/source/topic/plinth.rst b/mps/manual/source/topic/plinth.rst
index 8f26f267d70..f771f6c1c31 100644
--- a/mps/manual/source/topic/plinth.rst
+++ b/mps/manual/source/topic/plinth.rst
@@ -262,6 +262,11 @@ Library module
:c:func:`mps_lib_assert_fail_install`. For a discussion of the
default behaviour, see :ref:`topic-error-assertion-handling`.
+ .. warning::
+
+ This function must not call any function in MPS, and it must
+ not access memory managed by the MPS.
+
.. c:function:: extern mps_lib_assert_fail_t mps_lib_assert_fail_install(mps_lib_assert_fail_t handler)
This function customises the behaviour of the default assertion handler
@@ -277,6 +282,11 @@ Library module
Returns the previously installed handler.
+ .. warning::
+
+ The installed assertion handler must not call any function in
+ MPS, and it must not access memory managed by the MPS.
+
.. c:type:: typedef void (*mps_lib_assert_fail_t)(const char *, unsigned, const char *)
The type of assertion handlers passed to and returned by
diff --git a/mps/manual/source/topic/pool.rst b/mps/manual/source/topic/pool.rst
index 68ec8185f03..d1ffe56d45b 100644
--- a/mps/manual/source/topic/pool.rst
+++ b/mps/manual/source/topic/pool.rst
@@ -40,31 +40,6 @@ making it available for allocation.
:c:func:`mps_pool_destroy`.
-.. c:function:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, mps_pool_class_t pool_class, ...)
-
- .. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_pool_create_k` instead: the :term:`keyword
- arguments` interface is more reliable and produces better
- error messages.
-
- An alternative to :c:func:`mps_pool_create_k` that takes its
- extra arguments using the standard :term:`C` variable argument
- list mechanism.
-
-
-.. c:function:: mps_res_t mps_pool_create_v(mps_pool_t *pool_o, mps_arena_t arena, mps_pool_class_t pool_class, va_list args)
-
- .. deprecated:: starting with version 1.112.
-
- Use :c:func:`mps_pool_create_k` instead: the :term:`keyword
- arguments` interface is more reliable and produces better
- error messages.
-
- An alternative to :c:func:`mps_pool_create_k` that takes its extra
- arguments using the standard :term:`C` ``va_list`` mechanism.
-
-
.. c:function:: void mps_pool_destroy(mps_pool_t pool)
Destroy a :term:`pool`.
@@ -83,12 +58,12 @@ making it available for allocation.
.. warning::
- It is not safe to destroy an :term:`automatically managed
- ` pool if it contains any objects
+ It is not safe to carry on running the :term:`garbage
+ collector` after destroying an :term:`automatically managed
+ ` pool that contains any objects
that are :term:`reachable` from your roots, or any objects
that have been registered for :term:`finalization` but not yet
- finalized, and then to carry on running the :term:`garbage
- collector`.
+ finalized.
Our recommended approach is to destroy automatically managed
pools just before destroying the arena, and then only while
@@ -123,13 +98,6 @@ See the :ref:`pool` for a list of pool classes.
The type of :term:`pool classes`.
-.. c:type:: typedef mps_pool_class_t mps_class_t
-
- .. deprecated:: starting with version 1.115.
-
- The former name for ``mps_pool_class_t``, chosen when pools
- were the only objects in the MPS that belonged to classes.
-
.. index::
pair: pool; introspection
diff --git a/mps/manual/source/topic/porting.rst b/mps/manual/source/topic/porting.rst
index b58663a48b7..600dd7138de 100644
--- a/mps/manual/source/topic/porting.rst
+++ b/mps/manual/source/topic/porting.rst
@@ -38,29 +38,10 @@ usable.
See :ref:`design-lock` for the design, and ``lock.h`` for the
interface. There are implementations for Linux in ``lockli.c``,
- POSIX in ``lockix.c``, and Windows in ``lockw3.c``. There is a
- generic implementation in ``lockan.c``, which cannot actually take
- any locks and so only works for a single thread.
+ POSIX in ``lockix.c``, and Windows in ``lockw3.c``.
-#. The **thread manager** module suspends and resumes :term:`threads`,
- so that the MPS can gain exclusive access to :term:`memory (2)`,
- and so that it can scan the :term:`registers` and :term:`control
- stack` of suspended threads.
-
- See :ref:`design-thread-manager` for the design, and ``th.h`` for
- the interface. There are implementations for POSIX in ``thix.c``
- plus ``pthrdext.c``, OS X using Mach in ``thxc.c``, Windows in
- ``thw3.c``. There is a generic implementation in ``than.c``, which
- necessarily only supports a single thread.
-
-#. The **virtual mapping** module reserves :term:`address space` from
- the operating system (and returns it), and :term:`maps `
- address space to :term:`main memory` (and unmaps it).
-
- See :ref:`design-vm` for the design, and ``vm.h`` for the
- interface. There are implementations for POSIX in ``vmix.c``, and
- Windows in ``vmw3.c``. There is a generic implementation in
- ``vman.c``, which fakes virtual memory by calling :c:func:`malloc`.
+ There is a generic implementation in ``lockan.c``, which cannot
+ actually take any locks and so only works for a single thread.
#. The **memory protection** module applies :term:`protection` to
areas of :term:`memory (2)`, ensuring that attempts to read or
@@ -70,10 +51,13 @@ usable.
See :ref:`design-prot` for the design, and ``prot.h`` for the
interface. There are implementations for POSIX in ``protix.c`` plus
``protsgix.c``, Linux in ``protli.c``, Windows in ``protw3.c``, and
- OS X using Mach in ``protxc.c``. There is a generic implementation
- in ``protan.c``, which can't provide memory protection, so it
- forces memory to be scanned until that there is no further need to
- protect it.
+ OS X using Mach in ``protxc.c``.
+
+ There is a generic implementation in ``protan.c``, which can't
+ provide memory protection, so it forces memory to be scanned until
+ that there is no further need to protect it. This means it can't
+ support incremental collection, and has no control over pause
+ times.
#. The **protection mutator context** module figures out what the
:term:`mutator` was doing when it caused a :term:`protection
@@ -83,8 +67,10 @@ usable.
See :ref:`design-prmc` for the design, and ``prot.h`` for the
interface. There are implementations on Unix, Windows, and OS X for
- IA-32 and x86-64. There is a generic implementation in
- ``prmcan.c``, which can't provide these features.
+ IA-32 and x86-64.
+
+ There is a generic implementation in ``prmcan.c``, which can't
+ provide these features, and so only supports a single thread.
#. The **stack probe** module checks that there is enough space on the
:term:`control stack` for the MPS to complete any operation that it
@@ -93,8 +79,12 @@ usable.
See :ref:`design-sp` for the design, and ``sp.h`` for the
interface. There are implementations on Windows on IA-32 in
- ``spi3w3.c`` and x86-64 in ``spi6w3.c``. There is a generic
- implementation in ``span.c``, which can't provide this feature.
+ ``spi3w3.c`` and x86-64 in ``spi6w3.c``.
+
+ There is a generic implementation in ``span.c``, which can't
+ provide this feature, and so is only suitable for use with a client
+ program that does not handle stack overflow faults, or does not
+ call into the MPS from the handler.
#. The **stack and register scanning** module :term:`scans` the
:term:`registers` and :term:`control stack` of a thread.
@@ -103,8 +93,34 @@ usable.
interface. There are implementations for POSIX on IA-32 in
``ssixi3.c`` and x86-64 in ``ssixi6.c``, and for Windows with
Microsoft Visual C/C++ on IA-32 in ``ssw3i3mv.c`` and x86-64 in
- ``ssw3i6mv.c``. There is a generic implementation in ``ssan.c``,
- which calls :c:func:`setjmp` to spill the registers.
+ ``ssw3i6mv.c``.
+
+ There is a generic implementation in ``ssan.c``, which calls
+ :c:func:`setjmp` to spill the registers and scans the whole jump
+ buffer, thus overscanning compared to a platform-specific
+ implementation.
+
+#. The **thread manager** module suspends and resumes :term:`threads`,
+ so that the MPS can gain exclusive access to :term:`memory (2)`,
+ and so that it can scan the :term:`registers` and :term:`control
+ stack` of suspended threads.
+
+ See :ref:`design-thread-manager` for the design, and ``th.h`` for
+ the interface. There are implementations for POSIX in ``thix.c``
+ plus ``pthrdext.c``, OS X using Mach in ``thxc.c``, Windows in
+ ``thw3.c``.
+
+ There is a generic implementation in ``than.c``, which necessarily
+ only supports a single thread.
+
+#. The **virtual mapping** module reserves :term:`address space` from
+ the operating system (and returns it), and :term:`maps `
+ address space to :term:`main memory` (and unmaps it).
+
+ See :ref:`design-vm` for the design, and ``vm.h`` for the
+ interface. There are implementations for POSIX in ``vmix.c``, and
+ Windows in ``vmw3.c``. There is a generic implementation in
+ ``vman.c``, which fakes virtual memory by calling :c:func:`malloc`.
Platform detection
@@ -185,15 +201,17 @@ Makefile
--------
Add a makefile even if you expect to use an integrated development
-environment like Visual Studio or Xcode. Makefiles make it easier to
-carry out continuous integration and delivery.
+environment (IDE) like Visual Studio or Xcode. Makefiles make it
+easier to carry out continuous integration and delivery, and are less
+likely to stop working because of incompatibilities between IDE
+versions.
-The makefile must be named ``osarct.gmk``, and must define ``PFM`` to
-be the platform code, ``MPMPF`` to be the list of platform modules
-(the same files included by ``mps.c``), and ``LIBS`` to be the linker
-options for any libraries required by the test cases. Then it must
-include the compiler-specific makefile and ``comm.gmk``. For example,
-``lii6ll.gmk`` looks like this::
+On Unix platforms, the makefile must be named ``osarct.gmk``, and must
+define ``PFM`` to be the platform code, ``MPMPF`` to be the list of
+platform modules (the same files included by ``mps.c``), and ``LIBS``
+to be the linker options for any libraries required by the test cases.
+Then it must include the compiler-specific makefile and ``comm.gmk``.
+For example, ``lii6ll.gmk`` looks like this::
PFM = lii6ll
@@ -222,6 +240,29 @@ improve performance by compiling the MPS and their object format in
the same compilation unit. These steps would be more complicated if
the MPS required particular compilation options.
+On Windows, the makefile must be named ``osarct.nmk``, and must define
+``PFM`` to be the platform code, and ``MPMPF`` to be the list of
+platform modules (the same files included by ``mps.c``) in square
+brackets. Then it must include the compiler-specific makefile and
+``comm.nmk``. For example, ``w3i6mv.nmk`` looks like this::
+
+ PFM = w3i6mv
+
+ MPMPF = \
+ [lockw3] \
+ [mpsiw3] \
+ [prmci6w3] \
+ [proti6] \
+ [protw3] \
+ [spw3i6] \
+ [ssw3i6mv] \
+ [thw3] \
+ [thw3i6] \
+ [vmw3]
+
+ !INCLUDE mv.nmk
+ !INCLUDE comm.nmk
+
Porting strategy
----------------
@@ -230,15 +271,17 @@ Start the port by selecting existing implementations of the functional
modules, using the generic implementations where nothing else will do.
Then check that the "smoke tests" pass, by running::
- make -f osarct.gmk testrun
+ make -f osarct.gmk testrun # Unix
+ nmake /f osarct.nmk testrun # Windows
-Most or all of the test cases should pass at this point (if you're
+Most or all of the test cases should pass at this point. If you're
using the generic threading implementation, then the multi-threaded
-test cases ``amcssth`` and ``awlutth`` are expected to fail; and if
-you're using the generic lock implementation, then the lock
-utilization test case ``lockut`` is expected to fail). However,
-performance will be very poor if you're using the generic memory
-protection implementation.
+test cases are expected to fail. If you're using the generic lock
+implementation, then the lock utilization test case ``lockut`` is
+expected to fail. If you're using the generic memory protection
+implementation, all the tests that rely on incremental collection are
+expected to fail. See ``tool/testcases.txt`` for a database of test
+cases and the configurations in which they are expected to pass.
Now that there is a working system to build on, porting the necessary
modules to the new platform can be done incrementally. It's a good
diff --git a/mps/manual/source/topic/scanning.rst b/mps/manual/source/topic/scanning.rst
index ed9adbb045a..6b4c4a1d396 100644
--- a/mps/manual/source/topic/scanning.rst
+++ b/mps/manual/source/topic/scanning.rst
@@ -361,9 +361,9 @@ Scanning interface
.. c:function:: MPS_FIX_CALL(ss, call)
- Call a function from within a :term:`scan method`, between
- :c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`, passing
- the :term:`scan state` correctly.
+ Call a function to do some scanning, from within a :term:`scan
+ method`, between :c:func:`MPS_SCAN_BEGIN` and
+ :c:func:`MPS_SCAN_END`, passing the :term:`scan state` correctly.
``ss`` is the scan state that was passed to the scan method.
@@ -377,6 +377,9 @@ Scanning interface
must wrap the call with :c:func:`MPS_FIX_CALL` to ensure that the
scan state is passed correctly.
+ The function being called must use :c:func:`MPS_SCAN_BEGIN` and
+ :c:func:`MPS_SCAN_END` appropriately.
+
In example below, the scan method ``obj_scan`` fixes the object's
``left`` and ``right`` references, but delegates the scanning of
references inside the object's ``data`` member to the function
@@ -406,9 +409,11 @@ Scanning interface
.. warning::
- Use of :c:func:`MPS_FIX_CALL` is best avoided, as it forces
- values out of registers. The gains in simplicity of the code
- need to be measured against the loss in performance.
+ Use of :c:func:`MPS_FIX_CALL` is best avoided, as it may
+ force values out of registers (depending on compiler
+ optimisations such as inlining). The gains in simplicity of
+ the code ought to be measured against the loss in
+ performance.
.. index::
@@ -496,30 +501,3 @@ Fixing interface
In the case where the scan method does not need to do anything
between :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2`, you can use
the convenience macro :c:func:`MPS_FIX12`.
-
-
-.. c:function:: mps_res_t mps_fix(mps_ss_t ss, mps_addr_t *ref_io)
-
- .. deprecated:: starting with version 1.111.
-
- Use :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2` instead.
-
- :term:`Fix` a :term:`reference`.
-
- This is a function equivalent to::
-
- MPS_SCAN_BEGIN(ss);
- res = MPS_FIX12(ss, ref_io);
- MPS_SCAN_END(ss);
- return res;
-
- Because :term:`scanning ` is an operation on the
- :term:`critical path`, we recommend that you use
- :c:func:`MPS_FIX12` (or :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2`)
- to ensure that the "stage 1 fix" is inlined.
-
- .. note::
-
- If you call this between :c:func:`MPS_SCAN_BEGIN` and
- :c:func:`MPS_SCAN_END`, you must use :c:func:`MPS_FIX_CALL` to
- ensure that the scan state is passed correctly.
diff --git a/mps/manual/source/topic/telemetry.rst b/mps/manual/source/topic/telemetry.rst
index 4dc6d8d89a7..e25e71e4c59 100644
--- a/mps/manual/source/topic/telemetry.rst
+++ b/mps/manual/source/topic/telemetry.rst
@@ -388,41 +388,6 @@ further analysis by running :program:`mpseventsql`.
Telemetry interface
-------------------
-.. c:function:: mps_word_t mps_telemetry_control(mps_word_t reset_mask, mps_word_t flip_mask)
-
- .. deprecated:: starting with version 1.111.
-
- Use :c:func:`mps_telemetry_get`, :c:func:`mps_telemetry_reset`,
- and :c:func:`mps_telemetry_set` instead.
-
- Update and return the :term:`telemetry filter`.
-
- ``reset_mask`` is a :term:`bitmask` indicating the bits in the
- telemetry filter that should be reset.
-
- ``flip_mask`` is a bitmask indicating the bits in the telemetry
- filter whose value should be flipped after the resetting.
-
- Returns the previous value of the telemetry filter, prior to the
- reset and the flip.
-
- The parameters ``reset_mask`` and ``flip_mask`` allow the
- specification of any binary operation on the filter control. For
- typical operations, the parameters should be set as follows:
-
- ============ ============== =============
- Operation ``reset_mask`` ``flip_mask``
- ============ ============== =============
- ``set(M)`` ``M`` ``M``
- ------------ -------------- -------------
- ``reset(M)`` ``M`` ``0``
- ------------ -------------- -------------
- ``flip(M)`` ``0`` ``M``
- ------------ -------------- -------------
- ``read()`` ``0`` ``0``
- ============ ============== =============
-
-
.. c:function:: void mps_telemetry_flush(void)
Flush the internal event buffers into the :term:`telemetry stream`.
diff --git a/mps/manual/source/topic/thread.rst b/mps/manual/source/topic/thread.rst
index 0a4156613ac..9417c473b04 100644
--- a/mps/manual/source/topic/thread.rst
+++ b/mps/manual/source/topic/thread.rst
@@ -168,47 +168,3 @@ Thread interface
It is recommended that threads be deregistered only when they
are just about to exit.
-
-
-.. c:function:: void mps_tramp(void **r_o, mps_tramp_t f, void *p, size_t s)
-
- .. deprecated:: starting with version 1.111.
-
- Call a function via the MPS trampoline.
-
- ``r_o`` points to a location that will store the result of calling
- ``f``.
-
- ``f`` is the function to call.
-
- ``p`` and ``s`` are arguments that will be passed to ``f`` each
- time it is called. This is intended to make it easy to pass, for
- example, an array and its size as parameters.
-
- The MPS relies on :term:`barriers (1)` to protect memory
- that is in an inconsistent state. On some operating systems,
- barrier hits generate exceptions that have to be caught by a
- handler that is on the stack. On these operating systems, any code
- that uses memory managed by the MPS must be called from inside
- such an exception handler, that is, inside a call to
- :c:func:`mps_tramp`.
-
- If you have multiple threads that run code that uses memory
- managed by the MPS, each thread must execute such code inside a
- call to :c:func:`mps_tramp`.
-
- Starting with version 1.111, this is not required on any operating
- system supported by the MPS.
-
-
-.. index::
- single: trampoline
-
-.. c:type:: void *(*mps_tramp_t)(void *p, size_t s)
-
- .. deprecated:: starting with version 1.111.
-
- The type of a function called by :c:func:`mps_tramp`.
-
- ``p`` and ``s`` are the corresponding arguments that were passed
- to :c:func:`mps_tramp`.
diff --git a/mps/test/README b/mps/test/README
index 08f3f398c36..90edaf8857f 100644
--- a/mps/test/README
+++ b/mps/test/README
@@ -11,18 +11,19 @@ Testing on unix
From the test directory::
- $ PLATFORM=lii6ll # substitute your platform
- $ CODE=../code # code directory of the branch you are testing
- $ make -C $CODE -f $PLATFORM.gmk VARIETY=cool $PLATFORM/cool/mps.o
- $ alias qa="perl test/qa -i $CODE -l $CODE/$PLATFORM/cool/mps.o"
- $ qa clib
- $ qa run function/5.c
- $ qa runset testsets/passing
+ PLATFORM=lii6ll # substitute your platform
+ CODE=../code # code directory of the branch you are testing
+ make -B -C $CODE -f $PLATFORM.gmk VARIETY=cool $PLATFORM/cool/mps.o
+ alias qa="perl test/qa -i $CODE -l $CODE/$PLATFORM/cool/mps.o"
+ qa clib
+ qa run function/5.c
+ qa runset testsets/passing
Each test case is compiled in its turn to the file
``test/obj/$(uname -s)_$(uname -r)_$(uname -p)__unix/tmp_test``
so you can debug it with::
- $ lldb test/obj/$(uname -s)_$(uname -r)_$(uname -p)__unix/tmp_test
+ lldb test/obj/$(uname -s)_$(uname -r)_$(uname -p)__unix/tmp_test
-(Or ``gdb`` instead of ``lldb``.)
+Or ``gdb`` instead of ``lldb``. MMQA sets its own assertion handler,
+so you'll probably want to set a breakpoint on mmqa_assert_handler.
diff --git a/mps/test/argerr/111.c b/mps/test/argerr/111.c
index cba3b7feda8..6f60b0a3269 100644
--- a/mps/test/argerr/111.c
+++ b/mps/test/argerr/111.c
@@ -4,6 +4,10 @@ TEST_HEADER
summary = UNALIGNED base for mps_root_create_table
language = c
link = testlib.o
+OUTPUT_SPEC
+ assert = true
+ assertfile P= root.c
+ assertcond = AddrIsAligned(base, sizeof(Word))
END_HEADER
*/
diff --git a/mps/test/argerr/143.c b/mps/test/argerr/143.c
index 045b8d89893..9099a6c3c13 100644
--- a/mps/test/argerr/143.c
+++ b/mps/test/argerr/143.c
@@ -4,6 +4,10 @@ TEST_HEADER
summary = UNALIGNED stackpointer for mps_root_create_reg
language = c
link = testlib.o
+OUTPUT_SPEC
+ assert = true
+ assertfile P= mpsi.c
+ assertcond = AddrIsAligned(reg_scan_p, sizeof(Word))
END_HEADER
*/
diff --git a/mps/test/argerr/146.c b/mps/test/argerr/146.c
index a2fd7d76910..c6d465671eb 100644
--- a/mps/test/argerr/146.c
+++ b/mps/test/argerr/146.c
@@ -4,6 +4,8 @@ TEST_HEADER
summary = null scan state to fix (function)
language = c
link = testlib.o
+OUTPUT_SPEC
+ abort = true
END_HEADER
*/
@@ -449,7 +451,7 @@ static void test(void)
mps_ap_t ap;
int j;
- mycell *a;
+ mycell *a, *b;
cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");
@@ -481,9 +483,20 @@ static void test(void)
for (j=1; j<1000; j++)
{
- allocone(ap, 1000);
+ b = allocone(ap, 1000);
+ setref(b, 0, a);
+ a = b;
}
+ mps_arena_collect(arena);
+
+ mps_ap_destroy(ap);
+ mps_pool_destroy(pool);
+ mps_chain_destroy(chain);
+ mps_fmt_destroy(format);
+ mps_root_destroy(root);
+ mps_thread_dereg(thread);
+ mps_arena_destroy(arena);
}
int main(void)
diff --git a/mps/test/argerr/147.c b/mps/test/argerr/147.c
index ecb781e5e39..0b11507cc81 100644
--- a/mps/test/argerr/147.c
+++ b/mps/test/argerr/147.c
@@ -4,6 +4,8 @@ TEST_HEADER
summary = unaligned scan state to fix (function)
language = c
link = testlib.o
+OUTPUT_SPEC
+ abort = true
END_HEADER
*/
@@ -449,7 +451,7 @@ static void test(void)
mps_ap_t ap;
int j;
- mycell *a;
+ mycell *a, *b;
cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");
@@ -481,7 +483,9 @@ static void test(void)
for (j=1; j<1000; j++)
{
- allocone(ap, 1000);
+ b = allocone(ap, 1000);
+ setref(b, 0, a);
+ a = b;
}
}
diff --git a/mps/test/argerr/148.c b/mps/test/argerr/148.c
index b1ec5cbdd0f..814429c1cdb 100644
--- a/mps/test/argerr/148.c
+++ b/mps/test/argerr/148.c
@@ -4,6 +4,8 @@ TEST_HEADER
summary = null addr to fix (function)
language = c
link = testlib.o
+OUTPUT_SPEC
+ abort = true
END_HEADER
*/
@@ -449,7 +451,7 @@ static void test(void)
mps_ap_t ap;
int j;
- mycell *a;
+ mycell *a, *b;
cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");
@@ -481,7 +483,9 @@ static void test(void)
for (j=1; j<1000; j++)
{
- allocone(ap, 1000);
+ b = allocone(ap, 1000);
+ setref(b, 0, a);
+ a = b;
}
}
diff --git a/mps/test/argerr/149.c b/mps/test/argerr/149.c
index 422043e8cef..c86d9ce3983 100644
--- a/mps/test/argerr/149.c
+++ b/mps/test/argerr/149.c
@@ -450,7 +450,7 @@ static void test(void)
mps_ap_t ap;
int j;
- mycell *a;
+ mycell *a, *b;
cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");
@@ -482,7 +482,9 @@ static void test(void)
for (j=1; j<1000; j++)
{
- allocone(ap, 1000);
+ b = allocone(ap, 1000);
+ setref(b, 0, a);
+ a = b;
}
}
diff --git a/mps/test/argerr/150.c b/mps/test/argerr/150.c
index 4be2075aa0e..88d751f5d4a 100644
--- a/mps/test/argerr/150.c
+++ b/mps/test/argerr/150.c
@@ -449,7 +449,7 @@ static void test(void)
mps_ap_t ap;
int j;
- mycell *a;
+ mycell *a, *b;
cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");
@@ -481,7 +481,9 @@ static void test(void)
for (j=1; j<1000; j++)
{
- allocone(ap, 1000);
+ b = allocone(ap, 1000);
+ setref(b, 0, a);
+ a = b;
}
}
diff --git a/mps/test/argerr/151.c b/mps/test/argerr/151.c
index 6541675947b..19ed2169a93 100644
--- a/mps/test/argerr/151.c
+++ b/mps/test/argerr/151.c
@@ -450,7 +450,7 @@ static void test(void)
mps_ap_t ap;
int j;
- mycell *a;
+ mycell *a, *b;
cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena");
@@ -482,7 +482,9 @@ static void test(void)
for (j=1; j<1000; j++)
{
- allocone(ap, 1000);
+ b = allocone(ap, 1000);
+ setref(b, 0, a);
+ a = b;
}
}
diff --git a/mps/test/argerr/35.c b/mps/test/argerr/35.c
index 4508eac3bff..218721759bf 100644
--- a/mps/test/argerr/35.c
+++ b/mps/test/argerr/35.c
@@ -6,7 +6,7 @@ TEST_HEADER
link = testlib.o
OUTPUT_SPEC
assert = true
- assertfile P= poolmv.c
+ assertfile P= pool.c
assertcond = AddrIsAligned(old, pool->alignment)
END_HEADER
*/
diff --git a/mps/test/argerr/36.c b/mps/test/argerr/36.c
index 8704bc1dc2b..ac35d796cac 100644
--- a/mps/test/argerr/36.c
+++ b/mps/test/argerr/36.c
@@ -4,6 +4,10 @@ TEST_HEADER
summary = wrong size_t to free (MV)
language = c
link = testlib.o
+OUTPUT_SPEC
+ assert = true
+ assertfile P= dbgpool.c
+ assertcond = tag->size == size
END_HEADER
*/
@@ -25,11 +29,8 @@ static void test(void)
cdie(mps_thread_reg(&thread, arena), "register thread");
- cdie(
- mps_pool_create(
- &pool, arena, mps_class_mv(),
- (size_t) 4096, (size_t) 32, (size_t) 64*1024),
- "create pool");
+ cdie(mps_pool_create_k(&pool, arena, mps_class_mv_debug(), mps_args_none),
+ "create pool");
die(mps_alloc(&a, pool, 8),
"alloc a");
diff --git a/mps/test/conerr/22.c b/mps/test/conerr/22.c
index aa371bd68b6..fb020003628 100644
--- a/mps/test/conerr/22.c
+++ b/mps/test/conerr/22.c
@@ -22,7 +22,7 @@ static void test(void)
size_t avgSize;
size_t maxSize;
- mps_addr_t obj = (mps_addr_t)1;
+ mps_addr_t obj = (mps_addr_t)MPS_PF_ALIGN;
extendBy = (size_t) 4096;
avgSize = (size_t) 32;
diff --git a/mps/test/conerr/26.c b/mps/test/conerr/26.c
index 7114c056fc8..8fcabc44357 100644
--- a/mps/test/conerr/26.c
+++ b/mps/test/conerr/26.c
@@ -26,7 +26,7 @@ static void test(void)
cdie(mps_pool_create_k(&pool0, arena, mps_class_mv(), mps_args_none),
"create pool 0");
- cdie(mps_pool_create(&pool1, arena, mps_class_mv(), mps_args_none),
+ cdie(mps_pool_create_k(&pool1, arena, mps_class_mv(), mps_args_none),
"create pool 1");
cdie(mps_alloc(&obj, pool0, 152), "allocate in 0");
diff --git a/mps/test/conerr/3.c b/mps/test/conerr/3.c
index 85f340a5f5b..dae5b202009 100644
--- a/mps/test/conerr/3.c
+++ b/mps/test/conerr/3.c
@@ -1,7 +1,7 @@
/*
TEST_HEADER
id = $Id$
- summary = destroy an arena which isn't an arena, with a pointer in
+ summary = destroy an arena which isn't an arena
language = c
link = testlib.o
OUTPUT_SPEC
@@ -11,13 +11,15 @@ OUTPUT_SPEC
END_HEADER
*/
+#include "mpmst.h"
#include "testlib.h"
static void test(void)
{
+ char buf[sizeof(ArenaStruct)];
mps_arena_t arena;
- arena = (mps_arena_t)&arena;
+ arena = (void *)buf;
mps_arena_destroy(arena);
comment("Destroy arena.");
}
diff --git a/mps/test/function/103.c b/mps/test/function/103.c
index fc4a7fa160a..07a77bf2470 100644
--- a/mps/test/function/103.c
+++ b/mps/test/function/103.c
@@ -32,7 +32,9 @@ static void fillup(void)
mps_addr_t a;
char *b;
- mps_pool_create(&poolmv, arena, mps_class_mv(), 64, 64, 64);
+ die(mps_pool_create(&poolmv, arena, mps_class_mv(),
+ (size_t)64, (size_t)64, (size_t)64),
+ "mps_pool_create");
size=1024ul*1024ul;
while (size) {
while (mps_alloc(&a, poolmv, size)==MPS_RES_OK) {
diff --git a/mps/test/function/120.c b/mps/test/function/120.c
index 915965094c0..4bd55205998 100644
--- a/mps/test/function/120.c
+++ b/mps/test/function/120.c
@@ -27,7 +27,7 @@ void *stackpointer;
mps_arena_t arena;
mps_thr_t thread;
mps_pool_t pool;
-mps_pool_t pools[100];
+mps_pool_t pools[1000];
static void test(void) {
int i;
@@ -100,13 +100,17 @@ static void test(void) {
i = 0;
- while ((i < 100) && (res == MPS_RES_OK)) {
+ while (i < sizeof pools / sizeof pools[0]) {
res = mps_pool_create(&pools[i], arena, mps_class_mv(), (size_t) 64, (size_t) 64, (size_t) 64);
- i++;
+ if (res == MPS_RES_OK) {
+ i++;
+ } else {
+ break;
+ }
}
report_res("poolcr", res);
- for (i -= 2; i >= 0; i--) {
+ for (i--; i >= 0; i--) {
mps_pool_destroy(pools[i]);
}
diff --git a/mps/test/function/121.c b/mps/test/function/121.c
index 263fa705594..c5780e23ee7 100644
--- a/mps/test/function/121.c
+++ b/mps/test/function/121.c
@@ -11,50 +11,56 @@ END_HEADER
#include "testlib.h"
#include "mpsavm.h"
-#include "mpscmv.h"
-
-
-void *stackpointer;
+#include "mpsacl.h"
mps_arena_t arena;
-mps_thr_t thread;
-mps_pool_t pool;
-mps_pool_t pools[100];
+static char buffer[1024 * 1024];
static void test(void)
{
+ mps_res_t res, prev_res = MPS_RES_OK;
int i;
- for (i = 64; i >= 0; i--) {
- mps_res_t res;
+
+ /* VM arenas round up small sizes and so creation must succeed. */
+ for (i = 1024; i >= 0; i -= i/17 + 1) {
+ MPS_ARGS_BEGIN(args) {
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 1024 * i);
+ die(mps_arena_create_k(&arena, mps_arena_class_vm(), args),
+ "mps_arena_create");
+ } MPS_ARGS_END(args);
+ mps_arena_destroy(arena);
+ }
- comment("Trying arena of %d kB.", i);
- res = mps_arena_create(&arena, mps_arena_class_vm(), (size_t)(1024*i));
+ /* Client arenas have to work within the memory they are given and
+ * so must fail at some point. */
+ for (i = 1024; i >= 0; i -= i/17 + 1) {
+ MPS_ARGS_BEGIN(args) {
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_BASE, buffer);
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 1024 * i);
+ res = mps_arena_create_k(&arena, mps_arena_class_cl(), args);
+ } MPS_ARGS_END(args);
if (res == MPS_RES_OK) {
- res = mps_thread_reg(&thread, arena);
- if (res == MPS_RES_OK) {
- mps_thread_dereg(thread);
- } else {
- if (res != MPS_RES_MEMORY) {
- error("Wrong error code, %d, for mps_thread_reg.", res);
- }
+ if (prev_res != MPS_RES_OK) {
+ error("Success with smaller size.");
}
mps_arena_destroy(arena);
} else {
- report_res("arena_create", res);
if (res != MPS_RES_MEMORY) {
+ report_res("arena_create", res);
error("Wrong error code.");
}
}
+ prev_res = res;
+ }
+ if (res != MPS_RES_MEMORY) {
+ error("Wrong error code.");
}
}
int main(void)
{
- void *m;
- stackpointer=&m; /* hack to get stack pointer */
-
easy_tramp(test);
pass();
return 0;
diff --git a/mps/test/function/137.c b/mps/test/function/137.c
index 178d2f5e628..715dae9b4c8 100644
--- a/mps/test/function/137.c
+++ b/mps/test/function/137.c
@@ -53,10 +53,10 @@ static void test(void) {
mps_arena_commit_limit_set(arena, COMLIMIT1);
- die(
- mps_pool_create(&pool, arena, mps_class_mvff(),
- EXTENDBY, 8, 8, 0, 0, 1),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mvff(),
+ (size_t)EXTENDBY, (size_t)8, (mps_align_t)8,
+ (mps_bool_t)0, (mps_bool_t)0, (mps_bool_t)1),
+ "create MVFF pool");
for (i = 0; i < NSMALL; i++) {
die(mps_alloc(&smallObjects[i], pool, SMALLSIZE), "small alloc failed");
diff --git a/mps/test/function/139.c b/mps/test/function/139.c
index 14537004366..3ba3c2a3395 100644
--- a/mps/test/function/139.c
+++ b/mps/test/function/139.c
@@ -43,10 +43,10 @@ static void test(void) {
mps_arena_commit_limit_set(arena, COMLIMIT1);
- die(
- mps_pool_create(&pool, arena, mps_class_mvff(),
- EXTENDBY, 8, 8, 0, 0, 1),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mvff(),
+ (size_t)EXTENDBY, (size_t)8, (mps_align_t)8,
+ (mps_bool_t)0, (mps_bool_t)0, (mps_bool_t)1),
+ "create MVFF pool");
for (i = 0; i < NSMALL; i++) {
die(mps_alloc(&smallObjects[i], pool, SMALLSIZE), "small alloc failed");
diff --git a/mps/test/function/144.c b/mps/test/function/144.c
index efbcf4d9d29..4343be93fea 100644
--- a/mps/test/function/144.c
+++ b/mps/test/function/144.c
@@ -29,10 +29,10 @@ static void test(void) {
(size_t) (1024*1024*50)), "create arena");
cdie(mps_thread_reg(&thread, arena), "register thread");
- die(
- mps_pool_create(&pool, arena, mps_class_mvff_debug(), &debugOpts,
- 8192, 8, 8, 0, 0, 1),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mvff_debug(), &debugOpts,
+ (size_t)8192, (size_t)8, (mps_align_t)8,
+ (mps_bool_t)0, (mps_bool_t)0, (mps_bool_t)1),
+ "create MVFF pool");
die(mps_alloc(&a, pool, 64), "alloc a");
die(mps_alloc(&b, pool, 64), "alloc b");
diff --git a/mps/test/function/150.c b/mps/test/function/150.c
index 78eec6b2647..c8496f3d662 100644
--- a/mps/test/function/150.c
+++ b/mps/test/function/150.c
@@ -195,13 +195,12 @@ static void test(void)
/* register loads of objects for finalization (1000*4) */
a = allocone(apamc, 2, 1);
- b = a;
for (j=0; j<1000; j++) {
- a = allocone(apamc, 2, mps_rank_exact());
+ b = allocone(apamc, 2, mps_rank_exact());
c = allocone(apawl, 2, mps_rank_weak());
d = allocone(aplo, 2, mps_rank_exact()); /* rank irrelevant here! */
- mps_finalize(arena, (mps_addr_t*)&a);
+ mps_finalize(arena, (mps_addr_t*)&b);
mps_finalize(arena, (mps_addr_t*)&c);
mps_finalize(arena, (mps_addr_t*)&d);
mps_finalize(arena, (mps_addr_t*)&d);
@@ -209,7 +208,7 @@ static void test(void)
setref(a, 0, b);
setref(a, 1, c);
setref(c, 1, d);
- b = a;
+ a = b;
}
/* throw them all away and collect everything */
diff --git a/mps/test/function/158.c b/mps/test/function/158.c
index b257d879f30..7f54823d1db 100644
--- a/mps/test/function/158.c
+++ b/mps/test/function/158.c
@@ -29,10 +29,10 @@ static void test(void) {
(size_t) (1024*1024*50)), "create arena");
cdie(mps_thread_reg(&thread, arena), "register thread");
- die(
- mps_pool_create(&pool, arena, mps_class_mvff_debug(), &debugOpts,
- 8192, 8, 8, 1, 0, 0),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mvff_debug(), &debugOpts,
+ (size_t)8192, (size_t)8, (mps_align_t)8,
+ (mps_bool_t)1, (mps_bool_t)0, (mps_bool_t)0),
+ "create MVFF pool");
die(mps_alloc(&a, pool, 64), "alloc a");
diff --git a/mps/test/function/159.c b/mps/test/function/159.c
index d3fb350003f..987824dd737 100644
--- a/mps/test/function/159.c
+++ b/mps/test/function/159.c
@@ -29,10 +29,10 @@ static void test(void) {
(size_t) (1024*1024*50)), "create arena");
cdie(mps_thread_reg(&thread, arena), "register thread");
- die(
- mps_pool_create(&pool, arena, mps_class_mvff_debug(), &debugOpts,
- 8192, 8, 8, 0, 1, 0),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mvff_debug(), &debugOpts,
+ (size_t)8192, (size_t)8, (mps_align_t)8,
+ (mps_bool_t)0, (mps_bool_t)1, (mps_bool_t)0),
+ "create MVFF pool");
die(mps_alloc(&a, pool, 63), "alloc a");
diff --git a/mps/test/function/160.c b/mps/test/function/160.c
index 4c58a5058aa..af5b017e2a7 100644
--- a/mps/test/function/160.c
+++ b/mps/test/function/160.c
@@ -29,10 +29,9 @@ static void test(void) {
(size_t) (1024*1024*50)), "create arena");
cdie(mps_thread_reg(&thread, arena), "register thread");
- die(
- mps_pool_create(&pool, arena, mps_class_mv_debug(), &debugOpts,
- 8192, 8, 65536),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mv_debug(), &debugOpts,
+ (size_t)8192, (size_t)8, (size_t)65536),
+ "create MV pool");
die(mps_alloc(&a, pool, 64), "alloc a");
diff --git a/mps/test/function/161.c b/mps/test/function/161.c
index 93ede5ed738..23a0fb8be14 100644
--- a/mps/test/function/161.c
+++ b/mps/test/function/161.c
@@ -32,10 +32,9 @@ static void test(void)
(size_t) (1024*1024*50)), "create arena");
cdie(mps_thread_reg(&thread, arena), "register thread");
- die(
- mps_pool_create(&pool, arena, mps_class_mv_debug(), &debugOpts,
- 8192, 8, 65536),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mv_debug(), &debugOpts,
+ (size_t)8192, (size_t)8, (size_t)65536),
+ "create MVFF pool");
die(mps_alloc(&a, pool, 64), "alloc a");
diff --git a/mps/test/function/162.c b/mps/test/function/162.c
index 05245b7191c..8967b95b269 100644
--- a/mps/test/function/162.c
+++ b/mps/test/function/162.c
@@ -29,10 +29,9 @@ static void test(void) {
(size_t) (1024*1024*50)), "create arena");
cdie(mps_thread_reg(&thread, arena), "register thread");
- die(
- mps_pool_create(&pool, arena, mps_class_mv_debug(), &debugOpts,
- 8192, 8, 65536),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mv_debug(), &debugOpts,
+ (size_t)8192, (size_t)8, (size_t)65536),
+ "create MVFF pool");
die(mps_alloc(&a, pool, 63), "alloc a");
diff --git a/mps/test/function/163.c b/mps/test/function/163.c
index 90e04b83b23..9b735a076fa 100644
--- a/mps/test/function/163.c
+++ b/mps/test/function/163.c
@@ -53,10 +53,10 @@ static void test(void) {
mps_arena_commit_limit_set(arena, COMLIMIT1);
- die(
- mps_pool_create(&pool, arena, mps_class_mvff(),
- EXTENDBY, 8, MPS_PF_ALIGN, 0, 0, 1),
- "create MVFF pool");
+ die(mps_pool_create(&pool, arena, mps_class_mvff(),
+ (size_t)EXTENDBY, (size_t)8, (mps_align_t)MPS_PF_ALIGN,
+ (mps_bool_t)0, (mps_bool_t)0, (mps_bool_t)1),
+ "create MVFF pool");
for (i = 0; i < NSMALL; i++) {
die(mps_alloc(&smallObjects[i], pool, SMALLSIZE), "small alloc failed");
diff --git a/mps/test/function/18.c b/mps/test/function/18.c
index 60a17e52d57..45f1a0fe8cc 100644
--- a/mps/test/function/18.c
+++ b/mps/test/function/18.c
@@ -5,7 +5,7 @@ TEST_HEADER
language = c
link = testlib.o newfmt.o
OUTPUT_SPEC
- errtext = create pool: COMMIT_LIMIT
+ errtext = create AMC pool: COMMIT_LIMIT
END_HEADER
*/
@@ -48,8 +48,8 @@ static void test(void)
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&pool, arena, mps_class_mv(),
- 1024*32, 1024*16, 1024*256),
- "pool");
+ (size_t)(1024*32), (size_t)(1024*16), (size_t)(1024*256)),
+ "create MV pool");
do {
res = mps_alloc(&q, pool, 64*1024);
@@ -60,7 +60,7 @@ static void test(void)
while (1) {
p++;
die(mmqa_pool_create_chain(&pool, arena, mps_class_amc(), format, chain),
- "create pool");
+ "create AMC pool");
report("pool", "%i", p);
}
diff --git a/mps/test/function/19.c b/mps/test/function/19.c
index bdbe02f88f8..15fdecd9018 100644
--- a/mps/test/function/19.c
+++ b/mps/test/function/19.c
@@ -49,14 +49,14 @@ static void test(void)
die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create");
die(mps_pool_create(&pool, arena, mps_class_mv(),
- 1024*32, 1024*16, 1024*256),
- "pool");
+ (size_t)(1024*32), (size_t)(1024*16), (size_t)(1024*256)),
+ "create MV pool");
while (mps_alloc(&q, pool, 64*1024)==MPS_RES_OK);
p = 0;
cdie(mmqa_pool_create_chain(&pool, arena, mps_class_amc(), format, chain),
- "create pool");
+ "create AMC pool");
while (1) {
p++;
diff --git a/mps/test/function/20.c b/mps/test/function/20.c
index b66f96d4e67..3cec79e7df3 100644
--- a/mps/test/function/20.c
+++ b/mps/test/function/20.c
@@ -33,7 +33,8 @@ static void test(void) {
mps_stack_scan_ambig, stackpointer, 0), "create root");
die(mps_pool_create(&pool, arena, mps_class_mv(),
- 1024*32, 1024*16, 1024*256), "pool");
+ (size_t)(1024*32), (size_t)(1024*16), (size_t)(1024*256)),
+ "create MV pool");
while (mps_alloc(&q, pool, 64*1024)==MPS_RES_OK);
p=0;
diff --git a/mps/test/function/21.c b/mps/test/function/21.c
index d7e12e266ff..7b493f6602f 100644
--- a/mps/test/function/21.c
+++ b/mps/test/function/21.c
@@ -19,7 +19,8 @@ static void test(void) {
die(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create");
die(mps_pool_create(&pool, arena, mps_class_mv(),
- 1024*32, 1024*16, 1024*256), "pool");
+ (size_t)(1024*32), (size_t)(1024*16), (size_t)(1024*256)),
+ "create MV pool");
for (p=0; p<2000; p++) {
die(mps_alloc(&q, pool, 1024*1024), "alloc");
diff --git a/mps/test/function/22.c b/mps/test/function/22.c
index cbdaa909898..8927643e49f 100644
--- a/mps/test/function/22.c
+++ b/mps/test/function/22.c
@@ -19,7 +19,8 @@ static void test(void) {
die(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create");
die(mps_pool_create(&pool, arena, mps_class_mv(),
- 1024*32, 1024*16, 1024*256), "pool");
+ (size_t)(1024*32), (size_t)(1024*16), (size_t)(1024*256)),
+ "create MV pool");
die(mps_alloc(&q, pool, 1024*1024), "alloc");
diff --git a/mps/test/function/224.c b/mps/test/function/224.c
index 0cec33e1cd8..ec828bd9026 100644
--- a/mps/test/function/224.c
+++ b/mps/test/function/224.c
@@ -32,7 +32,7 @@ static void test(void)
die(mps_arena_commit_limit_set(arena, VMSIZE), "commit limit");
die(mps_pool_create(&pool, arena, mps_class_mv(),
- EXTENDBY, AVGSIZE, EXTENDBY),
+ (size_t)EXTENDBY, (size_t)AVGSIZE, (size_t)EXTENDBY),
"pool create");
for (p=0; psize = size;
+ return header + 1;
+}
+
+static void xfree(void *p)
+{
+ if (p) {
+ header_u *header = ((header_u *)p) - 1;
+ mps_free(malloc_pool, header, header->size);
+ }
+}
+
+static void test(void)
+{
+ mps_arena_t arena;
+ size_t i, j;
+ void *p[POINTERS] = {0};
+
+ cdie(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none),
+ "create arena");
+ cdie(mps_pool_create_k(&malloc_pool, arena, mps_class_mvff(), mps_args_none),
+ "create pool");
+
+ for (i = 0; i < ITERATIONS; ++i) {
+ j = ranint(POINTERS);
+ xfree(p[j]);
+ p[j] = xmalloc(ranint(POINTERS));
+ }
+ for (j = 0; j < POINTERS; ++j) {
+ xfree(p[j]);
+ }
+ asserts(mps_pool_free_size(malloc_pool) == mps_pool_total_size(malloc_pool),
+ "free size != total_size");
+
+ mps_pool_destroy(malloc_pool);
+ mps_arena_destroy(arena);
+}
+
+int main(void)
+{
+ easy_tramp(test);
+ pass();
+ return 0;
+}
diff --git a/mps/test/function/23.c b/mps/test/function/23.c
index afcf764a059..2046aa56b92 100644
--- a/mps/test/function/23.c
+++ b/mps/test/function/23.c
@@ -19,7 +19,9 @@ END_HEADER
#include "mpsavm.h"
#include "newfmt.h"
-
+#define EXTEND_BY ((size_t)(1024*128))
+#define MEAN_SIZE ((size_t)(1024*64))
+#define MAX_SIZE ((size_t)(1024*1024))
#define genCOUNT (3)
static mps_gen_param_s testChain[genCOUNT] = {
@@ -66,7 +68,7 @@ static void test(void)
comment("Sizes in megabytes:");
die(mps_pool_create(&poolMV, arena, mps_class_mv(),
- 1024*128, 1024*64, 1024*1024),
+ EXTEND_BY, MEAN_SIZE, MAX_SIZE),
"create MV pool");
i = 0;
while ((r=mps_alloc(&p, poolMV, 1024*1024)) == 0) i++;
@@ -76,7 +78,7 @@ static void test(void)
mps_pool_destroy(poolMV);
die(mps_pool_create(&poolMV, arena, mps_class_mv(),
- 1024*128, 1024*64, 1024*1024),
+ EXTEND_BY, MEAN_SIZE, MAX_SIZE),
"create MV pool");
i = 0;
while ((r=mps_alloc(&p, poolMV, 1024*1024)) == 0) i++;
@@ -88,7 +90,7 @@ static void test(void)
a = allocdumb(ap, 1024*1024*30); /* allocate 30 M object */
die(mps_pool_create(&poolMV, arena, mps_class_mv(),
- 1024*128, 1024*64, 1024*1024),
+ EXTEND_BY, MEAN_SIZE, MAX_SIZE),
"create MV pool");
i=0;
while ((r=mps_alloc(&p, poolMV, 1024*1024)) == 0) i++;
diff --git a/mps/test/function/96.c b/mps/test/function/96.c
index 210fbf46542..6504674cf41 100644
--- a/mps/test/function/96.c
+++ b/mps/test/function/96.c
@@ -32,7 +32,9 @@ static void fillup(void)
mps_addr_t a;
char *b;
- mps_pool_create(&poolmv, arena, mps_class_mv(), 64, 64, 64);
+ die(mps_pool_create(&poolmv, arena, mps_class_mv(),
+ (size_t)64, (size_t)64, (size_t)64),
+ "create MV pool");
size=1024ul*1024ul;
while (size) {
while (mps_alloc(&a, poolmv, size)==MPS_RES_OK) {
@@ -116,7 +118,9 @@ static void test(void)
for (j=0; j<1000*1024; j++) {
res=allocrdumb(&a, ap, 1024, mps_rank_exact());
if (res == MPS_RES_OK) {
- comment("%i ok", j);
+ if (j % 100000 == 0) {
+ comment("%i ok", j);
+ }
} else {
break;
}
diff --git a/mps/test/test/script/clib b/mps/test/test/script/clib
index be1a45c4fb3..6552a20b3b7 100644
--- a/mps/test/test/script/clib
+++ b/mps/test/test/script/clib
@@ -22,7 +22,7 @@ sub clib {
while (defined($tlfile = )) {
unless ($tlfile =~ /^%/) {
- chop($tlfile);
+ chomp($tlfile);
$tlfile = $testlib_dir."/".$tlfile;
$tlobj = $tlfile;
$tlobj =~ s/\.c/$obj_suffix/;
@@ -326,7 +326,7 @@ sub readSymbols {
}
while () {
- chop;
+ chomp;
if (/#define MMQA_SYMBOL_(.*)$/) {
$mps_symbols{$1} = 1;
} elsif (/#define MMQA_DEFINED_(.*)$/) {
@@ -340,7 +340,7 @@ sub readSymbols {
}
while () {
- chop;
+ chomp;
unless (/^%/) {
$mps_assumed{$_} = 1;
}
diff --git a/mps/test/test/script/headread b/mps/test/test/script/headread
index 8f5c35ca7b6..794027763b2 100644
--- a/mps/test/test/script/headread
+++ b/mps/test/test/script/headread
@@ -48,7 +48,7 @@ sub readheader {
$line = $_;
while (! /END_HEADER/) {
defined($_=) || die "Couldn't find end of test header in $infile.\n";
- chop;
+ chomp;
if ($line =~ /\\$/) {
chop($line);
$line = $line.$_;
diff --git a/mps/test/test/script/options b/mps/test/test/script/options
index 023b1f5c7ae..5ef905a09fb 100644
--- a/mps/test/test/script/options
+++ b/mps/test/test/script/options
@@ -26,7 +26,7 @@ sub platform_detect {
local $os = `uname`;
local $osrel = `uname -r`;
local $processor = `uname -p`;
- chop($os); chop($osrel); chop($processor);
+ chomp($os); chomp($osrel); chomp($processor);
$platform_class = $os."_".$osrel."_".$processor;
$platform_class =~ s/ /_/g;
$platform_phylum = "unix";
diff --git a/mps/test/test/script/runtest b/mps/test/test/script/runtest
index b540843eab4..64269c4382d 100644
--- a/mps/test/test/script/runtest
+++ b/mps/test/test/script/runtest
@@ -241,7 +241,7 @@ sub run_testset {
} else {
while () {
unless (/(^%)|(^\s*$)/) {
- chop;
+ chomp;
&run_from_testset($_);
}
}
diff --git a/mps/test/testsets/argerr b/mps/test/testsets/argerr
index cfea284dfd7..990040192b4 100644
--- a/mps/test/testsets/argerr
+++ b/mps/test/testsets/argerr
@@ -80,14 +80,14 @@ argerr/78.c
argerr/79.c
argerr/80.c
argerr/81.c
-argerr/82.c
-argerr/83.c
+% argerr/82.c -- see
+% argerr/83.c -- see
argerr/84.c
argerr/85.c
argerr/86.c
argerr/87.c
-argerr/88.c
-argerr/89.c
+% argerr/88.c -- see
+% argerr/89.c -- see
argerr/90.c
argerr/91.c
argerr/92.c
@@ -111,7 +111,7 @@ argerr/109.c
argerr/110.c
argerr/111.c
argerr/112.c
-argerr/113.c
+% argerr/113.c -- last argument to mps_root_create_table is count, not size
argerr/114.c
argerr/115.c
argerr/116.c
@@ -124,9 +124,9 @@ argerr/122.c
argerr/123.c
argerr/124.c
argerr/125.c
-argerr/126.c
+% argerr/126.c -- see
argerr/127.c
-argerr/128.c
+% argerr/128.c -- see
argerr/129.c
argerr/130.c
argerr/131.c
@@ -147,9 +147,9 @@ argerr/145.c
argerr/146.c
argerr/147.c
argerr/148.c
-argerr/149.c
-argerr/150.c
-argerr/151.c
-argerr/152.c
+% argerr/149.c -- you're allowed to fix non-references
+% argerr/150.c -- you're allowed to fix non-references
+% argerr/151.c -- you're allowed to fix unaligned references
+% argerr/152.c -- no way to check this
argerr/153.c
argerr/154.c
diff --git a/mps/test/testsets/conerr b/mps/test/testsets/conerr
index 3f108a9cb0f..12966b681a0 100644
--- a/mps/test/testsets/conerr
+++ b/mps/test/testsets/conerr
@@ -10,7 +10,7 @@ conerr/8.c
conerr/9.c
conerr/10.c
conerr/11.c
-conerr/12.c
+% conerr/12.c -- job003889
conerr/13.c
conerr/14.c
conerr/15.c
@@ -31,17 +31,17 @@ conerr/29.c
conerr/30.c
conerr/31.c
conerr/32.c
-conerr/33.c
+% conerr/33.c -- job003791
conerr/34.c
conerr/35.c
conerr/36.c
-conerr/37.c
+% conerr/37.c -- reserve/commit macros don't check arguments
conerr/37f.c
-conerr/38.c
+% conerr/38.c -- reserve/commit macros don't check arguments
conerr/38f.c
-conerr/39.c
+% conerr/39.c -- reserve/commit macros don't check arguments
conerr/39f.c
-conerr/40.c
+% conerr/40.c -- reserve/commit macros don't check arguments
conerr/40f.c
conerr/41.c
conerr/42.c
@@ -52,7 +52,7 @@ conerr/45.c
conerr/46.c
conerr/47.c
conerr/48.c
-conerr/49.c
+% conerr/49.c -- see design.mps.thread-manager.req.register.multi
conerr/50.c
conerr/51.c
conerr/52.c
@@ -60,6 +60,6 @@ conerr/53.c
conerr/54.c
conerr/55.c
conerr/56.c
-conerr/57.c
-conerr/58.c
+% conerr/57.c -- see
+% conerr/58.c -- see
conerr/59.c
diff --git a/mps/test/testsets/passing b/mps/test/testsets/passing
index bf298aae0b2..fde2ca5de8d 100644
--- a/mps/test/testsets/passing
+++ b/mps/test/testsets/passing
@@ -167,3 +167,5 @@ function/223.c
function/224.c
% 225 -- no such test
function/226.c
+function/227.c
+function/229.c
\ No newline at end of file
diff --git a/mps/tool/testrun.bat b/mps/tool/testrun.bat
index 2aaf8aa4956..5e9c0606ab7 100755
--- a/mps/tool/testrun.bat
+++ b/mps/tool/testrun.bat
@@ -35,11 +35,11 @@ mkdir %LOGDIR%
@rem Determine which tests to run.
set EXCLUDE=
-if "%TESTSUITE%"=="testrun" set EXCLUDE=LNX
-if "%TESTSUITE%"=="testci" set EXCLUDE=BNX
-if "%TESTSUITE%"=="testall" set EXCLUDE=NX
-if "%TESTSUITE%"=="testansi" set EXCLUDE=LNTX
-if "%TESTSUITE%"=="testpoll" set EXCLUDE=LNPTX
+if "%TESTSUITE%"=="testrun" set EXCLUDE=LNX
+if "%TESTSUITE%"=="testci" set EXCLUDE=BNX
+if "%TESTSUITE%"=="testall" set EXCLUDE=NX
+if "%TESTSUITE%"=="testansi" set EXCLUDE=LNTX
+if "%TESTSUITE%"=="testpollnone" set EXCLUDE=LNPTX
@rem Ensure that test cases don't pop up dialog box on abort()
set MPS_TESTLIB_NOABORT=true
diff --git a/mps/tool/testrun.sh b/mps/tool/testrun.sh
index cdb41ac458b..6ea7dfcb4dc 100755
--- a/mps/tool/testrun.sh
+++ b/mps/tool/testrun.sh
@@ -12,9 +12,9 @@
#
# Usage::
#
-# testrun.sh DIR ( SUITE | CASE1 CASE2 [...] )
+# testrun.sh [-s SUITE] [-r RUNNER] DIR [CASE1 CASE2 ...]
#
-# You can use this feature to run the same test many times, to get
+# You can use this program to run the same test many times, to get
# lots of random coverage. For example::
#
# yes amcss | head -100 | xargs tool/testrun.sh code/xc/Debug
@@ -22,38 +22,58 @@
# This runs the AMC stress test 100 times from the code/xc/Debug
# directory, reporting all failures.
+echo "MPS test suite"
+
+TEST_RUNNER=
+TEST_CASES=
+
+# Parse command-line arguments.
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -s)
+ TEST_SUITE=$2
+ case "$TEST_SUITE" in
+ testrun) EXCLUDE="LNW" ;;
+ testci) EXCLUDE="BNW" ;;
+ testall) EXCLUDE="NW" ;;
+ testansi) EXCLUDE="LNTW" ;;
+ testpollnone) EXCLUDE="LNPTW" ;;
+ *)
+ echo "Test suite $TEST_SUITE not recognized."
+ exit 1 ;;
+ esac
+ echo "Test suite: $TEST_SUITE"
+ TEST_CASE_DB=$(dirname -- "$0")/testcases.txt
+ TEST_CASES=$(<"$TEST_CASE_DB" grep -e '^[a-z]' |
+ grep -v -e "=[$EXCLUDE]" |
+ cut -d' ' -f1)
+ shift 2
+ ;;
+ -r)
+ TEST_RUNNER=$2
+ shift 2
+ ;;
+ -*)
+ echo "Unrecognized option $1"
+ exit 1
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
# Make a temporary output directory for the test logs.
LOGDIR=$(mktemp -d /tmp/mps.log.XXXXXX)
-echo "MPS test suite"
echo "Logging test output to $LOGDIR"
-
-# First argument is the directory containing the test cases.
+
+# Next argument is the directory containing the test cases.
TEST_DIR=$1
shift
echo "Test directory: $TEST_DIR"
# Determine which tests to run.
-TEST_CASE_DB=$(dirname -- "$0")/testcases.txt
-if [ $# -eq 1 ]; then
- TEST_SUITE=$1
- echo "Test suite: $TEST_SUITE"
- case $TEST_SUITE in
- testrun) EXCLUDE="LNW" ;;
- testci) EXCLUDE="BNW" ;;
- testall) EXCLUDE="NW" ;;
- testansi) EXCLUDE="LNTW" ;;
- testpoll) EXCLUDE="LNPTW" ;;
- *)
- echo "Test suite $TEST_SUITE not recognized."
- exit 1 ;;
- esac
- TEST_CASES=$(<"$TEST_CASE_DB" grep -e '^[a-z]' |
- grep -v -e "=[$EXCLUDE]" |
- cut -d' ' -f1)
-else
- echo "$# test cases from the command line"
- TEST_CASES=$*
-fi
+TEST_CASES="$TEST_CASES $*"
SEPARATOR=----------------------------------------
TEST_COUNT=0
@@ -67,16 +87,16 @@ for TESTCASE in $TEST_CASES; do
export MPS_TELEMETRY_FILENAME
echo "Running $TEST"
- TEST_COUNT=$(expr $TEST_COUNT + 1)
- if "$TEST_DIR/$TESTCASE" > "$LOGTEST" 2>&1; then
- PASS_COUNT=$(expr $PASS_COUNT + 1)
+ TEST_COUNT=$((TEST_COUNT + 1))
+ if $TEST_RUNNER "$TEST_DIR/$TESTCASE" > "$LOGTEST" 2>&1; then
+ PASS_COUNT=$((PASS_COUNT + 1))
else
echo "$TEST failed: log follows"
echo ${SEPARATOR}${SEPARATOR}
cat -- "$LOGTEST"
echo
echo ${SEPARATOR}${SEPARATOR}
- FAIL_COUNT=$(expr $FAIL_COUNT + 1)
+ FAIL_COUNT=$((FAIL_COUNT + 1))
fi
if [ -f "$MPS_TELEMETRY_FILENAME" ]; then