[Gd-chatter] r10957 - in trunk/mps: . code example example/hello-world manual manual/build-notes manual/wiki
housel at gwydiondylan.org
housel at gwydiondylan.org
Wed Nov 15 07:38:02 CET 2006
Author: housel
Date: Wed Nov 15 07:37:58 2006
New Revision: 10957
Added:
trunk/mps/code/xci3gc.gmk (contents, props changed)
trunk/mps/example/
trunk/mps/example/hello-world/
trunk/mps/example/hello-world/index.html (contents, props changed)
trunk/mps/example/index.html (contents, props changed)
trunk/mps/manual/wiki/
trunk/mps/manual/wiki/apguide.html (contents, props changed)
trunk/mps/manual/wiki/apinternals.html (contents, props changed)
trunk/mps/manual/wiki/gc.html (contents, props changed)
trunk/mps/manual/wiki/glossary.html (contents, props changed)
trunk/mps/manual/wiki/index.html (contents, props changed)
trunk/mps/manual/wiki/modes.html (contents, props changed)
trunk/mps/manual/wiki/pool_classes.html (contents, props changed)
trunk/mps/manual/wiki/template.html (contents, props changed)
trunk/mps/manual/wiki/unmanaged.html (contents, props changed)
Modified:
trunk/mps/code/amsss.c
trunk/mps/code/comm.gmk
trunk/mps/code/commpost.nmk
trunk/mps/code/finaltest.c
trunk/mps/code/lockutw3.c
trunk/mps/code/locv.c
trunk/mps/code/misc.h
trunk/mps/code/mpm.c
trunk/mps/code/mpstd.h
trunk/mps/code/poollo.c
trunk/mps/code/protocol.h
trunk/mps/code/testlib.c
trunk/mps/code/tract.c
trunk/mps/code/w3almv.nmk
trunk/mps/code/w3i3mv.nmk
trunk/mps/code/w3ppmv.nmk
trunk/mps/manual/build-notes/index.html
trunk/mps/manual/index.html
trunk/mps/readme.txt
Log:
Job: mps
Update to the current MPS development trunk.
Modified: trunk/mps/code/amsss.c
==============================================================================
--- trunk/mps/code/amsss.c (original)
+++ trunk/mps/code/amsss.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* amsss.c: POOL CLASS AMS STRESS TEST
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/amsss.c#11 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/amsss.c#12 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Portions copyright (c) 2002 Global Graphics Software.
*
@@ -74,7 +74,7 @@
static void *test(void *arg, size_t haveAmbigous)
{
mps_pool_t pool;
- mps_root_t exactRoot, ambigRoot;
+ mps_root_t exactRoot, ambigRoot = NULL;
size_t lastStep = 0, i, r;
unsigned long objs;
mps_ap_t busy_ap;
Modified: trunk/mps/code/comm.gmk
==============================================================================
--- trunk/mps/code/comm.gmk (original)
+++ trunk/mps/code/comm.gmk Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
# comm.gmk: COMMON GNUMAKEFILE FRAGMENT
#
-# $Id: //info.ravenbrook.com/project/mps/master/code/comm.gmk#19 $
+# $Id: //info.ravenbrook.com/project/mps/master/code/comm.gmk#21 $
# Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
#
# DESCRIPTION
@@ -269,7 +269,7 @@
finalcv finaltest arenacv bttest teletest \
abqtest cbstest btcv mv2test messtest steptest \
eventcnv walkt0 libcbt \
- mps.a
+ mps.a mpsplan.a
swall: mmsw.a replaysw
Modified: trunk/mps/code/commpost.nmk
==============================================================================
--- trunk/mps/code/commpost.nmk (original)
+++ trunk/mps/code/commpost.nmk Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
# commpost.nmk: SECOND COMMON FRAGMENT FOR PLATFORMS USING MV AND NMAKE
#
-# $Id: //info.ravenbrook.com/project/mps/master/code/commpost.nmk#21 $
+# $Id: //info.ravenbrook.com/project/mps/master/code/commpost.nmk#24 $
# Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
#
# DESCRIPTION
@@ -16,10 +16,11 @@
all: mpmss.exe amcss.exe amsss.exe amssshe.exe segsmss.exe awlut.exe awluthe.exe\
mpsicv.exe lockutw3.exe lockcov.exe poolncv.exe locv.exe qs.exe apss.exe \
- finalcv.exe finaltest.exe arenacv.exe bttest.exe teletest.exe protcv.exe \
+ finalcv.exe finaltest.exe arenacv.exe bttest.exe teletest.exe \
abqtest.exe cbstest.exe btcv.exe mv2test.exe messtest.exe steptest.exe \
locbwcss.exe locusss.exe \
- eventcnv.exe
+ eventcnv.exe \
+ mps.lib mpsplan.lib
swall: mmsw.lib replaysw.exe
@@ -31,7 +32,7 @@
mpmss.exe amcss.exe amcsshe.exe amsss.exe amssshe.exe segsmss.exe awlut.exe awluthe.exe dwstress.exe \
mpsicv.exe lockutw3.exe lockcov.exe poolncv.exe locv.exe qs.exe apss.exe \
- finalcv.exe finaltest.exe arenacv.exe bttest.exe teletest.exe protcv.exe \
+ finalcv.exe finaltest.exe arenacv.exe bttest.exe teletest.exe \
expt825.exe \
abqtest.exe cbstest.exe btcv.exe mv2test.exe messtest.exe steptest.exe \
walkt0.exe locbwcss.exe locusss.exe \
@@ -107,21 +108,22 @@
$(PFM)\$(VARIETY)\version.obj: FORCE
$(PFM)\$(VARIETY)\finalcv.exe: $(PFM)\$(VARIETY)\finalcv.obj \
- $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) $(FMTTESTOBJ) \
$(MRGOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\finaltest.exe: $(PFM)\$(VARIETY)\finaltest.obj \
- $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) $(FMTTESTOBJ) \
$(MRGOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\expt825.exe: $(PFM)\$(VARIETY)\expt825.obj \
- $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) $(FMTTESTOBJ) \
$(MRGOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\locv.exe: $(PFM)\$(VARIETY)\locv.obj \
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ)
$(PFM)\$(VARIETY)\mpmss.exe: $(PFM)\$(VARIETY)\mpmss.obj \
+ $(PFM)\$(VARIETY)\poolmvff.obj \
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\apss.exe: $(PFM)\$(VARIETY)\apss.obj \
@@ -140,46 +142,47 @@
$(PFM)\$(VARIETY)\lockutw3.exe: $(PFM)\$(VARIETY)\lockutw3.obj \
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ)
-$(PFM)\$(VARIETY)\protcv.exe: $(PFM)\$(VARIETY)\protcv.obj \
- $(MPMOBJ) $(PLINTHOBJ)
-
$(PFM)\$(VARIETY)\mpsicv.exe: $(PFM)\$(VARIETY)\mpsicv.obj \
- $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\amcss.exe: $(PFM)\$(VARIETY)\amcss.obj \
- $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\amcsshe.exe: $(PFM)\$(VARIETY)\amcsshe.obj \
- $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(HETESTOBJ) \
+ $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\amsss.exe: $(PFM)\$(VARIETY)\amsss.obj \
- $(MPMOBJ) $(AMSOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMSOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\amssshe.exe: $(PFM)\$(VARIETY)\amssshe.obj \
- $(MPMOBJ) $(AMSOBJ) $(PLINTHOBJ) $(HETESTOBJ) \
+ $(MPMOBJ) $(AMSOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\segsmss.exe: $(PFM)\$(VARIETY)\segsmss.obj \
- $(MPMOBJ) $(AMSOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMSOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\locbwcss.exe: $(PFM)\$(VARIETY)\locbwcss.obj \
$(PFM)\$(VARIETY)\poolmvff.obj \
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ)
+$(PFM)\$(VARIETY)\locusss.exe: $(PFM)\$(VARIETY)\locusss.obj \
+ $(PFM)\$(VARIETY)\poolmvff.obj \
+ $(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ)
+
$(PFM)\$(VARIETY)\dwstress.exe: $(PFM)\$(VARIETY)\dwstress.obj \
$(DWOBJ) $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ)
$(PFM)\$(VARIETY)\awlut.exe: $(PFM)\$(VARIETY)\awlut.obj \
- $(DWTESTOBJ) \
+ $(FMTTESTOBJ) \
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ) $(AWLOBJ)
$(PFM)\$(VARIETY)\awluthe.exe: $(PFM)\$(VARIETY)\awluthe.obj \
- $(HETESTOBJ) \
+ $(FMTTESTOBJ) \
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ) $(AWLOBJ)
$(PFM)\$(VARIETY)\poolncv.exe: $(PFM)\$(VARIETY)\poolncv.obj \
@@ -228,15 +231,15 @@
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\steptest.exe: $(PFM)\$(VARIETY)\steptest.obj \
- $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\walkt0.exe: $(PFM)\$(VARIETY)\walkt0.obj \
- $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\exposet0.exe: $(PFM)\$(VARIETY)\exposet0.obj \
- $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(DWOBJ) $(DWTESTOBJ) \
+ $(MPMOBJ) $(AMCOBJ) $(PLINTHOBJ) $(FMTTESTOBJ) \
$(TESTLIBOBJ)
$(PFM)\$(VARIETY)\mmsw.lib: $(SWOBJ)
Modified: trunk/mps/code/finaltest.c
==============================================================================
--- trunk/mps/code/finaltest.c (original)
+++ trunk/mps/code/finaltest.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* finaltest.c: LARGE-SCALE FINALIZATION TEST
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/finaltest.c#1 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/finaltest.c#2 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
@@ -241,7 +241,7 @@
}
-int main(int argc, char **argv)
+int main(void)
{
mps_arena_t arena;
mps_thr_t thread;
Modified: trunk/mps/code/lockutw3.c
==============================================================================
--- trunk/mps/code/lockutw3.c (original)
+++ trunk/mps/code/lockutw3.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* lockutw3.c: LOCK UTILIZATION TEST
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/lockutw3.c#8 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/lockutw3.c#9 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*/
@@ -31,7 +31,7 @@
}
} else {
incR(i >> 1);
- incR(i+1 >> 1);
+ incR( (i+1) >> 1);
}
LockReleaseRecursive(lock);
}
@@ -39,7 +39,7 @@
void inc(unsigned long i)
{
- incR(i+1>>1);
+ incR( (i+1) >>1);
i >>= 1;
while (i) {
LockClaim(lock);
Modified: trunk/mps/code/locv.c
==============================================================================
--- trunk/mps/code/locv.c (original)
+++ trunk/mps/code/locv.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* locv.c: LEAF OBJECT POOL CLASS COVERAGE TEST
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/locv.c#8 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/locv.c#10 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*
* This is (not much of) a coverage test for the Leaf Object
@@ -22,6 +22,9 @@
static void copy(mps_addr_t old, mps_addr_t new);
static void pad(mps_addr_t base, size_t size);
+static void stepper(mps_addr_t addr, mps_fmt_t fmt, mps_pool_t pool,
+ void *p, size_t s);
+
static mps_fmt_A_s locv_fmt =
{
(mps_align_t)4,
@@ -61,17 +64,26 @@
die(mps_reserve(&p, ap, (size_t)4), "mps_reserve 4");
*(mps_word_t *)p = 4;
cdie(mps_commit(ap, p, (size_t)4), "commit 4");
+
die(mps_reserve(&roots[1], ap, (size_t)8), "mps_reserve 8");
p = roots[1];
*(mps_word_t *)p = 8;
cdie(mps_commit(ap, p, (size_t)8), "commit 8");
+
die(mps_reserve(&p, ap, (size_t)4096), "mps_reserve 4096");
*(mps_word_t *)p = 4096;
cdie(mps_commit(ap, p, (size_t)4096), "commit 4096");
+
die(mps_reserve(&p, ap, (size_t)4), "mps_reserve last");
*(mps_word_t *)p = 4;
cdie(mps_commit(ap, p, (size_t)4), "commit last");
+ {
+ size_t count = 0;
+ mps_arena_formatted_objects_walk(arena, stepper, &count, 0);
+ cdie(count == 4, "walk 4 objects");
+ }
+
mps_ap_destroy(ap);
mps_pool_destroy(pool);
mps_fmt_destroy(format);
@@ -135,6 +147,22 @@
cdie(0, "pad");
}
+static void stepper(mps_addr_t addr, mps_fmt_t fmt, mps_pool_t pool,
+ void *p, size_t s)
+{
+ size_t *pcount;
+
+ testlib_unused(addr);
+ testlib_unused(fmt);
+ testlib_unused(pool);
+ testlib_unused(s);
+
+ pcount = p;
+ *pcount += 1;
+ return;
+}
+
+
/* C. COPYRIGHT AND LICENSE
*
Modified: trunk/mps/code/misc.h
==============================================================================
--- trunk/mps/code/misc.h (original)
+++ trunk/mps/code/misc.h Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* misc.h: MISCELLANEOUS DEFINITIONS
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/misc.h#11 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/misc.h#12 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2001 Global Graphics Software.
*
@@ -137,13 +137,14 @@
/* PARENT -- parent structure
*
* Given a pointer to a field of a structure this returns a pointer to
- * the main structure. PARENT(foo_t, x, foo->x) == foo.
+ * the main structure. PARENT(foo_t, x, &(foo->x)) == foo.
*
* This macro is thread-safe, see design.mps.misc.parent.thread-safe.
*
* That intermediate (void *) is required to stop some compilers complaining
* about alignment of 'type *' being greater than that of 'char *'. Which
- * is true, but not a bug, since p really is a pointer into a 'type' struct.
+ * is true, but not a bug, since the result really is a pointer to a 'type'
+ * struct.
*/
#define PARENT(type, field, p) \
Modified: trunk/mps/code/mpm.c
==============================================================================
--- trunk/mps/code/mpm.c (original)
+++ trunk/mps/code/mpm.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* mpm.c: GENERAL MPM SUPPORT
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/mpm.c#10 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/mpm.c#11 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*
* .purpose: Miscellaneous support for the implementation of the MPM
@@ -15,7 +15,7 @@
#include <float.h>
#include <limits.h>
-SRCID(mpm, "$Id: //info.ravenbrook.com/project/mps/master/code/mpm.c#10 $");
+SRCID(mpm, "$Id: //info.ravenbrook.com/project/mps/master/code/mpm.c#11 $");
#if defined(CHECK)
@@ -226,7 +226,8 @@
static Res WriteWord(mps_lib_FILE *stream, Word w, unsigned base,
unsigned width)
{
- static const char digit[16] = "0123456789ABCDEF";
+ static const char digit[16 + 1] = "0123456789ABCDEF";
+ /* + 1 for terminator: unused, but prevents compiler warning */
static const char pad = '0'; /* padding character */
char buf[MPS_WORD_WIDTH + 1]; /* enough for binary, */
/* plus one for terminator */
Modified: trunk/mps/code/mpstd.h
==============================================================================
--- trunk/mps/code/mpstd.h (original)
+++ trunk/mps/code/mpstd.h Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* mpstd.h: RAVENBROOK MEMORY POOL SYSTEM TARGET DETECTION
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/mpstd.h#12 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/mpstd.h#13 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2001 Global Graphics Software.
*
@@ -186,6 +186,24 @@
#define MPS_WORD_SHIFT 5
#define MPS_PF_ALIGN 8 /* .macos.ppc.align */
+/* GCC 4.0.1 (As supplied by Apple on Mac OS X 10.4.8 on an Intel Mac),
+ * gcc -E -dM
+ * And above for xcppgc.
+ */
+
+#elif defined(CONFIG_PF_XCI3GC) \
+ || defined(__APPLE__) && defined(__i386__) && defined(__MACH__) \
+ && defined(__GNUC__)
+#define MPS_PF_XCI3GC
+#define MPS_PF_STRING "xci3gc"
+#define MPS_OS_XC
+#define MPS_ARCH_I3
+#define MPS_BUILD_GC
+#define MPS_T_WORD unsigned long
+#define MPS_WORD_WIDTH 32
+#define MPS_WORD_SHIFT 5
+#define MPS_PF_ALIGN 4 /* I'm just guessing. */
+
/* GCC 2.5.8, gcc -E -dM, (__SVR4 indicates Solaris) */
#elif defined(CONFIG_PF_SUS8GC) \
Modified: trunk/mps/code/poollo.c
==============================================================================
--- trunk/mps/code/poollo.c (original)
+++ trunk/mps/code/poollo.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* poollo.c: LEAF POOL CLASS
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/poollo.c#12 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/poollo.c#13 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*
* DESIGN
@@ -12,7 +12,7 @@
#include "mpm.h"
#include "mps.h"
-SRCID(poollo, "$Id: //info.ravenbrook.com/project/mps/master/code/poollo.c#12 $");
+SRCID(poollo, "$Id: //info.ravenbrook.com/project/mps/master/code/poollo.c#13 $");
#define LOGen ((Serial)1)
@@ -460,7 +460,7 @@
}
object = AddrAdd(object, format->headerSize);
next = (*format->skip)(object);
- next = AddrSub(object, format->headerSize);
+ next = AddrSub(next, format->headerSize);
j = loIndexOfAddr(base, lo, next);
AVER(i < j);
(*f)(object, pool->format, pool, p, s);
Modified: trunk/mps/code/protocol.h
==============================================================================
--- trunk/mps/code/protocol.h (original)
+++ trunk/mps/code/protocol.h Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* protocol.h: PROTOCOL INHERITANCE DEFINITIONS
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/protocol.h#9 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/protocol.h#10 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*/
@@ -102,20 +102,22 @@
* If "pro" is an instance of "interface", then returns TRUE
* and sets coerceResult to point directly to the part of "pro"
* which contains the slots for "interface"
+ * RHSK 2006-04-05 s/interface/interfaceIn/: job000605, suspect msvc bug.
*/
typedef Bool (*ProtocolCoerceInstMethod)(ProtocolInst *coerceResult,
ProtocolInst pro,
- ProtocolClass interface);
+ ProtocolClass interfaceIn);
/* ProtocolCoerceClassMethod -- coerce "proClass" to an "interface" class
*
* If "proClass" is a subclass of "interface", then returns TRUE
* and sets coerceResult to point directly to the part of
* "proClass" which contains the slots for "interface".
+ * RHSK 2006-04-05 s/interface/interfaceIn/: job000605, suspect msvc bug.
*/
typedef Bool (*ProtocolCoerceClassMethod)(ProtocolClass *coerceResult,
ProtocolClass proClass,
- ProtocolClass interface);
+ ProtocolClass interfaceIn);
Modified: trunk/mps/code/testlib.c
==============================================================================
--- trunk/mps/code/testlib.c (original)
+++ trunk/mps/code/testlib.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* testlib.c: TEST LIBRARY
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/testlib.c#9 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/testlib.c#10 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Portions copyright (C) 2002 Global Graphics Software.
*
@@ -18,6 +18,16 @@
#endif
#include <time.h>
+#ifdef MPS_OS_W3
+#ifdef _MSC_VER
+#pragma warning(disable: 4702) /* unreachable code */
+ /* job000605: believed needed to prevent VC7 warning
+ * for error() below, in which va_end is mandated by
+ * ISO C (C99:7.15.1) even though it is unreachable.
+ */
+#endif
+#endif
+
/* rnd -- a random number generator
*
Modified: trunk/mps/code/tract.c
==============================================================================
--- trunk/mps/code/tract.c (original)
+++ trunk/mps/code/tract.c Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
/* tract.c: PAGE TABLES
*
- * $Id: //info.ravenbrook.com/project/mps/master/code/tract.c#9 $
+ * $Id: //info.ravenbrook.com/project/mps/master/code/tract.c#10 $
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
*
* .ullagepages: Pages whose page index is < allocBase are recorded as
@@ -14,7 +14,7 @@
#include "bt.h"
#include "mpm.h"
-SRCID(tract, "$Id: //info.ravenbrook.com/project/mps/master/code/tract.c#9 $");
+SRCID(tract, "$Id: //info.ravenbrook.com/project/mps/master/code/tract.c#10 $");
static void ChunkDecache(Arena arena, Chunk chunk);
@@ -22,7 +22,7 @@
/* TractArena -- get the arena of a tract */
-#define TractArena(seg) PoolArena(TractPool(tract))
+#define TractArena(tract) PoolArena(TractPool(tract))
/* TractCheck -- check the integrity of a tract */
Modified: trunk/mps/code/w3almv.nmk
==============================================================================
--- trunk/mps/code/w3almv.nmk (original)
+++ trunk/mps/code/w3almv.nmk Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
# w3almv.nmk: WINDOWS (ALPHA) NMAKE FILE
#
-# $Id: //info.ravenbrook.com/project/mps/master/code/w3almv.nmk#10 $
+# $Id: //info.ravenbrook.com/project/mps/master/code/w3almv.nmk#11 $
# Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
PFM = w3almv
@@ -36,8 +36,7 @@
AWL = <poolawl>
LO = <poollo>
DW = <fmtdy> <fmtno>
-DWTEST = <fmtdytst>
-HETEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
+FMTTEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
POOLN = <pooln>
TESTLIB = <testlib>
@@ -77,10 +76,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\he\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\he\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\he\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\he\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\he\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\he\)
@@ -108,10 +105,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\ce\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\ce\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\ce\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\ce\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\ce\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\ce\)
@@ -139,10 +134,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\hi\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\hi\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\hi\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\hi\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\hi\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\hi\)
@@ -170,10 +163,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\ci\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\ci\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\ci\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\ci\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\ci\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\ci\)
@@ -201,10 +192,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\ti\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\ti\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\ti\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\ti\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\ti\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\ti\)
@@ -232,10 +221,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\wi\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\wi\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\wi\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\wi\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\wi\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\wi\)
@@ -263,10 +250,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3almv\we\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3almv\we\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3almv\we\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3almv\we\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3almv\we\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3almv\we\)
Modified: trunk/mps/code/w3i3mv.nmk
==============================================================================
--- trunk/mps/code/w3i3mv.nmk (original)
+++ trunk/mps/code/w3i3mv.nmk Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
# w3i3mv.nmk: WINDOWS (INTEL) NMAKE FILE
#
-# $Id: //info.ravenbrook.com/project/mps/master/code/w3i3mv.nmk#13 $
+# $Id: //info.ravenbrook.com/project/mps/master/code/w3i3mv.nmk#14 $
# Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
PFM = w3i3mv
@@ -37,8 +37,7 @@
LO = <poollo>
SNC = <poolsnc>
DW = <fmtdy> <fmtno>
-DWTEST = <fmtdytst>
-HETEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
+FMTTEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
POOLN = <pooln>
TESTLIB = <testlib>
@@ -77,10 +76,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\he\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\he\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\he\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\he\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\he\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\he\)
@@ -108,10 +105,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\ce\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\ce\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\ce\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\ce\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\ce\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\ce\)
@@ -139,10 +134,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\hi\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\hi\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\hi\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\hi\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\hi\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\hi\)
@@ -170,10 +163,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\ci\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\ci\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\ci\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\ci\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\ci\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\ci\)
@@ -201,10 +192,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\ti\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\ti\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\ti\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\ti\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\ti\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\ti\)
@@ -232,10 +221,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\wi\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\wi\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\wi\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\wi\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\wi\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\wi\)
@@ -263,10 +250,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3i3mv\we\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3i3mv\we\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3i3mv\we\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3i3mv\we\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3i3mv\we\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3i3mv\we\)
Modified: trunk/mps/code/w3ppmv.nmk
==============================================================================
--- trunk/mps/code/w3ppmv.nmk (original)
+++ trunk/mps/code/w3ppmv.nmk Wed Nov 15 07:37:58 2006
@@ -1,6 +1,6 @@
# w3ppmv.nmk: WINDOWS (POWERPC) NMAKE FILE
#
-# $Id: //info.ravenbrook.com/project/mps/master/code/w3ppmv.nmk#10 $
+# $Id: //info.ravenbrook.com/project/mps/master/code/w3ppmv.nmk#11 $
# Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
PFM = w3ppmv
@@ -33,8 +33,7 @@
AWL = <poolawl>
LO = <poollo>
DW = <fmtdy> <fmtno>
-DWTEST = <fmtdytst>
-HETEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
+FMTTEST = <fmthe> <fmtdy> <fmtno> <fmtdytst>
POOLN = <pooln>
TESTLIB = <testlib>
@@ -74,10 +73,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\he\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\he\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\he\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\he\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\he\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\he\)
@@ -105,10 +102,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\ce\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\ce\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\ce\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\ce\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\ce\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\ce\)
@@ -136,10 +131,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\hi\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\hi\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\hi\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\hi\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\hi\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\hi\)
@@ -167,10 +160,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\ci\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\ci\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\ci\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\ci\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\ci\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\ci\)
@@ -198,10 +189,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\ti\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\ti\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\ti\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\ti\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\ti\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\ti\)
@@ -229,10 +218,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\wi\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\wi\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\wi\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\wi\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\wi\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\wi\)
@@ -260,10 +247,8 @@
SNCOBJ = $(SNCOBJ0:>=.obj)
DWOBJ0 = $(DW:<=w3ppmv\we\)
DWOBJ = $(DWOBJ0:>=.obj)
-DWTESTOBJ0 = $(DWTEST:<=w3ppmv\we\)
-DWTESTOBJ = $(DWTESTOBJ0:>=.obj)
-HETESTOBJ0 = $(HETEST:<=w3ppmv\we\)
-HETESTOBJ = $(HETESTOBJ0:>=.obj)
+FMTTESTOBJ0 = $(FMTTEST:<=w3ppmv\we\)
+FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj)
POOLNOBJ0 = $(POOLN:<=w3ppmv\we\)
POOLNOBJ = $(POOLNOBJ0:>=.obj)
TESTLIBOBJ0 = $(TESTLIB:<=w3ppmv\we\)
Added: trunk/mps/code/xci3gc.gmk
==============================================================================
--- (empty file)
+++ trunk/mps/code/xci3gc.gmk Wed Nov 15 07:37:58 2006
@@ -0,0 +1,63 @@
+# xci3gc.gmk: BUILD FOR MACOS X (CARBON)/INTEL IA32/GCC PLATFORM
+#
+# $Id: //info.ravenbrook.com/project/mps/master/code/xci3gc.gmk#3 $
+# Copyright (c) 2001,2006 Ravenbrook Limited. See end of file for license.
+#
+# Naively copied from xcppgc.gmk, could do with going over properly.
+
+PFM = xci3gc
+
+MPMPF = lockan.c than.c vmxc.c \
+ protan.c prmcan.c span.c ssan.c
+SWPF = than.c vmxc.c protsw.c prmcan.c ssan.c
+
+LIBS =
+
+RANLIB=ranlib
+
+include gc.gmk
+
+CC = cc
+
+include comm.gmk
+
+
+# C. COPYRIGHT AND LICENSE
+#
+# Copyright (C) 2001-2006 Ravenbrook Limited <http://www.ravenbrook.com/>.
+# 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.
Added: trunk/mps/example/hello-world/index.html
==============================================================================
--- (empty file)
+++ trunk/mps/example/hello-world/index.html Wed Nov 15 07:37:58 2006
@@ -0,0 +1,609 @@
+# Confidential: no. Readership: MPS users. Status: complete.
+# Author: RHSK 2006-02-17. Copyright (C) 2006 Ravenbrook Limited
+# <http://www.ravenbrook.com/>. All rights reserved.
+# See end of file for license.
+# $Id: //info.ravenbrook.com/project/mps/master/example/hello-world/index.txt#1 $
+
+
+This is the "hello-world" example; it shows you how to call the MPS from
+your code.
+
+To begin, get a copy of the MPS-kit from:
+ <http://www.ravenbrook.com/project/mps/release/>
+
+Unpack the MPS-kit. (You don't need to compile anything yet, so you can
+skip the MPS-kit readme.txt file for now).
+
+The MPS-kit unpacks to a directory named "mps-kit-1.106.2" (or similar),
+with subdirectories like this:
+
+ mps-kit-1.106.2/
+ code/
+ design/
+ example/
+ manual/
+ procedure/
+ test/
+ tool/
+
+The MPS is a software library, implemented in C. The types, functions,
+macros, constants, etc (collectively called "facilities") are declared
+in the MPS header files: your code must '#include' the MPS header files
+for the facilities you use. The facilities are implemented in the MPS
+libraries: your code must link with the libraries containing the
+facilities you use. The examples below show how to do this.
+
+
+The "mps.h" header file
+-----------------------
+
+Here is a tiny C program to #include the "mps.h" header file and check
+that it compiles:
+
+ /* Demo File: 01checkmpsheader.c */
+ /* Simple C client of the MPS */
+
+ #include "mps.h"
+
+ int main(void)
+ {
+ mps_arena_t ArenaDemo;
+ return 0; /* success */
+ }
+
+The "mps.h" header file declares the major (non-optional) MPS
+facilities, and all MPS client code needs to #include it. Find the
+"mps.h" header file in the "code" subdirectory of the MPS-kit:
+
+ mps-kit-1.106.2/code/mps.h
+
+For now, just put a copy of "mps.h" into a working directory where you
+can try the following examples. Now you can compile and run
+"01checkmpsheader.c". On Unix you might use:
+
+ % gcc 01checkmpsheader.c
+ % ./a.out && echo "success"
+
+
+Choosing an arena class
+-----------------------
+
+The first step in using the MPS is to create an "arena". Inside this
+arena you will create "pools". Inside the pools you will create
+"objects". Arenas, pools, and objects are abstract data types: you must
+use MPS functions to create, change, and destroy them.
+
+The arena abstracts the source of memory from which MPS will allocate:
+there are different classes of arena for different sorts of memory
+source. We will start with the "CL" arena class -- the "CL" stands for
+"client". A CL arena takes a big block of memory provided by the client
+(our demo program), and uses that as the source of memory in which to
+create pools and objects.
+
+The code to create a CL arena will look roughly like this:
+ mps_arena_create(&ArenaDemo, mps_arena_class_cl(), arg1, arg2, ...)
+
+Notice that the "CL" arena class is an abstract constant: the constant
+is not compiled into your code; instead, you call the MPS function
+mps_arena_class_cl() to obtain it. (Most MPS constants work this way;
+it avoids some versioning issues, and makes it easier to port the MPS to
+tricky platforms).
+
+
+Additional MPS header files
+---------------------------
+
+The "mps_arena_class_cl" function is declared in the additional MPS
+header file "mpsacl.h" ("mpsa" stands for "MPS Arena class"). So put a
+copy of "mpsacl.h" into your working directory. The source code to use
+it looks like this:
+
+ /* Demo File: 02checkarenaclassheader.c */
+ /* Simple C client of the MPS */
+
+ #include "mps.h"
+ #include "mpsacl.h" /* for mps_arena_class_cl */
+
+ int main(void)
+ {
+ mps_arena_t ArenaDemo;
+ mps_arena_class_t ArenaClassDemo = NULL;
+
+ ArenaClassDemo = mps_arena_class_cl();
+ return 0; /* success */
+ }
+
+To compile (but not link) this on Unix you might use the following
+command. (The "-c" tells gcc to stop after compilation).
+
+ % gcc -c 02checkarenaclassheader.c
+
+However, when you try to link, it will fail because we don't have the
+MPS library to hand:
+
+ % gcc 02checkarenaclassheader.c
+ % # (this will fail)
+
+
+The MPS library: "mps.a"
+------------------------
+
+The MPS library is available on many platforms: Windows, many Unixes,
+Mac OS X, etc. See the MPS-kit readme.txt file for details. For
+example, to compile the MPS library for Mac OS X, you might use this:
+
+ % cd mps-kit-1.106.2/code; make -f xcppgc.gmk VARIETY=ci mps.a
+
+Briefly: "-f xcppgc.gmk" tells the buildsystem to use the makefile for
+Mac OS X ("xc"), for the PowerPC architecture ("pp"), using the GCC
+compiler ("gc"). "VARIETY=ci" tells it to build the 'cool internal'
+variety, which includes asserts and other run-time checks.
+
+Object files and libraries are placed in a separate subdirectory,
+according to platform and variety: using the command above makes the
+library in "xcppgc/ci/mps.a". (The "mps.a" on the "make" command-line
+is a predefined target that the buildsystem recognises).
+
+There is nothing magical about "mps.a": it is just a collection of
+object files built from MPS C source files. You can tailor your own
+collection with extras or omissions. The MPS-kit build system is
+configured to build an "mps.a" with the 'most commonly used' files,
+selecting the appropriate variant where there is a platform dependent
+choice.
+
+However, when we try to link with it, we find that the MPS library
+itself has dependencies:
+
+ % gcc 02checkarenaclassheader.c mps-kit-1.106.2/code/xcppgc/ci/mps.a
+ % # (this will fail)
+
+
+The MPS plinth: "mpsplan.a"
+---------------------------
+
+The dependency is because the MPS needs to call some functions in the
+client code (our demo program). The MPS can do this in two different
+ways: through the plinth interface, or through callbacks. The plinth
+interface is for general purpose utility functions, such as
+"mps_lib_memcpy" and "mps_lib_assert_fail". The client must provide
+these utility functions, and the MPS uses them. The idea here is that
+the MPS should not assume how the client wants these jobs to be done.
+
+(Note: The MPS also makes some direct operating-system calls.
+Platform-specific source code files in the MPS use direct calls to
+cooperate with the operating-system in a platform-dependent manner, such
+as to write-protect pages of memory. These calls do not involve client
+code. In contrast, the plinth interface deals with platform-independent
+concepts that the client may have an interest in.)
+
+We don't have to write our own plinth: the MPS-kit includes an example
+plinth that uses the standard C library. This example plinth is called
+"mpsplan.a". ("pl" means plinth; "an" means "ANSI", ie. the standard C
+library).
+
+To build the example plinth for Mac OS X, use:
+
+ % cd mps-kit-1.106.2/code; make -f xcppgc.gmk VARIETY=ci mpsplan.a
+
+Now we can link and run our simple demo file:
+
+ % gcc 02checkarenaclassheader.c mps-kit-1.106.2/code/xcppgc/ci/mps.a mps-kit-1.106.2/code/xcppgc/ci/mpsplan.a
+ % ./a.out && echo "success"
+
+
+Recap
+-----
+
+We have now found and are using:
+ - the main "mps.h" header file;
+ - the additional MPS header file "mpsacl.h";
+ - (in "mpsacl.h") the identifier function "mps_arena_class_cl"
+ for the "CL" arena class we want to use;
+
+We have built and are using:
+ - the MPS library "mps.a";
+ - the example plinth "mpsplan.a".
+
+Now we can start to use more MPS functions. In the next three sections
+we will create an arena (of class "CL"), create a pool (of class "MV"),
+and then allocate some memory.
+
+
+Creating an arena
+-----------------
+
+Look up the reference manual entry for mps_arena_class_cl() at
+<http://www.ravenbrook.com/project/mps/master/manual/reference/#
+mps_arena_class_cl>. The notes and example code in the manual entry
+describe the additional parameters that we need to pass to
+"mps_arena_create()". For a "CL" class arena, we first allocate a big
+block of memory, and then call mps_arena_create passing the count of
+bytes and a pointer to the first byte:
+
+ /* Demo File: 03arena_create.c */
+ /* Simple C client of the MPS */
+
+ #include <stdlib.h> /* for malloc */
+ #include <stdio.h> /* for printf */
+
+ #include "mps.h"
+ #include "mpsacl.h" /* for mps_arena_class_cl */
+
+ int main(void)
+ {
+ void *pBlock = NULL;
+ size_t cbBlock = 1024 * 1024;
+ mps_arena_t ArenaDemo = NULL;
+
+ mps_res_t res;
+
+ pBlock = malloc(cbBlock);
+ if(pBlock == NULL) {
+ printf("malloc failed!\n");
+ exit(1);
+ }
+
+ res = mps_arena_create(
+ &ArenaDemo,
+ mps_arena_class_cl(),
+ cbBlock,
+ pBlock
+ );
+ switch (res) {
+ case MPS_RES_OK:
+ break;
+ case MPS_RES_MEMORY:
+ printf("mps_arena_create: cbBlock too small\n");
+ exit(2);
+ case MPS_RES_FAIL:
+ printf(
+ "mps_arena_create: refused; "
+ "see MPS reference manual\n"
+ );
+ exit(2);
+ }
+
+ /* rest of program */
+ printf("Success.\n");
+ return 0;
+ }
+
+To run this file:
+
+ % gcc 03arena_create.c mps-kit-1.106.2/code/xcppgc/ci/mps.a mps-kit-1.106.2/code/xcppgc/ci/mpsplan.a
+ % ./a.out
+
+
+Creating a pool
+---------------
+
+Before allocating memory, we must create a "pool". A pool abstracts a
+collection of objects that are managed in the same way. The "way an
+object is managed" means the protocol used by the client and MPS to
+create, maintain, and destroy the object.
+
+We will create a pool of the "MV" pool class. "MV" roughly stands for
+"manual, variable". "Manual" means the client explicitly tells the MPS
+when to free the object (in contrast to an "automatic" protocol, ie.
+with automatic garbage collection, where the client never calls free).
+"Variable" means the pool can hold objects of varying sizes.
+
+The functions we need are "mps_class_mv()" and "mps_pool_create()" --
+these are analogous to the "mps_arena_class_cl" and "mps_arena_create"
+we needed for creating an arena. [Note the inconsistent naming:
+"mps_class_mv" should really be called "mps_pool_class_mv".]
+
+Put a copy of "mpscmv.h" into your working directory ("mpsc" stands for
+"MPS (pool) Class"; "MV" is the name of the pool class). It declares
+the "mps_class_mv" function, and some useful pool-class-specific
+functions. We will use "mps_class_mv()" and "mps_mv_free_size()".
+
+If you attempt to look up the reference manual entries for
+"mps_class_mv()" and "mps_pool_create()", you will find they are
+missing. Section 4 of the reference manual lists them as valid
+client-callable functions, but currently undocumented:
+
+ <http://www.ravenbrook.com/project/mps/master/manual/reference/#section-4>
+
+Don't despair. Look in the "code" subdirectory of the MPS-kit, and find
+the file "poolmv.h".
+
+The "poolmv.h" file is internal to the MPS, and contains part of the
+implementation of the "MV" pool class. The MPS tries hard to keep its
+external interface (header files beginning "mps...") separate from its
+internal details. Where the external documentation is lacking, you can
+look at internal materials such as design documentation, implementation
+files, and module test files, but be aware that you have crossed over to
+the 'internal world' of the MPS. Two differences you may notice in
+internal code are that the types used are different, and function names
+are different. It should go without saying that your client code should
+never rely on the particular details of the MPS implementation. If you
+(as an MPS user writing client code) find yourself needing to look
+inside the MPS implementation, that suggests there is a fault in the
+external documentation: please contact us and let us know.
+
+The parameters used to create a pool of class "MV" are discussed in the
+comments at the top of the "poolmv.h" file. When creating a pool of
+class "MV", mps_pool_create requires three extra arguments, which hold
+tuning parameters that help the pool to perform its tasks efficiently.
+The first and third arguments relate to the size of the pool; the second
+argument relates to the size of objects in the pool. (See the comments
+in "poolmv.h" for more detail).
+
+All three arguments are counts of bytes. The correct type for client
+code to specify counts of bytes is "size_t". (This is not documented;
+it ought to be documented under "mps_class_mv" in the reference manual.
+Note that it is incorrect to use the "Size" type -- this is an
+MPS-internal type.)
+
+Finally, note that:
+ "mpscmv.h" is an 'external' header file -- part of the interface
+ to the MPS, which you #include.
+ "poolmv.h" is an 'internal' header file, *not* a client-visible
+ MPS header: your code should not (and does not need
+ to) #include it.
+
+Here is code to create an arena, and create an MV class pool within it:
+
+ /* Demo File: 04pool_create.c */
+ /* Simple C client of the MPS */
+
+ #include <stdlib.h> /* for malloc */
+ #include <stdio.h> /* for printf */
+
+ #include "mps.h"
+ #include "mpsacl.h" /* for mps_arena_class_cl */
+ #include "mpscmv.h" /* for mps_class_mv */
+
+ int main(void)
+ {
+ void *pBlock = NULL;
+ size_t cbBlock = 1024 * 1024;
+ mps_arena_t ArenaDemo = NULL;
+ mps_pool_t PoolDemo = NULL;
+
+ mps_res_t res;
+
+ {
+ /* Create arena */
+
+ pBlock = malloc(cbBlock);
+ if(pBlock == NULL) {
+ printf("malloc failed!\n");
+ exit(1);
+ }
+
+ res = mps_arena_create(
+ &ArenaDemo,
+ mps_arena_class_cl(),
+ cbBlock,
+ pBlock
+ );
+ if (res != MPS_RES_OK) {
+ printf("mps_arena_create: failed with res %d.\n", res);
+ exit(2);
+ }
+ }
+
+ {
+ /* Create pool */
+
+ size_t cbPoolExtend = 1024;
+ size_t cbObjectAvg = 32;
+ size_t cbPoolMax = 64 * 1024;
+
+ size_t cbPoolFree = 0;
+
+ res = mps_pool_create(
+ &PoolDemo,
+ ArenaDemo,
+ mps_class_mv(),
+ cbPoolExtend,
+ cbObjectAvg,
+ cbPoolMax
+ );
+ if (res != MPS_RES_OK) {
+ printf("mps_pool_create: failed with res %d.\n", res);
+ exit(2);
+ }
+
+ cbPoolFree = mps_mv_free_size(PoolDemo);
+ printf(
+ "PoolDemo has %lu bytes free.\n",
+ (unsigned long)cbPoolFree
+ );
+ }
+
+ /* rest of program */
+ {
+ printf("Success.\n");
+ return 0;
+ }
+ }
+
+Compiling and running this produces the possibly surprising result that
+the freshly-created pool has zero (0) bytes free:
+
+ % gcc 04pool_create.c mps-kit-1.106.2/code/xcppgc/ci/mps.a mps-kit-1.106.2/code/xcppgc/ci/mpsplan.a
+ % ./a.out
+ % # (should say: "PoolDemo has 0 bytes free.")
+
+Pools request chunks of storage from their arena when they need it, and
+return it afterwards. The MV pool class code does not request storage
+until the first object is allocated; this is why PoolDemo has 0 bytes
+free initially: it has not yet claimed memory from the arena.
+
+
+Allocating some memory
+----------------------
+
+Finally, we can now allocate some memory! We use the simple "mps_alloc"
+function, and store the text "hello, world" in the memory, and print it
+out.
+
+ /* Demo File: 05alloc.c */
+ /* Simple C client of the MPS */
+
+ #include <stdlib.h> /* for malloc */
+ #include <stdio.h> /* for printf */
+ #include <string.h> /* for strcpy */
+
+ #include "mps.h"
+ #include "mpsacl.h" /* for mps_arena_class_cl */
+ #include "mpscmv.h" /* for mps_class_mv */
+
+ static void reportPoolmv(mps_pool_t Pool)
+ {
+ size_t cbPoolFree = mps_mv_free_size(Pool);
+ printf(
+ "Pool has %lu bytes free.\n",
+ (unsigned long)cbPoolFree
+ );
+ }
+
+ int main(void)
+ {
+ void *pBlock = NULL;
+ size_t cbBlock = 1024 * 1024;
+ mps_arena_t ArenaDemo = NULL;
+ mps_pool_t PoolDemo = NULL;
+
+ mps_res_t res;
+
+ {
+ /* Create arena */
+
+ pBlock = malloc(cbBlock);
+ if(pBlock == NULL) {
+ printf("malloc failed!\n");
+ exit(1);
+ }
+
+ res = mps_arena_create(
+ &ArenaDemo,
+ mps_arena_class_cl(),
+ cbBlock,
+ pBlock
+ );
+ if (res != MPS_RES_OK) {
+ printf("mps_arena_create: failed with res %d.\n", res);
+ exit(2);
+ }
+ }
+
+ {
+ /* Create pool */
+
+ size_t cbPoolExtend = 1024;
+ size_t cbObjectAvg = 32;
+ size_t cbPoolMax = 64 * 1024;
+
+ size_t cbPoolFree = 0;
+
+ res = mps_pool_create(
+ &PoolDemo,
+ ArenaDemo,
+ mps_class_mv(),
+ cbPoolExtend,
+ cbObjectAvg,
+ cbPoolMax
+ );
+ if (res != MPS_RES_OK) {
+ printf("mps_pool_create: failed with res %d.\n", res);
+ exit(2);
+ }
+
+ reportPoolmv(PoolDemo);
+ }
+
+ {
+ /* Allocate memory */
+
+ size_t cbBuffer = 100;
+ void *p = NULL;
+
+ res = mps_alloc(&p, PoolDemo, cbBuffer);
+ if (res != MPS_RES_OK) {
+ printf("mps_alloc: failed with res %d.\n", res);
+ exit(2);
+ }
+
+ reportPoolmv(PoolDemo);
+
+ {
+ /* Show that it really is memory */
+
+ char *pbBuffer = (char *)p;
+
+ strcpy(pbBuffer, "hello--world\n");
+ pbBuffer[5] = ',';
+ pbBuffer[6] = ' ';
+ printf(pbBuffer);
+ }
+ }
+
+ printf(
+ "Success: The hello-world example code successfully allocated\n"
+ "some memory using mps_alloc(), in an MV pool, in a CL arena.\n"
+ );
+ return 0;
+ }
+
+To compile and run this:
+
+ % gcc 05alloc.c mps-kit-1.106.2/code/xcppgc/ci/mps.a mps-kit-1.106.2/code/xcppgc/ci/mpsplan.a
+ % ./a.out
+ % # (should say: "PoolDemo has 0 bytes free.")
+ % # (and then: "PoolDemo has NNNN bytes free.", where NNNN depends on platform.)
+ % # (and then: "hello, world")
+
+That's the end of this example code.
+
+
+DOCUMENT HISTORY
+
+2006-02-17 RHSK Created from scratch, referencing version/1.106.1
+2006-04-10 RHSK Tidy for release; refer to version/1.106.2
+
+
+COPYRIGHT AND LICENSE
+
+Copyright (C) 2006 Ravenbrook Limited <http://www.ravenbrook.com/>.
+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.
+
+[END]
Added: trunk/mps/example/index.html
==============================================================================
--- (empty file)
+++ trunk/mps/example/index.html Wed Nov 15 07:37:58 2006
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+
+<title>Example Code</title>
+
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000" link="#000099" vlink="#660066" alink="#FF0000">
+
+<div align="center">
+
+<p>
+<a href="/">Ravenbrook</a> /
+<a href="/project/">Projects</a> /
+<a href="/project/mps/">Memory Pool System</a> /
+<a href="/project/mps/master/">Master Product Sources</a>
+</p>
+
+<p><i><a href="/project/mps/">Memory Pool System Project</a></i></p>
+
+<hr />
+
+
+<h1>Example Code</h1>
+
+<address>
+<a href="mailto:rhsk at ravenbrook.com">Richard Kistruck</a>,
+<a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>,
+2006-04-10
+</address>
+
+</div>
+
+
+<h2><a id="section-1" name="section-1">1. Introduction</a></h2>
+
+<p>This is the catalogue of example code for the Memory Pool System product.</p>
+
+<p> The example code shows you how to write code that uses the MPS. (In other words, how to use facilities in "mps.h").</p>
+
+<p>The simplest example — "hello-world" — gets you started using the MPS to allocate some memory to store and print the text "hello, world".</p>
+
+<p>This document is not confidential. The readership of this document is developers of client code that uses the MPS interface.</p>
+
+<p>Related documents:</p>
+<ul> <li> the MPS <a href="../manual/reference/">reference manual</a> </li></ul>
+
+
+<h2><a id="section-2" name="section-2">2. Example Code</a></h2>
+
+<table>
+
+<tr valign="top">
+ <td><code><a href="hello-world/">hello-world/</a></code></td>
+ <td>simplest call to mps_alloc() — START HERE!</td>
+</tr>
+
+</table>
+
+
+<h2><a id="section-A" name="section-A">A. References</a></h2>
+
+<!-- Template Entry
+
+<table>
+
+<tr valign="top">
+
+ <td>[<a id="ref-#REF#" name="ref-#REF#" href="#REF_URL#">#REF_NAME#</a>]</td>
+
+ <td>
+ "#REF_TITLE#";
+ #REF_AUTHOR#;
+ <URL: <a href="#REF_URL#">#REF_URL#</a>>;
+ #REF_DATE#.
+ </td>
+
+</tr>
+
+</table>
+
+-->
+
+
+<h2><a id="section-B" name="section-B">B. Document History</a></h2>
+
+<table>
+
+<tr valign="top">
+ <td>2006-04-10</td>
+ <td><a href="mailto:rhsk at ravenbrook.com">RHSK</a></td>
+ <td>Created (based on ../manual/index.txt).</td>
+</tr>
+
+</table>
+
+
+<h2><a id="section-C" name="section-C">C. Copyright and License</a></h2>
+
+<p> This document is copyright © 2006 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options. </p>
+
+<p> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </p>
+
+<ol>
+
+<li> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </li>
+
+<li> 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. </li>
+
+<li> 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. </li>
+
+</ol>
+
+<p> <strong> 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. </strong> </p>
+
+
+<hr />
+
+<div align="center">
+
+<p><code>$Id: //info.ravenbrook.com/project/mps/master/example/index.html#1 $</code></p>
+
+<p>
+<a href="/">Ravenbrook</a> /
+<a href="/project/">Projects</a> /
+<a href="/project/mps/">Memory Pool System</a> /
+<a href="/project/mps/master/">Master Product Sources</a>
+</p>
+
+</div>
+
+</body>
+
+</html>
Modified: trunk/mps/manual/build-notes/index.html
==============================================================================
--- trunk/mps/manual/build-notes/index.html (original)
+++ trunk/mps/manual/build-notes/index.html Wed Nov 15 07:37:58 2006
@@ -48,6 +48,10 @@
removed from master sources. RHSK.
See <http://www.ravenbrook.com/project/mps/issue/job000602/>
+2006-10-10
+Intel Macs. It's now possible to use xci3gc.gmk to build on Intel
+architectures. Protection and threads not supported.
+
3. WINDOWS
@@ -66,11 +70,12 @@
B. DOCUMENT HISTORY
2005-02-02 RHSK Created based on mps kit readme.txt.
+2006-10-10 DRJ Note re Intel Macs.
C. COPYRIGHT AND LICENSE
-Copyright (C) 2005 Ravenbrook Limited <http://www.ravenbrook.com/>.
+Copyright (C) 2005,2006 Ravenbrook Limited <http://www.ravenbrook.com/>.
All rights reserved. This is an open source license. Contact
Ravenbrook for commercial licensing options.
@@ -108,4 +113,4 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-$Id: //info.ravenbrook.com/project/mps/master/manual/build-notes/index.txt#3 $
+$Id: //info.ravenbrook.com/project/mps/master/manual/build-notes/index.txt#5 $
Modified: trunk/mps/manual/index.html
==============================================================================
--- trunk/mps/manual/index.html (original)
+++ trunk/mps/manual/index.html Wed Nov 15 07:37:58 2006
@@ -71,6 +71,14 @@
<tr valign="top">
+ <td><code><a href="wiki/">wiki/</a></code></td>
+
+ <td>Wiki: incomplete notes, the precursor to more formal documentation</td>
+
+</tr>
+
+<tr valign="top">
+
<td><code><a href="supplement/dll-notes/">supplement/dll-notes/</a></code></td>
<td>Notes on the MPS DLL (the MPS library in dynamically linkable form)</td>
@@ -148,12 +156,18 @@
</tr>
+<tr valign="top">
+ <td>2006-05-25</td>
+ <td><a href="mailto:rhsk at ravenbrook.com">RHSK</a></td>
+ <td>Add wiki/</td>
+</tr>
+
</table>
<h2><a id="section-C" name="section-C">C. Copyright and License</a></h2>
-<p> This document is copyright © 2002-2005 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options. </p>
+<p> This document is copyright © 2002-2006 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options. </p>
<p> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </p>
@@ -174,7 +188,7 @@
<div align="center">
-<p><code>$Id: //info.ravenbrook.com/project/mps/master/manual/index.html#5 $</code></p>
+<p><code>$Id: //info.ravenbrook.com/project/mps/master/manual/index.html#6 $</code></p>
<p>
<a href="/">Ravenbrook</a> /
Added: trunk/mps/manual/wiki/apguide.html
==============================================================================
--- (empty file)
+++ trunk/mps/manual/wiki/apguide.html Wed Nov 15 07:37:58 2006
@@ -0,0 +1,580 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+ <title>MPS Wiki: Allocation Points -- User's Guide</title>
+ <style type = "text/css">
+ <!--
+ div.banner {text-align:center}
+ dt {font-weight:bold}
+
+ -->
+ </style>
+</head>
+
+<body>
+
+<div class="banner">
+
+<p>
+<a href="/">Ravenbrook</a>
+/ <a href="/project/">Projects</a>
+/ <a href="/project/mps/">Memory Pool System</a>
+/ <a href="/project/mps/master/">Master Product Sources</a>
+/ <a href="/project/mps/master/manual/">Manuals</a>
+/ <a href="/project/mps/master/manual/wiki/">Wiki</a>
+</p>
+
+<p><i><a href="/project/mps/">Memory Pool System Project</a></i></p>
+
+<hr />
+
+<h1>MPS Wiki: Allocation Points -- User's Guide</h1>
+
+<address>
+<a href="mailto:rhsk at ravenbrook.com">Richard Kistruck</a>,
+<a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>,
+2006-06-09
+</address>
+
+</div>
+
+<p> This wiki article contains incomplete and informal notes about the MPS, the precursor to more formal documentation. Not confidential. Readership: MPS users and developers. </p>
+
+<p>These notes on Allocation Points were written by RHSK between
+ 2006-06-07 and 2006-06-22, following research and discussion with
+ RB and NB.
+ <strong>Warning:</strong> the text in this User's Guide
+ is preliminary, but believed to be 'conservatively correct'.
+ In other words, I think if you follow these guidelines, your code
+ will be correct, and will not violate the current or future
+ definitions of the MPS ap protocol. But this is not (yet) an
+ accurate statement of the MPS ap protocol. RHSK 2006-06-13.</p>
+
+<p>[<strong>Note:</strong> some constraints
+ may be mentioned only here, and not yet in other places they
+ should be mentioned, such as the Reference Manual.
+ Notably, the client's obligation to ensure there are no exact
+ references to a failed new-object, before it calls mps_ap_trip,
+ is suspected to be new. RHSK 2006-06-13]</p>
+
+<h2>Introduction</h2>
+
+<p>Allocation points are an MPS protocol that the client uses to
+ allocate memory with low overhead, and low synchronization
+ cost (with an asynchronous collector and with other threads).</p>
+
+<p>The allocation point protocol is designed to work with
+ incremental collections and multi-threaded clients.
+ (And even if your particular client is
+ single-threaded and non-incremental,
+ for the purposes of using allocation points
+ it's easiest to assume you are coding for this case).</p>
+
+<p>The assumption is that, <em>between any
+ two client instructions</em>, the MPS can interrupt you, move
+ objects around (if they are in a moving pool) and collect
+ garbage. To cope with this, allocating is a two-step process.</p>
+
+<p><strong>Important:</strong>
+ <a id="assume.ambig-workspace" class="tag">.assume.ambig-workspace</a>:
+ this User's Guide
+ assumes that you have declared your stack and registers to
+ be a root that is ambiguously scanned, using mps_root_create_reg
+ and passing the mps_stack_scan_ambig function to it.
+ This is the simplest way to write a client.
+ Other scenarios are possible, but
+ their implications for correct Allocation Point use
+ are not yet documented here.</p>
+
+<p>The rest of this Allocation Points User's Guide contains the following
+ sections:</p>
+<ul>
+ <li>Creating and destroying allocation points</li>
+ <li>Overview of two-step allocation</li>
+ <li>The graph of managed references</li>
+ <li>mps_reserve</li>
+ <li>Building the object</li>
+ <li>mps_commit</li>
+ <li>Common mistakes</li>
+</ul>
+
+
+<h2>Creating and destroying allocation points</h2>
+
+<p>To create an allocation point in a pool,
+ call <code>mps_ap_create</code>.
+ This may require additional arguments, depending on the pool
+ class. See pool class documentation.</p>
+
+<p>An allocation point <strong>MUST NOT</strong> be used by more
+ than one thread. (Each thread must have its own allocation point or
+ points).</p>
+
+<p>Destroy an allocation point with <code>mps_ap_destroy</code>.</p>
+
+<h2>Overview of two-step allocation</h2>
+
+<p>When the client is building (creating and formatting) a new
+ object, you can think of it as being 'in a race' with the MPS.
+ The object is 'under
+ construction', and the MPS cannot manage it in the normal way.
+ So the client should build the object quickly, and then
+ commit it to MPS management. Rarely, the MPS has to move other
+ objects around right in the middle of this build phase: that's
+ a (small) price you pay for having an asynchronous collector.
+ If this happens, the MPS will tell the client that it has 'lost the
+ race'. Objects have moved around, and the new object is invalid.
+ The client must start building it again from scratch.</p>
+
+<p>The client starts building the new object with
+ <code>mps_reserve</code>, and
+ marks it complete by calling <code>mps_commit</code>.
+ Almost always, <code>mps_commit</code> succeeds. But if the
+ client did not complete the object in time, then
+ <code>mps_commit</code> fails (returns 0).</p>
+
+<p>This is how the client should build a new object:</p>
+<ol>
+ <li> <code>mps_reserve</code> some memory,</li>
+ <li> build a new object in it,</li>
+ <li> store a reference to the new object in an
+ ambiguously-scanned place
+ (but <strong>NOT</strong> in any exactly-scanned place),</li>
+ <li> <code>mps_commit</code> the new object to MPS management;</li>
+</ol>
+
+<p>If commit succeeds, the object is complete, and immediately
+ becomes just a normal allocated object.
+ The client may write a reference to the
+ new object into some older object (thereby connecting the
+ new object into the client's graph of objects).</p>
+
+<p>If commit fails, the new object no longer exists:
+ the data has gone and any references that used to refer to it
+ are now dangling pointers.
+ The client should simply try to build the
+ object again.</p>
+
+<p>In pseudo-code, the standard allocation point idiom is:</p>
+
+<blockquote><pre><code>
+ do
+ mps_reserve
+ initialize new object
+ make an ambiguous reference to new object
+ while (! mps_commit)
+ link new object into my object graph
+</code></pre></blockquote>
+
+<p>(Do not worry about getting stuck in this loop:
+ commit usually fails at most once per collection,
+ so it is very rare for commit to fail even once,
+ let alone twice).</p>
+
+<p>In C, this typically looks like this:</p>
+
+<blockquote><pre><code>int make_object(mps_ap_t ap, object *parent)
+{
+ void *p;
+ object *neo = NULL;
+
+ do {
+ if (mps_reserve(&p, ap, SIZE_OBJECT) != MPS_RES_OK) {
+ goto fail_make_object;
+ }
+ /* Build the new object */
+ neo = p;
+ neo->formatcode = FORMAT_CLIENT; /* (not fwd or pad) */
+ neo->type = TYPE_OBJECT;
+ neo->size = SIZE_OBJECT;
+ neo->parent = parent;
+ neo->family = parent->family;
+ neo->child = NULL;
+ /* neo (ambiguous reference) preserves the new object */
+ } while (! mps_commit(ap, p, SIZE_OBJECT));
+
+ /* Success: link the new object into my object graph */
+ parent->child = neo;
+ return TRUE;
+
+fail_make_object:
+ return FALSE; /* out of memory, etc */
+}
+</code></pre></blockquote>
+
+<p>Note that, throughout this User's Guide, we assume that
+ the stack and registers are declared as ambiguous roots
+ (<a href="#assume.ambig-workspace">.assume.ambig-workspace</a>)
+ which means that the <code>neo</code> pointer
+ keeps the new object alive for us.</p>
+
+<p>The rest of this User's Guide goes through these steps in more
+ detail.</p>
+
+
+<h2>The graph of managed references</h2>
+
+<p>The MPS is a moving garbage collector: it supports
+ preserve-by-copying pools, whose objects are 'mobile'.
+ Whenever the MPS moves an object, it will ensure that
+ all managed references are updated to point to the
+ new location -- and this happens instantaneously as far
+ as the client sees it.</p>
+
+<p>The client should assume that, between <em>any pair of
+ instructions</em>, the MPS may 'shake' this graph, moving
+ all the mobile objects, and updating all the managed
+ references.</p>
+
+<p>Any parts of the graph that are no longer connected
+ (no longer reachable from declared roots) may be collected,
+ and the memory that those objects occupied may be unmapped,
+ or re-used for different objects.</p>
+
+<p>The client usually takes care to ensure that all the
+ references it
+ holds are managed. To be managed, the reference must be
+ in a declared root (such as a scanned stack or a global variable),
+ or in a formatted object that is reachable from a root.</p>
+
+<p>It is okay for a careful client to hold unmanaged references,
+ but:</p>
+<ul>
+ <li> they'd better not be to a mobile object! Remember, mobile
+ objects could move at any time, and unmanaged references
+ will be left 'dangling'.</li>
+ <li> they'd better not be the only reference to an object,
+ or that object might get collected, again leaving a dangling
+ reference.</li>
+</ul>
+
+<h2>mps_reserve</h2>
+
+<p>Call <code>mps_reserve</code>, passing the size of the
+ new object you wish to create.
+ The size must be aligned to the pool alignment.
+ This is in contrast to mps_alloc, which (for some pools) allows
+ unaligned sizes.</p>
+
+<p><em class="note">[Normally, use <code>mps_reserve</code>
+ (the lower-case C macro).
+ But if you are using a weak compiler that does not detect common
+ subexpressions, you may find that using
+ <code>MPS_RESERVE_BLOCK</code> (functionally identical) generates
+ faster code.
+ Or it may generate slower code. It depends on your compiler, and
+ you will have to conduct tests to find out.]</em></p>
+
+<p><code>mps_reserve</code> returns a reference to a piece
+ of new memory for the client to build a new object in.
+ During this build, the MPS pins the piece of memory, and
+ treats it as raw data.</p>
+
+<p>"Pinned" means: it will not move, be collected, be unmapped,
+ or anything like that. You may keep an unmanaged reference to
+ it at this time.</p>
+
+<p>"Raw data" means two things:</p>
+
+<p>Firstly, "raw data" means that any references stored IN the
+ new object are <em>unmanaged</em>. This means:</p>
+<ul>
+ <li> references in the new object will not get updated if
+ the graph of managed references to mobile objects is 'shaken';</li>
+ <li> references in the new object do not
+ preserve any old objects they point to.</li>
+</ul>
+
+<p>Secondly, "raw data" means that any references TO the new
+ object are treated like other references to unmanaged memory:</p>
+<ul>
+ <li> the MPS will not call the client's format code to answer
+ questions about the new object.</li>
+</ul>
+
+<h2>Building the object</h2>
+
+<p>The client will typically do all these things:</p>
+<ul>
+ <li> write data that makes the new object 'valid' for the
+ client's format;</li>
+ <li> write other data into the new object;</li>
+ <li> store references to existing objects IN
+ the new object;</li>
+ <li> keep (in a local variable) an ambiguous reference TO the
+ new object.</li>
+</ul>
+
+<p>However, during the build, there are a couple of restrictions:</p>
+<ul>
+ <li>
+ <p>Once the client has stored a reference IN the new object,
+ it <strong>MUST NOT</strong> read it out again —
+ any reference stored in the new object is unmanaged,
+ and may have become stale.</p>
+
+ <p>(Actually, the restriction is: the moment a reference to an
+ existing mobile object is written into the new object, that
+ reference (in the new object) may become stale. And you'd better
+ not use (dereference) a stale reference. And you'd better not
+ write it into any exactly-scanned cell (such as in an existing
+ object).
+ Reading it into an ambiguously-scanned cell (such as an ambiguously
+ scanned register or stack cell) is okay as long as you don't
+ dereference it.
+ Writing it back into another part of the new object is okay too.
+ Just don't trust it to be a valid reference.)</p>
+ </li>
+ <li>
+ <p>The client <strong>MUST NOT</strong> store a reference TO the
+ new object in any exactly-scanned place.</p>
+
+ <p><em class="note">[Note: this is in fact possible, but the
+ protocol for doing it is more complex, and beyond the scope of
+ this guide. RHSK 2006-06-22]</em></p>
+
+ <p>This means the client should NOT connect the new object into
+ the graph of managed objects during the build.</p>
+ </li>
+</ul>
+
+<p>Before the end of the build phase:</p>
+<ul>
+ <li> the new object must be validly formatted;</li>
+ <li> all exactly-scanned cells in the new object must
+ contain valid references;</li>
+ <li> the new object must be ambiguously reachable.</li>
+</ul>
+
+<p>Optionally, for improved robustness to bugs, consider initialising
+ <em>all</em> parts of the new object, including parts that are not
+ yet being used to store useful data (such as a string buffer).
+ You might want to make this compile-time switchable, for debugging.</p>
+
+<blockquote class="note">
+ <p><em class="note">If you leave these unused parts
+ uninitialised, they may contain data that
+ looks like a valid object -- this is called a "spoof object".
+ (This might be the 'ghost' of a previous object, or just random
+ junk that happens to look like a valid object).</em></p>
+
+ <p><em class="note">This is completely legal: spoof objects
+ do not cause a problem for the MPS.</em></p>
+
+ <p><em class="note">
+ However, this might leave you with less safety margin than you
+ want, especially when developing a new client.
+ If there were to be a bug in your code (or indeed in
+ the MPS) that resulted in a bogus exact reference to this spoof,
+ it might go undetected,
+ and arbitrary corruption might occur before the bug came to light.
+ So, consider filling these as-yet unused parts with specially
+ chosen dummy values, at least as an option for debugging.
+ Choose dummy values that your format code will recognise as
+ not permitted at the start of a valid formatted object.
+ You will then detect bogus exact references more promptly.</em></p>
+
+ <p><em class="note">[RHSK 2006-06-15:
+ In poolamc, these ghosts will be forwarding pointers,
+ and they will usually get unmapped (though
+ unless we use zeroed / secure / etc VM they may get mapped-in
+ again intact).
+ But if the tract is nailed they won't even get unmapped.
+ And ghost forwarding pointers are just as bad news as any other
+ spoof.
+ There's currently no format method "destroy". If there was,
+ we could call it in the reclaim phase, to allow format code to
+ safely mark these ghosts as dead. Actually, perhaps that's a
+ valid use of the 'pad' method?
+ ]</em></p>
+</blockquote>
+
+
+<h2>mps_commit</h2>
+
+<p>When you call <code>mps_commit</code>, it will either fail or succeed.</p>
+
+<p>Almost always, <code>mps_commit</code> succeeds.
+ If it succeeds, that means: </p>
+<ul>
+ <li> all the references written IN the new object are valid (in
+ other words, a successful commit is the MPS's way of telling
+ you that these references did not become stale while they were
+ sitting unmanaged in the new object);</li>
+ <li> all the references TO the new object are valid;</li>
+ <li> the new object is now just a normal object like any other;</li>
+ <li> it may get collected if there are no references
+ to it;</li>
+ <li> if the pool supports mps_free, you may manually free the
+ new object.</li>
+</ul>
+
+<p>Occasionally but rarely, <code>mps_commit</code> fails.
+ This means:</p>
+<ul>
+ <li> the new object no longer exists —
+ the memory may even be unmapped by the time
+ <code>mps_commit</code> returns;</li>
+ <li> there must be no exact references to the new object.</li>
+</ul>
+
+<p>If commit fails, the client usually tries making the object again
+ (although this is not required: it is allowed to just give up!).
+ This is why the standard allocation point idiom has a
+ do...while loop.</p>
+
+
+<h2>Common mistakes</h2>
+
+<p>Here are some examples of mistakes to avoid:</p>
+
+<blockquote><pre><strong>The example below is INCORRECT.</strong>
+
+<code>typedef struct object_s {
+ int formatcode; /* FORMAT_CLIENT, _FWD, or _PAD */
+ int type;
+ size_t size;
+ struct object_s *family;
+ struct object_s *parent;
+ struct object_s *child;
+} object;
+
+int make_object(mps_ap_t ap, object *parent)
+{
+ void *p;
+ object *neo = NULL;
+
+ do {
+ if (mps_reserve(&p, ap, SIZE_OBJECT) != MPS_RES_OK) {
+ goto fail_make_object;
+ }
+ /* Build the new object */
+ neo = p;
+ neo->formatcode = FORMAT_CLIENT;
+ neo->type = TYPE_OBJECT;
+ neo->size = SIZE_OBJECT;
+ neo->parent = parent;
+ neo->family = neo->parent->family; /*--- incorrect-1 ---*/
+ parent->child = neo; /*--- incorrect-2 ---*/
+
+ /* neo (ambiguous reference) preserves the new object */
+ } while (! mps_commit(ap, p, SIZE_OBJECT));
+
+ neo->child = NULL; /*--- incorrect-3 ---*/
+ return TRUE;
+
+fail_make_object:
+ return FALSE; /* out of memory, etc */
+}
+
+<strong>The example above is INCORRECT.</strong>
+</code></pre></blockquote>
+
+<p>Incorrect-1: do not read references from the new object.
+ Dereferencing <code>neo->parent</code> is illegal.
+ (The code should use <code>parent->family</code>).</p>
+
+<p>Incorrect-2: making an exact reference to the new object is illegal.
+ (The code should only do this after a successful commit).</p>
+
+<p>Incorrect-3: the <code>child</code> slot (in this example) is
+ exactly scanned, and it MUST be initialised before the call to
+ commit.
+ (The code shown is initialising it too late).</p>
+
+
+<h2>Conclusion and further details</h2>
+
+<p>Although this User's Guide explains the protocol in terms of the
+ pre-packaged macros
+ <code>mps_reserve</code> and <code>mps_commit</code>,
+ that is a simplification.
+ The MPS allocation point protocol is designed as a
+ binary protocol, defined at the level of atomic machine operations.
+ The precise specification of the binary protocol is beyond the
+ scope of this document.</p>
+
+<p>For further discussion of Allocation Points, see
+ <a href="apinternals.html">Allocation Points -- Internals</a>.
+</p>
+
+<h2><a id="section-B" name="section-B">B. Document History</a></h2>
+
+<pre>
+(As part of GC article)
+ 2006-06-09 RHSK Allocation points: how it's supposed to be, from RB
+ 2006-06-09.
+ 2006-06-09 RHSK Allocation points: must make at least one ambiguous ref
+ and no exact refs to new object before calling commit.
+ 2006-06-12 RHSK Allocation points: minor edits for clarity.
+ 2006-06-12 RHSK Allocation point internals: Scenario; A mutator with
+ ambiguous references only (to the new object); How
+ bad is a bogus exact reference?; quick notes on: with
+ exact refs; flipping at other times.
+ 2006-06-13 RHSK Allocation point user's guide: Tidy; clarify-- not
+ yet complete.
+ Distinguish it from section on AP internals.
+ 2006-06-14 RHSK Allocation point user's guide: standard reserve-commit
+ idiom: corrections, and now assume ambiguous reg+stack:
+ transitioning to this assumption.
+ Add .talk.RB.2006-06-13 about standard r-c idiom
+ Add .talk.RB.2006-06-14 about Modes of use of MPS,
+ and Promises to not flip (single-threaded).
+ Add .think.RHSK.2006-06-14 about how we could support
+ unscanned reg+stack, even with multi-threaded, moving
+ collector.
+ 2006-06-15 RHSK Allocation Points: clarifications and further notes
+ into User Guide and Internals, including initializing
+ as-yet unused parts of new objects to reduce spoofing.
+ 2006-06-22 RHSK Move rough notes .talk.RB.2006-06-13 etc elsewhere.
+ Make AP User Guide consistently .assume.ambig-workspace,
+ moving notes to APInternals; add Intro and Mistakes;
+ check example code.
+
+(This article)
+ 2006-06-22 RHSK Created from GC article.
+ 2006-06-23 RHSK Move AP Internals discussion to its own article.
+</pre>
+
+
+<h2><a id="section-C" name="section-C">C. Copyright and License</a></h2>
+
+<p> This document is copyright © 2006 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options. </p>
+
+<p> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </p>
+
+<ol>
+
+<li> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </li>
+
+<li> 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. </li>
+
+<li> Redistributions in any form must be accompanied by information on how to obtain complete source code for the 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. </li>
+
+</ol>
+
+<p> <strong> 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. </strong> </p>
+
+
+<hr />
+
+<div class="banner">
+
+<p><code>$Id: //info.ravenbrook.com/project/mps/master/manual/wiki/apguide.html#3 $</code></p>
+
+<p>
+<a href="/">Ravenbrook</a>
+/ <a href="/project/">Projects</a>
+/ <a href="/project/mps/">Memory Pool System</a>
+/ <a href="/project/mps/master/">Master Product Sources</a>
+/ <a href="/project/mps/master/manual/">Manuals</a>
+/ <a href="/project/mps/master/manual/wiki/">Wiki</a>
+</p>
+
+</div>
+
+</body>
+
+</html>
Added: trunk/mps/manual/wiki/apinternals.html
==============================================================================
--- (empty file)
+++ trunk/mps/manual/wiki/apinternals.html Wed Nov 15 07:37:58 2006
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+ <title>MPS Wiki: Allocation Points -- Internals</title>
+ <style type = "text/css">
+ <!--
+ div.banner {text-align:center}
+ dt {font-weight:bold}
+
+ -->
+ </style>
+</head>
+
+<body>
+
+<div class="banner">
+
+<p>
+<a href="/">Ravenbrook</a>
+/ <a href="/project/">Projects</a>
+/ <a href="/project/mps/">Memory Pool System</a>
+/ <a href="/project/mps/master/">Master Product Sources</a>
+/ <a href="/project/mps/master/manual/">Manuals</a>
+/ <a href="/project/mps/master/manual/wiki/">Wiki</a>
+</p>
+
+<p><i><a href="/project/mps/">Memory Pool System Project</a></i></p>
+
+<hr />
+
+<h1>MPS Wiki: Allocation Points -- Internals</h1>
+
+<address>
+<a href="mailto:rhsk at ravenbrook.com">Richard Kistruck</a>,
+<a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>,
+2006-06-09
+</address>
+
+</div>
+
+<p> This wiki article contains incomplete and informal notes about the MPS, the precursor to more formal documentation. Not confidential. Readership: MPS developers. </p>
+
+<p>These notes on Allocation Points were written by RHSK between
+ 2006-06-12 and 2006-06-23, following research and discussion with
+ RB and NB.</p>
+
+<p><strong>Warning:</strong> this article is more of a technical
+ discussion than a set of facts. It is not authoritative.
+ This is not (yet) an accurate statement of the MPS ap protocol.
+ RHSK 2006-06-23.</p>
+
+<h2><a id="synchronization">Synchronization</a></h2>
+
+<p>The synchronization issues are a little tricky.</p>
+
+<h3>scenario</h3>
+
+<p>The MPS allocation point protocol is a binary protocol. You don't
+ have to use the mps_reserve and mps_commit macros, but they are
+ conventional and useful pre-packaged implementations.
+ I'm using them as an example of correct protocol, referring to
+ <a href="http://www.ravenbrook.com/project/mps/master/code/mps.h">mps.h#17</a>.
+ It looks like this:</p>
+
+<pre><code>#define mps_reserve(_p_o, _mps_ap, _size) \
+ ((char *)(_mps_ap)->alloc + (_size) > (char *)(_mps_ap)->alloc && \
+ (char *)(_mps_ap)->alloc + (_size) <= (char *)(_mps_ap)->limit ? \
+ ((_mps_ap)->alloc = \
+ (mps_addr_t)((char *)(_mps_ap)->alloc + (_size)), \
+ *(_p_o) = (_mps_ap)->init, \
+ MPS_RES_OK) : \
+ mps_ap_fill(_p_o, _mps_ap, _size))
+
+#define mps_commit(_mps_ap, _p, _size) \
+ ((_mps_ap)->init = (_mps_ap)->alloc, \
+ (_mps_ap)->limit != 0 || mps_ap_trip(_mps_ap, _p, _size))
+</code></pre>
+
+<p>Abstractly, the mutator code has a cycle of four operations on the
+ allocation point:</p>
+<dl>
+ <dt> Lr </dt>
+ <dd> read Limit at reserve </dd>
+
+ <dt> A </dt>
+ <dd> write Alloc at reserve </dd>
+
+ <dt> I </dt>
+ <dd> write Init at commit </dd>
+
+ <dt> Lc </dt>
+ <dd> read Limit at commit </dd>
+</dl>
+
+<p>The normal cycle is Lr A I Lc.</p>
+
+<p>After Lr, the mutator checks that A + size <= Lr. If this fails,
+ then the mutator does mps_ap_fill instead of A. So Lr mps_ap_fill I Lc
+ is also a valid cycle.</p>
+
+<p>After Lc, the mutator checks that Lc != 0. If this fails, the
+ mutator will call mps_ap_trip before beginning a new cycle. So
+ Lr A I Lc mps_ap_trip is also a valid cycle.</p>
+
+<p>The mutator cannot interrupt the
+ collector.</p>
+
+<p>The collector can interrupt the mutator (between any
+ two mutator instructions). The collector can only see the A, I,
+ and mps_ap_trip (if present) operations; Lr and Lc are invisible
+ to it.</p>
+
+<p>If the ap is not going to trip, the collector sees two
+ equivalence classes:</p>
+<ul>
+ <li> (A)</li>
+ <li> (I Lc Lr)</li>
+</ul>
+
+<p>If the ap is going to trip, the collector sees four
+ equivalence classes:</p>
+<ul>
+ <li> (A)</li>
+ <li> (I Lc)</li>
+ <li> (the call to mps_ap_trip)</li>
+ <li> (mps_ap_trip Lr)</li>
+</ul>
+
+<p>The collector has two responsibilities:</p>
+<dl>
+ <dt> FIX </dt>
+ <dd> to fix (or not fix) references TO the object;</dd>
+ <dt> SCAN </dt>
+ <dd> to scan (or not scan) references IN the object.</dd>
+</dl>
+
+<h3>A mutator with ambiguous references only (to the new object)</h3>
+
+<p>Let's see what's required for a mutator that promises to make no
+ exact references to the new object until Lc succeeds,
+ and promises to have at least one ambiguous reference to the
+ new object when it sets I.</p>
+
+<p>Consider a flip -- f1 -- in state A.</p>
+
+<p>The collector at f1 sees (A), and recognises that the I..A region
+ is unmanaged memory.
+ The object is never going to be valid,
+ because it may contain stale references from before the flip, and the
+ collector can't fix them.</p>
+
+<p>The f1 collector writes L = 0, tripping the allocation
+ point, and the rest of this collection is easy.
+ The FIX responsibility is easy:
+ all references to the new object are ambiguous, so the
+ collector can fix them or not -- it
+ doesn't matter.
+ For SCAN, the collector must not scan the new object
+ (because it is not yet formatted), so
+ it must not scan the buffered pool beyond I.</p>
+
+<p>Further collections at this point are idempotent.</p>
+
+<p>Now, suppose the mutator then restarts, but only gets as far
+ as (I Lc) before we have a second collection and a
+ second flip -- f2.</p>
+
+<p>For FIX, f2 can fix or not -- it still doesn't matter.</p>
+
+<p>But for SCAN, f2 <strong>MUST NOT</strong> scan the new object.
+ Why not?</p>
+
+<p>The mutator's format code will be okay: the fact
+ that I is set tells f2 that the object
+ is fully formatted.</p>
+
+<p>But there is a problem: the object may contain stale exact
+ references -- unfixed references from before f1.
+ These stale exact references will be bogus.
+ Opinions differ on the implications of bogus exact references.
+ See the next section for a discussion.</p>
+
+<p>Additionally, the collector is not <em>obliged</em> to scan the
+ object: this object is dead!
+ The mutator will later notice that Lr == 0 and realise the object
+ is invalid. The mutator is not relying
+ on this object to keep anything else alive.</p>
+
+<p>It is easy to avoid scanning the invalid object:
+ the first flip in state (A), f1, must record the value of I.
+ Call the recorded pointer If1.
+ Collections must not scan beyond If1.
+ If1 remains set until the mutator calls mps_ap_trip,
+ which resets If1 to 0.
+ [Note: I have not checked whether the MPS
+ records and uses If1 -- RHSK 2006-06-12]</p>
+
+<h3>How bad is a bogus exact reference?</h3>
+
+<p>Tucker said:</p>
+<blockquote><p>I believe the collector must be prepared to deal
+ with exact dangling pointers anyways, so this complex
+ mechanism is unnecessary.
+ [<a href="/project/mps/mail/1997/05/12/12-46/1.txt">//info.ravenbrook.com/project/mps/mail/1997/05/12/12-46/1.txt:X-MMInfo-Tag: mail.ptw.1997-05-12.12-46(1)</a>]
+</p></blockquote>
+
+<p>I'm not convinced.</p>
+
+<p>Fixing a bogus exact reference is bad news.
+ The worst case is spoofing:
+ Imagine the bogus exact reference points at part of a
+ JPEG that <em>just happens</em> to look like a validly formatted
+ object.
+ If this JPEG is in the middle of an object in a moving MPS
+ pool, fixing the bogus exact reference will overwrite a portion
+ of the JPEG with a forwarding object.
+ It gets worse: the spoof object is preserved and will later be
+ scanned, producing more bogus exact references!
+ For "JPEG", you can substitute "encrypted string".</p>
+
+<p>The only safe way to cope with such a bogus reference is for
+ Fix to verify that the reference points to the start of a real
+ object, which it could do by iterating the format skip method
+ from some known point in the pool.</p>
+
+<p>The consequences of fixing a bogus exact
+ reference may be:</p>
+<ul>
+ <li> Referent is not in MPS memory:
+ <ul>
+ <li> MPS must detect and ignore these; there should be a
+ debug option to report it;</li>
+ </ul>
+ </li>
+ <li> Referent is not validly formatted:
+ <ul>
+ <li> mutator format code crashes; or</li>
+ <li> mutator format code does something stupid or
+ illegal, and causes corruption or makes MPS crash; or</li>
+ <li> (if we're lucky) mutator format code detects this
+ and avoids any harmful action.</li>
+ </ul>
+ </li>
+ <li> Referent appears validly formatted, but is a spoof
+ (that is, it is actually data inside some other
+ object):
+ <ul>
+ <li> in a moving pool: the object is silently corrupted
+ with a forwarding pointer, and the spoof object is
+ preserved and will later be scanned, producing more
+ bogus exact references!</li>
+ <li> in a non-moving pool: object is safe from corruption,
+ but MPS greying/blackening code needs to be robust to
+ this case.</li>
+ </ul>
+ </li>
+ <li> Referent is a validly formatted but dead object:
+ <ul>
+ <li>it gets needlessly preserved;</li>
+ <li>if it had been dead for some time, this dead object may
+ itself contain bogus exact references, and these will get
+ 'fixed' too.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Also, more arcanely, I wonder whether there's a problem if the
+ referent violates the tri-colour invariant (when scanning at
+ black)? Does the MPS care about this, or does it 'safely' just
+ cause more conservatism? Does MPS detect and flag this in
+ debug versions? Could it?</p>
+
+<p>If MPS or format code detects a bogus exact reference, it could
+ assert, and/or to fix them to a canonical special value.</p>
+
+<p>Some possible contracts between mutator and collector:</p>
+<ol>
+ <li>Mutator and collector promise never to have bogus exact
+ references. The collector is permitted to crash if it
+ encounters one.</li>
+ <li>Mutator agrees that bogus exact references are wrong.
+ But mutator would like a helpful error message, please.
+ (Collector is not permitted to crash).</li>
+ <li>Mutator wants permission to keep bogus exact references
+ in certain circumstances, such as on the stack. Collector
+ must cope safely. Need to specify how this is guaranteed,
+ based on intimate knowledge of the mutator's behaviour.
+ Dodgy.</li>
+ <li>Mutator wants permission to keep bogus exact references
+ in general. Collector must safely cope with all the cases
+ of bogus exact references listed above. I believe the MPS
+ does not currently do this. It would require a very fast
+ check at fix time that the reference is to the start of a
+ valid object in an MPS client pool.</li>
+</ol>
+
+<h3>with exact refs</h3>
+
+<p>For an all-exact mode of use, mutator must make an exact pointer
+before setting I=A, and must keep it at least until it after
+it has read Lc to see whther the commit succeeded.</p>
+
+<p>So, some additions to the AP User's Guide, in the section on mps_reserve:</p>
+
+<blockquote>
+<p>Secondly, "raw data" means that any references TO the new
+ object are treated like other references to unmanaged memory.
+ [.belief.refs-to-uninit-safe:
+ We're 'sure', but I need to check this. What does Fix
+ actually do with a pointer into the init-alloc zone? We
+ hope it ignores it. RHSK 2006-06-09]
+ Because of this, you are permitted to connect the new object
+ into your graph of managed objects immediately. The MPS gives
+ you these guarantees:</p>
+<ul>
+ <li> the new object is pinned (won't move), so references to it
+ that you write in old objects won't become stale at this time
+ (but see <code>mps_commit</code> below!)</li>
+ <li> although the new object is 'reachable' by these references,
+ at this stage (while I < A) the MPS knows it
+ is not yet managed, and will not try to preserve it;</li>
+ <li> the MPS will not call the client's format code to answer
+ questions about the new object.</li>
+</ul>
+</blockquote>
+
+<p>And to the section on mps_commit:</p>
+<blockquote>
+ <p>When this happens the client should take care to clear up any
+ managed references to the (now vanished) new object.</p>
+
+ <p>[But there's a hole here, before the client does this.
+ Are managed (aka scanned) references TO
+ it still safe? They were safe during building
+ (by .belief.refs-to-uninit-safe). But now the AP pointers have
+ gone away. Are they still safe?
+ Clearly, if they are only RankAMBIG, they are safe.
+ What if they are RankEXACT?
+ RHSK 2006-06-09]</p>
+
+ <p>[Discussion with RB 2006-06-09: yes, that's a problem for exact
+ references. Must not make any exact refs to a new object. And
+ unmanaged refs are not sufficient, because they won't preserve the
+ new object during commit. So must make at least one ambiguous
+ ref to new object before calling commit. That's the truth
+ currently. There are various ways to solve this to allow
+ purely-exact mutators. For instance,
+ keep the old init..alloc address-space flagged as a zombie zone,
+ until some communication with mutator (perhaps another reserve
+ from same AP?) indicates that mutator has removed all those
+ pesky exact refs to the now-dead ex-new object. RHSK 2006-06-09]</p>
+</blockquote>
+
+<p>See <a href="unmanaged.html">issues with unmanaged workspace</a> for
+ a discussion of the "abort" phase, which we need to define
+ for allocation points.</p>
+
+<p>The MPS needs to keep the buffer mapped for some time --
+ until the mutator has stopped writing into it.
+ The MPS needs to remember If1 forever.
+ The MPS needs to remember the rest of the
+ about-to-be-detached buffer structure for some time --
+ when is the MPS permitted to detach the buffer?</p>
+
+<p>Keeping the buffer mapped consumes resource.
+ There must be a contract with the mutator about when the
+ MPS is permitted to free it.
+</p>
+
+<p>We could define the protocol such that there is a window:
+ after the mutator discovers that it has lost the race, but
+ while the collector is still remembering that this object
+ is invalid. The mutator could use this window to null-out
+ exact references to the new object.</p>
+
+<p>This window could be after Lc and before calling mps_ap_trip.
+ During this time,
+ the collector must keep the new object as pinned unmanaged
+ memory. By calling mps_ap_trip, the mutator promises that
+ it has nulled-out any exact references to the new object,
+ and the collector in mps_ap_trip may unmap the memory or
+ safely re-use it without fear of spoofing.</p>
+
+<p>Or, we could leave the window open until mps_ap_fill is
+ called. We just need to define it.</p>
+
+<h3>flipping at other times</h3>
+
+<p>Perhaps the collector wants to flip even when the ap is not
+ at (A). Need to analyse synchronization issues here.</p>
+
+<h2><a id="section-B" name="section-B">B. Document History</a></h2>
+
+<pre>
+(As part of GC article)
+ 2006-06-12 RHSK Allocation point internals: Scenario; A mutator with
+ ambiguous references only (to the new object); How
+ bad is a bogus exact reference?; quick notes on: with
+ exact refs; flipping at other times.
+ 2006-06-15 RHSK Allocation Points: clarifications and further notes
+ into User Guide and Internals, including initializing
+ as-yet unused parts of new objects to reduce spoofing.
+ 2006-06-22 RHSK Move rough notes .talk.RB.2006-06-13 etc elsewhere.
+ Make AP User Guide consistently .assume.ambig-workspace,
+ moving notes to APInternals; add Intro and Mistakes;
+ check example code.
+
+(As part of AP User Guide article)
+ 2006-06-22 RHSK Created from GC article.
+
+(This article)
+ 2006-06-23 RHSK Created from AP User Guide article.
+</pre>
+
+
+<h2><a id="section-C" name="section-C">C. Copyright and License</a></h2>
+
+<p> This document is copyright © 2006 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options. </p>
+
+<p> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </p>
+
+<ol>
+
+<li> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </li>
+
+<li> 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. </li>
+
+<li> Redistributions in any form must be accompanied by information on how to obtain complete source code for the 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. </li>
+
+</ol>
+
+<p> <strong> 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. </strong> </p>
+
+
+<hr />
+
+<div class="banner">
+
+<p><code>$Id: //info.ravenbrook.com/project/mps/master/manual/wiki/apinternals.html#1 $</code></p>
+
+<p>
+<a href="/">Ravenbrook</a>
+/ <a href="/project/">Projects</a>
+/ <a href="/project/mps/">Memory Pool System</a>
+/ <a href="/project/mps/master/">Master Product Sources</a>
+/ <a href="/project/mps/master/manual/">Manuals</a>
+/ <a href="/project/mps/master/manual/wiki/">Wiki</a>
+</p>
+
+</div>
+
+</body>
+
+</html>
Added: trunk/mps/manual/wiki/gc.html
==============================================================================
--- (empty file)
+++ trunk/mps/manual/wiki/gc.html Wed Nov 15 07:37:58 2006
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+ <title>MPS Wiki: Garbage Collection</title>
+ <style type = "text/css">
+ <!--
+ div.banner {text-align:center}
+ dt {font-weight:bold}
+
+ -->
+ </style>
+</head>
+
+<body>
+
+<div class="banner">
+
+<p>
+<a href="/">Ravenbrook</a>
+/ <a href="/project/">Projects</a>
+/ <a href="/project/mps/">Memory Pool System</a>
+/ <a href="/project/mps/master/">Master Product Sources</a>
+/ <a href="/project/mps/master/manual/">Manuals</a>
+/ <a href="/project/mps/master/manual/wiki/">Wiki</a>
+</p>
+
+<p><i><a href="/project/mps/">Memory Pool System Project</a></i></p>
+
+<hr />
+
+<h1>MPS Wiki: Garbage Collection</h1>
+
+<address>
+<a href="mailto:rhsk at ravenbrook.com">Richard Kistruck</a>,
+<a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>,
+2006-06-02
+</address>
+
+</div>
+
+<p> This wiki article contains incomplete and informal notes about the MPS, the precursor to more formal documentation. Not confidential. Readership: MPS users and developers. </p>
+
+<p>Notes on getting started with GC -- Garbage Collection.</p>
+
+<h2>Introduction</h2>
+
+<h3>The essential MPS concepts for GC are:</h3>
+<dl>
+ <dt> <a href="#Format">Format↓</a></dt>
+ <dd> lets the MPS ask the client a question about an object;</dd>
+
+ <dt> <a href="#Root">Root↓</a></dt>
+ <dd> tell the MPS which things (eg. stack, globals) are always alive.</dd>
+</dl>
+
+<h3>The advanced MPS concepts for GC are:</h3>
+<dl>
+ <dt> Allocation Point
+ (see <a href="apguide.html">user's guide</a>)</dt>
+ <dd> reserve memory, build a new object, and commit
+ it to MPS management.
+ </dd>
+
+ <dt> <a href="#Protection">Protection and incremental collection↓</a></dt>
+ <dd> MPS sets operating-system read- or write-barriers on certain
+ pages. When client tries to use this protected memory, the MPS
+ interrupts and does just enough garbage-collection to allow the
+ client to see this page.
+ </dd>
+</dl>
+
+
+<h2><a id="Format">Format</a></h2>
+
+<p>The client can choose how to format its objects, but the MPS will
+sometimes need to ask the client some questions about an object, such
+as:</p>
+<ul>
+ <li> how big is it? (so that if it is dead the MPS collects only that
+ object)</li>
+ <li> what pointers does it contain? (so the MPS can mark referred-to
+ objects as still alive)</li>
+</ul>
+
+<p>For each type of question, the client must provide a function that gives
+the answer. These functions are called "format methods", and are
+collected together into a "format"
+(mps_fmt_t). Usually the client developer writes these functions,
+calls "<code>mps_fmt_create_...</code>" to
+collect them into a format, and passes this format to the MPS as an
+argument to <code>mps_pool_create()</code>.</p>
+
+<p>A client's format code is 'special'. It is called at special times (eg.
+when handling an interrupt), and is quite restricted in what it is
+allowed to do. Format code is often on the critical path for memory
+management operations. The full requirement for a format is
+complicated; see documentation in the Reference Manual. But
+here's a simplified overview:</p>
+
+<p>No format is required for an object in a non-scanned, non-collectable
+pool -- the MPS never needs to know the internal details of objects in
+these pools.</p>
+
+<p>For collectable and/or scannable pools, the client's format code
+generally needs to support three types of object:</p>
+<ol>
+ <li> the client's own initialized objects;</li>
+ <li> on behalf of the MPS, a "forwarding object";</li>
+ <li> on behalf of the MPS, a "padding object".</li>
+</ol>
+
+<p>A forwarding object is a placeholder that the MPS uses when it has moved
+the object that used to be there. ('Normal' client code never sees
+these forwarding objects; only client format code does).</p>
+
+<p>A padding object is a 'dummy' object that the MPS uses when there is not
+enough room (eg. at the end of a memory page) to put a real client
+object.</p>
+
+<p>The client must be able to distinguish between these three types
+of object. To guarantee this, client code MUST initialize
+memory obtained from the MPS (by mps_alloc or mps_reserve) BEFORE it
+makes any other call into the MPS from that thread (including the call to
+mps_commit). Here, "initialize" means at least enough initialization
+that the client's format code handles the object correctly, including
+whether it is a client object, a forwarding object, or a padding object.
+[See also protocol.mps.format.rel.ap. RHSK 2006-06-02]</p>
+
+<h3><a id="format-methods">The most important format methods are:</a></h3>
+
+<p>Indicate the size of a collectable client object:</p>
+<ul>
+ <li> Skip (see <a href="../reference/index.html#mps_fmt_skip_t">mps_fmt_skip_t</a>):
+ client must tell the MPS how big this object is.</li>
+</ul>
+
+<p>List all references from this object to (other) collectable objects:</p>
+<ul>
+ <li> Scan (see <a href="../reference/index.html#mps_fmt_scan_t">mps_fmt_scan_t</a>):
+ client must 'scan' the object for pointers, and tell
+ the MPS to 'fix' each pointer it finds;</li>
+</ul>
+
+<p>Move this client object (obsolete, see below):</p>
+<ul>
+ <li> Copy (obsolete) (see <a href="../reference/index.html#mps_fmt_copy_t">mps_fmt_copy_t</a>):
+ client must copy the object to a new location.</li>
+</ul>
+
+<p>Create/use a forwarding object (used by an incremental moving pool after moving a client object):</p>
+<ul>
+ <li> Fwd (see <a href="../reference/index.html#mps_fmt_fwd_t">mps_fmt_fwd_t</a>):
+ client must create a forwarding object here, and store
+ the supplied forwarding pointer in it;</li>
+ <li> IsFwd (see <a href="../reference/index.html#mps_fmt_isfwd_t">mps_fmt_isfwd_t</a>):
+ client must test whether this is a forwarding object
+ (created by the Fwd method), and if so return the
+ forwarding pointer stored in it. (This is how the
+ MPS remembers where a moved object was moved to).</li>
+</ul>
+
+<p>Create a padding object:</p>
+<ul>
+ <li> Pad (see <a href="../reference/index.html#mps_fmt_pad_t">mps_fmt_pad_t</a>):
+ create a padding object here, please.</li>
+</ul>
+
+<h3><a id="format-methods-copy-is-obsolete">Format Methods: the Copy method is obsolete</a></h3>
+
+<p>The Copy method is obsolete, and is never called. The MPS just uses
+<code>mps_lib_memcpy()</code> to copy the bytes to the new location.
+It knows how many bytes to copy by using the Skip method.</p>
+
+<p>Historical notes: The original justification for Copy was:</p>
+<ul>
+ <li> client (knowing the object's data fields) might intelligently
+ copy less than all the bytes;</li>
+ <li> client might alter the data, eg. fixing-up internal pointers.</li>
+</ul>
+<p>... but this didn't happen with actual clients, and the interface
+to the copy method didn't pass the skip-size (which the MPS has
+already determined by calling Skip) and so didn't allow an efficient
+copy method to be written. So it was dropped, in 1998 or earlier.
+The only place this memcpy currently occurs is in poolamc.c, in
+AMCFix() (and now AMCHeaderFix() too).</p>
+
+<p>There are notes on this change at
+<a href="../../design/trace/#fix.nocopy">design/trace/#fix.nocopy</a>.</p>
+
+<h3><a id="format-variants">Format Variants</a></h3>
+
+<p>There are several different ways to package-up the format methods -- these different ways are called 'variants'. MPS currently supports four format variants. The creation functions for these are:</p>
+<ul>
+ <li> <a href="../reference/index.html#mps_fmt_create_A">mps_fmt_create_A</a>;</li>
+ <li> <a href="../reference/index.h