From feaa22a74fb4cdb43acf53d7870553032f779c7a Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 22:43:58 +0100 Subject: [PATCH 01/24] Remove unnecessary calls to mps_args_done -- these crept back in via the merge of the cbs-tract-alloc branch. Copied from Perforce Change: 185143 ServerID: perforce.ravenbrook.com --- mps/code/apss.c | 1 - mps/code/arena.c | 6 ++---- mps/code/locbwcss.c | 1 - mps/code/locusss.c | 1 - mps/code/mv2test.c | 1 - mps/code/sacss.c | 1 - 6 files changed, 2 insertions(+), 9 deletions(-) diff --git a/mps/code/apss.c b/mps/code/apss.c index 6e4c7f3a71b..3a60587d412 100644 --- a/mps/code/apss.c +++ b/mps/code/apss.c @@ -186,7 +186,6 @@ int main(int argc, char *argv[]) MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 2 * testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); - MPS_ARGS_DONE(args); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); diff --git a/mps/code/arena.c b/mps/code/arena.c index d5833c65441..749208aeee2 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -1,7 +1,7 @@ /* arena.c: ARENA ALLOCATION FEATURES * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .sources: is the main design document. */ @@ -224,7 +224,6 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct)); MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, arena->alignment); MPS_ARGS_ADD(piArgs, MFSExtendSelf, FALSE); - MPS_ARGS_DONE(piArgs); res = PoolInit(ArenaCBSBlockPool(arena), arena, PoolClassMFS(), piArgs); } MPS_ARGS_END(piArgs); AVER(res == ResOK); /* no allocation, no failure expected */ @@ -234,7 +233,6 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) /* Initialise the freeCBS. */ MPS_ARGS_BEGIN(cbsiArgs) { MPS_ARGS_ADD(cbsiArgs, CBSBlockPool, ArenaCBSBlockPool(arena)); - MPS_ARGS_DONE(cbsiArgs); res = CBSInit(ArenaFreeCBS(arena), arena, arena, alignment, /* fastFind */ TRUE, arena->zoned, cbsiArgs); } MPS_ARGS_END(cbsiArgs); @@ -1321,7 +1319,7 @@ Res ArenaAddrObject(Addr *pReturn, Arena arena, Addr addr) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/locbwcss.c b/mps/code/locbwcss.c index e37f59cbc30..0e40c254635 100644 --- a/mps/code/locbwcss.c +++ b/mps/code/locbwcss.c @@ -197,7 +197,6 @@ int main(int argc, char *argv[]) MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); - MPS_ARGS_DONE(args); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); diff --git a/mps/code/locusss.c b/mps/code/locusss.c index 22a35ab6e4e..3dfbc78afe1 100644 --- a/mps/code/locusss.c +++ b/mps/code/locusss.c @@ -220,7 +220,6 @@ static void runArenaTest(size_t size, MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); - MPS_ARGS_DONE(args); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); diff --git a/mps/code/mv2test.c b/mps/code/mv2test.c index 37435dfc7fd..40d53d0589f 100644 --- a/mps/code/mv2test.c +++ b/mps/code/mv2test.c @@ -173,7 +173,6 @@ static void stress_with_arena_class(mps_arena_class_t aclass, Bool zoned) MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, zoned); - MPS_ARGS_DONE(args); die(mps_arena_create_k(&arena, aclass, args), "mps_arena_create"); } MPS_ARGS_END(args); diff --git a/mps/code/sacss.c b/mps/code/sacss.c index d2300de1898..91f951524fc 100644 --- a/mps/code/sacss.c +++ b/mps/code/sacss.c @@ -185,7 +185,6 @@ int main(int argc, char *argv[]) MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); - MPS_ARGS_DONE(args); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); From 6ef4b6e0c6a94da7e9512abf160ea4bd24a4e19d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 11:49:19 +0100 Subject: [PATCH 02/24] Explain how to call mps_root_create_table() safely (avoiding type punning). fix example for mps_root_create_table_masked(). use the recommended approach in qs.c. Copied from Perforce Change: 185223 ServerID: perforce.ravenbrook.com --- mps/code/qs.c | 5 +---- mps/manual/source/guide/lang.rst | 4 ++++ mps/manual/source/topic/interface.rst | 8 ++++---- mps/manual/source/topic/root.rst | 28 ++++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/mps/code/qs.c b/mps/code/qs.c index 2ccc9423184..31005b4fc9b 100644 --- a/mps/code/qs.c +++ b/mps/code/qs.c @@ -334,7 +334,6 @@ static void *go(void *p, size_t s) mps_fmt_t format; mps_chain_t chain; mps_addr_t base; - mps_addr_t *addr; testlib_unused(p); testlib_unused(s); @@ -357,9 +356,7 @@ static void *go(void *p, size_t s) "RootCreateTable"); base = &activationStack; - addr = base; - die(mps_root_create_table(&actroot, arena, mps_rank_ambig(), 0, - addr, sizeof(QSCell)/sizeof(mps_addr_t)), + die(mps_root_create_table(&actroot, arena, mps_rank_ambig(), 0, base, 1), "RootCreateTable"); /* makes a random list */ diff --git a/mps/manual/source/guide/lang.rst b/mps/manual/source/guide/lang.rst index 3b71f61ff20..916782424d5 100644 --- a/mps/manual/source/guide/lang.rst +++ b/mps/manual/source/guide/lang.rst @@ -905,6 +905,10 @@ changes size:: 3. The order of operations at the end is important: the old root must be de-registered before its memory is freed. + 4. When calling :c:func:`mps_root_create_table`, take care to + avoid undefined behaviour due to :term:`type punning`. See the + :ref:`warning `. + .. topics:: :ref:`topic-root`. diff --git a/mps/manual/source/topic/interface.rst b/mps/manual/source/topic/interface.rst index eb3d0dcfeca..478c22b8026 100644 --- a/mps/manual/source/topic/interface.rst +++ b/mps/manual/source/topic/interface.rst @@ -205,11 +205,11 @@ Instead, we recommend this approach:: struct foo *fp; res = mps_alloc(&p, pool, sizeof(struct foo)); if(res) /* handle error case */; - fp = (struct foo *)p; + fp = p; -This is portable because conversion from ``void *`` to any other -:term:`object pointer` type is defined by :ref:`ISO/IEC 9899:1990 -` §6.3.2.3.1. +This has defined behaviour because conversion from ``void *`` to any +other :term:`object pointer` type is defined by :ref:`ISO/IEC +9899:1990 ` §6.3.2.3.1. .. index:: diff --git a/mps/manual/source/topic/root.rst b/mps/manual/source/topic/root.rst index efc87fb8e45..8fbe0dc2e68 100644 --- a/mps/manual/source/topic/root.rst +++ b/mps/manual/source/topic/root.rst @@ -514,6 +514,28 @@ Root interface The registered root description persists until it is destroyed by calling :c:func:`mps_root_destroy`. + .. _topic-root-type-pun: + + .. warning:: + + The ``base`` argument has type ``mps_addr_t *`` (a typedef for + ``void **``) but the table of references most likely has some + other pointer type, ``my_object *`` say. It is tempting to + write:: + + mps_root_create_table(..., (mps_addr_t *)my_table, ...) + + but this is :term:`type punning`, and its behaviour is not + defined in ANSI/ISO Standard C. (GCC and Clang have a warning + flag ``-Wstrict-aliasing`` which detects some errors of this + form.) + + To ensure well-defined behaviour, the pointer must be + converted via ``void *`` (or via :c:type:`mps_addr_t`, which + is a typedef for ``void *``), like this:: + + mps_addr_t base = my_table; + mps_root_create_table(..., base, ...) .. c:function:: mps_res_t mps_root_create_table_masked(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_addr_t *base, size_t count, mps_word_t mask) @@ -558,13 +580,17 @@ Root interface mps_res_t res; mps_root_t root; + mps_addr_t base = symtab; res = mps_root_create_table_masked(&root, arena, mps_rank_exact(), (mps_rm_t)0, - symtab, symtab_size * 2, + base, symtab_size * 2, (mps_word_t)TAG_MASK); if (res != MPS_RES_OK) errror("can't create symtab root"); + .. warning:: + + See the warning for :c:func:`mps_root_create_table` above. .. c:function:: void mps_root_destroy(mps_root_t root) From 55931db9142a7731c6a199629ac34e1fde48c2e2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 11:49:33 +0100 Subject: [PATCH 03/24] Improve wording. Copied from Perforce Change: 185224 ServerID: perforce.ravenbrook.com --- mps/manual/source/topic/finalization.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/manual/source/topic/finalization.rst b/mps/manual/source/topic/finalization.rst index 0f1d1d908ed..32f618f19e7 100644 --- a/mps/manual/source/topic/finalization.rst +++ b/mps/manual/source/topic/finalization.rst @@ -157,7 +157,7 @@ Cautions prompt release of scarce resources. For example, Scheme provides the ``(with-input-from-file)`` procedure which specifies that the created port has :term:`dynamic extent` (and so can be closed as - soon as the procedure exits). + soon as the procedure exits, even if it is still reachable). #. The MPS does not finalize objects in the context of :c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`. @@ -185,8 +185,8 @@ Cautions described under :c:func:`mps_pool_destroy`, but the objects do not get finalized. - The only reliable way to ensure that all finalizable object - gets finalized is to maintain a table of :term:`weak + The only reliable way to ensure that all finalizable objects + are finalized is to maintain a table of :term:`weak references (1)` to all such objects. The weak references don't prevent the objects from being finalized, but you can iterate over the list at an appropriate point and finalize any From 94e3fff083eed4833b6e8547dc1be822397e4aa6 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 12:16:59 +0100 Subject: [PATCH 04/24] Turn on -wswitch-default for gcc. Add missing default: cases to switch statements. Copied from Perforce Change: 185226 ServerID: perforce.ravenbrook.com --- mps/code/eventcnv.c | 3 +++ mps/code/fbmtest.c | 23 ++++++++++++----------- mps/code/gc.gmk | 1 + mps/code/gcbench.c | 8 ++++++-- mps/code/mpsicv.c | 5 +++-- mps/code/prmci3li.c | 9 +++++---- mps/code/prmci3w3.c | 9 +++++---- mps/code/prmci3xc.c | 9 +++++---- mps/code/prmci6li.c | 9 +++++---- mps/code/prmci6w3.c | 9 +++++---- mps/code/prmci6xc.c | 9 +++++---- mps/code/sacss.c | 18 +++++++++--------- 12 files changed, 64 insertions(+), 48 deletions(-) diff --git a/mps/code/eventcnv.c b/mps/code/eventcnv.c index 82fef956eba..355b6efa2a2 100644 --- a/mps/code/eventcnv.c +++ b/mps/code/eventcnv.c @@ -264,6 +264,9 @@ static void readLog(FILE *stream) event->EventInit.f5, MPS_WORD_WIDTH); break; + default: + /* No special treatment needed. */ + break; } (void)EVENT_CLOCK_PRINT(stdout, eventTime); diff --git a/mps/code/fbmtest.c b/mps/code/fbmtest.c index f98c49032a9..2b6437c216d 100644 --- a/mps/code/fbmtest.c +++ b/mps/code/fbmtest.c @@ -432,20 +432,23 @@ static void find(FBMState state, Size size, Bool high, FindDelete findDelete) remainderLimit = origLimit = addrOfIndex(state, expectedLimit); switch(findDelete) { - case FindDeleteNONE: { + case FindDeleteNONE: /* do nothing */ - } break; - case FindDeleteENTIRE: { + break; + case FindDeleteENTIRE: remainderBase = remainderLimit; - } break; - case FindDeleteLOW: { + break; + case FindDeleteLOW: expectedLimit = expectedBase + size; remainderBase = addrOfIndex(state, expectedLimit); - } break; - case FindDeleteHIGH: { + break; + case FindDeleteHIGH: expectedBase = expectedLimit - size; remainderLimit = addrOfIndex(state, expectedBase); - } break; + break; + default: + cdie(0, "invalid findDelete"); + break; } if (findDelete != FindDeleteNONE) { @@ -528,9 +531,7 @@ static void test(FBMState state, unsigned n) { size = fbmRnd(ArraySize / 10) + 1; high = fbmRnd(2) ? TRUE : FALSE; switch(fbmRnd(6)) { - case 0: - case 1: - case 2: findDelete = FindDeleteNONE; break; + default: findDelete = FindDeleteNONE; break; case 3: findDelete = FindDeleteLOW; break; case 4: findDelete = FindDeleteHIGH; break; case 5: findDelete = FindDeleteENTIRE; break; diff --git a/mps/code/gc.gmk b/mps/code/gc.gmk index 608ced354b0..826cb0ef659 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -25,6 +25,7 @@ CFLAGSCOMPILER := \ -Wshadow \ -Wstrict-aliasing=2 \ -Wstrict-prototypes \ + -Wswitch-default \ -Wwrite-strings CFLAGSCOMPILERSTRICT := -ansi -pedantic diff --git a/mps/code/gcbench.c b/mps/code/gcbench.c index 214636649f1..61b6e925e94 100644 --- a/mps/code/gcbench.c +++ b/mps/code/gcbench.c @@ -331,8 +331,8 @@ int main(int argc, char *argv[]) { double mort = 0.0; cap = (size_t)strtoul(optarg, &p, 10); switch(toupper(*p)) { - case 'G': cap *= 1024; - case 'M': cap *= 1024; + case 'G': cap *= 1024; /* fall through */ + case 'M': cap *= 1024; /* fall through */ case 'K': p++; break; default: cap = 0; break; } @@ -356,6 +356,10 @@ int main(int argc, char *argv[]) { case 'G': arenasize *= 1024; case 'M': arenasize *= 1024; case 'K': arenasize *= 1024; break; + case '\0': break; + default: + fprintf(stderr, "Bad arena size %s\n", optarg); + return EXIT_FAILURE; } } break; diff --git a/mps/code/mpsicv.c b/mps/code/mpsicv.c index cba8a69f300..a4d8c3750b5 100644 --- a/mps/code/mpsicv.c +++ b/mps/code/mpsicv.c @@ -516,7 +516,8 @@ static void *test(void *arg, size_t s) if (rnd() % patternFREQ == 0) { switch(rnd() % 4) { - case 0: case 1: + case 0: /* fall through */ + case 1: die(mps_ap_alloc_pattern_begin(ap, ramp), "alloc_pattern_begin"); ++rampCount; break; @@ -528,7 +529,7 @@ static void *test(void *arg, size_t s) --rampCount; } break; - case 3: + default: die(mps_ap_alloc_pattern_reset(ap), "alloc_pattern_reset"); rampCount = 0; break; diff --git a/mps/code/prmci3li.c b/mps/code/prmci3li.c index 8d1b409e2dc..6a36ae7db2b 100644 --- a/mps/code/prmci3li.c +++ b/mps/code/prmci3li.c @@ -1,7 +1,7 @@ /* prmci3li.c: PROTECTION MUTATOR CONTEXT INTEL 386 (LINUX) * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This module implements the part of the protection module * that decodes the MutatorFaultContext. @@ -57,9 +57,10 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) case 5: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EBP]); case 6: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ESI]); case 7: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EDI]); + default: + NOTREACHED; + return NULL; /* Avoids compiler warning. */ } - NOTREACHED; - return (MRef)NULL; /* Avoids compiler warning. */ } @@ -107,7 +108,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/prmci3w3.c b/mps/code/prmci3w3.c index f3d2e2386cc..4cf9584c988 100644 --- a/mps/code/prmci3w3.c +++ b/mps/code/prmci3w3.c @@ -1,7 +1,7 @@ /* prmci3w3.c: PROTECTION MUTATOR CONTEXT INTEL 386 (Win32) * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * PURPOSE * @@ -46,9 +46,10 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext context, unsigned int regnum) case 5: return (MRef)&wincont->Ebp; case 6: return (MRef)&wincont->Esi; case 7: return (MRef)&wincont->Edi; + default: + NOTREACHED; + return NULL; /* suppress warning */ } - NOTREACHED; - return NULL; /* suppress warning */ } @@ -80,7 +81,7 @@ void Prmci3StepOverIns(MutatorFaultContext context, Size inslen) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/prmci3xc.c b/mps/code/prmci3xc.c index b08ee3a1c4c..786145fc084 100644 --- a/mps/code/prmci3xc.c +++ b/mps/code/prmci3xc.c @@ -1,7 +1,7 @@ /* prmci3xc.c: PROTECTION MUTATOR CONTEXT INTEL 386 (MAC OS X) * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This module implements the part of the protection module * that decodes the MutatorFaultContext. @@ -55,9 +55,10 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) case 5: return (MRef)((char *)&mfc->threadState->__ebp); case 6: return (MRef)((char *)&mfc->threadState->__esi); case 7: return (MRef)((char *)&mfc->threadState->__edi); + default: + NOTREACHED; + return NULL; /* Avoids compiler warning. */ } - NOTREACHED; - return (MRef)NULL; /* Avoids compiler warning. */ } @@ -104,7 +105,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/prmci6li.c b/mps/code/prmci6li.c index 9c15fcdf6ff..2f8bf9afc62 100644 --- a/mps/code/prmci6li.c +++ b/mps/code/prmci6li.c @@ -1,7 +1,7 @@ /* prmci6li.c: PROTECTION MUTATOR CONTEXT x64 (LINUX) * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This module implements the part of the protection module * that decodes the MutatorFaultContext. @@ -61,9 +61,10 @@ MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) case 13: return &gregs[REG_R13]; case 14: return &gregs[REG_R14]; case 15: return &gregs[REG_R15]; + default: + NOTREACHED; + return NULL; /* Avoids compiler warning. */ } - NOTREACHED; - return (MRef)NULL; /* Avoids compiler warning. */ } @@ -111,7 +112,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/prmci6w3.c b/mps/code/prmci6w3.c index 8faca025450..81641c00526 100644 --- a/mps/code/prmci6w3.c +++ b/mps/code/prmci6w3.c @@ -1,7 +1,7 @@ /* prmci6w3.c: PROTECTION MUTATOR CONTEXT INTEL 386 (Win32) * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * PURPOSE * @@ -52,9 +52,10 @@ MRef Prmci6AddressHoldingReg(MutatorFaultContext context, unsigned int regnum) case 13: return (MRef)&wincont->R13; case 14: return (MRef)&wincont->R14; case 15: return (MRef)&wincont->R15; + default: + NOTREACHED; + return NULL; /* suppress warning */ } - NOTREACHED; - return NULL; /* suppress warning */ } @@ -86,7 +87,7 @@ void Prmci6StepOverIns(MutatorFaultContext context, Size inslen) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/prmci6xc.c b/mps/code/prmci6xc.c index f3d0413d1a6..02ccb840b6c 100644 --- a/mps/code/prmci6xc.c +++ b/mps/code/prmci6xc.c @@ -1,7 +1,7 @@ /* prmci6xc.c: PROTECTION MUTATOR CONTEXT x64 (MAC OS X) * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This module implements the part of the protection module * that decodes the MutatorFaultContext. @@ -58,9 +58,10 @@ MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) case 13: return (MRef)((char *)&mfc->threadState->__r13); case 14: return (MRef)((char *)&mfc->threadState->__r14); case 15: return (MRef)((char *)&mfc->threadState->__r15); + default: + NOTREACHED; + return NULL; /* Avoids compiler warning. */ } - NOTREACHED; - return (MRef)NULL; /* Avoids compiler warning. */ } @@ -107,7 +108,7 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/sacss.c b/mps/code/sacss.c index 91f951524fc..ee86c83989d 100644 --- a/mps/code/sacss.c +++ b/mps/code/sacss.c @@ -94,26 +94,26 @@ static mps_res_t stress(mps_class_t class, /* upper half, as when allocating them again we want smaller objects */ /* see randomSize() */ switch (k % 2) { - case 0: { + case 0: for (i=testSetSIZE/2; i Date: Fri, 4 Apr 2014 12:51:07 +0100 Subject: [PATCH 05/24] Check classes after defining them. Copied from Perforce Change: 185228 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 1 + mps/code/arenacl.c | 5 +++-- mps/code/arenavm.c | 1 + mps/code/buffer.c | 7 +++++-- mps/code/fotest.c | 1 + mps/code/poolabs.c | 10 ++++++++-- mps/code/poolamc.c | 4 ++++ mps/code/poolams.c | 7 +++++-- mps/code/poolawl.c | 6 ++++-- mps/code/poollo.c | 6 ++++-- mps/code/poolmfs.c | 5 +++-- mps/code/poolmrg.c | 7 +++++-- mps/code/poolmv.c | 6 ++++-- mps/code/poolmv2.c | 5 +++-- mps/code/poolmvff.c | 6 ++++-- mps/code/pooln.c | 5 +++-- mps/code/poolsnc.c | 7 +++++-- mps/code/protocol.c | 7 ++++--- mps/code/reserv.c | 5 +++-- mps/code/seg.c | 6 ++++-- mps/code/segsmss.c | 2 ++ 21 files changed, 76 insertions(+), 33 deletions(-) diff --git a/mps/code/arena.c b/mps/code/arena.c index 749208aeee2..4f8c465e1ae 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -79,6 +79,7 @@ DEFINE_CLASS(AbstractArenaClass, class) class->describe = ArenaTrivDescribe; class->pagesMarkAllocated = NULL; class->sig = ArenaClassSig; + AVERT(ArenaClass, class); } diff --git a/mps/code/arenacl.c b/mps/code/arenacl.c index e900a3b4dbf..2f954032203 100644 --- a/mps/code/arenacl.c +++ b/mps/code/arenacl.c @@ -1,7 +1,7 @@ /* arenacl.c: ARENA CLASS USING CLIENT MEMORY * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .design: See . * @@ -434,6 +434,7 @@ DEFINE_ARENA_CLASS(ClientArenaClass, this) this->free = ClientFree; this->chunkInit = ClientChunkInit; this->chunkFinish = ClientChunkFinish; + AVERT(ArenaClass, this); } @@ -447,7 +448,7 @@ mps_arena_class_t mps_arena_class_cl(void) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index d37fb96c485..03a3af2f3a2 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -1159,6 +1159,7 @@ DEFINE_ARENA_CLASS(VMArenaClass, this) this->compact = VMCompact; this->describe = VMArenaDescribe; this->pagesMarkAllocated = VMPagesMarkAllocated; + AVERT(ArenaClass, this); } diff --git a/mps/code/buffer.c b/mps/code/buffer.c index c63310980ee..51b4ba58299 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -1,7 +1,7 @@ /* buffer.c: ALLOCATION BUFFER IMPLEMENTATION * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This is (part of) the implementation of allocation buffers. * Several macros which also form part of the implementation are in @@ -1220,6 +1220,7 @@ DEFINE_CLASS(BufferClass, class) class->setRankSet = bufferNoSetRankSet; class->reassignSeg = bufferNoReassignSeg; class->sig = BufferClassSig; + AVERT(BufferClass, class); } @@ -1472,6 +1473,7 @@ DEFINE_CLASS(SegBufClass, class) class->rankSet = segBufRankSet; class->setRankSet = segBufSetRankSet; class->reassignSeg = segBufReassignSeg; + AVERT(BufferClass, class); } @@ -1532,12 +1534,13 @@ DEFINE_CLASS(RankBufClass, class) class->name = "RANKBUF"; class->varargs = rankBufVarargs; class->init = rankBufInit; + AVERT(BufferClass, class); } /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/fotest.c b/mps/code/fotest.c index 4025d20a2c6..3fecb81e5ec 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -60,6 +60,7 @@ DEFINE_POOL_CLASS(OOMPoolClass, this) { INHERIT_CLASS(this, AbstractAllocFreePoolClass); this->alloc = OOMAlloc; + AVERT(PoolClass, this); } diff --git a/mps/code/poolabs.c b/mps/code/poolabs.c index af355577cc5..27aa767d940 100644 --- a/mps/code/poolabs.c +++ b/mps/code/poolabs.c @@ -1,7 +1,7 @@ /* poolabs.c: ABSTRACT POOL CLASSES * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * * PURPOSE @@ -151,36 +151,42 @@ DEFINE_CLASS(AbstractPoolClass, class) class->debugMixin = PoolNoDebugMixin; class->labelled = FALSE; class->sig = PoolClassSig; + AVERT(PoolClass, class); } DEFINE_CLASS(AbstractAllocFreePoolClass, class) { INHERIT_CLASS(class, AbstractPoolClass); PoolClassMixInAllocFree(class); + AVERT(PoolClass, class); } DEFINE_CLASS(AbstractBufferPoolClass, class) { INHERIT_CLASS(class, AbstractPoolClass); PoolClassMixInBuffer(class); + AVERT(PoolClass, class); } DEFINE_CLASS(AbstractSegBufPoolClass, class) { INHERIT_CLASS(class, AbstractBufferPoolClass); class->bufferClass = SegBufClassGet; + AVERT(PoolClass, class); } DEFINE_CLASS(AbstractScanPoolClass, class) { INHERIT_CLASS(class, AbstractSegBufPoolClass); PoolClassMixInScan(class); + AVERT(PoolClass, class); } DEFINE_CLASS(AbstractCollectPoolClass, class) { INHERIT_CLASS(class, AbstractScanPoolClass); PoolClassMixInCollect(class); + AVERT(PoolClass, class); } @@ -677,7 +683,7 @@ BufferClass PoolNoBufferClass(void) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 4e479266b7d..e568b7adb53 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -370,6 +370,7 @@ DEFINE_SEG_CLASS(amcSegClass, class) class->size = sizeof(amcSegStruct); class->init = AMCSegInit; class->describe = AMCSegDescribe; + AVERT(SegClass, class); } @@ -691,6 +692,7 @@ DEFINE_BUFFER_CLASS(amcBufClass, class) class->size = sizeof(amcBufStruct); class->init = AMCBufInit; class->finish = AMCBufFinish; + AVERT(BufferClass, class); } @@ -2509,6 +2511,7 @@ DEFINE_POOL_CLASS(AMCPoolClass, this) this->walk = AMCWalk; this->bufferClass = amcBufClassGet; this->describe = AMCDescribe; + AVERT(PoolClass, this); } @@ -2522,6 +2525,7 @@ DEFINE_POOL_CLASS(AMCZPoolClass, this) this->init = AMCZInit; this->grey = PoolNoGrey; this->scan = PoolNoScan; + AVERT(PoolClass, this); } diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 8937a09113d..f463aed2e84 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -1,7 +1,7 @@ /* poolams.c: AUTOMATIC MARK & SWEEP POOL CLASS * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (c) 2002 Global Graphics Software. * * @@ -609,6 +609,7 @@ DEFINE_CLASS(AMSSegClass, class) class->merge = AMSSegMerge; class->split = AMSSegSplit; class->describe = AMSSegDescribe; + AVERT(SegClass, class); } @@ -1686,6 +1687,7 @@ DEFINE_CLASS(AMSPoolClass, this) this->reclaim = AMSReclaim; this->freewalk = AMSFreeWalk; this->describe = AMSDescribe; + AVERT(PoolClass, this); } @@ -1713,6 +1715,7 @@ DEFINE_POOL_CLASS(AMSDebugPoolClass, this) this->size = sizeof(AMSDebugStruct); this->varargs = AMSDebugVarargs; this->debugMixin = AMSDebugMixin; + AVERT(PoolClass, this); } @@ -1740,7 +1743,7 @@ Bool AMSCheck(AMS ams) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 83890b34b6e..1ca13d5346f 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -1,7 +1,7 @@ /* poolawl.c: AUTOMATIC WEAK LINKED POOL CLASS * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * * DESIGN @@ -288,6 +288,7 @@ DEFINE_SEG_CLASS(AWLSegClass, class) class->size = sizeof(AWLSegStruct); class->init = AWLSegInit; class->finish = AWLSegFinish; + AVERT(SegClass, class); } @@ -1280,6 +1281,7 @@ DEFINE_POOL_CLASS(AWLPoolClass, this) this->fixEmergency = AWLFix; this->reclaim = AWLReclaim; this->walk = AWLWalk; + AVERT(PoolClass, this); } @@ -1307,7 +1309,7 @@ static Bool AWLCheck(AWL awl) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poollo.c b/mps/code/poollo.c index f81ab6a1815..eef07aee89a 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -1,7 +1,7 @@ /* poollo.c: LEAF POOL CLASS * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * DESIGN * @@ -73,6 +73,7 @@ DEFINE_SEG_CLASS(LOSegClass, class) class->size = sizeof(LOSegStruct); class->init = loSegInit; class->finish = loSegFinish; + AVERT(SegClass, class); } @@ -793,6 +794,7 @@ DEFINE_POOL_CLASS(LOPoolClass, this) this->fixEmergency = LOFix; this->reclaim = LOReclaim; this->walk = LOWalk; + AVERT(PoolClass, this); } @@ -821,7 +823,7 @@ static Bool LOCheck(LO lo) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 0149da55ee0..80183b42b52 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -1,7 +1,7 @@ /* poolmfs.c: MANUAL FIXED SMALL UNIT POOL * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * This is the implementation of the MFS pool class. * @@ -347,6 +347,7 @@ DEFINE_POOL_CLASS(MFSPoolClass, this) this->alloc = MFSAlloc; this->free = MFSFree; this->describe = MFSDescribe; + AVERT(PoolClass, this); } @@ -385,7 +386,7 @@ Bool MFSCheck(MFS mfs) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c index c945029a9db..271b881bfb2 100644 --- a/mps/code/poolmrg.c +++ b/mps/code/poolmrg.c @@ -1,7 +1,7 @@ /* poolmrg.c: MANUAL RANK GUARDIAN POOL * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * * @@ -302,6 +302,7 @@ DEFINE_SEG_CLASS(MRGLinkSegClass, class) class->name = "MRGLSEG"; class->size = sizeof(MRGLinkSegStruct); class->init = MRGLinkSegInit; + AVERT(SegClass, class); } @@ -314,6 +315,7 @@ DEFINE_SEG_CLASS(MRGRefSegClass, class) class->name = "MRGRSEG"; class->size = sizeof(MRGRefSegStruct); class->init = MRGRefSegInit; + AVERT(SegClass, class); } @@ -862,6 +864,7 @@ DEFINE_POOL_CLASS(MRGPoolClass, this) this->blacken = PoolTrivBlacken; this->scan = MRGScan; this->describe = MRGDescribe; + AVERT(PoolClass, this); } @@ -873,7 +876,7 @@ PoolClass PoolClassMRG(void) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolmv.c b/mps/code/poolmv.c index 9acd64380f6..88d96cf950e 100644 --- a/mps/code/poolmv.c +++ b/mps/code/poolmv.c @@ -1,7 +1,7 @@ /* poolmv.c: MANUAL VARIABLE POOL * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * * **** RESTRICTION: This pool may not allocate from the arena control @@ -792,6 +792,7 @@ DEFINE_POOL_CLASS(MVPoolClass, this) this->alloc = MVAlloc; this->free = MVFree; this->describe = MVDescribe; + AVERT(PoolClass, this); } @@ -811,6 +812,7 @@ DEFINE_POOL_CLASS(MVDebugPoolClass, this) this->size = sizeof(MVDebugStruct); this->varargs = MVDebugVarargs; this->debugMixin = MVDebugMixin; + AVERT(PoolClass, this); } @@ -901,7 +903,7 @@ Bool MVCheck(MV mv) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index d9d063dc39e..c98dab21459 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -1,7 +1,7 @@ /* poolmv2.c: MANUAL VARIABLE-SIZED TEMPORAL POOL * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: A manual-variable pool designed to take advantage of * placement according to predicted deathtime. @@ -145,6 +145,7 @@ DEFINE_POOL_CLASS(MVTPoolClass, this) this->bufferFill = MVTBufferFill; this->bufferEmpty = MVTBufferEmpty; this->describe = MVTDescribe; + AVERT(PoolClass, this); } /* Macros */ @@ -1488,7 +1489,7 @@ CBS _mps_mvt_cbs(mps_pool_t mps_pool) { /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index e1d1d094d38..b218e687440 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -1,7 +1,7 @@ /* poolmvff.c: First Fit Manual Variable Pool * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * * .purpose: This is a pool class for manually managed objects of @@ -720,6 +720,7 @@ DEFINE_POOL_CLASS(MVFFPoolClass, this) this->bufferFill = MVFFBufferFill; this->bufferEmpty = MVFFBufferEmpty; this->describe = MVFFDescribe; + AVERT(PoolClass, this); } @@ -739,6 +740,7 @@ DEFINE_POOL_CLASS(MVFFDebugPoolClass, this) this->size = sizeof(MVFFDebugStruct); this->varargs = MVFFDebugVarargs; this->debugMixin = MVFFDebugMixin; + AVERT(PoolClass, this); } @@ -828,7 +830,7 @@ CBS _mps_mvff_cbs(mps_pool_t mps_pool) { /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/pooln.c b/mps/code/pooln.c index f0851f56fd5..87abba8cb1d 100644 --- a/mps/code/pooln.c +++ b/mps/code/pooln.c @@ -1,7 +1,7 @@ /* pooln.c: NULL POOL CLASS * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. */ #include "pooln.h" @@ -287,6 +287,7 @@ DEFINE_POOL_CLASS(NPoolClass, this) this->reclaim = NReclaim; this->traceEnd = NTraceEnd; this->describe = NDescribe; + AVERT(PoolClass, this); } @@ -313,7 +314,7 @@ Bool PoolNCheck(PoolN poolN) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index 800a1482efc..1ac5e408dce 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -1,7 +1,7 @@ /* poolsnc.c: STACK NO CHECKING POOL CLASS * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * DESIGN * @@ -185,6 +185,7 @@ DEFINE_BUFFER_CLASS(SNCBufClass, class) class->size = sizeof(SNCBufStruct); class->init = SNCBufInit; class->finish = SNCBufFinish; + AVERT(BufferClass, class); } @@ -261,6 +262,7 @@ DEFINE_SEG_CLASS(SNCSegClass, class) class->name = "SNCSEG"; class->size = sizeof(SNCSegStruct); class->init = sncSegInit; + AVERT(SegClass, class); } @@ -682,6 +684,7 @@ DEFINE_POOL_CLASS(SNCPoolClass, this) this->framePopPending = SNCFramePopPending; this->walk = SNCWalk; this->bufferClass = SNCBufClassGet; + AVERT(PoolClass, this); } @@ -707,7 +710,7 @@ static Bool SNCCheck(SNC snc) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/protocol.c b/mps/code/protocol.c index 6a53613d54b..af7ac26e8c3 100644 --- a/mps/code/protocol.c +++ b/mps/code/protocol.c @@ -1,7 +1,7 @@ /* pool.c: PROTOCOL IMPLEMENTATION * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * DESIGN * @@ -18,7 +18,7 @@ SRCID(protocol, "$Id$"); Bool ProtocolClassCheck(ProtocolClass class) { CHECKS(ProtocolClass, class); - CHECKS(ProtocolClass, class->superclass); + CHECKU(ProtocolClass, class->superclass); CHECKL(FUNCHECK(class->coerceInst)); CHECKL(FUNCHECK(class->coerceClass)); return TRUE; @@ -118,6 +118,7 @@ DEFINE_CLASS(ProtocolClass, theClass) theClass->superclass = theClass; theClass->coerceInst = ProtocolCoerceInst; theClass->coerceClass = ProtocolCoerceClass; + AVERT(ProtocolClass, theClass); } @@ -126,7 +127,7 @@ DEFINE_CLASS(ProtocolClass, theClass) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/reserv.c b/mps/code/reserv.c index 310695c97df..eae0140f108 100644 --- a/mps/code/reserv.c +++ b/mps/code/reserv.c @@ -1,7 +1,7 @@ /* reserv.c: ARENA RESERVOIR * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * IMPROVEMENTS * @@ -74,6 +74,7 @@ DEFINE_POOL_CLASS(ReservoirPoolClass, this) this->offset = offsetof(ReservoirStruct, poolStruct); this->init = ResPoolInit; this->finish = ResPoolFinish; + AVERT(PoolClass, this); } @@ -416,7 +417,7 @@ void ReservoirFinish (Reservoir reservoir) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/seg.c b/mps/code/seg.c index 891c14296cf..3787c5dea7a 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -1,7 +1,7 @@ /* seg.c: SEGMENTS * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .design: The design for this module is . * @@ -1683,6 +1683,7 @@ DEFINE_CLASS(SegClass, class) class->split = segTrivSplit; class->describe = segTrivDescribe; class->sig = SegClassSig; + AVERT(SegClass, class); } @@ -1707,6 +1708,7 @@ DEFINE_CLASS(GCSegClass, class) class->merge = gcSegMerge; class->split = gcSegSplit; class->describe = gcSegDescribe; + AVERT(SegClass, class); } @@ -1726,7 +1728,7 @@ void SegClassMixInNoSplitMerge(SegClass class) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index ed25bf305ee..d5ef0ca2491 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -294,6 +294,7 @@ DEFINE_SEG_CLASS(AMSTSegClass, class) class->finish = amstSegFinish; class->split = amstSegSplit; class->merge = amstSegMerge; + AVERT(SegClass, class); } @@ -674,6 +675,7 @@ DEFINE_POOL_CLASS(AMSTPoolClass, this) this->init = AMSTInit; this->finish = AMSTFinish; this->bufferFill = AMSTBufferFill; + AVERT(PoolClass, this); } From 9bb6b2f8be333906766b9b0a1567b981c69c55bd Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 17:05:08 +0100 Subject: [PATCH 06/24] Tidy-up of attributes and pool classes: * Bring design up to date. * New function PoolHasAttr encapsulates attribute checking. * Abstract classes are abstract and mustn't be checked. * The dummy pool class in fotest needs a size. * Abstract pool classes null out methods that they can't provide a generic implementation for, to force subclasses to provide one. * New function PoolTrivFramePopPending provides a generic implementation of that method. * Rename PoolNoFreeWalk to PoolTrivFreeWalk since it has NOOP rather than NOTREACHED. * Check that AttrMOVINGGC implies AttrGC. * Remove unimplemented attributes (BUF_RESERVE, BUF_ALLOC, INCR_RB, INCR_WB, PM) * AMC now inherits from AMCZ instead of the other way round. This is simpler: AMC adds features to AMCZ rather than AMCZ taking features away (and not quite getting it right). * Similarly, LO inherits from AbstractSegBufPoolClass + PoolClassMixInCollect so that it doesn't have to clear AttrSCAN and the scan methods. * Fix bug in MFSCheck -- mustn't check unroundedUnitSize >= UNIT_MIN since small unit sizes are rounded up to UNIT_MIN. * Don't see AttrFREE in MRG (since no free method is supplied). * Check AttrSCAN systematically (in PoolScan and SegCheck) rather than opportunistically in TraceStart and TraceQuantum. Copied from Perforce Change: 185231 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 1 - mps/code/buffer.c | 4 ++-- mps/code/fotest.c | 1 + mps/code/locus.c | 6 +++--- mps/code/mpm.h | 4 +++- mps/code/pool.c | 17 +++++++--------- mps/code/poolabs.c | 49 +++++++++++++++++++++++++++++---------------- mps/code/poolamc.c | 27 ++++++++++++------------- mps/code/poolams.c | 1 + mps/code/poollo.c | 7 ++----- mps/code/poolmfs.c | 2 +- mps/code/poolmrg.c | 2 +- mps/code/pooln.c | 3 +-- mps/code/seg.c | 2 ++ mps/code/trace.c | 18 ++++++++--------- mps/code/walk.c | 10 ++++----- mps/design/type.txt | 36 +++++++++------------------------ 17 files changed, 91 insertions(+), 99 deletions(-) diff --git a/mps/code/arena.c b/mps/code/arena.c index 4f8c465e1ae..749208aeee2 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -79,7 +79,6 @@ DEFINE_CLASS(AbstractArenaClass, class) class->describe = ArenaTrivDescribe; class->pagesMarkAllocated = NULL; class->sig = ArenaClassSig; - AVERT(ArenaClass, class); } diff --git a/mps/code/buffer.c b/mps/code/buffer.c index 51b4ba58299..1e8b0b7b614 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -205,7 +205,7 @@ static Res BufferInit(Buffer buffer, BufferClass class, AVERT(BufferClass, class); AVERT(Pool, pool); /* The PoolClass should support buffer protocols */ - AVER((pool->class->attr & AttrBUF)); /* .trans.mod */ + AVER(PoolHasAttr(pool, AttrBUF)); arena = PoolArena(pool); /* Initialize the buffer. See for a definition of */ @@ -383,7 +383,7 @@ void BufferFinish(Buffer buffer) pool = BufferPool(buffer); /* The PoolClass should support buffer protocols */ - AVER((pool->class->attr & AttrBUF)); /* .trans.mod */ + AVER(PoolHasAttr(pool, AttrBUF)); AVER(BufferIsReady(buffer)); /* */ diff --git a/mps/code/fotest.c b/mps/code/fotest.c index 3fecb81e5ec..58b25d6b65c 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -60,6 +60,7 @@ DEFINE_POOL_CLASS(OOMPoolClass, this) { INHERIT_CLASS(this, AbstractAllocFreePoolClass); this->alloc = OOMAlloc; + this->size = sizeof(PoolStruct); AVERT(PoolClass, this); } diff --git a/mps/code/locus.c b/mps/code/locus.c index f0ba7415cde..24f401c2c4f 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -1,7 +1,7 @@ /* locus.c: LOCUS MANAGER * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * DESIGN * @@ -370,7 +370,7 @@ Res ChainCondemnAll(Chain chain, Trace trace) Ring segNode, nextSegNode; AVERT(Pool, pool); - AVER((pool->class->attr & AttrGC) != 0); + AVER(PoolHasAttr(pool, AttrGC)); RING_FOR(segNode, PoolSegRing(pool), nextSegNode) { Seg seg = SegOfPoolRing(segNode); @@ -508,7 +508,7 @@ Bool LocusCheck(Arena arena) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/mpm.h b/mps/code/mpm.h index da45d9aedd2..9548923ab0c 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -183,6 +183,7 @@ extern Res PoolDescribe(Pool pool, mps_lib_FILE *stream); #define PoolSegRing(pool) (&(pool)->segRing) #define PoolArenaRing(pool) (&(pool)->arenaRing) #define PoolOfArenaRing(node) RING_ELT(Pool, arenaRing, node) +#define PoolHasAttr(pool, Attr) (((pool)->class->attr & (Attr)) != 0) extern Bool PoolFormat(Format *formatReturn, Pool pool); @@ -263,10 +264,11 @@ extern Res PoolTrivFramePush(AllocFrame *frameReturn, Pool pool, Buffer buf); extern Res PoolNoFramePop(Pool pool, Buffer buf, AllocFrame frame); extern Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame); extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame); +extern void PoolTrivFramePopPending(Pool pool, Buffer buf, AllocFrame frame); extern Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr); extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step, void *p, size_t s); -extern void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p); +extern void PoolTrivFreeWalk(Pool pool, FreeBlockStepMethod f, void *p); extern PoolDebugMixin PoolNoDebugMixin(Pool pool); extern BufferClass PoolNoBufferClass(void); diff --git a/mps/code/pool.c b/mps/code/pool.c index 0524d69525c..75f5dc959d5 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -18,9 +18,6 @@ * .purpose.dispatch: Dispatch functions that implement the generic * function dispatch mechanism for Pool Classes (PoolAlloc, PoolFix, * etc.). - * .purpose.core: A selection of default, trivial, or useful methods - * that Pool Classes can use as the implementations for some of their - * methods (such as PoolTrivWhiten, PoolNoFix, etc.). * * SOURCES * @@ -47,6 +44,7 @@ Bool PoolClassCheck(PoolClass class) /* greater than the size of the class-specific portion of the instance */ CHECKL(class->offset <= (size_t)(class->size - sizeof(PoolStruct))); CHECKL(AttrCheck(class->attr)); + CHECKL(!(class->attr & AttrMOVINGGC) || (class->attr & AttrGC)); CHECKL(FUNCHECK(class->varargs)); CHECKL(FUNCHECK(class->init)); CHECKL(FUNCHECK(class->finish)); @@ -94,11 +92,9 @@ Bool PoolCheck(Pool pool) /* Cannot check pool->bufferSerial */ CHECKL(RingCheck(&pool->segRing)); CHECKL(AlignCheck(pool->alignment)); - /* normally pool->format iff pool->class->attr&AttrFMT, but not */ - /* during pool initialization */ - if (pool->format != NULL) { - CHECKL((pool->class->attr & AttrFMT) != 0); - } + /* normally pool->format iff PoolHasAttr(pool, AttrFMT), but during + * pool initialization pool->format may not yet be set. */ + CHECKL(pool->format == NULL || PoolHasAttr(pool, AttrFMT)); CHECKL(pool->fillMutatorSize >= 0.0); CHECKL(pool->emptyMutatorSize >= 0.0); CHECKL(pool->fillInternalSize >= 0.0); @@ -288,7 +284,7 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size, AVER(pReturn != NULL); AVERT(Pool, pool); - AVER((pool->class->attr & AttrALLOC) != 0); + AVER(PoolHasAttr(pool, AttrALLOC)); AVER(size > 0); AVER(BoolCheck(withReservoirPermit)); @@ -318,7 +314,7 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size, void PoolFree(Pool pool, Addr old, Size size) { AVERT(Pool, pool); - AVER((pool->class->attr & AttrFREE) != 0); + AVER(PoolHasAttr(pool, AttrFREE)); AVER(old != NULL); /* The pool methods should check that old is in pool. */ AVER(size > 0); @@ -383,6 +379,7 @@ Res PoolScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) AVER(totalReturn != NULL); AVERT(ScanState, ss); AVERT(Pool, pool); + AVER(PoolHasAttr(pool, AttrSCAN)); AVERT(Seg, seg); AVER(ss->arena == pool->arena); diff --git a/mps/code/poolabs.c b/mps/code/poolabs.c index 27aa767d940..cb6f49debb9 100644 --- a/mps/code/poolabs.c +++ b/mps/code/poolabs.c @@ -65,12 +65,13 @@ void PoolClassMixInAllocFree(PoolClass class) void PoolClassMixInBuffer(PoolClass class) { /* Can't check class because it's not initialized yet */ - class->attr |= (AttrBUF | AttrBUF_RESERVE); + class->attr |= AttrBUF; class->bufferFill = PoolTrivBufferFill; class->bufferEmpty = PoolTrivBufferEmpty; /* By default, buffered pools treat frame operations as NOOPs */ class->framePush = PoolTrivFramePush; class->framePop = PoolTrivFramePop; + class->framePopPending = PoolTrivFramePopPending; class->bufferClass = BufferClassGet; } @@ -84,8 +85,10 @@ void PoolClassMixInScan(PoolClass class) class->access = PoolSegAccess; class->blacken = PoolTrivBlacken; class->grey = PoolTrivGrey; - /* Scan is part of the scanning protocol - but there is */ - /* no useful default method */ + /* scan is part of the scanning protocol, but there is no useful + * default method. + */ + class->scan = NULL; } @@ -95,6 +98,10 @@ void PoolClassMixInFormat(PoolClass class) { /* Can't check class because it's not initialized yet */ class->attr |= AttrFMT; + /* walk is part of the format protocol, but there is no useful + * default method. + */ + class->walk = NULL; } @@ -103,10 +110,14 @@ void PoolClassMixInFormat(PoolClass class) void PoolClassMixInCollect(PoolClass class) { /* Can't check class because it's not initialized yet */ - class->attr |= (AttrGC | AttrINCR_RB); + class->attr |= AttrGC; class->whiten = PoolTrivWhiten; - /* Fix & reclaim are part of the collection protocol - but there */ - /* are no useful default methods for them. */ + /* fix, fixEmergency and reclaim are part of the collection + * protocol, but there are no useful default methods for them. + */ + class->fix = NULL; + class->fixEmergency = NULL; + class->reclaim = NULL; class->rampBegin = PoolTrivRampBegin; class->rampEnd = PoolTrivRampEnd; } @@ -145,48 +156,42 @@ DEFINE_CLASS(AbstractPoolClass, class) class->framePopPending = PoolNoFramePopPending; class->addrObject = PoolNoAddrObject; class->walk = PoolNoWalk; - class->freewalk = PoolNoFreeWalk; + class->freewalk = PoolTrivFreeWalk; class->bufferClass = PoolNoBufferClass; class->describe = PoolTrivDescribe; class->debugMixin = PoolNoDebugMixin; class->labelled = FALSE; class->sig = PoolClassSig; - AVERT(PoolClass, class); } DEFINE_CLASS(AbstractAllocFreePoolClass, class) { INHERIT_CLASS(class, AbstractPoolClass); PoolClassMixInAllocFree(class); - AVERT(PoolClass, class); } DEFINE_CLASS(AbstractBufferPoolClass, class) { INHERIT_CLASS(class, AbstractPoolClass); PoolClassMixInBuffer(class); - AVERT(PoolClass, class); } DEFINE_CLASS(AbstractSegBufPoolClass, class) { INHERIT_CLASS(class, AbstractBufferPoolClass); class->bufferClass = SegBufClassGet; - AVERT(PoolClass, class); } DEFINE_CLASS(AbstractScanPoolClass, class) { INHERIT_CLASS(class, AbstractSegBufPoolClass); PoolClassMixInScan(class); - AVERT(PoolClass, class); } DEFINE_CLASS(AbstractCollectPoolClass, class) { INHERIT_CLASS(class, AbstractScanPoolClass); PoolClassMixInCollect(class); - AVERT(PoolClass, class); } @@ -602,7 +607,7 @@ Res PoolNoFramePop(Pool pool, Buffer buf, AllocFrame frame) { AVERT(Pool, pool); AVERT(Buffer, buf); - /* frame is of a abstract type & can't be checked */ + /* frame is of an abstract type & can't be checked */ UNUSED(frame); NOTREACHED; return ResUNIMPL; @@ -613,7 +618,7 @@ void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame) { AVERT(Pool, pool); AVERT(Buffer, buf); - /* frame is of a abstract type & can't be checked */ + /* frame is of an abstract type & can't be checked */ UNUSED(frame); NOTREACHED; } @@ -632,12 +637,22 @@ Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame) { AVERT(Pool, pool); AVERT(Buffer, buf); - /* frame is of a abstract type & can't be checked */ + /* frame is of an abstract type & can't be checked */ UNUSED(frame); return ResOK; } +void PoolTrivFramePopPending(Pool pool, Buffer buf, AllocFrame frame) +{ + AVERT(Pool, pool); + AVERT(Buffer, buf); + /* frame is of an abstract type & can't be checked */ + UNUSED(frame); + NOOP; +} + + Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr) { AVER(pReturn != NULL); @@ -662,7 +677,7 @@ void PoolNoWalk(Pool pool, Seg seg, } -void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p) +void PoolTrivFreeWalk(Pool pool, FreeBlockStepMethod f, void *p) { AVERT(Pool, pool); AVER(FUNCHECK(f)); diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index e568b7adb53..fd74778c9c3 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -2484,23 +2484,23 @@ static Res AMCDescribe(Pool pool, mps_lib_FILE *stream) } -/* AMCPoolClass -- the class definition */ +/* AMCZPoolClass -- the class definition */ -DEFINE_POOL_CLASS(AMCPoolClass, this) +DEFINE_POOL_CLASS(AMCZPoolClass, this) { - INHERIT_CLASS(this, AbstractCollectPoolClass); + INHERIT_CLASS(this, AbstractSegBufPoolClass); PoolClassMixInFormat(this); - this->name = "AMC"; + PoolClassMixInCollect(this); + this->name = "AMCZ"; this->size = sizeof(AMCStruct); this->offset = offsetof(AMCStruct, poolStruct); this->attr |= AttrMOVINGGC; this->varargs = AMCVarargs; - this->init = AMCInit; + this->init = AMCZInit; this->finish = AMCFinish; this->bufferFill = AMCBufferFill; this->bufferEmpty = AMCBufferEmpty; this->whiten = AMCWhiten; - this->scan = AMCScan; this->fix = AMCFix; this->fixEmergency = AMCFixEmergency; this->reclaim = AMCReclaim; @@ -2515,16 +2515,15 @@ DEFINE_POOL_CLASS(AMCPoolClass, this) } -/* AMCZPoolClass -- the class definition */ +/* AMCPoolClass -- the class definition */ -DEFINE_POOL_CLASS(AMCZPoolClass, this) +DEFINE_POOL_CLASS(AMCPoolClass, this) { - INHERIT_CLASS(this, AMCPoolClass); - this->name = "AMCZ"; - this->attr &= ~(AttrSCAN | AttrINCR_RB); - this->init = AMCZInit; - this->grey = PoolNoGrey; - this->scan = PoolNoScan; + INHERIT_CLASS(this, AMCZPoolClass); + PoolClassMixInScan(this); + this->name = "AMC"; + this->init = AMCInit; + this->scan = AMCScan; AVERT(PoolClass, this); } diff --git a/mps/code/poolams.c b/mps/code/poolams.c index f463aed2e84..96df165896a 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -1685,6 +1685,7 @@ DEFINE_CLASS(AMSPoolClass, this) this->fix = AMSFix; this->fixEmergency = AMSFix; this->reclaim = AMSReclaim; + this->walk = PoolNoWalk; /* TODO: job003738 */ this->freewalk = AMSFreeWalk; this->describe = AMSDescribe; AVERT(PoolClass, this); diff --git a/mps/code/poollo.c b/mps/code/poollo.c index eef07aee89a..08aa146d656 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -775,21 +775,18 @@ static void LOReclaim(Pool pool, Trace trace, Seg seg) DEFINE_POOL_CLASS(LOPoolClass, this) { - INHERIT_CLASS(this, AbstractCollectPoolClass); + INHERIT_CLASS(this, AbstractSegBufPoolClass); PoolClassMixInFormat(this); + PoolClassMixInCollect(this); this->name = "LO"; this->size = sizeof(LOStruct); this->offset = offsetof(LOStruct, poolStruct); - this->attr &= ~(AttrSCAN | AttrINCR_RB); this->varargs = LOVarargs; this->init = LOInit; this->finish = LOFinish; this->bufferFill = LOBufferFill; this->bufferEmpty = LOBufferEmpty; this->whiten = LOWhiten; - this->grey = PoolNoGrey; - this->blacken = PoolNoBlacken; - this->scan = PoolNoScan; this->fix = LOFix; this->fixEmergency = LOFix; this->reclaim = LOReclaim; diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 80183b42b52..6bf29c15873 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -370,7 +370,7 @@ Bool MFSCheck(MFS mfs) CHECKS(MFS, mfs); CHECKD(Pool, &mfs->poolStruct); CHECKL(mfs->poolStruct.class == EnsureMFSPoolClass()); - CHECKL(mfs->unroundedUnitSize >= UNIT_MIN); + CHECKL(mfs->unitSize >= UNIT_MIN); CHECKL(mfs->extendBy >= UNIT_MIN); CHECKL(BoolCheck(mfs->extendSelf)); arena = PoolArena(&mfs->poolStruct); diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c index 271b881bfb2..aebb22595ea 100644 --- a/mps/code/poolmrg.c +++ b/mps/code/poolmrg.c @@ -857,7 +857,7 @@ DEFINE_POOL_CLASS(MRGPoolClass, this) this->name = "MRG"; this->size = sizeof(MRGStruct); this->offset = offsetof(MRGStruct, poolStruct); - this->attr |= (AttrSCAN | AttrFREE | AttrINCR_RB); + this->attr |= AttrSCAN; this->init = MRGInit; this->finish = MRGFinish; this->grey = PoolTrivGrey; diff --git a/mps/code/pooln.c b/mps/code/pooln.c index 87abba8cb1d..6840c1417f8 100644 --- a/mps/code/pooln.c +++ b/mps/code/pooln.c @@ -270,8 +270,7 @@ DEFINE_POOL_CLASS(NPoolClass, this) this->name = "N"; this->size = sizeof(PoolNStruct); this->offset = offsetof(PoolNStruct, poolStruct); - this->attr = AttrSCAN | AttrALLOC | AttrFREE | AttrBUF | - AttrBUF_RESERVE | AttrGC; + this->attr |= (AttrALLOC | AttrBUF | AttrFREE | AttrGC | AttrSCAN); this->init = NInit; this->finish = NFinish; this->alloc = NAlloc; diff --git a/mps/code/seg.c b/mps/code/seg.c index 3787c5dea7a..98864fb450f 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -727,6 +727,8 @@ Bool SegCheck(Seg seg) CHECKL(seg->sm == AccessSetEMPTY); CHECKL(seg->pm == AccessSetEMPTY); } else { + /* Segments with ranks may only belong to scannable pools. */ + CHECKL(PoolHasAttr(pool, AttrSCAN)); /* : The Tracer only permits */ /* one rank per segment [ref?] so this field is either empty or a */ /* singleton. */ diff --git a/mps/code/trace.c b/mps/code/trace.c index 6fb666925b2..df258df17dc 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -363,7 +363,7 @@ Res TraceAddWhite(Trace trace, Seg seg) if(TraceSetIsMember(SegWhite(seg), trace)) { trace->white = ZoneSetUnion(trace->white, ZoneSetOfSeg(trace->arena, seg)); /* if the pool is a moving GC, then condemned objects may move */ - if(pool->class->attr & AttrMOVINGGC) { + if(PoolHasAttr(pool, AttrMOVINGGC)) { trace->mayMove = ZoneSetUnion(trace->mayMove, ZoneSetOfSeg(trace->arena, seg)); } @@ -410,8 +410,9 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet) /* the requested zone set. Otherwise, we would bloat the */ /* foundation to no gain. Note that this doesn't exclude */ /* any segments from which the condemned set was derived, */ - if((SegPool(seg)->class->attr & AttrGC) != 0 - && ZoneSetSuper(condemnedSet, ZoneSetOfSeg(arena, seg))) { + if(PoolHasAttr(SegPool(seg), AttrGC) + && ZoneSetSuper(condemnedSet, ZoneSetOfSeg(arena, seg))) + { res = TraceAddWhite(trace, seg); if(res != ResOK) return res; @@ -827,7 +828,7 @@ static void traceReclaim(Trace trace) AVER_CRITICAL(!TraceSetIsMember(SegGrey(seg), trace)); if(TraceSetIsMember(SegWhite(seg), trace)) { - AVER_CRITICAL((pool->class->attr & AttrGC) != 0); + AVER_CRITICAL(PoolHasAttr(pool, AttrGC)); STATISTIC(++trace->reclaimCount); PoolReclaim(pool, trace, seg); @@ -1617,9 +1618,6 @@ Res TraceStart(Trace trace, double mortality, double finishingTime) /* This is indicated by the rankSet begin non-empty. Such */ /* segments may only belong to scannable pools. */ if(SegRankSet(seg) != RankSetEMPTY) { - /* Segments with ranks may only belong to scannable pools. */ - AVER((SegPool(seg)->class->attr & AttrSCAN) != 0); - /* Turn the segment grey if there might be a reference in it */ /* to the white set. This is done by seeing if the summary */ /* of references in the segment intersects with the */ @@ -1634,8 +1632,9 @@ Res TraceStart(Trace trace, double mortality, double finishingTime) } } - if((SegPool(seg)->class->attr & AttrGC) - && !TraceSetIsMember(SegWhite(seg), trace)) { + if(PoolHasAttr(SegPool(seg), AttrGC) + && !TraceSetIsMember(SegWhite(seg), trace)) + { trace->notCondemned += size; } } @@ -1730,7 +1729,6 @@ void TraceQuantum(Trace trace) if(traceFindGrey(&seg, &rank, arena, trace->ti)) { Res res; - AVER((SegPool(seg)->class->attr & AttrSCAN) != 0); res = traceScanSeg(TraceSetSingle(trace), rank, arena, seg); /* Allocation failures should be handled by emergency mode, and we don't expect any other error in a normal GC trace. */ diff --git a/mps/code/walk.c b/mps/code/walk.c index d08fd160eec..0fcc37a151c 100644 --- a/mps/code/walk.c +++ b/mps/code/walk.c @@ -1,7 +1,7 @@ /* walk.c: OBJECT WALKER * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. */ #include "mpm.h" @@ -77,7 +77,7 @@ static void ArenaFormattedObjectsWalk(Arena arena, FormattedObjectsStepMethod f, do { Pool pool; pool = SegPool(seg); - if (pool->class->attr & AttrFMT) { + if (PoolHasAttr(pool, AttrFMT)) { ShieldExpose(arena, seg); PoolWalk(pool, seg, f, p, s); ShieldCover(arena, seg); @@ -243,7 +243,7 @@ static Res RootsWalkFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) /* If the segment isn't GCable then the ref is not to the heap and */ /* shouldn't be passed to the client. */ - AVER((SegPool(seg)->class->attr & AttrGC) != 0); + AVER(PoolHasAttr(SegPool(seg), AttrGC)); /* Call the client closure - .assume.rootaddr */ rsc->f((mps_addr_t*)refIO, (mps_root_t)rsc->root, rsc->p, rsc->s); @@ -307,7 +307,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, /* NOTE: I'm not sure why this is. RB 2012-07-24 */ if (SegFirst(&seg, arena)) { do { - if ((SegPool(seg)->class->attr & AttrGC) != 0) { + if (PoolHasAttr(SegPool(seg), AttrGC)) { res = TraceAddWhite(trace, seg); AVER(res == ResOK); } @@ -363,7 +363,7 @@ void mps_arena_roots_walk(mps_arena_t mps_arena, mps_roots_stepper_t f, /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/design/type.txt b/mps/design/type.txt index 6a7efc93529..46ce384f965 100644 --- a/mps/design/type.txt +++ b/mps/design/type.txt @@ -426,39 +426,21 @@ attributes, which are: =================== =========================================================== Attribute Description =================== =========================================================== -``AttrFMT`` Contains formatted objects. -------------------- ----------------------------------------------------------- -``AttrSCAN`` Contains references and must be scanned. -------------------- ----------------------------------------------------------- -``AttrPM_NO_READ`` May not be read protected. -------------------- ----------------------------------------------------------- -``AttrPM_NO_WRITE`` May not be write protected. -------------------- ----------------------------------------------------------- ``AttrALLOC`` Supports the ``PoolAlloc`` interface. -------------------- ----------------------------------------------------------- +``AttrBUF`` Supports the buffer interface. +``AttrFMT`` Contains formatted objects. + Used to decide which pools to walk. ``AttrFREE`` Supports the ``PoolFree`` interface. -------------------- ----------------------------------------------------------- -``AttrBUF`` Supports the allocation buffer interface. -------------------- ----------------------------------------------------------- -``AttrBUF_RESERVE`` Supports the reserve/commit protocol on allocation buffers. -------------------- ----------------------------------------------------------- -``AttrBUF_ALLOC`` Supports the alloc protocol on allocation buffers. -------------------- ----------------------------------------------------------- ``AttrGC`` Is garbage collecting, that is, parts may be reclaimed. -------------------- ----------------------------------------------------------- -``AttrINCR_RB`` Is incremental, requiring a read barrier. -------------------- ----------------------------------------------------------- -``AttrINCR_WB`` Is incremental, requiring a write barrier. + Used to decide which segments are condemned. +``AttrMOVINGGC`` Is moving, that is, objects may move in memory. + Used to update the set of zones that might have moved + and so implement location dependency. +``AttrSCAN`` Contains references and must be scanned. =================== =========================================================== There is an attribute field in the pool class (``PoolClassStruct``) -which declares the attributes of that class. These attributes are only -used for consistency checking at the moment. - -.. note:: - - It's no longer true that they are only used for consistency - checking -- drj 1998-05-07 +which declares the attributes of that class. ``typedef int RootVar`` From 2d7805b65b2a4fc4caae615f3c00ef983c45c07a Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 18:22:13 +0100 Subject: [PATCH 07/24] Allocate with the right size. Copied from Perforce Change: 185233 ServerID: perforce.ravenbrook.com --- mps/test/function/6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/test/function/6.c b/mps/test/function/6.c index 6c761089d85..7e56e09317a 100644 --- a/mps/test/function/6.c +++ b/mps/test/function/6.c @@ -61,7 +61,7 @@ static void test(void) for (j = 1; j < 100; j++) { comment("%i of 100", j); - p = allocdumb(ap, sizeof(mps_ld_s)); + p = allocdumb(ap, sizeof(mycell)); ld = (mps_ld_t) getdata(p); b = a; From cd377eb05005c1d38217cc3bed18cbc7acf60b1d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 21:59:45 +0100 Subject: [PATCH 08/24] Refactor finaltest so that it is capable of testing different pool classes. Copied from Perforce Change: 185235 ServerID: perforce.ravenbrook.com --- mps/code/finaltest.c | 174 ++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 102 deletions(-) diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index ee7a55ee3e7..dd6146851df 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -20,6 +20,8 @@ #include "mpslib.h" #include "mps.h" #include "mpscamc.h" +#include "mpscams.h" +#include "mpscawl.h" #include "mpsavm.h" #include "fmtdy.h" #include "fmtdytst.h" @@ -32,14 +34,8 @@ #define testArenaSIZE ((size_t)16<<20) #define rootCOUNT 20 -#define maxtreeDEPTH 12 +#define maxtreeDEPTH 10 #define collectionCOUNT 10 -#define genCOUNT 2 - -/* testChain -- generation parameters for the test */ - -static mps_gen_param_s testChain[genCOUNT] = { - { 150, 0.85 }, { 170, 0.45 } }; /* global object counter */ @@ -123,119 +119,90 @@ static void register_indirect_tree(mps_word_t tree, mps_arena_t arena) } } +static mps_addr_t test_awl_find_dependent(mps_addr_t addr) +{ + testlib_unused(addr); + return NULL; +} static void *root[rootCOUNT]; -static void *test(void *arg, size_t s) +static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap, + mps_word_t (*make)(mps_word_t, mps_ap_t), + void (*reg)(mps_word_t, mps_arena_t)) +{ + size_t collections = 0; + size_t finals = 0; + size_t i; + + object_count = 0; + + printf("Making some %s finalized trees of objects.\n", name); + /* make some trees */ + for(i = 0; i < rootCOUNT; ++i) { + root[i] = (void *)(*make)(maxtreeDEPTH, ap); + (*reg)((mps_word_t)root[i], arena); + } + + printf("Losing all pointers to the trees.\n"); + /* clean out the roots */ + for(i = 0; i < rootCOUNT; ++i) { + root[i] = 0; + } + + while (finals < object_count && collections < collectionCOUNT) { + mps_word_t final_this_time = 0; + printf("Collecting..."); + (void)fflush(stdout); + die(mps_arena_collect(arena), "collect"); + printf(" Done.\n"); + ++ collections; + while (mps_message_poll(arena)) { + mps_message_t message; + mps_addr_t objaddr; + cdie(mps_message_get(&message, arena, + mps_message_type_finalization()), + "get"); + mps_message_finalization_ref(&objaddr, arena, message); + mps_message_discard(arena, message); + ++ final_this_time; + } + finals += final_this_time; + printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST + " of %"PRIuLONGEST"\n", final_this_time, finals, object_count); + } + cdie(finals == object_count, "Not all objects were finalized."); +} + +static void *test(mps_arena_t arena, mps_class_t pool_class) { mps_ap_t ap; mps_fmt_t fmt; - mps_chain_t chain; - mps_word_t finals; - mps_pool_t amc; + mps_pool_t pool; mps_root_t mps_root; - mps_arena_t arena; - mps_message_t message; - size_t i; - - arena = (mps_arena_t)arg; - (void)s; die(mps_fmt_create_A(&fmt, arena, dylan_fmt_A()), "fmt_create\n"); - die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); - die(mps_pool_create(&amc, arena, mps_class_amc(), fmt, chain), - "pool_create amc\n"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt); + MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent); + die(mps_pool_create_k(&pool, arena, pool_class, args), + "pool_create\n"); + } MPS_ARGS_END(args); die(mps_root_create_table(&mps_root, arena, mps_rank_exact(), (mps_rm_t)0, root, (size_t)rootCOUNT), "root_create\n"); - die(mps_ap_create(&ap, amc, mps_rank_exact()), "ap_create\n"); + die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create\n"); mps_message_type_enable(arena, mps_message_type_finalization()); mps_arena_park(arena); - object_count = 0; - - printf("Making some finalized trees of objects.\n"); - /* make some trees */ - for(i = 0; i < rootCOUNT; ++i) { - root[i] = (void *)make_numbered_tree(maxtreeDEPTH, ap); - register_numbered_tree((mps_word_t)root[i], arena); - } - - printf("Losing all pointers to the trees.\n"); - /* clean out the roots */ - for(i = 0; i < rootCOUNT; ++i) { - root[i] = 0; - } - - finals = 0; - - while ((finals < object_count) && - (mps_collections(arena) < collectionCOUNT)) { - mps_word_t final_this_time = 0; - printf("Collecting..."); - (void)fflush(stdout); - die(mps_arena_collect(arena), "collect"); - printf(" Done.\n"); - while (mps_message_poll(arena)) { - mps_addr_t objaddr; - cdie(mps_message_get(&message, arena, - mps_message_type_finalization()), - "get"); - mps_message_finalization_ref(&objaddr, arena, message); - mps_message_discard(arena, message); - ++ final_this_time; - } - finals += final_this_time; - printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST - " of %"PRIuLONGEST"\n", - final_this_time, finals, object_count); - } - - object_count = 0; - - printf("Making some indirectly finalized trees of objects.\n"); - /* make some trees */ - for(i = 0; i < rootCOUNT; ++i) { - root[i] = (void *)make_indirect_tree(maxtreeDEPTH, ap); - register_indirect_tree((mps_word_t)root[i], arena); - } - - printf("Losing all pointers to the trees.\n"); - /* clean out the roots */ - for(i = 0; i < rootCOUNT; ++i) { - root[i] = 0; - } - - finals = 0; - - while ((finals < object_count) && - (mps_collections(arena) < collectionCOUNT)) { - mps_word_t final_this_time = 0; - printf("Collecting..."); - (void)fflush(stdout); - die(mps_arena_collect(arena), "collect"); - printf(" Done.\n"); - while (mps_message_poll(arena)) { - mps_addr_t objaddr; - cdie(mps_message_get(&message, arena, - mps_message_type_finalization()), - "get"); - mps_message_finalization_ref(&objaddr, arena, message); - mps_message_discard(arena, message); - ++ final_this_time; - } - finals += final_this_time; - printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST - " of %"PRIuLONGEST"\n", - final_this_time, finals, object_count); - } + test_trees("numbered", arena, ap, make_numbered_tree, register_numbered_tree); + test_trees("indirect", arena, ap, make_indirect_tree, register_indirect_tree); mps_ap_destroy(ap); mps_root_destroy(mps_root); - mps_pool_destroy(amc); - mps_chain_destroy(chain); + mps_pool_destroy(pool); mps_fmt_destroy(fmt); return NULL; @@ -246,14 +213,17 @@ int main(int argc, char *argv[]) { mps_arena_t arena; mps_thr_t thread; - void *r; testlib_init(argc, argv); die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "arena_create\n"); die(mps_thread_reg(&thread, arena), "thread_reg\n"); - mps_tramp(&r, test, arena, 0); + + test(arena, mps_class_amc()); + /* TODO: test(arena, mps_class_ams()); */ + /* TODO: test(arena, mps_class_awl()); */ + mps_thread_dereg(thread); mps_arena_destroy(arena); From 474cff250d72eb3655c441773425a314c5a84534 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 22:00:39 +0100 Subject: [PATCH 09/24] Mmqa test case function/46.c now passes; update passing. Copied from Perforce Change: 185236 ServerID: perforce.ravenbrook.com --- mps/test/function/46.c | 2 +- mps/test/testsets/passing | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mps/test/function/46.c b/mps/test/function/46.c index d79138215ea..c5cd9437859 100644 --- a/mps/test/function/46.c +++ b/mps/test/function/46.c @@ -169,6 +169,6 @@ int main(void) stackpointer=&m; /* hack to get stack pointer */ easy_tramp(test); - report("result", "unknown"); + pass(); return 0; } diff --git a/mps/test/testsets/passing b/mps/test/testsets/passing index 41421d36166..64c72fe2982 100644 --- a/mps/test/testsets/passing +++ b/mps/test/testsets/passing @@ -7,7 +7,7 @@ function/1.c % function/3.c -- interactive test, can't run unattended % function/4.c -- interactive test, can't run unattended function/5.c -% function/6.c -- job003494 +function/6.c function/7.c % function/8.c -- tries to exhaust memory by mps_arena_create function/9.c @@ -48,12 +48,12 @@ function/42.c function/43.c function/44.c function/45.c -% function/46.c -- report("result", "unknown"); @@@@ +function/46.c function/47.c function/48.c function/49.c function/50.c -% function/51.c -- would pass if we allowed iter = 4 @@@@ +% function/51.c -- job003739 function/52.c function/53.c function/55.c From 31cfac1675706145e332bc9063c4b2c81a41fb6f Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 11:04:18 +0100 Subject: [PATCH 10/24] The empty accessset is actually accesssetempty. Copied from Perforce Change: 185242 ServerID: perforce.ravenbrook.com --- mps/design/type.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mps/design/type.txt b/mps/design/type.txt index 46ce384f965..9ab6a782377 100644 --- a/mps/design/type.txt +++ b/mps/design/type.txt @@ -413,8 +413,8 @@ represented in the obvious way:: ``typedef unsigned AccessSet`` -_`.access-set`: An ``AccessSet`` is a bitset of ``Access`` -modes, which are ``AccessREAD`` and ``AccessWRITE``. ``AccessNONE`` is +_`.access-set`: An ``AccessSet`` is a bitset of ``Access`` modes, +which are ``AccessREAD`` and ``AccessWRITE``. ``AccessSetEMPTY`` is the empty ``AccessSet``. From a7bc489409e30dee2a0550ba850402872a23e00e Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 11:47:36 +0100 Subject: [PATCH 11/24] Refactor walkt0 test case so that it can test different pool classes. Copied from Perforce Change: 185244 ServerID: perforce.ravenbrook.com --- mps/code/walkt0.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/mps/code/walkt0.c b/mps/code/walkt0.c index 3365874c153..629a5276ead 100644 --- a/mps/code/walkt0.c +++ b/mps/code/walkt0.c @@ -11,6 +11,8 @@ #include "testlib.h" #include "mpslib.h" #include "mpscamc.h" +#include "mpscams.h" +#include "mpscawl.h" #include "mpsavm.h" #include "mpstd.h" #ifdef MPS_OS_W3 @@ -126,11 +128,16 @@ static void stepper(mps_addr_t object, mps_fmt_t format, return; } +static mps_addr_t test_awl_find_dependent(mps_addr_t addr) +{ + testlib_unused(addr); + return NULL; +} + /* test -- the body of the test */ -static void *test(void *arg, size_t s) +static void *test(mps_arena_t arena, mps_class_t pool_class) { - mps_arena_t arena; mps_chain_t chain; mps_fmt_t format; mps_pool_t pool; @@ -139,14 +146,15 @@ static void *test(void *arg, size_t s) unsigned long objs; struct stepper_data sdStruct, *sd; - arena = (mps_arena_t)arg; - (void)s; /* unused */ - die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); - die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain), - "pool_create(amc)"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); + MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent); + die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); + } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create"); @@ -199,7 +207,6 @@ int main(int argc, char *argv[]) { mps_arena_t arena; mps_thr_t thread; - void *r; testlib_init(argc, argv); @@ -207,7 +214,11 @@ int main(int argc, char *argv[]) testArenaSIZE), "arena_create"); die(mps_thread_reg(&thread, arena), "thread_reg"); - mps_tramp(&r, test, arena, 0); + + test(arena, mps_class_amc()); + test(arena, mps_class_awl()); + /* TODO: test(arena, mps_class_ams()); -- see job003738 */ + mps_thread_dereg(thread); mps_arena_destroy(arena); From 2f9067da367fdb8ace512e52b18c02e443ba3894 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 15:52:56 +0100 Subject: [PATCH 12/24] Event arenablacklistzone was deleted, but event_version_minor was not updated; and the instruction "when you retire an event type, don't delete it from the list -- comment it out" was not followed. Delete TODO item: EVENT_VERSION numbers are parameters to the EventInit event. Copied from Perforce Change: 185246 ServerID: perforce.ravenbrook.com --- mps/code/eventdef.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h index cc3b3d61c21..4ce313dcfc8 100644 --- a/mps/code/eventdef.h +++ b/mps/code/eventdef.h @@ -1,7 +1,7 @@ /* -- Event Logging Definitions * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .source: * @@ -31,14 +31,13 @@ * the median version when changing an existing event, * and the major version when changing the format of the event file. * - * TODO: These should go into a header that appears at the start of a - * telemetry stream, but they aren't currently used. Keep updating them - * anyway. RB 2012-09-07 + * These are passed as parameters to the EventInit event at the start + * of a telemetry stream, allowing that stream to be identified. */ #define EVENT_VERSION_MAJOR ((unsigned)1) #define EVENT_VERSION_MEDIAN ((unsigned)1) -#define EVENT_VERSION_MINOR ((unsigned)6) +#define EVENT_VERSION_MINOR ((unsigned)7) /* EVENT_LIST -- list of event types and general properties @@ -192,7 +191,8 @@ /* new events for performance analysis of large heaps. */ \ EVENT(X, TraceCondemnZones , 0x0083, TRUE, Trace) \ EVENT(X, ArenaGenZoneAdd , 0x0084, TRUE, Arena) \ - EVENT(X, ArenaUseFreeZone , 0x0085, TRUE, Arena) + EVENT(X, ArenaUseFreeZone , 0x0085, TRUE, Arena) \ + /* EVENT(X, ArenaBlacklistZone , 0x0086, TRUE, Arena) */ /* Remember to update EventNameMAX and EventCodeMAX above! @@ -745,7 +745,7 @@ /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * From 906209e2d0faed4833d5b5a87e5523837b940949 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 15:53:34 +0100 Subject: [PATCH 13/24] Remove todo -- this was done in change 179501. Copied from Perforce Change: 185247 ServerID: perforce.ravenbrook.com --- mps/code/clock.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/mps/code/clock.h b/mps/code/clock.h index a027f4af07a..253f7a5e0e4 100644 --- a/mps/code/clock.h +++ b/mps/code/clock.h @@ -1,6 +1,6 @@ /* clock.h -- Fast clocks and timers * - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * $Id$ */ @@ -15,10 +15,6 @@ * * On platforms that support it, we want to stamp events with a very cheap * and fast high-resolution timer. - * - * TODO: This is a sufficiently complicated nest of ifdefs that it should - * be quarantined in its own header with KEEP OUT signs attached. - * RB 2012-09-11 */ /* Microsoft C provides an intrinsic for the Intel rdtsc instruction. @@ -169,7 +165,7 @@ typedef mps_clock_t EventClock; /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * From c2383c4ec91c8d0ce8a732d9db371eeaf53063a6 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 15:53:54 +0100 Subject: [PATCH 14/24] Remove unneeded headers. Copied from Perforce Change: 185248 ServerID: perforce.ravenbrook.com --- mps/code/mpsi.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c index 38b8e62f56c..297fae64732 100644 --- a/mps/code/mpsi.c +++ b/mps/code/mpsi.c @@ -1,7 +1,7 @@ /* mpsi.c: MEMORY POOL SYSTEM C INTERFACE LAYER * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (c) 2002 Global Graphics Software. * * .purpose: This code bridges between the MPS interface to C, @@ -46,11 +46,6 @@ #include "mpm.h" #include "mps.h" #include "sac.h" -#include "chain.h" - -/* TODO: Remove these includes when varargs support is removed. */ -#include "mpsacl.h" -#include "mpsavm.h" #include @@ -1935,7 +1930,7 @@ void mps_chain_destroy(mps_chain_t chain) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * From ee5b6b12b3e5bfd92aea81195d2c5bd336a94651 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 16:44:07 +0100 Subject: [PATCH 15/24] Poolarena must be thread-safe, so add a comment. Copied from Perforce Change: 185250 ServerID: perforce.ravenbrook.com --- mps/code/mpm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 9548923ab0c..d830674512f 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -178,6 +178,7 @@ extern Bool PoolClassCheck(PoolClass class); extern Bool PoolCheck(Pool pool); extern Res PoolDescribe(Pool pool, mps_lib_FILE *stream); +/* Must be thread-safe. See . */ #define PoolArena(pool) ((pool)->arena) #define PoolAlignment(pool) ((pool)->alignment) #define PoolSegRing(pool) (&(pool)->segRing) From 46da5d0d69992fd7a2c3a60075edc41303bd9bc2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 17:24:08 +0100 Subject: [PATCH 16/24] Fix typo. Copied from Perforce Change: 185252 ServerID: perforce.ravenbrook.com --- mps/design/keyword-arguments.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mps/design/keyword-arguments.txt b/mps/design/keyword-arguments.txt index 0c698036875..849829ca661 100644 --- a/mps/design/keyword-arguments.txt +++ b/mps/design/keyword-arguments.txt @@ -103,10 +103,10 @@ but ``arg.h`` provides a macro for this:: We define keys as static structures (rather than, say, an enum) because: - The set of keys can be extended indefinitely. -- The set of keys can be extended by indepdently linked modules. +- The set of keys can be extended by independently linked modules. - The structure contents allow strong checking of argument lists. -In the MPS Interface, we declare keys like this:: +In the MPS C Interface, we declare keys like this:: extern const struct mps_key_s _mps_key_extend_by; #define MPS_KEY_EXTEND_BY (&_mps_key_extend_by) From 70d946f065cd3bb56075a1b28c112ab22564159f Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 17:24:33 +0100 Subject: [PATCH 17/24] Fix typo. Copied from Perforce Change: 185253 ServerID: perforce.ravenbrook.com --- mps/manual/source/topic/scanning.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/manual/source/topic/scanning.rst b/mps/manual/source/topic/scanning.rst index 1dbb15399c8..474ec637dd8 100644 --- a/mps/manual/source/topic/scanning.rst +++ b/mps/manual/source/topic/scanning.rst @@ -56,7 +56,7 @@ region to be scanned. They must carry out the following steps: a pointer to a location containing the reference. #. If :c:func:`MPS_FIX2` returns a :term:`result code` other than - :c:func:`MPS_RES_OK`, return this result code from the scanning + :c:macro:`MPS_RES_OK`, return this result code from the scanning function as soon as practicable. #. If :c:func:`MPS_FIX2` returns :c:macro:`MPS_RES_OK`, it may have From 12c2544befe57e78974ad64b3ad284b86663f33c Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 17:25:11 +0100 Subject: [PATCH 18/24] Write release notes for release 1.111.0. Copied from Perforce Change: 185254 ServerID: perforce.ravenbrook.com --- mps/manual/source/release.rst | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 3e6f650e146..46733076724 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -144,3 +144,86 @@ Other changes exception while the MPS is holding the arena lock. See job003640_. .. _job003640: https://www.ravenbrook.com/project/mps/issue/job003640/ + + +.. _release-notes-1.111: + +Release 1.111.0 +--------------- + +New features +............ + +#. Reporting features have been removed from the :ref:`mpseventcnv + ` utility. Instead, the telemetry system + comes with two new utility programs to assist with reporting and + analysis: :ref:`mpseventtxt ` converts an + event stream into human-readable form, and :ref:`mpseventsql + ` loads an event stream into a SQLite + database for further analysis. See :ref:`topic-telemetry`. + +#. The new pool class MFS provide manually managed allocation of + fixed-size objects. See :ref:`pool-mfs`. + +#. The new pool class MVT provide manually managed allocation of + variable-size objects using a *temporal fit* allocation policy + (that is, objects that are allocated togther are expected to be + freed together). See :ref:`pool-mvt`. + + +Interface changes +................. + +#. It is no longer necessary for client programs to use + :c:func:`mps_tramp` to ensure that exceptions due to barrier hits + are caught. This function is now deprecated. + +#. You can set the environment variable + :envvar:`MPS_TELEMETRY_CONTROL` to ``all`` to make the telemetry + system output all events. See :ref:`topic-telemetry`. + +#. New functions :c:func:`mps_telemetry_get`, + :c:func:`mps_telemetry_set` and :c:func:`mps_telemetry_reset` + provide a more convenient interface to telemetry control than + :c:func:`mps_telemetry_control`, which is now deprecated. See + :ref:`topic-telemetry`. + +#. The pool classes :ref:`pool-mv` and :ref:`pool-snc` are now + deprecated. + +#. Allocation frames are now deprecated. See :ref:`topic-frame`. + +#. Additionally, the functions :c:func:`mps_arena_expose`, + :c:func:`mps_arena_unsafe_expose_remember_protection`, + :c:func:`mps_arena_unsafe_restore_protection`, + :c:func:`mps_arena_roots_walk`, and :c:func:`mps_fix` are now + deprecated. + + +Other changes +............. + +#. :c:func:`mps_arena_step` no longer unclamps the arena as a side + effect. If the arena is clamped or parked before calling + :c:func:`mps_arena_step`, it is clamped afterwards. See job003320_. + + .. _job003320: https://www.ravenbrook.com/project/mps/issue/job003320/ + +#. The ambiguous stack scanner, :c:func:`mps_stack_scan_ambig`, no + longer asserts on Linux when there are multiple threads. See + job003412_. + + .. _job003412: https://www.ravenbrook.com/project/mps/issue/job003412/ + +#. It is no longer possible for the "ramp" allocation pattern, + :c:func:`mps_alloc_pattern_ramp()`, to get stuck. Now + :c:func:`mps_ap_alloc_pattern_end` reliably clears this pattern. + See job003454_. + + .. _job003454: https://www.ravenbrook.com/project/mps/issue/job003454/ + +#. The build system now correctly detects the FreeBSD operating system + running on the x86-64 architecture, for FreeBSD version 9.1 or + later. See job003473_. + + .. _job003473: https://www.ravenbrook.com/project/mps/issue/job003473/ From 116021aef09b1d63766aa5181f9e99e7e053feb2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 20:00:31 +0100 Subject: [PATCH 19/24] Complete design.mps.type and design.mps.interface-c and move them to "current" design in the manual. Remove unused enumeration FormatVariety from mpmtypes. Improve wording of manual entry on MPS_RM_PROT. Copied from Perforce Change: 185259 ServerID: perforce.ravenbrook.com --- mps/code/mpmtypes.h | 17 +- mps/design/interface-c.txt | 247 ++++---- mps/design/type.txt | 914 +++++++++++++++++------------ mps/manual/source/design/index.rst | 2 + mps/manual/source/design/old.rst | 2 - mps/manual/source/topic/root.rst | 2 +- 6 files changed, 683 insertions(+), 501 deletions(-) diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index 9aac8322b35..693a2262247 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -1,7 +1,7 @@ /* mpmtypes.h: MEMORY POOL MANAGER TYPES * * $Id$ - * Copyright (c) 2001-2002, 2006 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (c) 2001 Global Graphics Software. * * .design: @@ -41,7 +41,7 @@ typedef unsigned Shift; /* */ typedef unsigned Serial; /* */ typedef Addr Ref; /* */ typedef void *Pointer; /* */ -typedef Word Clock; /* processor time */ +typedef Word Clock; /* */ typedef MPS_T_ULONGEST ULongest; /* */ typedef mps_arg_s ArgStruct; @@ -60,7 +60,6 @@ typedef unsigned TraceSet; /* */ typedef unsigned TraceState; /* */ typedef unsigned AccessSet; /* */ typedef unsigned Attr; /* */ -typedef unsigned FormatVariety; typedef int RootVar; /* */ typedef Word *BT; /* */ @@ -300,16 +299,6 @@ typedef struct TraceMessageStruct *TraceMessage; /* trace end */ AttrGC | AttrINCR_RB | AttrINCR_WB | AttrMOVINGGC) -/* Format varieties */ -enum { - FormatVarietyA = 1, - FormatVarietyB, - FormatVarietyAutoHeader, - FormatVarietyFixed, - FormatVarietyLIMIT -}; - - /* Segment preferences */ enum { SegPrefHigh = 1, @@ -465,7 +454,7 @@ typedef double WriteFD; /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002, 2006 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/design/interface-c.txt b/mps/design/interface-c.txt index fabf45f6344..1585318fa28 100644 --- a/mps/design/interface-c.txt +++ b/mps/design/interface-c.txt @@ -6,7 +6,7 @@ C interface design :Tag: design.mps.interface.c :Author: Richard Brooksby :Date: 1996-07-29 -:Status: incomplete document +:Status: complete design :Revision: $Id$ :Copyright: See `Copyright and License`_. :Index terms: pair: C interface; design @@ -29,7 +29,9 @@ Goals _`.goal.c`: The file impl.h.mps is the C external interface to the MPS. It is the default interface between client code written in C and -the MPS. _`.goal.cpp`: impl.h.mps is not specifically designed to be +the MPS. + +_`.goal.cpp`: impl.h.mps is not specifically designed to be an interface to C++, but should be usable from C++. @@ -38,36 +40,32 @@ Requirements _`.req`: The interface must provide an interface from client code written in C to the functionality of the MPS required by the product -(see req.product), Dylan (req.dylan), and the Core RIP (req.epcore). +(see req.product), and Open Dylan (req.dylan). -``mps.h`` may not include internal MPS header files (such as -``pool.h``). +_`.req.separation`: The external interface may not include internal +MPS header files (such as ``pool.h``). -It is essential that the interface cope well with change, in order to -avoid restricting possible future MPS developments. This means that -the interface must be "open ended" in its definitions. This accounts -for some of the apparently tortuous methods of doing things -(``mps_fmt_A_t``, for example). The requirement is that the MPS should +_`.req.flexibility`: It is essential that the interface cope well with +change, in order to avoid restricting possible future MPS +developments. This means that the interface must be "open ended" in +its definitions. This accounts for some of the apparently tortuous +methods of doing things (such as the keyword argument mechanism; see +design.mps.keyword-arguments_). The requirement is that the MPS should be able to add new functionality, or alter the implementation of existing functionality, without affecting existing client code. A stronger requirement is that the MPS should be able to change without *recompiling* client code. This is not always possible. -.. note:: +.. _design.mps.keyword-arguments: keyword-arguments - `.naming.global` was presumably done in response to unwritten - requirements regarding the use of the name spaces in C, perhaps - these: +_`.req.name.iso`: The interface shall not conflict in terms of +naming with any interfaces specified by ISO C and all reasonable +future versions. - - _`.req.name.iso`: The interface shall not conflict in terms of - naming with any interfaces specified by ISO C and all reasonable - future versions. - - - _`.req.name.general`: The interface shall use a documented and - reasonably small portion of the namespace so that clients can - interoperate easily. - - David Jones, 1998-10-01. +_`.req.name.general`: The interface shall use a documented and +reasonably small portion of the namespace so that clients can use the +MPS C interface in combination with other interfaces without name +conflicts. Architecture @@ -82,13 +80,18 @@ layer" which does the job of converting types and checking parameters before calling through to the MPS proper, using internal MPS methods. -General conventions -------------------- +Naming conventions +------------------ _`.naming`: The external interface names should adhere to the -documented interface conventions; these are found in -doc.mps.ref-man.if-conv(0).naming. They are paraphrased/recreated -here. +documented interface conventions; these are found in the “`Interface +conventions`_” chapter of the Reference Manual. They are +paraphrased/recreated here. + +.. _Interface conventions: ../topic/interface.html + +_`.naming.file`: All files in the external interface have names +starting with ``mps``. _`.naming.unixy`: The external interface does not follow the same naming conventions as the internal code. The interface is designed to @@ -97,13 +100,13 @@ resemble a more conventional C, Unix, or Posix naming convention. _`.naming.case`: Identifiers are in lower case, except non-function-like macros, which are in upper case. -_`.naming.global`: All publicised identifiers are -prefixed ``mps_`` or ``MPS_``. +_`.naming.global`: All documented identifiers begin ``mps_`` or +``MPS_``. -_`.naming.all`: All identifiers defined by the MPS -should begin ``mps_`` or ``MPS_`` or ``_mps_``. +_`.naming.all`: All identifiers defined by the MPS begin ``mps_`` or +``MPS_`` or ``_mps_``. -_`.naming.type`: Types are suffixed ``_t``. +_`.naming.type`: Types are suffixed ``_t``, except for structure and union types. _`.naming.struct`: Structure types and tags are suffixed ``_s``. @@ -117,15 +120,14 @@ structure and union members, macros, macro parameters, labels. _`.naming.scope.labels`: labels (for ``goto`` statements) should be rare, only in special block macros and probably not even then. -.. note:: - - This principle is not adhered to in the source code, which uses - ``goto`` for handling error cases. Gareth Rees, 2013-05-27. - _`.naming.scope.other`: The naming convention would also extend to enumeration types and parameters in functions prototypes but both of those are prohibited from having names in an interface file. + +Type conventions +---------------- + _`.type.gen`: The interface defines memory addresses as ``void *`` and sizes as ``size_t`` for compatibility with standard C (in particular, with ``malloc()``). These types must be binary compatible with the @@ -139,13 +141,13 @@ which are never defined. These types are cast to the corresponding internal types in ``mpsi.c``. _`.type.trans`: Some transparent structures are defined. The client is -expected to read these, or poke about in them, under restrictions -which should be documented. The most important is probably the -allocation point (``mps_ap_s``) which is part of allocation buffers. -The transparent structures must be binary compatible with -corresponding internal structures. For example, the fields of -``mps_ap_s`` must correspond with ``APStruct`` internally. This is -checked by ``mpsi.c`` in ``mps_check()``. +expected to read these, or poke about in them, under documented +restrictions. The most important is the allocation point structure +(``mps_ap_s``) which is part of allocation buffers. The transparent +structures must be binary compatible with corresponding internal +structures. For example, the fields of ``mps_ap_s`` must correspond +with ``APStruct`` internally. This is checked by ``mpsi.c`` in +``mps_check()``. _`.type.pseudo`: Some pseudo-opaque structures are defined. These only exist so that code can be inlined using macros. The client code @@ -153,9 +155,9 @@ shouldn't mess with them. The most important case of this is the scan state (``mps_ss_s``) which is accessed by the in-line scanning macros, ``MPS_SCAN_*`` and ``MPS_FIX*``. -_`.type.enum`: There should be no enumeration types in the interface. -Note that enum specifiers (to declare integer constants) are fine as -long as no type is declared. See guide.impl.c.misc.enum.type. +_`.type.enum`: There are no enumeration types in the interface. Note +that enum specifiers (to declare integer constants) are fine as long +as no type is declared. See guide.impl.c.misc.enum.type. _`.type.fun`: Whenever function types or derived function types (such as pointer to function) are declared a prototype should be used and @@ -184,39 +186,32 @@ See guide.impl.c.misc.prototype.parameters. Checking -------- -_`.check.space`: When the arena needs to be recovered from a parameter -it is check using ``AVERT(Foo, foo)`` before any attempt to call -``FooArena(foo)``. The macro ``AVERT()`` in impl.h.assert performs -simple thread-safe checking of ``foo``, so it can be called outside of -``ArenaEnter()`` and ``ArenaLeave()``. +_`.check.avert`: Before any use of a function paramater ``FOO *foo`` +it is checked using ``AVERT(Foo, foo)``. The macro ``AVERT()`` in +impl.h.check performs simple thread-safe checking of ``foo``, so it +can be called outside of ``ArenaEnter()`` and ``ArenaLeave()``. _`.check.types`: We use definitions of types in both our external interface and our internal code, and we want to make sure that they are compatible. (The external interface changes less often and hides -more information.) At first, we were just checking their sizes, which -wasn't very good, but I've come up with some macros which check the -assignment compatibility of the types too. This is a sufficiently -useful trick that I thought I'd send it round. It may be useful in -other places where types and structures need to be checked for -compatibility at compile time. - -These macros don't generate warnings on the compilers I've tried. +more information.) This checking uses the following macros. ``COMPATLVALUE(lvalue1, lvalue2)`` -This macro checks the assignment compatibility of two lvalues. It uses -``sizeof()`` to ensure that the assignments have no effect. :: +_`.check.types.compat.lvalue`: This macro checks the assignment +compatibility of two lvalues. It uses ``sizeof()`` to ensure that the +assignments have no effect. :: #define COMPATLVALUE(lv1, lv2) \ ((void)sizeof((lv1) = (lv2)), (void)sizeof((lv2) = (lv1)), TRUE) ``COMPATTYPE(type1, type2)`` -This macro checks that two types are assignment-compatible and equal -in size. The hack here is that it generates an lvalue for each type by -casting zero to a pointer to the type. The use of ``sizeof()`` avoids -the undefined behaviour that would otherwise result from dereferencing -a null pointer. :: +_`.check.types.compat.type`: This macro checks that two types are +assignment-compatible and equal in size. The hack here is that it +generates an lvalue for each type by casting zero to a pointer to the +type. The use of ``sizeof()`` avoids the undefined behaviour that +would otherwise result from dereferencing a null pointer. :: #define COMPATTYPE(t1, t2) \ (sizeof(t1) == sizeof(t2) && \ @@ -224,8 +219,8 @@ a null pointer. :: ``COMPATFIELDAPPROX(structure1, field1, structure2, field2)`` -This macro checks that the offset and size of two fields in two -structure types are the same. :: +_`.check.types.compat.field.approx`: This macro checks that the offset +and size of two fields in two structure types are the same. :: #define COMPATFIELDAPPROX(s1, f1, s2, f2) \ (sizeof(((s1 *)0)->f1) == sizeof(((s2 *)0)->f2) && \ @@ -233,8 +228,8 @@ structure types are the same. :: ``COMPATFIELD(structure1, field1, structure2, field2)`` -This macro checks the offset, size, and assignment-compatibility of -two fields in two structure types. :: +_`.check.types.compat.field`: This macro checks the offset, size, and +assignment-compatibility of two fields in two structure types. :: #define COMPATFIELD(s1, f1, s2, f2) \ (COMPATFIELDAPPROX(s1, f1, s2, f2) && \ @@ -247,21 +242,34 @@ Binary compatibility issues As in, "Enumeration types are not allowed" (see mail.richard.1995-09-08.09-28). -There are two main aspects to run-time compatibility: binary interface -and protocol. The binary interface is all the information needed to -correctly use the library, and includes external symbol linkage, +_`.compat`: There are two main aspects to run-time compatibility: +binary interface and protocol. + +_`.compat.binary`: The binary interface is all the information needed +to correctly use the library, and includes external symbol linkage, calling conventions, type representation compatibility, structure -layouts, etc. The protocol is how the library is actually used by the -client code -- whether this is called before that -- and determines -the semantic correctness of the client with respect to the library. +layouts, etc. -The binary interface is determined completely by the header file and -the target. The header file specifies the external names and the -types, and the target platform specifies calling conventions and type -representation. There is therefore a many-to-one mapping between the -header file version and the binary interface. +_`.compat.binary.unneeded`: Binary compatibility is not required by +the open source MPS: we expect (and indeed, recommend) that a client +program is compiled against the MPS sources. Nonetheless we try to +maintain binary compatibility in case the capability is required in +future. -The protocol is determined by the implementation of the library. +_`.compat.binary.dependencies`: The binary interface is determined +completely by the header file and the target. The header file +specifies the external names and the types, and the target platform +specifies calling conventions and type representation. There is +therefore a many-to-one mapping between the header file version and +the binary interface. + +_`.compat.protocol`: The protocol is how the library is actually used +by the client code -- whether this is called before that -- and +determines the semantic correctness of the client with respect to the +library. + +_`.compat.protocol.dependencies`: The protocol is determined by the +implementation of the library. Constraints @@ -291,34 +299,59 @@ interface constrains ``Word`` to being the same size as C's generic pointer type, ``void *``. +Implementation +-------------- + +_`.impl`: The external interface consists of the following header +files: + +_`.impl.mps`: ``mps.h`` is the main external interface, containing of +type and function declarations needed by all clients of the MPS. + +_`.impl.mpstd`: ``mpstd.h`` is the MPS target detection header. It +decodes preprocessor symbols which are predefined by build +environments in order to determine the target platform (see +design.mps.config_), and then defines uniform symbols, such as +``MPS_ARCH_I3``, for use externally and internally by the MPS. +``mpstd.h`` is not included by any of the other external headers, as +it relies on exact set of preprocessor constants defined by compilers. + +.. _design.mps.config: config + +_`.impl.mpsio`: ``mpsio.h`` is the interface to the MPS I/O subsystem, +part of the plinth. See design.mps.io_. + +.. _design.mps.io: io + +_`.impl.mpslib`: ``mpslib.h`` is the interface to the MPS Library +Interface, part of the plinth. See design.mps.lib_. + +.. _design.mps.lib: lib + +_`.impl.mpsa`: Interfaces to arena classes are in files with names +starting ``mpsa``: for example, the interface to the Virtual Memory +arena class is in ``mpsavm.h``. + +_`.impl.mpsc`: Interfaces to pool classes are in files with names +starting ``mpsc``: for example, the interface to the MVFF pool class +is in ``mpscmvff.h``. + + Notes ----- -The file ``mpstd.h`` is the MPS target detection header. It decodes -preprocessor symbols which are predefined by build environments in -order to determine the target platform, and then defines uniform -symbols, such as ``MPS_ARCH_I3``, for use internally by the MPS. +_`.fmt.extend`: ``mps_fmt_A_t`` is so called because new pool classes +might require new format methods, but these methods cannot be added to +the format structure without breaking binary compatibility. Therefore +these new pool classes would use new format structures named +``mps_fmt_B_t`` and so on. -There is a design document for the mps interface, -design.mps.interface, but it was written before we had the idea of -having a C interface layer. It is quite relevant, though, and could be -updated. We should use it during the review. - -All exported identifiers and file names should begin with ``mps_`` or -``MPS_`` so that they don't clash with other systems. - -We should probably have a specialized set of rules and a special -checklist for this interface. - -_`.fmt.extend`: This paragraph should be an explanation of why -``mps_fmt_A_t`` is so called. The underlying reason is future -extensibility. - -_`.thread-safety`: Most calls through this interface lock the space +_`.thread-safety`: Most calls through this interface lock the arena and therefore make the MPM single-threaded. In order to do this they -must recover the space from their parameters. Methods such as -``ThreadSpace()`` must therefore be callable when the space is *not* -locked. These methods are tagged with the tag of this note. +must recover the arena from their parameters. Methods such as +``FormatArena()`` and ``ThreadArena()`` must therefore be callable +when the arena is *not* locked. These methods are tagged with the tag +of this note. _`.lock-free`: Certain functions inside the MPM are thread-safe and do not need to be serialized by using locks. They are marked with the tag diff --git a/mps/design/type.txt b/mps/design/type.txt index 9ab6a782377..e5f347d244b 100644 --- a/mps/design/type.txt +++ b/mps/design/type.txt @@ -6,7 +6,7 @@ General MPS types :Tag: design.mps.type :Author: Richard Brooksby :Date: 1996-10-23 -:Status: incomplete document +:Status: complete document :Revision: $Id$ :Copyright: See `Copyright and License`_. :Index terms: pair: general types; design @@ -32,6 +32,87 @@ say ``Byte`` in your code if it's what you mean. Concrete types -------------- +``typedef unsigned AccessSet`` + +_`.access-set`: An ``AccessSet`` is a bitset of ``Access`` modes, +which are ``AccessREAD`` and ``AccessWRITE``. ``AccessSetEMPTY`` is +the empty ``AccessSet``. + + +``typedef struct AddrStruct *Addr`` + +_`.addr`: ``Addr`` is the type used for "managed addresses", that is, +addresses of objects managed by the MPS. + +_`.addr.def`: ``Addr`` is defined as ``struct AddrStruct *``, but +``AddrStruct`` is never defined. This means that ``Addr`` is always an +incomplete type, which prevents accidental dereferencing, arithmetic, +or assignment to other pointer types. + +_`.addr.use`: ``Addr`` should be used whenever the code needs to deal +with addresses. It should not be used for the addresses of memory +manager data structures themselves, so that the memory manager remains +amenable to working in a separate address space. Be careful not to +confuse ``Addr`` with ``void *``. + +_`.addr.ops`: Limited arithmetic is allowed on addresses using +``AddrAdd()`` and ``AddrOffset()`` (impl.c.mpm). Addresses may also be +compared using the relational operators ``==``, ``!=``, ``<``, ``<=``, +``>``, and ``>=``. + +_`.addr.ops.mem`: We need efficient operators similar to ``memset()``, +``memcpy()``, and ``memcmp()`` on ``Addr``; these are called ``AddrSet()``, +``AddrCopy()``, and ``AddrComp()``. When ``Addr`` is compatible with +``void *``, these are implemented through the functions +``mps_lib_memset()``, ``mps_lib_memcpy()``, and ``mps_lib_memcmp()`` +functions in the plinth (impl.h.mpm). + +_`.addr.conv.c`: ``Addr`` is converted to ``mps_addr_t`` in the MPS C +Interface. ``mps_addr_t`` is defined to be the same as ``void *``, so +using the MPS C Interface confines the memory manager to the same +address space as the client data. + + +``typedef Word Align`` + +_`.align`: ``Align`` is an unsigned integral type which is used to +represent the alignment of managed addresses. All alignments are +positive powers of two. ``Align`` is large enough to hold the maximum +possible alignment. + +_`.align.use`: ``Align`` should be used whenever the code needs to +deal with the alignment of a managed address. + +_`.align.conv.c`: ``Align`` is converted to ``mps_align_t`` in the MPS +C Interface. + + +``typedef unsigned Attr`` + +_`.attr`: Pool attributes. A bitset of pool or pool class +attributes, which are: + +=================== =================================================== +Attribute Description +=================== =================================================== +``AttrALLOC`` Supports the ``PoolAlloc`` interface. +``AttrBUF`` Supports the buffer interface. +``AttrFMT`` Contains formatted objects. + Used to decide which pools to walk. +``AttrFREE`` Supports the ``PoolFree`` interface. +``AttrGC`` Is garbage collecting, that is, parts may be + reclaimed. Used to decide which segments are + condemned. +``AttrMOVINGGC`` Is moving, that is, objects may move in memory. + Used to update the set of zones that might have + moved and so implement location dependency. +``AttrSCAN`` Contains references and must be scanned. +=================== =================================================== + +There is an attribute field in the pool class (``PoolClassStruct``) +which declares the attributes of that class. + + ``typedef int Bool`` _`.bool`: The ``Bool`` type is mostly defined so that the intention of @@ -71,63 +152,135 @@ for ``BoolCheck`` on the PC Aaron. "With" ran in 97.7% of the time (averaged over 3 runs). -``typedef int Res`` +``typedef unsigned BufferMode`` -_`.res`: ``Res`` is the type of result codes. A result code indicates -the success or failure of an operation, along with the reason for -failure. Like Unix error codes, the meaning of the code depends on the -call that returned it. These codes are just broad categories with -mnemonic names for various sorts of problems. +_`.buffermode`: ``BufferMode`` is a bitset of buffer attributes. See +design.mps.buffer_. It is a sum of the following: -=================== ======================================================= -Result code Description -=================== ======================================================= -``ResOK`` The operation succeeded. Return parameters may only be - updated if OK is returned, otherwise they must be left - untouched. -------------------- ------------------------------------------------------- -``ResFAIL`` Something went wrong which doesn't fall into any of the - other categories. The exact meaning depends on the - call. See documentation. -------------------- ------------------------------------------------------- -``ResRESOURCE`` A needed resource could not be obtained. Which resource - depends on the call. See also ``ResMEMORY``, which is a - special case of this. -------------------- ------------------------------------------------------- -``ResMEMORY`` Needed memory (committed memory, not address space) - could not be obtained. -------------------- ------------------------------------------------------- -``ResLIMIT`` An internal limitation was reached. For example, the - maximum number of somethings was reached. We should - avoid returning this by not including static - limitations in our code, as far as possible. (See - rule.impl.constrain and - rule.impl.limits.) -------------------- ------------------------------------------------------- -``ResUNIMPL`` The operation, or some vital part of it, is - unimplemented. This might be returned by functions - which are no longer supported, or by operations which - are included for future expansion, but not yet - supported. -------------------- ------------------------------------------------------- -``ResIO`` An I/O error occurred. Exactly what depends on the - function. -------------------- ------------------------------------------------------- -``ResCOMMIT_LIMIT`` The arena's commit limit would have been exceeded - as a result of allocation. -------------------- ------------------------------------------------------- -``ResPARAM`` An invalid parameter was passed. Normally reserved for - parameters passed from the client. -=================== ======================================================= +.. _design.mps.buffer: buffer -_`.res.use`: ``Res`` should be returned from any function which might -fail. Any other results of the function should be passed back in -"return" parameters (pointers to locations to fill in with the -results). +======================== ============================================== +Mode Description +======================== ============================================== +``BufferModeATTACHED`` Buffer is attached to a region of memory. +``BufferModeFLIPPED`` Buffer has been flipped. +``BufferModeLOGGED`` Buffer emits the events ``BufferReserve`` and + ``BufferCommit``. +``BufferModeTRANSITION`` Buffer is in the process of being detached. +======================== ============================================== -.. note:: This is documented elsewhere, I think -- richard -_`.res.use.spec`: The most specific code should be returned. +``typedef unsigned char Byte`` + +_`.byte`: ``Byte`` is an unsigned integral type corresponding to the +unit in which most sizes are measured, and also the units of +``sizeof``. + +_`.byte.use`: ``Byte`` should be used in preference to ``char`` or +``unsigned char`` wherever it is necessary to deal with bytes +directly. + +_`.byte.source`: ``Byte`` is a just pedagogic version of ``unsigned +char``, since ``char`` is the unit of ``sizeof``. + + +``typedef Word Clock`` + +_`.clock`: ``Clock`` is an unsigned integral type representing clock +time since some epoch. + +_`.clock.use`: A ``Clock`` value is returned by the plinth function +``mps_clock``. It is used to make collection scheduling decisions and +to calibrate the time stamps on events in the telemetry stream. + +_`.clock.units`: The plinth function ``mps_clocks_per_sec`` defines +the units of a ``Clock`` value. + +_`.clock.conv.c`: ``Clock`` is converted to ``mps_clock_t`` in the MPS +C Interface. + + +``typedef unsigned Compare`` + +_`.compare`: ``Compare`` is the type of tri-state comparison +values. + +================== ==================================================== +Value Description +================== ==================================================== +``CompareLESS`` A value compares less than another value. +``CompareEQUAL`` Two values compare the same. +``CompareGREATER`` A value compares greater than another value. +================== ==================================================== + + +``typedef Word Count`` + +_`.count`: ``Count`` is an unsigned integral type which is large +enough to hold the size of any collection of objects in the MPS. + +_`.count.use`: ``Count`` should be used for a number of objects +(control or managed) where the maximum number of objects cannot be +statically determined. If the maximum number can be statically +determined then the smallest unsigned integer with a large enough +range may be used instead (although ``Count`` may be preferable for +clarity). + +_`.count.use.other`: ``Count`` may also be used to count things that +aren't represented by objects (for example, levels), but only where it +can be determined that the maximum count is less than the number of +objects. + + +``typedef Size Epoch`` + +_`.epoch`: An ``Epoch`` is a count of the number of flips that have +occurred. It is used in the implementation of location dependencies. + +``Epoch`` is converted to ``mps_word_t`` in the MPS C Interface, as a +field of ``mps_ld_s``. + + +``typedef unsigned FindDelete`` + +_`.finddelete`: ``FindDelete`` represents an instruction to one of the +*find* methods of a ``Land`` as to what it should do if it finds a +suitable block. See design.mps.land_. It takes one of the following +values: + +.. _design.mps.land: land + +==================== ================================================== +Value Description +==================== ================================================== +``FindDeleteNONE`` Don't delete after finding. +``FindDeleteLOW`` Delete from low end of block. +``FindDeleteHIGH`` Delete from high end of block. +``FindDeleteENTIRE`` Delete entire block. +==================== ================================================== + + +``typedef unsigned FrameState`` + +_`.framestate`: ``FrameState`` represents the current state in a +buffer frame's lifecycle. See design.mps.alloc-frame_. It takes one of +the following values: + +.. _design.mps.alloc-frame: alloc-frame + +========================== ============================================ +State Description +========================== ============================================ +``BufferFrameVALID`` Indicates that ``PushFrame()`` can be a + lightweight operation and need not be + synchronized. +``BufferFramePOP_PENDING`` Indicates that there has been a + ``PopFrame()`` operation that the pool + must respond to. +``BufferFrameDISABLED`` Indicates that the pool has disabled + support for lightweight operations for + this buffer. +========================== ============================================ ``typedef void (*Fun)(void)`` @@ -142,6 +295,328 @@ through to a third function ``h``, where ``h`` knows the real type of ``f`` but ``g`` doesn't. +``typedef Word Index`` + +_`.index`: ``Index`` is an unsigned integral type which is large +enough to hold any array index. + +_`.index.use`: ``Index`` should be used where the maximum size of the +array cannot be statically determined. If the maximum size can be +determined then the smallest unsigned integer with a large enough +range may be used instead. + + +``typedef unsigned MessageType`` + +_`.messagetype`: ``MessageType`` is the type of a message. See +design.mps.message_. It takes one of the following values: + +.. _design.mps.message: message + +=========================== =========================================== +Message type Description +=========================== =========================================== +``MessageTypeFINALIZATION`` A block is finalizable. +``MessageTypeGC`` A garbage collection finished. +``MessageTypeGCSTART`` A garbage collection started. +=========================== =========================================== + + +``typedef unsigned Rank`` + +_`.rank`: ``Rank`` is an enumeration which represents the rank of a +reference. The ranks are: + +============= ===== ================================================== +Rank Index Description +============= ===== ================================================== +``RankAMBIG`` 0 The reference is ambiguous. That is, it must be + assumed to be a reference, but not updated in + case it isn't. +``RankEXACT`` 1 The reference is exact, and refers to an object. +``RankFINAL`` 2 The reference is exact and final, so special + action is required if only final or weak + references remain to the object. +``RankWEAK`` 3 The reference is exact and weak, so should + be deleted if only weak references remain to the + object. +============= ===== ================================================== + +``Rank`` is stored with segments and roots, and passed around. + +``Rank`` is converted to ``mps_rank_t`` in the MPS C Interface. + +The ordering of the ranks is important. It is the order in which the +references must be scanned in order to respect the properties of +references of the ranks. Therefore they are declared explicitly with +their integer values. + +.. note:: Could ``Rank`` be a ``short``? + +.. note:: + + This documentation should be expanded and moved to its own + document, then referenced from the implementation more thoroughly. + + +``typedef unsigned RankSet`` + +_`.rankset`: ``RankSet`` is a set of ranks, represented as a bitset. + + +``typedef Addr Ref`` + +_`.ref`: ``Ref`` is a reference to a managed object (as opposed to any +old managed address). ``Ref`` should be used where a reference is +intended. + +.. note:: This isn't too clear -- richard + + +``typedef Word RefSet`` + +_`.refset`: ``RefSet`` is a conservative approximation to a set of +references. See design.mps.refset_. + +.. _design.mps.refset: refset + + +``typedef int Res`` + +_`.res`: ``Res`` is the type of result codes. A result code indicates +the success or failure of an operation, along with the reason for +failure. Like Unix error codes, the meaning of the code depends on the +call that returned it. These codes are just broad categories with +mnemonic names for various sorts of problems. + +=================== =================================================== +Result code Description +=================== =================================================== +``ResOK`` The operation succeeded. Return parameters may only + be updated if OK is returned, otherwise they must + be left untouched. +``ResCOMMIT_LIMIT`` The arena's commit limit would have been exceeded + as a result of allocation. +``ResFAIL`` Something went wrong which doesn't fall into any of + the other categories. The exact meaning depends + on the call. See documentation. +``ResIO`` An I/O error occurred. Exactly what depends on the + function. +``ResLIMIT`` An internal limitation was reached. For example, + the maximum number of somethings was reached. We + should avoid returning this by not including + static limitations in our code, as far as + possible. (See rule.impl.constrain and + rule.impl.limits.) +``ResMEMORY`` Needed memory (committed memory, not address space) + could not be obtained. +``ResPARAM`` An invalid parameter was passed. Normally reserved + for parameters passed from the client. +``ResRESOURCE`` A needed resource could not be obtained. Which + resource depends on the call. See also + ``ResMEMORY``, which is a special case of this. +``ResUNIMPL`` The operation, or some vital part of it, is + unimplemented. This might be returned by + functions which are no longer supported, or by + operations which are included for future + expansion, but not yet supported. +=================== =================================================== + +_`.res.use`: ``Res`` should be returned from any function which might +fail. Any other results of the function should be passed back in +"return" parameters (pointers to locations to fill in with the +results). + +.. note:: This is documented elsewhere, I think -- richard + +_`.res.use.spec`: The most specific code should be returned. + + +``typedef unsigned RootMode`` + +_`.rootmode`: ``RootMode`` is an unsigned integral type which is used +to represent an attribute of a root: + +============================= ========================================= +Root mode Description +============================= ========================================= +``RootModeCONSTANT`` Client program will not change the root + after it is registered. +``RootModePROTECTABLE`` Root is protectable: the MPS may place + a barrier on any page containing any + part of the root. +``RootModePROTECTABLE_INNER`` Root is protectable: the MPS may place + a barrier on any page completely covered + by part of the root. +============================= ========================================== + +_`.rootmode.const.unused`: ``RootModeCONSTANT`` has no effect. This +mode was introduced in the hope of being able to maintain a +:term:`remembered set` for the root without needing a :term:`write +barrier`, but it can't work as described, since you can't reliably +create a valid registered constant root that contains any references. +(If you add the references before registering the root, they may have +become invalid; but you can't add them afterwards because the root is +supposed to be constant.) + +_`.rootmode.conv.c`: ``RootMode`` is converted to ``mps_rm_t`` in the MPS C +Interface. + + +``typedef int RootVar`` + +_`.rootvar`: The type ``RootVar`` is the type of the +discriminator for the union within ``RootStruct``. + + +``typedef int SegPrefKind`` + +_`.segprefkind`: The type ``SegPrefKind`` expresses a preference about +where the arena should place a segment. It takes one of the following +values: + +================== ==================================================== +Kind Description +================== ==================================================== +``SegPrefHigh`` Place the segment high in the address space. +``SegPrefLow`` Place the segment low in the address space. +``SegPrefZoneSet`` Place the segment in specified zones. +================== ==================================================== + + +``typedef unsigned Serial`` + +_`.serial`: A ``Serial`` is a number which is assigned to a structure +when it is initialized. The serial number is taken from a field in the +parent structure, which is incremented. Thus, every instance of a +structure has a unique "name" which is a path of structures from the +global root. For example:: + + space[3].pool[5].buffer[2] + +Why? Consistency checking, debugging, and logging. Not well thought +out. + + +``typedef unsigned Shift`` + +_`.shift`: ``Shift`` is an unsigned integral type which can hold the +amount by which a ``Word`` can be shifted. It is therefore large +enough to hold the word width (in bits). + +_`.shift.use`: ``Shift`` should be used whenever a shift value (the +right-hand operand of the ``<<`` or ``>>`` operators) is intended, to +make the code clear. It should also be used for structure fields which +have this use. + + +``typedef unsigned long Sig`` + +_`.sig`: ``Sig`` is the type of signatures, which are written into +structures when they are created, and invalidated when they are +destroyed. They provide a limited form of run-time type checking and +dynamic scope checking. See design.mps.sig_. + +.. _design.mps.sig: sig + + +``typedef Word Size`` + +_`.size`: ``Size`` is an unsigned integral type large enough to +hold the size of any object which the MPS might manage. + +_`.size.byte`: ``Size`` should hold a size calculated in bytes. + +.. warning:: + + This is violated by ``GenParams.capacity`` (which is measured in + kilobytes). + +_`.size.use`: ``Size`` should be used whenever the code needs to deal +with the size of managed memory or client objects. It should not be +used for the sizes of the memory manager's own data structures, so +that the memory manager is amenable to working in a separate address +space. Be careful not to confuse it with ``size_t``. + +_`.size.ops`: ``SizeIsAligned()``, ``SizeAlignUp()``, +``SizeAlignDown()`` and ``SizeRoundUp()``. + +_`.size.conv.c`: ``Size`` is converted to ``size_t`` in the MPS C +Interface. This constrains the memory manager to the same address +space as the client data. + + +``typedef unsigned TraceId`` + +_`.traceid`: A ``TraceId`` is an unsigned integer which is less than +``TRACE_MAX``. Each running trace has a different ``TraceId`` which is +used to index into tables and bitfields used to remember the state of +that trace. + + +``typedef unsigned TraceSet`` + +_`.traceset`: A ``TraceSet`` is a bitset of ``TraceId``, +represented in the obvious way:: + + member(ti, ts) ⇔ ((1<``, and ``>=``. - -_`.addr.ops.mem`: We need efficient operators similar to ``memset()``, -``memcpy()``, and ``memcmp()`` on ``Addr``; these are called ``AddrSet()``, -``AddrCopy()``, and ``AddrComp()``. When ``Addr`` is compatible with -``void *``, these are implemented through the functions -``mps_lib_memset()``, ``mps_lib_memcpy()``, and ``mps_lib_memcmp()`` -functions in the plinth (impl.h.mpm). - -.. note:: - - No other implementation exists at present. pekka 1998-09-07 - -_`.addr.conv.c`: ``Addr`` is converted to ``mps_addr_t`` in the MPS C -Interface. ``mps_addr_t`` is defined to be the same as ``void *``, so -using the MPS C Interface confines the memory manager to the same -address space as the client data. - - -``typedef Word Size`` - -_`.size`: ``Size`` is an unsigned integral type large enough to -hold the size of any object which the MPS might manage. - -_`.size.byte`: ``Size`` should hold a size calculated in bytes. - -.. warning:: This may not be true for all existing code. - -_`.size.use`: ``Size`` should be used whenever the code needs to deal -with the size of managed memory or client objects. It should not be -used for the sizes of the memory manager's own data structures, so -that the memory manager is amenable to working in a separate address -space. Be careful not to confuse it with ``size_t``. - -_`.size.ops`: ``SizeIsAligned()``, ``SizeAlignUp()``, -``SizeAlignDown()`` and ``SizeRoundUp()``. - -_`.size.conv.c`: ``Size`` is converted to ``size_t`` in the MPS C -Interface. This constrains the memory manager to the same address -space as the client data. - - -``typedef Word Align`` - -_`.align`: ``Align`` is an unsigned integral type which is used to -represent the alignment of managed addresses. All alignments are -positive powers of two. ``Align`` is large enough to hold the maximum -possible alignment. - -_`.align.use`: ``Align`` should be used whenever the code needs to -deal with the alignment of a managed address. - -_`.align.conv.c`: ``Align`` is converted to ``mps_align_t`` in the MPS -C Interface. - - -``typedef unsigned Shift`` - -_`.shift`: ``Shift`` is an unsigned integral type which can hold the -amount by which a ``Word`` can be shifted. It is therefore large -enough to hold the word width (in bits). - -_`.shift.use`: ``Shift`` should be used whenever a shift value (the -right-hand operand of the ``<<`` or ``>>`` operators) is intended, to -make the code clear. It should also be used for structure fields which -have this use. - -_`.shift.conv.c`: ``Shift`` is converted to ``mps_shift_t`` in the MPS -C Interface. - - -``typedef Addr Ref`` - -_`.ref`: ``Ref`` is a reference to a managed object (as opposed to any -old managed address). ``Ref`` should be used where a reference is -intended. - -.. note:: This isn't too clear -- richard - - -``typedef Word RefSet`` - -_`.refset`: ``RefSet`` is a conservative approximation to a set of -references. See design.mps.refset. - - -``typedef unsigned Rank`` - -_`.rank`: ``Rank`` is an enumeration which represents the rank of a -reference. The ranks are: - -============= ===== ===================================================== -Rank Index Description -============= ===== ===================================================== -``RankAMBIG`` 0 The reference is ambiguous. That is, it must be - assumed to be a reference, but not updated in case it - isn't. -------------- ----- ----------------------------------------------------- -``RankEXACT`` 1 The reference is exact, and refers to an object. -------------- ----- ----------------------------------------------------- -``RankFINAL`` 2 The reference is exact and final, so special action - is required if only final or weak references remain - to the object. -------------- ----- ----------------------------------------------------- -``RankWEAK`` 3 The reference is exact and weak, so should be deleted - if only weak references remain to the object. -============= ===== ===================================================== - -``Rank`` is stored with segments and roots, and passed around. - -``Rank`` is converted to ``mps_rank_t`` in the MPS C Interface. - -The ordering of the ranks is important. It is the order in which the -references must be scanned in order to respect the properties of -references of the ranks. Therefore they are declared explicitly with -their integer values. - -.. note:: Could ``Rank`` be a ``short``? - -.. note:: - - This documentation should be expanded and moved to its own - document, then referenced from the implementation more thoroughly. - - -``typedef Size Epoch`` - -_`.epoch`: An ``Epoch`` is a count of the number of flips that have -occurred. It is used in the implementation of location dependencies. - -``Epoch`` is converted to ``mps_word_t`` in the MPS C Interface, as a -field of ``mps_ld_s``. - - -``typedef unsigned TraceId`` - -_`.traceid`: A ``TraceId`` is an unsigned integer which is less than -``TRACE_MAX``. Each running trace has a different ``TraceId`` which is -used to index into tables and bitfields used to remember the state of -that trace. - - -``typedef unsigned TraceSet`` - -_`.traceset`: A ``TraceSet`` is a bitset of ``TraceId``, -represented in the obvious way:: - - member(ti, ts) ⇔ ((1< Date: Sun, 6 Apr 2014 21:50:56 +0100 Subject: [PATCH 20/24] Must check against treeempty, not null. Copied from Perforce Change: 185261 ServerID: perforce.ravenbrook.com --- mps/code/dbgpool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/code/dbgpool.c b/mps/code/dbgpool.c index ab0bc7d3cfd..5edeae45035 100644 --- a/mps/code/dbgpool.c +++ b/mps/code/dbgpool.c @@ -1,7 +1,7 @@ /* dbgpool.c: POOL DEBUG MIXIN * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * * .source: design.mps.object-debug @@ -573,7 +573,7 @@ static void TagWalk(Pool pool, ObjectsStepMethod step, void *p) AVERT(PoolDebugMixin, debug); node = SplayTreeFirst(&debug->index); - while (node != NULL) { + while (node != TreeEMPTY) { Tag tag = TagOfTree(node); step(tag->addr, tag->size, NULL, pool, &tag->userdata, p); @@ -691,7 +691,7 @@ void PoolClassMixInDebug(PoolClass class) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * From d3d2795fceef542323e04efe5531de38bcf00d90 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 22:51:05 +0100 Subject: [PATCH 21/24] Improve control over checking: 1. Where Type is a pointer type with a signature, replace CHECKL(TypeCheck(val)) with CHECKD(Type, val). 2. Where Type is a pointer type with no signature, replace CHECKL(TypeCheck(val)) with CHECKD_NOSIG(Type, val). 3. Where Type is a pointer type with a signature, but the structure is not visible at point of checking, replace CHECKL(TypeCheck(val)) with CHECKD_NOSIG(Type, val). Reference 4. Make BTCheck extern and use it where possible. 5. Replace AVER(TypeCheck(val)) with AVERT(Type, val). Copied from Perforce Change: 185263 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 16 ++++++----- mps/code/arenacl.c | 6 ++-- mps/code/arenavm.c | 10 +++---- mps/code/arg.c | 12 ++++---- mps/code/boot.c | 6 ++-- mps/code/bt.c | 38 ++++++++++++------------- mps/code/bt.h | 5 ++-- mps/code/buffer.c | 16 +++++------ mps/code/cbs.c | 16 +++++------ mps/code/dbgpool.c | 4 +-- mps/code/format.c | 8 +++--- mps/code/global.c | 24 ++++++++-------- mps/code/locus.c | 8 +++--- mps/code/message.c | 14 +++++----- mps/code/mpm.c | 12 ++++---- mps/code/mpsi.c | 4 +-- mps/code/pool.c | 10 +++---- mps/code/poolabs.c | 10 +++---- mps/code/poolamc.c | 10 +++---- mps/code/poolams.c | 32 ++++++++++----------- mps/code/poolawl.c | 12 ++++---- mps/code/poollo.c | 10 +++---- mps/code/poolmfs.c | 10 +++---- mps/code/poolmrg.c | 18 ++++++------ mps/code/poolmv.c | 10 +++---- mps/code/poolmv2.c | 9 ++---- mps/code/poolmvff.c | 12 ++++---- mps/code/pooln.c | 4 +-- mps/code/poolsnc.c | 14 +++++----- mps/code/protocol.c | 2 +- mps/code/pthrdext.c | 8 +++--- mps/code/reserv.c | 4 +-- mps/code/root.c | 18 ++++++------ mps/code/sa.c | 8 ++---- mps/code/sac.c | 6 ++-- mps/code/seg.c | 66 ++++++++++++++++++++++---------------------- mps/code/segsmss.c | 8 +++--- mps/code/splay.c | 2 +- mps/code/than.c | 6 ++-- mps/code/thix.c | 6 ++-- mps/code/thw3.c | 6 ++-- mps/code/thxc.c | 6 ++-- mps/code/trace.c | 16 +++++------ mps/code/tract.c | 8 +++--- mps/code/walk.c | 2 +- mps/design/check.txt | 33 +++++++++++++++------- 46 files changed, 287 insertions(+), 278 deletions(-) diff --git a/mps/code/arena.c b/mps/code/arena.c index 749208aeee2..30f7687ce81 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -86,7 +86,7 @@ DEFINE_CLASS(AbstractArenaClass, class) Bool ArenaClassCheck(ArenaClass class) { - CHECKL(ProtocolClassCheck(&class->protocol)); + CHECKD(ProtocolClass, &class->protocol); CHECKL(class->name != NULL); /* Should be <=6 char C identifier */ CHECKL(class->size >= sizeof(ArenaStruct)); /* Offset of generic Pool within class-specific instance cannot be */ @@ -147,7 +147,7 @@ Bool ArenaCheck(Arena arena) if (arena->primary != NULL) { CHECKD(Chunk, arena->primary); } - CHECKL(RingCheck(&arena->chunkRing)); + CHECKD_NOSIG(Ring, &arena->chunkRing); /* nothing to check for chunkSerial */ CHECKD(ChunkCacheEntry, &arena->chunkCache); @@ -155,7 +155,9 @@ Bool ArenaCheck(Arena arena) CHECKL(BoolCheck(arena->hasFreeCBS)); if (arena->hasFreeCBS) - CHECKL(CBSCheck(ArenaFreeCBS(arena))); + CHECKD(CBS, ArenaFreeCBS(arena)); + + CHECKL(BoolCheck(arena->zoned)); return TRUE; } @@ -179,7 +181,7 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) AVER(arena != NULL); AVERT(ArenaClass, class); - AVER(AlignCheck(alignment)); + AVERT(Align, alignment); if (ArgPick(&arg, args, MPS_KEY_ARENA_ZONED)) zoned = arg.val.b; @@ -284,7 +286,7 @@ Res ArenaCreate(Arena *arenaReturn, ArenaClass class, ArgList args) AVER(arenaReturn != NULL); AVERT(ArenaClass, class); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); /* We must initialise the event subsystem very early, because event logging will start as soon as anything interesting happens and expect to write @@ -556,7 +558,7 @@ Res ControlAlloc(void **baseReturn, Arena arena, size_t size, AVERT(Arena, arena); AVER(baseReturn != NULL); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); AVER(arena->poolReady); res = PoolAlloc(&base, ArenaControlPool(arena), (Size)size, @@ -1021,7 +1023,7 @@ Res ArenaAlloc(Addr *baseReturn, SegPref pref, Size size, Pool pool, AVERT(SegPref, pref); AVER(size > (Size)0); AVERT(Pool, pool); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); arena = PoolArena(pool); AVERT(Arena, arena); diff --git a/mps/code/arenacl.c b/mps/code/arenacl.c index 2f954032203..3d07f529779 100644 --- a/mps/code/arenacl.c +++ b/mps/code/arenacl.c @@ -67,7 +67,7 @@ static Bool ClientChunkCheck(ClientChunk clChunk) CHECKS(ClientChunk, clChunk); chunk = ClientChunk2Chunk(clChunk); - CHECKL(ChunkCheck(chunk)); + CHECKD(Chunk, chunk); CHECKL(clChunk->freePages <= chunk->pages); /* check they don't overlap (knowing the order) */ CHECKL((Addr)(chunk + 1) < (Addr)chunk->allocTable); @@ -201,7 +201,7 @@ static void ClientArenaVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[1].key = MPS_KEY_ARENA_CL_BASE; args[1].val.addr = va_arg(varargs, Addr); args[2].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -228,7 +228,7 @@ static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args) AVER(arenaReturn != NULL); AVER((ArenaClass)mps_arena_class_cl() == class); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); ArgRequire(&arg, args, MPS_KEY_ARENA_SIZE); size = arg.val.size; diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 03a3af2f3a2..1bcc6272f35 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -99,8 +99,8 @@ static Bool VMChunkCheck(VMChunk vmchunk) CHECKS(VMChunk, vmchunk); chunk = VMChunk2Chunk(vmchunk); - CHECKL(ChunkCheck(chunk)); - CHECKL(VMCheck(vmchunk->vm)); + CHECKD(Chunk, chunk); + CHECKD_NOSIG(VM, vmchunk->vm); /* */ CHECKL(VMAlign(vmchunk->vm) == ChunkPageSize(chunk)); CHECKL(vmchunk->overheadMappedLimit <= (Addr)chunk->pageTable); CHECKD(SparseArray, &vmchunk->pages); @@ -174,7 +174,7 @@ static Bool VMArenaCheck(VMArena vmArena) CHECKL(VMMapped(primary->vm) <= arena->committed); } - CHECKL(RingCheck(&vmArena->spareRing)); + CHECKD_NOSIG(Ring, &vmArena->spareRing); /* FIXME: Can't check VMParams */ @@ -438,7 +438,7 @@ static void VMArenaVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[0].key = MPS_KEY_ARENA_SIZE; args[0].val.size = va_arg(varargs, Size); args[1].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -493,7 +493,7 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args) AVER(arenaReturn != NULL); AVER(class == VMArenaClassGet()); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); ArgRequire(&arg, args, MPS_KEY_ARENA_SIZE); userSize = arg.val.size; diff --git a/mps/code/arg.c b/mps/code/arg.c index 442066824ad..e3fea68754d 100644 --- a/mps/code/arg.c +++ b/mps/code/arg.c @@ -1,7 +1,7 @@ /* arg.c: ARGUMENT LISTS * * $Id$ - * Copyright (c) 2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2013-2014 Ravenbrook Limited. See end of file for license. * * .source: See . */ @@ -52,7 +52,7 @@ Bool ArgCheckAddr(Arg arg) { } Bool ArgCheckPoolDebugOptions(Arg arg) { - CHECKL(PoolDebugOptionsCheck((PoolDebugOptions)arg->val.pool_debug_options)); + CHECKD_NOSIG(PoolDebugOptions, (PoolDebugOptions)arg->val.pool_debug_options); return TRUE; } @@ -138,7 +138,7 @@ Bool ArgListCheck(ArgList args) CHECKL(args != NULL); for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i) { CHECKL(i < MPS_ARGS_MAX); - CHECKL(ArgCheck(&args[i])); + CHECKD_NOSIG(Arg, &args[i]); } return TRUE; } @@ -150,7 +150,7 @@ Bool ArgPick(ArgStruct *argOut, ArgList args, Key key) { Index i; AVER(argOut != NULL); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); AVERT(Key, key); for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i) @@ -185,14 +185,14 @@ void ArgTrivVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) { UNUSED(varargs); args[0].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/boot.c b/mps/code/boot.c index f42d5ded7cc..eff8409fc1e 100644 --- a/mps/code/boot.c +++ b/mps/code/boot.c @@ -1,7 +1,7 @@ /* boot.c: BOOTSTRAP ALLOCATOR * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .overview: A structure and protocols for allocating memory from a * given block. Very simple, it basically just increments a pointer. @@ -101,7 +101,7 @@ Res BootAlloc(void **pReturn, BootBlock boot, size_t size, size_t align) AVER(pReturn != NULL); AVERT(BootBlock, boot); AVER(size > 0); - AVER(AlignCheck((Align)align)); + AVERT(Align, (Align)align); /* Align alloc pointer up and bounds check. */ blockBase = PointerAlignUp(boot->alloc, align); @@ -127,7 +127,7 @@ Res BootAlloc(void **pReturn, BootBlock boot, size_t size, size_t align) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/bt.c b/mps/code/bt.c index a58e501ee52..8535d09e995 100644 --- a/mps/code/bt.c +++ b/mps/code/bt.c @@ -1,7 +1,7 @@ /* bt.c: BIT TABLES * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * READERSHIP * @@ -215,7 +215,7 @@ void BTDestroy(BT bt, Arena arena, Count length) * discussed in review.impl.c.bt.4. */ -static Bool BTCheck(BT bt) +Bool BTCheck(BT bt) { AVER(bt != NULL); AVER(AddrIsAligned((Addr)bt, sizeof(Word))); @@ -244,7 +244,7 @@ Size (BTSize)(Count n) Bool (BTGet)(BT t, Index i) { - AVER(BTCheck(t)); + AVERT(BT, t); /* Can't check i */ /* see macro in */ @@ -259,7 +259,7 @@ Bool (BTGet)(BT t, Index i) void (BTSet)(BT t, Index i) { - AVER(BTCheck(t)); + AVERT(BT, t); /* Can't check i */ /* see macro in */ @@ -274,7 +274,7 @@ void (BTSet)(BT t, Index i) void (BTRes)(BT t, Index i) { - AVER(BTCheck(t)); + AVERT(BT, t); /* Can't check i */ /* see macro in */ @@ -289,7 +289,7 @@ void (BTRes)(BT t, Index i) void BTSetRange(BT t, Index base, Index limit) { - AVER(BTCheck(t)); + AVERT(BT, t); AVER(base < limit); #define SINGLE_SET_RANGE(i) \ @@ -311,7 +311,7 @@ void BTSetRange(BT t, Index base, Index limit) Bool BTIsResRange(BT bt, Index base, Index limit) { - AVER(BTCheck(bt)); + AVERT(BT, bt); AVER(base < limit); /* Can't check range of base or limit */ @@ -335,7 +335,7 @@ Bool BTIsResRange(BT bt, Index base, Index limit) Bool BTIsSetRange(BT bt, Index base, Index limit) { - AVER(BTCheck(bt)); + AVERT(BT, bt); AVER(base < limit); /* Can't check range of base or limit */ @@ -363,7 +363,7 @@ Bool BTIsSetRange(BT bt, Index base, Index limit) void BTResRange(BT t, Index base, Index limit) { - AVER(BTCheck(t)); + AVERT(BT, t); AVER(base < limit); #define SINGLE_RES_RANGE(i) \ @@ -876,8 +876,8 @@ Bool BTFindShortResRangeHigh(Index *baseReturn, Index *limitReturn, Bool BTRangesSame(BT comparand, BT comparator, Index base, Index limit) { - AVER(BTCheck(comparand)); - AVER(BTCheck(comparator)); + AVERT(BT, comparand); + AVERT(BT, comparator); AVER(base < limit); #define SINGLE_RANGES_SAME(i) \ @@ -912,8 +912,8 @@ Bool BTRangesSame(BT comparand, BT comparator, Index base, Index limit) void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit) { - AVER(BTCheck(fromBT)); - AVER(BTCheck(toBT)); + AVERT(BT, fromBT); + AVERT(BT, toBT); AVER(fromBT != toBT); AVER(base < limit); @@ -947,8 +947,8 @@ void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit) void BTCopyRange(BT fromBT, BT toBT, Index base, Index limit) { - AVER(BTCheck(fromBT)); - AVER(BTCheck(toBT)); + AVERT(BT, fromBT); + AVERT(BT, toBT); AVER(fromBT != toBT); AVER(base < limit); @@ -991,8 +991,8 @@ void BTCopyOffsetRange(BT fromBT, BT toBT, { Index fromBit, toBit; - AVER(BTCheck(fromBT)); - AVER(BTCheck(toBT)); + AVERT(BT, fromBT); + AVERT(BT, toBT); AVER(fromBT != toBT); AVER(fromBase < fromLimit); AVER(toBase < toLimit); @@ -1016,7 +1016,7 @@ Count BTCountResRange(BT bt, Index base, Index limit) Count c = 0; Index bit; - AVER(BTCheck(bt)); + AVERT(BT, bt); AVER(base < limit); for (bit = base; bit < limit; ++bit) @@ -1027,7 +1027,7 @@ Count BTCountResRange(BT bt, Index base, Index limit) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/bt.h b/mps/code/bt.h index 29000b957b8..4876f66715a 100644 --- a/mps/code/bt.h +++ b/mps/code/bt.h @@ -1,7 +1,7 @@ /* bt.h: Bit Table Interface * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .source: */ @@ -39,6 +39,7 @@ extern void (BTRes)(BT bt, Index index); END +extern Bool BTCheck(BT bt); extern Res BTCreate(BT *btReturn, Arena arena, Count length); extern void BTDestroy(BT bt, Arena arena, Count length); @@ -76,7 +77,7 @@ extern Count BTCountResRange(BT bt, Index base, Index limit); /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/buffer.c b/mps/code/buffer.c index 1e8b0b7b614..baa553a19a2 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -45,7 +45,7 @@ Bool BufferCheck(Buffer buffer) CHECKU(Arena, buffer->arena); CHECKU(Pool, buffer->pool); CHECKL(buffer->arena == buffer->pool->arena); - CHECKL(RingCheck(&buffer->poolRing)); /* */ + CHECKD_NOSIG(Ring, &buffer->poolRing); CHECKL(BoolCheck(buffer->isMutator)); CHECKL(buffer->fillSize >= 0.0); CHECKL(buffer->emptySize >= 0.0); @@ -605,7 +605,7 @@ Res BufferReserve(Addr *pReturn, Buffer buffer, Size size, AVER(size > 0); AVER(SizeIsAligned(size, BufferPool(buffer)->alignment)); AVER(BufferIsReady(buffer)); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* Is there enough room in the unallocated portion of the buffer to */ /* satisfy the request? If so, just increase the alloc marker and */ @@ -1182,7 +1182,7 @@ static Res bufferTrivDescribe(Buffer buffer, mps_lib_FILE *stream) Bool BufferClassCheck(BufferClass class) { - CHECKL(ProtocolClassCheck(&class->protocol)); + CHECKD(ProtocolClass, &class->protocol); CHECKL(class->name != NULL); /* Should be <=6 char C identifier */ CHECKL(class->size >= sizeof(BufferStruct)); CHECKL(FUNCHECK(class->varargs)); @@ -1241,7 +1241,7 @@ Bool SegBufCheck(SegBuf segbuf) CHECKS(SegBuf, segbuf); buffer = &segbuf->bufferStruct; - CHECKL(BufferCheck(buffer)); + CHECKD(Buffer, buffer); CHECKL(RankSetCheck(segbuf->rankSet)); if (buffer->mode & BufferModeTRANSITION) { @@ -1251,7 +1251,7 @@ Bool SegBufCheck(SegBuf segbuf) } else { /* The buffer is attached to a segment. */ CHECKL(segbuf->seg != NULL); - CHECKL(SegCheck(segbuf->seg)); + CHECKD(Seg, segbuf->seg); /* To avoid recursive checking, leave it to SegCheck to make */ /* sure the buffer and segment fields tally. */ @@ -1487,7 +1487,7 @@ static void rankBufVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[0].key = MPS_KEY_RANK; args[0].val.rank = va_arg(varargs, Rank); args[1].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } /* rankBufInit -- RankBufClass init method */ @@ -1501,10 +1501,10 @@ static Res rankBufInit(Buffer buffer, Pool pool, ArgList args) AVERT(Buffer, buffer); AVERT(Pool, pool); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); if (ArgPick(&arg, args, MPS_KEY_RANK)) rank = arg.val.rank; - AVER(RankCheck(rank)); + AVERT(Rank, rank); /* Initialize the superclass fields first via next-method call */ super = BUFFER_SUPERCLASS(RankBufClass); diff --git a/mps/code/cbs.c b/mps/code/cbs.c index c57c322d267..456271a9e9b 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -1,7 +1,7 @@ /* cbs.c: COALESCING BLOCK STRUCTURE IMPLEMENTATION * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .intro: This is a portable implementation of coalescing block * structures. @@ -85,7 +85,7 @@ static Bool CBSBlockCheck(CBSBlock block) /* See .enter-leave.simple. */ UNUSED(block); /* Required because there is no signature */ CHECKL(block != NULL); - CHECKL(TreeCheck(cbsBlockTree(block))); + CHECKD_NOSIG(Tree, cbsBlockTree(block)); /* If the block is in the middle of being deleted, */ /* the pointers will be equal. */ @@ -245,9 +245,9 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, AVERT(Arena, arena); AVER(cbs != NULL); - AVER(AlignCheck(alignment)); - AVER(BoolCheck(fastFind)); - AVER(BoolCheck(zoned)); + AVERT(Align, alignment); + AVERT(Bool, fastFind); + AVERT(Bool, zoned); if (ArgPick(&arg, args, CBSBlockPool)) blockPool = arg.val.pool; @@ -915,8 +915,8 @@ Res CBSFindInZones(Range rangeReturn, Range oldRangeReturn, AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(CBS, cbs); - /* AVER(ZoneSetCheck(zoneSet)); */ - AVER(BoolCheck(high)); + /* AVERT(ZoneSet, zoneSet); */ + AVERT(Bool, high); cbsFind = high ? CBSFindLast : CBSFindFirst; splayFind = high ? SplayFindLast : SplayFindFirst; @@ -1086,7 +1086,7 @@ Res CBSDescribe(CBS cbs, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/dbgpool.c b/mps/code/dbgpool.c index 5edeae45035..77c1d6eaf40 100644 --- a/mps/code/dbgpool.c +++ b/mps/code/dbgpool.c @@ -34,8 +34,6 @@ typedef tagStruct *Tag; /* tag init methods: copying the user-supplied data into the tag */ -#define TagInitMethodCheck(f) FUNCHECK(f) - static void TagTrivInit(void* tag, va_list args) { UNUSED(tag); UNUSED(args); @@ -75,7 +73,7 @@ Bool PoolDebugMixinCheck(PoolDebugMixin debug) /* Nothing to check about freeTemplate */ /* Nothing to check about freeSize */ if (debug->tagInit != NULL) { - CHECKL(TagInitMethodCheck(debug->tagInit)); + CHECKL(FUNCHECK(debug->tagInit)); /* Nothing to check about tagSize */ CHECKD(Pool, debug->tagPool); CHECKL(COMPATTYPE(Addr, void*)); /* tagPool relies on this */ diff --git a/mps/code/format.c b/mps/code/format.c index fb72680535b..88a86283ef8 100644 --- a/mps/code/format.c +++ b/mps/code/format.c @@ -1,7 +1,7 @@ /* format.c: OBJECT FORMATS * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (c) 2002 Global Graphics Software. * * DESIGN @@ -21,7 +21,7 @@ Bool FormatCheck(Format format) CHECKS(Format, format); CHECKU(Arena, format->arena); CHECKL(format->serial < format->arena->formatSerial); - CHECKL(RingCheck(&format->arenaRing)); + CHECKD_NOSIG(Ring, &format->arenaRing); CHECKL(AlignCheck(format->alignment)); /* TODO: Define the concept of the maximum alignment it is possible to request from the MPS, document and provide an interface to it, and then @@ -114,7 +114,7 @@ Res FormatCreate(Format *formatReturn, Arena arena, ArgList args) AVER(formatReturn != NULL); AVERT(Arena, arena); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); if (ArgPick(&arg, args, MPS_KEY_FMT_ALIGN)) fmtAlign = arg.val.align; @@ -217,7 +217,7 @@ Res FormatDescribe(Format format, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/global.c b/mps/code/global.c index 0bf481cb136..072b21253ac 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -119,7 +119,7 @@ Bool GlobalsCheck(Globals arenaGlobals) CHECKS(Globals, arenaGlobals); arena = GlobalsArena(arenaGlobals); CHECKL(arena->serial < arenaSerial); - CHECKL(RingCheck(&arenaGlobals->globalRing)); + CHECKD_NOSIG(Ring, &arenaGlobals->globalRing); CHECKL(MPSVersion() == arenaGlobals->mpsVersionString); @@ -138,16 +138,16 @@ Bool GlobalsCheck(Globals arenaGlobals) CHECKL(arenaGlobals->emptyInternalSize >= 0.0); CHECKL(BoolCheck(arenaGlobals->bufferLogging)); - CHECKL(RingCheck(&arenaGlobals->poolRing)); - CHECKL(RingCheck(&arenaGlobals->rootRing)); - CHECKL(RingCheck(&arenaGlobals->rememberedSummaryRing)); + CHECKD_NOSIG(Ring, &arenaGlobals->poolRing); + CHECKD_NOSIG(Ring, &arenaGlobals->rootRing); + CHECKD_NOSIG(Ring, &arenaGlobals->rememberedSummaryRing); CHECKL(arenaGlobals->rememberedSummaryIndex < RememberedSummaryBLOCK); /* RingIsSingle imples index == 0 */ CHECKL(!RingIsSingle(&arenaGlobals->rememberedSummaryRing) || arenaGlobals->rememberedSummaryIndex == 0); - CHECKL(RingCheck(&arena->formatRing)); - CHECKL(RingCheck(&arena->messageRing)); - /* Don't check enabledMessageTypes */ + CHECKD_NOSIG(Ring, &arena->formatRing); + CHECKD_NOSIG(Ring, &arena->messageRing); + CHECKD_NOSIG(BT, arena->enabledMessageTypes); CHECKL(BoolCheck(arena->isFinalPool)); if (arena->isFinalPool) { CHECKD(Pool, arena->finalPool); @@ -155,7 +155,7 @@ Bool GlobalsCheck(Globals arenaGlobals) CHECKL(arena->finalPool == NULL); } - CHECKL(RingCheck(&arena->threadRing)); + CHECKD_NOSIG(Ring, &arena->threadRing); CHECKL(BoolCheck(arena->insideShield)); CHECKL(arena->shCacheLimit <= ShieldCacheSIZE); @@ -189,8 +189,8 @@ Bool GlobalsCheck(Globals arenaGlobals) TRACE_SET_ITER_END(ti, trace, TraceSetUNIV, arena); for(rank = 0; rank < RankLIMIT; ++rank) - CHECKL(RingCheck(&arena->greyRing[rank])); - CHECKL(RingCheck(&arena->chainRing)); + CHECKD_NOSIG(Ring, &arena->greyRing[rank]); + CHECKD_NOSIG(Ring, &arena->chainRing); CHECKL(arena->tracedSize >= 0.0); CHECKL(arena->tracedTime >= 0.0); @@ -212,7 +212,7 @@ Bool GlobalsCheck(Globals arenaGlobals) /* we also check the statics now. */ CHECKL(BoolCheck(arenaRingInit)); - CHECKL(RingCheck(&arenaRing)); + CHECKD_NOSIG(Ring, &arenaRing); CHECKL(BoolCheck(arena->emergency)); @@ -632,7 +632,7 @@ Bool ArenaAccess(Addr addr, AccessSet mode, MutatorFaultContext context) arenaClaimRingLock(); /* */ mps_exception_info = context; - AVER(RingCheck(&arenaRing)); + AVERT(Ring, &arenaRing); RING_FOR(node, &arenaRing, nextNode) { Globals arenaGlobals = RING_ELT(Globals, globalRing, node); diff --git a/mps/code/locus.c b/mps/code/locus.c index 24f401c2c4f..a704c8b820b 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -89,7 +89,7 @@ static Bool GenDescCheck(GenDesc gen) CHECKL(gen->mortality <= 1.0); CHECKL(gen->proflow >= 0.0); CHECKL(gen->proflow <= 1.0); - CHECKL(RingCheck(&gen->locusRing)); + CHECKD_NOSIG(Ring, &gen->locusRing); return TRUE; } @@ -192,7 +192,7 @@ Bool ChainCheck(Chain chain) CHECKS(Chain, chain); CHECKU(Arena, chain->arena); - CHECKL(RingCheck(&chain->chainRing)); + CHECKD_NOSIG(Ring, &chain->chainRing); CHECKL(TraceSetCheck(chain->activeTraces)); CHECKL(chain->genCount > 0); for (i = 0; i < chain->genCount; ++i) { @@ -458,7 +458,7 @@ Bool PoolGenCheck(PoolGen gen) /* nothing to check about serial */ CHECKU(Pool, gen->pool); CHECKU(Chain, gen->chain); - CHECKL(RingCheck(&gen->genRing)); + CHECKD_NOSIG(Ring, &gen->genRing); CHECKL(gen->newSize <= gen->totalSize); return TRUE; } @@ -501,7 +501,7 @@ void LocusFinish(Arena arena) Bool LocusCheck(Arena arena) { /* Can't check arena, because this is part of ArenaCheck. */ - CHECKL(GenDescCheck(&arena->topGen)); + CHECKD(GenDesc, &arena->topGen); return TRUE; } diff --git a/mps/code/message.c b/mps/code/message.c index 75b01d328d8..eba94182837 100644 --- a/mps/code/message.c +++ b/mps/code/message.c @@ -1,7 +1,7 @@ /* message.c: MPS/CLIENT MESSAGES * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * DESIGN * @@ -53,7 +53,7 @@ Bool MessageCheck(Message message) CHECKS(Message, message); CHECKU(Arena, message->arena); CHECKD(MessageClass, message->class); - CHECKL(RingCheck(&message->queueRing)); + CHECKD_NOSIG(Ring, &message->queueRing); /* postedClock is uncheckable for clocked message types, */ /* but must be 0 for unclocked message types: */ CHECKL(MessageIsClocked(message) || (message->postedClock == 0)); @@ -186,7 +186,7 @@ void MessageEmpty(Arena arena) static Bool MessageTypeEnabled(Arena arena, MessageType type) { AVERT(Arena, arena); - AVER(MessageTypeCheck(type)); + AVERT(MessageType, type); return BTGet(arena->enabledMessageTypes, type); } @@ -194,7 +194,7 @@ static Bool MessageTypeEnabled(Arena arena, MessageType type) void MessageTypeEnable(Arena arena, MessageType type) { AVERT(Arena, arena); - AVER(MessageTypeCheck(type)); + AVERT(MessageType, type); BTSet(arena->enabledMessageTypes, type); } @@ -204,7 +204,7 @@ void MessageTypeDisable(Arena arena, MessageType type) Message message; AVERT(Arena, arena); - AVER(MessageTypeCheck(type)); + AVERT(MessageType, type); /* Flush existing messages of this type */ while(MessageGet(&message, arena, type)) { @@ -252,7 +252,7 @@ Bool MessageGet(Message *messageReturn, Arena arena, MessageType type) AVER(messageReturn != NULL); AVERT(Arena, arena); - AVER(MessageTypeCheck(type)); + AVERT(MessageType, type); RING_FOR(node, &arena->messageRing, next) { Message message = RING_ELT(Message, queueRing, node); @@ -427,7 +427,7 @@ const char *MessageNoGCStartWhy(Message message) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002, 2008 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/mpm.c b/mps/code/mpm.c index 5436327c7ef..f544acca401 100644 --- a/mps/code/mpm.c +++ b/mps/code/mpm.c @@ -1,7 +1,7 @@ /* mpm.c: GENERAL MPM SUPPORT * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: Miscellaneous support for the implementation of the MPM * and pool classes. @@ -132,7 +132,7 @@ Bool AlignCheck(Align align) Bool (WordIsAligned)(Word word, Align align) { - AVER(AlignCheck(align)); + AVERT(Align, align); return WordIsAligned(word, align); } @@ -141,7 +141,7 @@ Bool (WordIsAligned)(Word word, Align align) Word (WordAlignUp)(Word word, Align align) { - AVER(AlignCheck(align)); + AVERT(Align, align); return WordAlignUp(word, align); } @@ -167,7 +167,7 @@ Word (WordRoundUp)(Word word, Size modulus) Word (WordAlignDown)(Word word, Align alignment) { - AVER(AlignCheck(alignment)); + AVERT(Align, alignment); return WordAlignDown(word, alignment); } @@ -212,7 +212,7 @@ Shift SizeLog2(Size size) Addr (AddrAlignDown)(Addr addr, Align alignment) { - AVER(AlignCheck(alignment)); + AVERT(Align, alignment); return AddrAlignDown(addr, alignment); } @@ -604,7 +604,7 @@ Bool StringEqual(const char *s1, const char *s2) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c index 297fae64732..3df0913df83 100644 --- a/mps/code/mpsi.c +++ b/mps/code/mpsi.c @@ -454,7 +454,7 @@ mps_res_t mps_fmt_create_k(mps_fmt_t *mps_fmt_o, AVER(mps_fmt_o != NULL); AVERT(Arena, arena); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); res = FormatCreate(&format, arena, args); @@ -652,7 +652,7 @@ mps_res_t mps_pool_create_k(mps_pool_t *mps_pool_o, mps_arena_t arena, AVER(mps_pool_o != NULL); AVERT(Arena, arena); AVERT(PoolClass, class); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); res = PoolCreate(&pool, arena, class, args); diff --git a/mps/code/pool.c b/mps/code/pool.c index 75f5dc959d5..87b627400e2 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -37,7 +37,7 @@ SRCID(pool, "$Id$"); Bool PoolClassCheck(PoolClass class) { - CHECKL(ProtocolClassCheck(&class->protocol)); + CHECKD(ProtocolClass, &class->protocol); CHECKL(class->name != NULL); /* Should be <=6 char C identifier */ CHECKL(class->size >= sizeof(PoolStruct)); /* Offset of generic Pool within class-specific instance cannot be */ @@ -87,10 +87,10 @@ Bool PoolCheck(Pool pool) CHECKL(pool->serial < ArenaGlobals(pool->arena)->poolSerial); CHECKD(PoolClass, pool->class); CHECKU(Arena, pool->arena); - CHECKL(RingCheck(&pool->arenaRing)); - CHECKL(RingCheck(&pool->bufferRing)); + CHECKD_NOSIG(Ring, &pool->arenaRing); + CHECKD_NOSIG(Ring, &pool->bufferRing); /* Cannot check pool->bufferSerial */ - CHECKL(RingCheck(&pool->segRing)); + CHECKD_NOSIG(Ring, &pool->segRing); CHECKL(AlignCheck(pool->alignment)); /* normally pool->format iff PoolHasAttr(pool, AttrFMT), but during * pool initialization pool->format may not yet be set. */ @@ -286,7 +286,7 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size, AVERT(Pool, pool); AVER(PoolHasAttr(pool, AttrALLOC)); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); res = (*pool->class->alloc)(pReturn, pool, size, withReservoirPermit); if (res != ResOK) diff --git a/mps/code/poolabs.c b/mps/code/poolabs.c index cb6f49debb9..aa2ee5adcbd 100644 --- a/mps/code/poolabs.c +++ b/mps/code/poolabs.c @@ -210,7 +210,7 @@ void PoolTrivFinish(Pool pool) Res PoolTrivInit(Pool pool, ArgList args) { AVERT(Pool, pool); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); UNUSED(args); return ResOK; } @@ -221,7 +221,7 @@ Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size, AVER(pReturn != NULL); AVERT(Pool, pool); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); NOTREACHED; return ResUNIMPL; } @@ -232,7 +232,7 @@ Res PoolTrivAlloc(Addr *pReturn, Pool pool, Size size, AVER(pReturn != NULL); AVERT(Pool, pool); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); return ResLIMIT; } @@ -262,7 +262,7 @@ Res PoolNoBufferFill(Addr *baseReturn, Addr *limitReturn, AVERT(Pool, pool); AVERT(Buffer, buffer); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); NOTREACHED; return ResUNIMPL; } @@ -279,7 +279,7 @@ Res PoolTrivBufferFill(Addr *baseReturn, Addr *limitReturn, AVERT(Pool, pool); AVERT(Buffer, buffer); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); res = PoolAlloc(&p, pool, size, withReservoirPermit); if(res != ResOK) return res; diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index fd74778c9c3..f3e56b3803e 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -525,7 +525,7 @@ static Bool amcGenCheck(amcGen gen) CHECKU(AMC, amc); CHECKL(gen->type == AMCPTypeGen); CHECKD(Buffer, gen->forward); - CHECKL(RingCheck(&gen->amcRing)); + CHECKD_NOSIG(Ring, &gen->amcRing); CHECKL((gen->pgen.totalSize == 0) == (gen->segs == 0)); arena = amc->poolStruct.arena; CHECKL(gen->pgen.totalSize >= gen->segs * ArenaAlign(arena)); @@ -586,7 +586,7 @@ typedef struct amcBufStruct { static Bool amcBufCheck(amcBuf amcbuf) { CHECKS(amcBuf, amcbuf); - CHECKL(SegBufCheck(&amcbuf->segbufStruct)); + CHECKD(SegBuf, &amcbuf->segbufStruct); if(amcbuf->gen != NULL) CHECKD(amcGen, amcbuf->gen); CHECKL(BoolCheck(amcbuf->forHashArrays)); @@ -963,7 +963,7 @@ static void AMCVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[1].key = MPS_KEY_CHAIN; args[1].val.chain = va_arg(varargs, Chain); args[2].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -2242,7 +2242,7 @@ static void AMCTraceEnd(Pool pool, Trace trace) amc = Pool2AMC(pool); AVERT(AMC, amc); ti = trace->ti; - AVER(TraceIdCheck(ti)); + AVERT(TraceId, ti); STATISTIC_STAT ({ Count pRetMin = 100; @@ -2604,7 +2604,7 @@ static Bool AMCCheck(AMC amc) CHECKD(Pool, &amc->poolStruct); CHECKL(IsSubclassPoly(amc->poolStruct.class, EnsureAMCPoolClass())); CHECKL(RankSetCheck(amc->rankSet)); - CHECKL(RingCheck(&amc->genRing)); + CHECKD_NOSIG(Ring, &amc->genRing); CHECKL(BoolCheck(amc->gensBooted)); if(amc->gensBooted) { CHECKD(amcGen, amc->nursery); diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 96df165896a..c67a2efd684 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -48,7 +48,7 @@ Bool AMSSegCheck(AMSSeg amsseg) { Seg seg = AMSSeg2Seg(amsseg); CHECKS(AMSSeg, amsseg); - CHECKL(GCSegCheck(&amsseg->gcSegStruct)); + CHECKD(GCSeg, &amsseg->gcSegStruct); CHECKU(AMS, amsseg->ams); CHECKL(AMS2Pool(amsseg->ams) == SegPool(seg)); CHECKD_NOSIG(Ring, &amsseg->segRing); @@ -60,7 +60,7 @@ Bool AMSSegCheck(AMSSeg amsseg) CHECKL(BoolCheck(amsseg->allocTableInUse)); if (!amsseg->allocTableInUse) CHECKL(amsseg->firstFree <= amsseg->grains); - CHECKL(amsseg->allocTable != NULL); + CHECKD_NOSIG(BT, amsseg->allocTable); if (SegWhite(seg) != TraceSetEMPTY) { /* */ @@ -71,8 +71,8 @@ Bool AMSSegCheck(AMSSeg amsseg) CHECKL(BoolCheck(amsseg->marksChanged)); CHECKL(BoolCheck(amsseg->ambiguousFixes)); CHECKL(BoolCheck(amsseg->colourTablesInUse)); - CHECKL(amsseg->nongreyTable != NULL); - CHECKL(amsseg->nonwhiteTable != NULL); + CHECKD_NOSIG(BT, amsseg->nongreyTable); + CHECKD_NOSIG(BT, amsseg->nonwhiteTable); return TRUE; } @@ -218,7 +218,7 @@ static Res AMSSegInit(Seg seg, Pool pool, Addr base, Size size, AVERT(AMS, ams); arena = PoolArena(pool); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); /* Initialize the superclass fields first via next-method call */ super = SEG_SUPERCLASS(AMSSegClass); @@ -638,7 +638,7 @@ static Res AMSSegSizePolicy(Size *sizeReturn, AVER(sizeReturn != NULL); AVERT(Pool, pool); AVER(size > 0); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); arena = PoolArena(pool); @@ -667,7 +667,7 @@ static Res AMSSegCreate(Seg *segReturn, Pool pool, Size size, AVERT(Pool, pool); AVER(size > 0); AVERT(RankSet, rankSet); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); ams = Pool2AMS(pool); AVERT(AMS,ams); @@ -735,7 +735,7 @@ static void AMSVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[2].key = MPS_KEY_AMS_SUPPORT_AMBIGUOUS; args[2].val.b = va_arg(varargs, Bool); args[3].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } static void AMSDebugVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) @@ -764,7 +764,7 @@ static Res AMSInit(Pool pool, ArgList args) ArgStruct arg; AVERT(Pool, pool); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); if (ArgPick(&arg, args, MPS_KEY_CHAIN)) chain = arg.val.chain; @@ -933,7 +933,7 @@ static Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn, AVERT(Buffer, buffer); AVER(size > 0); AVER(SizeIsAligned(size, PoolAlignment(pool))); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* Check that we're not in the grey mutator phase (see */ /* ). */ @@ -997,7 +997,7 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit) AVERT(Buffer,buffer); AVER(BufferIsReady(buffer)); seg = BufferSeg(buffer); - AVER(SegCheck(seg)); + AVERT(Seg, seg); AVER(init <= limit); AVER(AddrIsAligned(init, PoolAlignment(pool))); AVER(AddrIsAligned(limit, PoolAlignment(pool))); @@ -1075,7 +1075,7 @@ static Res AMSCondemn(Pool pool, Trace trace, Seg seg) AVERT(AMS, ams); AVERT(Trace, trace); - AVER(SegCheck(seg)); + AVERT(Seg, seg); amsseg = Seg2AMSSeg(seg); AVERT(AMSSeg, amsseg); @@ -1261,7 +1261,7 @@ static Res amsScanObject(Seg seg, Index i, Addr p, Addr next, void *clos) AVER(clos != NULL); closure = (amsScanClosure)clos; AVERT(ScanState, closure->ss); - AVER(BoolCheck(closure->scanAllObjects)); + AVERT(Bool, closure->scanAllObjects); format = AMS2Pool(amsseg->ams)->format; AVERT(Format, format); @@ -1307,7 +1307,7 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) ams = Pool2AMS(pool); AVERT(AMS, ams); arena = PoolArena(pool); - AVER(SegCheck(seg)); + AVERT(Seg, seg); amsseg = Seg2AMSSeg(seg); AVERT(AMSSeg, amsseg); @@ -1725,7 +1725,7 @@ DEFINE_POOL_CLASS(AMSDebugPoolClass, this) Bool AMSCheck(AMS ams) { CHECKS(AMS, ams); - CHECKL(PoolCheck(AMS2Pool(ams))); + CHECKD(Pool, AMS2Pool(ams)); CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet())); CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift)); CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment); @@ -1733,7 +1733,7 @@ Bool AMSCheck(AMS ams) CHECKD(PoolGen, &ams->pgen); CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams))))); CHECKL(FUNCHECK(ams->segSize)); - CHECKL(RingCheck(&ams->segRing)); + CHECKD_NOSIG(Ring, &ams->segRing); CHECKL(FUNCHECK(ams->allocRing)); CHECKL(FUNCHECK(ams->segsDestroy)); CHECKL(FUNCHECK(ams->segClass)); diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 1ca13d5346f..6332a91b7cd 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -187,7 +187,7 @@ static Res AWLSegInit(Seg seg, Pool pool, Addr base, Size size, AVERT(Pool, pool); arena = PoolArena(pool); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); ArgRequire(&arg, args, awlKeySegRankSet); rankSet = arg.val.u; AVERT(RankSet, rankSet); @@ -451,10 +451,10 @@ static Res AWLSegCreate(AWLSeg *awlsegReturn, Arena arena; AVER(awlsegReturn != NULL); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); AVERT(Pool, pool); AVER(size > 0); - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); awl = Pool2AWL(pool); AVERT(AWL, awl); @@ -520,7 +520,7 @@ static void AWLVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[1].key = MPS_KEY_AWL_FIND_DEPENDENT; args[1].val.addr_method = va_arg(varargs, mps_awl_find_dependent_t); args[2].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -627,7 +627,7 @@ static Res AWLBufferFill(Addr *baseReturn, Addr *limitReturn, AVERT(Pool, pool); AVERT(Buffer, buffer); AVER(size > 0); - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); awl = Pool2AWL(pool); AVERT(AWL, awl); @@ -835,7 +835,7 @@ static void AWLBlacken(Pool pool, TraceSet traceSet, Seg seg) AWLSeg awlseg; AVERT(Pool, pool); - AVER(TraceSetCheck(traceSet)); + AVERT(TraceSet, traceSet); AVERT(Seg, seg); awl = Pool2AWL(pool); diff --git a/mps/code/poollo.c b/mps/code/poollo.c index 08aa146d656..d8f23584fba 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -82,7 +82,7 @@ DEFINE_SEG_CLASS(LOSegClass, class) static Bool LOSegCheck(LOSeg loseg) { CHECKS(LOSeg, loseg); - CHECKL(GCSegCheck(&loseg->gcSegStruct)); + CHECKD(GCSeg, &loseg->gcSegStruct); CHECKU(LO, loseg->lo); CHECKL(loseg->mark != NULL); CHECKL(loseg->alloc != NULL); @@ -113,7 +113,7 @@ static Res loSegInit(Seg seg, Pool pool, Addr base, Size size, AVERT(Pool, pool); arena = PoolArena(pool); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); lo = PoolPoolLO(pool); AVERT(LO, lo); @@ -287,7 +287,7 @@ static Res loSegCreate(LOSeg *loSegReturn, Pool pool, Size size, AVER(loSegReturn != NULL); AVERT(Pool, pool); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); lo = PoolPoolLO(pool); AVERT(LO, lo); @@ -461,7 +461,7 @@ static void LOVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[0].key = MPS_KEY_FORMAT; args[0].val.format = va_arg(varargs, Format); args[1].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -559,7 +559,7 @@ static Res LOBufferFill(Addr *baseReturn, Addr *limitReturn, AVER(BufferRankSet(buffer) == RankSetEMPTY); AVER(size > 0); AVER(SizeIsAligned(size, PoolAlignment(pool))); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* Try to find a segment with enough space already. */ RING_FOR(node, &pool->segRing, nextNode) { diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 6bf29c15873..fbb125a71f2 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -86,7 +86,7 @@ static void MFSVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[1].key = MPS_KEY_MFS_UNIT_SIZE; args[1].val.size = va_arg(varargs, Size); args[2].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } ARG_DEFINE_KEY(mfs_unit_size, Size); @@ -102,7 +102,7 @@ static Res MFSInit(Pool pool, ArgList args) ArgStruct arg; AVER(pool != NULL); - AVER(ArgListCheck(args)); + AVERT(ArgList, args); ArgRequire(&arg, args, MPS_KEY_MFS_UNIT_SIZE); unitSize = arg.val.size; @@ -116,7 +116,7 @@ static Res MFSInit(Pool pool, ArgList args) extendSelf = arg.val.b; AVER(extendBy >= unitSize); - AVER(BoolCheck(extendSelf)); + AVERT(Bool, extendSelf); mfs = PoolPoolMFS(pool); arena = PoolArena(pool); @@ -250,7 +250,7 @@ static Res MFSAlloc(Addr *pReturn, Pool pool, Size size, AVER(pReturn != NULL); AVER(size == mfs->unroundedUnitSize); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); f = mfs->freeList; @@ -378,7 +378,7 @@ Bool MFSCheck(MFS mfs) CHECKL(SizeAlignUp(mfs->unroundedUnitSize, mfs->poolStruct.alignment) == mfs->unitSize); if(mfs->tractList != NULL) { - CHECKL(TractCheck(mfs->tractList)); + CHECKD_NOSIG(Tract, mfs->tractList); } return TRUE; } diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c index aebb22595ea..93d9f8bd25e 100644 --- a/mps/code/poolmrg.c +++ b/mps/code/poolmrg.c @@ -130,9 +130,9 @@ static Bool MRGCheck(MRG mrg) CHECKS(MRG, mrg); CHECKD(Pool, &mrg->poolStruct); CHECKL(MRG2Pool(mrg)->class == PoolClassMRG()); - CHECKL(RingCheck(&mrg->entryRing)); - CHECKL(RingCheck(&mrg->freeRing)); - CHECKL(RingCheck(&mrg->refRing)); + CHECKD_NOSIG(Ring, &mrg->entryRing); + CHECKD_NOSIG(Ring, &mrg->freeRing); + CHECKD_NOSIG(Ring, &mrg->refRing); CHECKL(mrg->extendBy == ArenaAlign(PoolArena(MRG2Pool(mrg)))); return TRUE; } @@ -183,7 +183,7 @@ static Bool MRGLinkSegCheck(MRGLinkSeg linkseg) Seg seg; CHECKS(MRGLinkSeg, linkseg); - CHECKL(SegCheck(&linkseg->segStruct)); + CHECKD(Seg, &linkseg->segStruct); seg = LinkSeg2Seg(linkseg); if (NULL != linkseg->refSeg) { /* see .link.nullref */ CHECKL(SegPool(seg) == SegPool(RefSeg2Seg(linkseg->refSeg))); @@ -198,10 +198,10 @@ static Bool MRGRefSegCheck(MRGRefSeg refseg) Seg seg; CHECKS(MRGRefSeg, refseg); - CHECKL(GCSegCheck(&refseg->gcSegStruct)); + CHECKD(GCSeg, &refseg->gcSegStruct); seg = RefSeg2Seg(refseg); CHECKL(SegPool(seg) == SegPool(LinkSeg2Seg(refseg->linkSeg))); - CHECKL(RingCheck(&refseg->mrgRing)); + CHECKD_NOSIG(Ring, &refseg->mrgRing); CHECKD(MRGLinkSeg, refseg->linkSeg); CHECKL(refseg->linkSeg->refSeg == refseg); return TRUE; @@ -224,7 +224,7 @@ static Res MRGLinkSegInit(Seg seg, Pool pool, Addr base, Size size, mrg = Pool2MRG(pool); AVERT(MRG, mrg); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); /* Initialize the superclass fields first via next-method call */ super = SEG_SUPERCLASS(MRGLinkSegClass); @@ -267,7 +267,7 @@ static Res MRGRefSegInit(Seg seg, Pool pool, Addr base, Size size, mrg = Pool2MRG(pool); AVERT(MRG, mrg); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); AVERT(MRGLinkSeg, linkseg); /* Initialize the superclass fields first via next-method call */ @@ -631,7 +631,7 @@ static Res MRGInit(Pool pool, ArgList args) MRG mrg; AVER(pool != NULL); /* Can't check more; see pool contract @@@@ */ - AVER(ArgListCheck(args)); + AVERT(ArgList, args); UNUSED(args); mrg = Pool2MRG(pool); diff --git a/mps/code/poolmv.c b/mps/code/poolmv.c index 88d96cf950e..0ce4f28c95d 100644 --- a/mps/code/poolmv.c +++ b/mps/code/poolmv.c @@ -138,11 +138,11 @@ static Bool MVSpanCheck(MVSpan span) CHECKS(MVSpan, span); - CHECKL(RingCheck(&span->spans)); + CHECKD_NOSIG(Ring, &span->spans); CHECKU(MV, span->mv); CHECKD_NOSIG(Tract, span->tract); - CHECKL(MVBlockCheck(&span->base)); - CHECKL(MVBlockCheck(&span->limit)); + CHECKD_NOSIG(MVBlock, &span->base); + CHECKD_NOSIG(MVBlock, &span->limit); /* The block chain starts with the base sentinel. */ CHECKL(span->blocks == &span->base); /* Since there is a limit sentinel, the chain can't end just after the */ @@ -193,7 +193,7 @@ static void MVVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[2].key = MPS_KEY_MAX_SIZE; args[2].val.size = va_arg(varargs, Size); args[3].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } static void MVDebugVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) @@ -570,7 +570,7 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size, span->mv = mv; /* Set the p field for each tract of the span */ TRACT_FOR(tract, addr, arena, base, limit) { - AVER(TractCheck(tract)); + AVERT(Tract, tract); AVER(TractP(tract) == NULL); AVER(TractPool(tract) == pool); TractSetP(tract, (void *)span); diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index c98dab21459..b2903481b45 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -200,7 +200,7 @@ static void MVTVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[4].key = MPS_KEY_MVT_FRAG_LIMIT; args[4].val.d = (double)va_arg(varargs, Count) / 100.0; args[5].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -364,9 +364,7 @@ static Bool MVTCheck(MVT mvt) CHECKD(Pool, &mvt->poolStruct); CHECKL(mvt->poolStruct.class == MVTPoolClassGet()); CHECKD(CBS, &mvt->cbsStruct); - /* CHECKL(CBSCheck(MVTCBS(mvt))); */ CHECKD(ABQ, &mvt->abqStruct); - /* CHECKL(ABQCheck(MVTABQ(mvt))); */ CHECKD(Freelist, &mvt->flStruct); CHECKL(mvt->reuseSize >= 2 * mvt->fillSize); CHECKL(mvt->fillSize >= mvt->maxSize); @@ -380,8 +378,7 @@ static Bool MVTCheck(MVT mvt) if (mvt->splinter) { CHECKL(AddrOffset(mvt->splinterBase, mvt->splinterLimit) >= mvt->minSize); - /* CHECKD(Seg, mvt->splinterSeg); */ - CHECKL(SegCheck(mvt->splinterSeg)); + CHECKD(Seg, mvt->splinterSeg); CHECKL(mvt->splinterBase >= SegBase(mvt->splinterSeg)); CHECKL(mvt->splinterLimit <= SegLimit(mvt->splinterSeg)); } @@ -688,7 +685,7 @@ static Res MVTBufferFill(Addr *baseReturn, Addr *limitReturn, AVER(BufferIsReset(buffer)); AVER(minSize > 0); AVER(SizeIsAligned(minSize, pool->alignment)); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* Allocate oversize blocks exactly, directly from the arena. */ diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index b218e687440..201d2047104 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -228,7 +228,7 @@ static Res MVFFAddSeg(Seg *segReturn, AVERT(MVFF, mvff); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); pool = MVFF2Pool(mvff); arena = PoolArena(pool); @@ -339,7 +339,7 @@ static Res MVFFAlloc(Addr *aReturn, Pool pool, Size size, AVER(aReturn != NULL); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); size = SizeAlignUp(size, PoolAlignment(pool)); @@ -510,7 +510,7 @@ static void MVFFVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[5].key = MPS_KEY_MVFF_FIRST_FIT; args[5].val.b = va_arg(varargs, Bool); args[6].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } static void MVFFDebugVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) @@ -571,9 +571,9 @@ static Res MVFFInit(Pool pool, ArgList args) AVER(avgSize > 0); /* .arg.check */ AVER(avgSize <= extendBy); /* .arg.check */ AVER(SizeIsAligned(align, MPS_PF_ALIGN)); - AVER(BoolCheck(slotHigh)); - AVER(BoolCheck(arenaHigh)); - AVER(BoolCheck(firstFit)); + AVERT(Bool, slotHigh); + AVERT(Bool, arenaHigh); + AVERT(Bool, firstFit); mvff = Pool2MVFF(pool); diff --git a/mps/code/pooln.c b/mps/code/pooln.c index 6840c1417f8..3a7e26df34c 100644 --- a/mps/code/pooln.c +++ b/mps/code/pooln.c @@ -71,7 +71,7 @@ static Res NAlloc(Addr *pReturn, Pool pool, Size size, AVER(pReturn != NULL); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); return ResLIMIT; /* limit of nil blocks exceeded */ } @@ -110,7 +110,7 @@ static Res NBufferFill(Addr *baseReturn, Addr *limitReturn, AVERT(Buffer, buffer); AVER(BufferIsReset(buffer)); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); NOTREACHED; /* can't create buffers, so shouldn't fill them */ return ResUNIMPL; diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index 1ac5e408dce..e9afe98a96b 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -90,9 +90,9 @@ static Bool SNCBufCheck(SNCBuf sncbuf) CHECKS(SNCBuf, sncbuf); segbuf = &sncbuf->segBufStruct; - CHECKL(SegBufCheck(segbuf)); + CHECKD(SegBuf, segbuf); if (sncbuf->topseg != NULL) { - CHECKL(SegCheck(sncbuf->topseg)); + CHECKD(Seg, sncbuf->topseg); } return TRUE; } @@ -217,7 +217,7 @@ typedef struct SNCSegStruct { static Bool SNCSegCheck(SNCSeg sncseg) { CHECKS(SNCSeg, sncseg); - CHECKL(GCSegCheck(&sncseg->gcSegStruct)); + CHECKD(GCSeg, &sncseg->gcSegStruct); if (NULL != sncseg->next) { CHECKS(SNCSeg, sncseg->next); } @@ -238,7 +238,7 @@ static Res sncSegInit(Seg seg, Pool pool, Addr base, Size size, sncseg = SegSNCSeg(seg); AVERT(Pool, pool); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); /* Initialize the superclass fields first via next-method call */ super = SEG_SUPERCLASS(SNCSegClass); @@ -367,7 +367,7 @@ static void SNCVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) args[0].key = MPS_KEY_FORMAT; args[0].val.format = va_arg(varargs, Format); args[1].key = MPS_KEY_ARGS_END; - AVER(ArgListCheck(args)); + AVERT(ArgList, args); } @@ -433,7 +433,7 @@ static Res SNCBufferFill(Addr *baseReturn, Addr *limitReturn, AVERT(Pool, pool); AVERT(Buffer, buffer); AVER(size > 0); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); AVER(BufferIsReset(buffer)); snc = Pool2SNC(pool); @@ -702,7 +702,7 @@ static Bool SNCCheck(SNC snc) CHECKD(Pool, &snc->poolStruct); CHECKL(snc->poolStruct.class == SNCPoolClassGet()); if (snc->freeSegs != NULL) { - CHECKL(SegCheck(snc->freeSegs)); + CHECKD(Seg, snc->freeSegs); } return TRUE; } diff --git a/mps/code/protocol.c b/mps/code/protocol.c index af7ac26e8c3..bcc8ae56863 100644 --- a/mps/code/protocol.c +++ b/mps/code/protocol.c @@ -30,7 +30,7 @@ Bool ProtocolClassCheck(ProtocolClass class) Bool ProtocolInstCheck(ProtocolInst inst) { CHECKS(ProtocolInst, inst); - CHECKL(ProtocolClassCheck(inst->class)); + CHECKD(ProtocolClass, inst->class); return TRUE; } diff --git a/mps/code/pthrdext.c b/mps/code/pthrdext.c index 7185a0ff441..59d5899c326 100644 --- a/mps/code/pthrdext.c +++ b/mps/code/pthrdext.c @@ -1,7 +1,7 @@ /* pthreadext.c: POSIX THREAD EXTENSIONS * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: Provides extension to Pthreads. * @@ -178,8 +178,8 @@ extern Bool PThreadextCheck(PThreadext pthreadext) CHECKS(PThreadext, pthreadext); /* can't check ID */ - CHECKL(RingCheck(&pthreadext->threadRing)); - CHECKL(RingCheck(&pthreadext->idRing)); + CHECKD_NOSIG(Ring, &pthreadext->threadRing); + CHECKD_NOSIG(Ring, &pthreadext->idRing); if (pthreadext->suspendedMFC == NULL) { /* not suspended */ CHECKL(RingIsSingle(&pthreadext->threadRing)); @@ -366,7 +366,7 @@ unlock: /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/reserv.c b/mps/code/reserv.c index eae0140f108..02b18d66d88 100644 --- a/mps/code/reserv.c +++ b/mps/code/reserv.c @@ -95,7 +95,7 @@ Bool ReservoirCheck(Reservoir reservoir) /* could call ReservoirIsConsistent, but it's costly. */ tract = reservoir->reserve; if (tract != NULL) { - CHECKL(TractCheck(tract)); + CHECKD_NOSIG(Tract, tract); CHECKL(TractPool(tract) == ReservoirPool(reservoir)); } CHECKL(SizeIsAligned(reservoir->reservoirLimit, ArenaAlign(arena))); @@ -282,7 +282,7 @@ Bool ReservoirDeposit(Reservoir reservoir, Addr *baseIO, Size *sizeIO) /* put as many pages as necessary into the reserve & free the rest */ TRACT_FOR(tract, addr, arena, base, limit) { - AVER(TractCheck(tract)); + AVERT(Tract, tract); if (reservoir->reservoirSize < reslimit) { /* Reassign the tract to the reservoir pool */ TractFinish(tract); diff --git a/mps/code/root.c b/mps/code/root.c index edb932f800a..4277550a7fb 100644 --- a/mps/code/root.c +++ b/mps/code/root.c @@ -1,7 +1,7 @@ /* root.c: ROOT IMPLEMENTATION * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This is the implementation of the root datatype. * @@ -98,7 +98,7 @@ Bool RootCheck(Root root) CHECKS(Root, root); CHECKU(Arena, root->arena); CHECKL(root->serial < ArenaGlobals(root->arena)->rootSerial); - CHECKL(RingCheck(&root->arenaRing)); + CHECKD_NOSIG(Ring, &root->arenaRing); CHECKL(RankCheck(root->rank)); CHECKL(TraceSetCheck(root->grey)); /* Don't need to check var here, because of the switch below */ @@ -121,7 +121,7 @@ Bool RootCheck(Root root) case RootREG: CHECKL(root->the.reg.scan != NULL); - CHECKL(ThreadCheck(root->the.reg.thread)); + CHECKD_NOSIG(Thread, root->the.reg.thread); /* */ break; case RootFMT: @@ -261,7 +261,7 @@ Res RootCreateTable(Root *rootReturn, Arena arena, AVER(rootReturn != NULL); AVERT(Arena, arena); - AVER(RankCheck(rank)); + AVERT(Rank, rank); AVER(base != 0); AVER(base < limit); @@ -281,7 +281,7 @@ Res RootCreateTableMasked(Root *rootReturn, Arena arena, AVER(rootReturn != NULL); AVERT(Arena, arena); - AVER(RankCheck(rank)); + AVERT(Rank, rank); AVER(base != 0); AVER(base < limit); /* Can't check anything about mask. */ @@ -302,7 +302,7 @@ Res RootCreateReg(Root *rootReturn, Arena arena, AVER(rootReturn != NULL); AVERT(Arena, arena); - AVER(RankCheck(rank)); + AVERT(Rank, rank); AVERT(Thread, thread); AVER(scan != NULL); @@ -322,7 +322,7 @@ Res RootCreateFmt(Root *rootReturn, Arena arena, AVER(rootReturn != NULL); AVERT(Arena, arena); - AVER(RankCheck(rank)); + AVERT(Rank, rank); AVER(FUNCHECK(scan)); AVER(base != 0); AVER(base < limit); @@ -342,7 +342,7 @@ Res RootCreateFun(Root *rootReturn, Arena arena, Rank rank, AVER(rootReturn != NULL); AVERT(Arena, arena); - AVER(RankCheck(rank)); + AVERT(Rank, rank); AVER(FUNCHECK(scan)); theUnion.fun.scan = scan; @@ -671,7 +671,7 @@ Res RootsDescribe(Globals arenaGlobals, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/sa.c b/mps/code/sa.c index 59ddd4be178..e8bddfa5bbc 100644 --- a/mps/code/sa.c +++ b/mps/code/sa.c @@ -48,13 +48,11 @@ Bool SparseArrayCheck(SparseArray sa) CHECKS(SparseArray, sa); CHECKL(sa->base != NULL); CHECKL(sa->elementSize >= 1); - /* TODO: CHECKD(VM, sa->vm); once VMStruct becomes visible */ - CHECKL(VMCheck(sa->vm)); + CHECKD_NOSIG(VM, sa->vm); /* */ CHECKL(sa->elementSize <= VMAlign(sa->vm)); CHECKL(sa->length > 0); - /* TODO: Make BTCheck extern and use everywhere. */ - /* CHECKL(BTCheck(sa->mapped)); */ - /* CHECKL(BTCheck(sa->pages)); */ + CHECKD_NOSIG(BT, sa->mapped); + CHECKD_NOSIG(BT, sa->pages); CHECKL(sa->shift == SizeLog2(VMAlign(sa->vm))); return TRUE; } diff --git a/mps/code/sac.c b/mps/code/sac.c index 2a87f9a2810..435988cf867 100644 --- a/mps/code/sac.c +++ b/mps/code/sac.c @@ -1,7 +1,7 @@ /* sac.c: SEGREGATED ALLOCATION CACHES * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. */ #include "mpm.h" @@ -249,7 +249,7 @@ Res SACFill(Addr *p_o, SAC sac, Size size, Bool hasReservoirPermit) AVER(p_o != NULL); AVERT(SAC, sac); AVER(size != 0); - AVER(BoolCheck(hasReservoirPermit)); + AVERT(Bool, hasReservoirPermit); esac = ExternalSACOfSAC(sac); sacFind(&i, &blockSize, sac, size); @@ -384,7 +384,7 @@ void SACFlush(SAC sac) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/seg.c b/mps/code/seg.c index 98864fb450f..069b2c50049 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -68,7 +68,7 @@ Res SegAlloc(Seg *segReturn, SegClass class, SegPref pref, AVERT(SegPref, pref); AVER(size > (Size)0); AVERT(Pool, pool); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); arena = PoolArena(pool); AVERT(Arena, arena); @@ -152,7 +152,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size, AVER(SizeIsAligned(size, align)); class = seg->class; AVERT(SegClass, class); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); limit = AddrAdd(base, size); seg->limit = limit; @@ -168,7 +168,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size, seg->sig = SegSig; /* set sig now so tract checks will see it */ TRACT_FOR(tract, addr, arena, base, limit) { - AVER(TractCheck(tract)); /* */ + AVERT(Tract, tract); AVER(TractP(tract) == NULL); AVER(!TractHasSeg(tract)); AVER(TractPool(tract) == pool); @@ -196,7 +196,7 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size, failInit: RingFinish(SegPoolRing(seg)); TRACT_FOR(tract, addr, arena, base, limit) { - AVER(TractCheck(tract)); /* */ + AVERT(Tract, tract); TRACT_UNSET_SEG(tract); } seg->sig = SigInvalid; @@ -233,7 +233,7 @@ static void SegFinish(Seg seg) limit = SegLimit(seg); TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) { - AVER(TractCheck(tract)); /* */ + AVERT(Tract, tract); TractSetWhite(tract, TraceSetEMPTY); TRACT_UNSET_SEG(tract); } @@ -263,7 +263,7 @@ static void SegFinish(Seg seg) void SegSetGrey(Seg seg, TraceSet grey) { AVERT(Seg, seg); - AVER(TraceSetCheck(grey)); + AVERT(TraceSet, grey); AVER(grey == TraceSetEMPTY || SegRankSet(seg) != RankSetEMPTY); /* Don't dispatch to the class method if there's no actual change in @@ -281,7 +281,7 @@ void SegSetGrey(Seg seg, TraceSet grey) void SegSetWhite(Seg seg, TraceSet white) { AVERT(Seg, seg); - AVER(TraceSetCheck(white)); + AVERT(TraceSet, white); seg->class->setWhite(seg, white); } @@ -296,7 +296,7 @@ void SegSetWhite(Seg seg, TraceSet white) void SegSetRankSet(Seg seg, RankSet rankSet) { AVERT(Seg, seg); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); AVER(rankSet != RankSetEMPTY || SegSummary(seg) == RefSetEMPTY); seg->class->setRankSet(seg, rankSet); } @@ -322,7 +322,7 @@ void SegSetSummary(Seg seg, RefSet summary) void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary) { AVERT(Seg, seg); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); #ifdef PROTECTION_NONE if (rankSet != RankSetEMPTY) { @@ -582,7 +582,7 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi, mid = SegLimit(segLo); limit = SegLimit(segHi); AVER(SegBase(segHi) == SegLimit(segLo)); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); arena = PoolArena(SegPool(segLo)); ShieldFlush(arena); /* see */ @@ -634,7 +634,7 @@ Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at, AVER(AddrIsAligned(at, arena->alignment)); AVER(at > base); AVER(at < limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); ShieldFlush(arena); /* see */ @@ -690,7 +690,7 @@ Bool SegCheck(Seg seg) /* can't assume nailed is subset of white - mightn't be during whiten */ /* CHECKL(TraceSetSub(seg->nailed, seg->white)); */ CHECKL(TraceSetCheck(seg->grey)); - CHECKL(TractCheck(seg->firstTract)); /* */ + CHECKD_NOSIG(Tract, seg->firstTract); pool = SegPool(seg); CHECKU(Pool, pool); arena = PoolArena(pool); @@ -704,7 +704,7 @@ Bool SegCheck(Seg seg) TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, seg->limit) { Seg trseg = NULL; /* suppress compiler warning */ - CHECKL(TractCheck(tract)); /* */ + CHECKD_NOSIG(Tract, tract); CHECKL(TRACT_SEG(&trseg, tract) && (trseg == seg)); CHECKL(TractWhite(tract) == seg->white); CHECKL(TractPool(tract) == pool); @@ -716,7 +716,7 @@ Bool SegCheck(Seg seg) /* the segment is initialized.) */ /* CHECKL(RingNext(&seg->poolRing) != &seg->poolRing); */ - CHECKL(RingCheck(&seg->poolRing)); + CHECKD_NOSIG(Ring, &seg->poolRing); /* "pm", "sm", and "depth" not checked. See .check.shield. */ CHECKL(RankSetCheck(seg->rankSet)); @@ -762,8 +762,8 @@ static Res segTrivInit(Seg seg, Pool pool, Addr base, Size size, AVER(SegBase(seg) == base); AVER(SegSize(seg) == size); AVER(SegPool(seg) == pool); - AVER(BoolCheck(reservoirPermit)); - AVER(ArgListCheck(args)); + AVERT(Bool, reservoirPermit); + AVERT(ArgList, args); UNUSED(args); return ResOK; } @@ -783,7 +783,7 @@ static void segTrivFinish(Seg seg) static void segNoSetGrey(Seg seg, TraceSet grey) { AVERT(Seg, seg); - AVER(TraceSetCheck(grey)); + AVERT(TraceSet, grey); AVER(seg->rankSet != RankSetEMPTY); NOTREACHED; } @@ -794,7 +794,7 @@ static void segNoSetGrey(Seg seg, TraceSet grey) static void segNoSetWhite(Seg seg, TraceSet white) { AVERT(Seg, seg); - AVER(TraceSetCheck(white)); + AVERT(TraceSet, white); NOTREACHED; } @@ -804,7 +804,7 @@ static void segNoSetWhite(Seg seg, TraceSet white) static void segNoSetRankSet(Seg seg, RankSet rankSet) { AVERT(Seg, seg); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); NOTREACHED; } @@ -824,7 +824,7 @@ static void segNoSetSummary(Seg seg, RefSet summary) static void segNoSetRankSummary(Seg seg, RankSet rankSet, RefSet summary) { AVERT(Seg, seg); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); UNUSED(summary); NOTREACHED; } @@ -864,7 +864,7 @@ static Res segNoMerge(Seg seg, Seg segHi, AVER(SegLimit(seg) == mid); AVER(SegBase(segHi) == mid); AVER(SegLimit(segHi) == limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); NOTREACHED; return ResFAIL; } @@ -900,7 +900,7 @@ static Res segTrivMerge(Seg seg, Seg segHi, AVER(SegLimit(seg) == mid); AVER(SegBase(segHi) == mid); AVER(SegLimit(segHi) == limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* .similar. */ AVER(seg->rankSet == segHi->rankSet); @@ -918,7 +918,7 @@ static Res segTrivMerge(Seg seg, Seg segHi, seg->limit = limit; TRACT_FOR(tract, addr, arena, mid, limit) { - AVER(TractCheck(tract)); /* */ + AVERT(Tract, tract); AVER(TractHasSeg(tract)); AVER(segHi == TractP(tract)); AVER(TractPool(tract) == pool); @@ -948,7 +948,7 @@ static Res segNoSplit(Seg seg, Seg segHi, AVER(mid < limit); AVER(SegBase(seg) == base); AVER(SegLimit(seg) == limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); NOTREACHED; return ResFAIL; @@ -979,7 +979,7 @@ static Res segTrivSplit(Seg seg, Seg segHi, AVER(mid < limit); AVER(SegBase(seg) == base); AVER(SegLimit(seg) == limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* Segment may not be exposed, or in the shield cache */ /* See & */ @@ -1001,7 +1001,7 @@ static Res segTrivSplit(Seg seg, Seg segHi, RingInit(SegPoolRing(segHi)); TRACT_FOR(tract, addr, arena, mid, limit) { - AVER(TractCheck(tract)); /* */ + AVERT(Tract, tract); AVER(TractHasSeg(tract)); AVER(seg == TractP(tract)); AVER(TractPool(tract) == pool); @@ -1092,7 +1092,7 @@ Bool GCSegCheck(GCSeg gcseg) Seg seg; CHECKS(GCSeg, gcseg); seg = &gcseg->segStruct; - CHECKL(SegCheck(seg)); + CHECKD(Seg, seg); if (gcseg->buffer != NULL) { CHECKU(Buffer, gcseg->buffer); @@ -1102,7 +1102,7 @@ Bool GCSegCheck(GCSeg gcseg) } /* The segment should be on a grey ring if and only if it is grey. */ - CHECKL(RingCheck(&gcseg->greyRing)); + CHECKD_NOSIG(Ring, &gcseg->greyRing); CHECKL((seg->grey == TraceSetEMPTY) == RingIsSingle(&gcseg->greyRing)); @@ -1134,7 +1134,7 @@ static Res gcSegInit(Seg seg, Pool pool, Addr base, Size size, AVER(SizeIsAligned(size, align)); gcseg = SegGCSeg(seg); AVER(&gcseg->segStruct == seg); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); /* Initialize the superclass fields first via next-method call */ super = SEG_SUPERCLASS(GCSegClass); @@ -1311,7 +1311,7 @@ static void gcSegSetWhite(Seg seg, TraceSet white) TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) { Seg trseg = NULL; /* suppress compiler warning */ - AVER_CRITICAL(TractCheck(tract)); /* */ + AVERT_CRITICAL(Tract, tract); AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg)); TractSetWhite(tract, white); } @@ -1499,7 +1499,7 @@ static Res gcSegMerge(Seg seg, Seg segHi, AVER(SegLimit(seg) == mid); AVER(SegBase(segHi) == mid); AVER(SegLimit(segHi) == limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); buf = gcsegHi->buffer; /* any buffer on segHi must be reassigned */ AVER(buf == NULL || gcseg->buffer == NULL); /* See .buffer */ @@ -1565,7 +1565,7 @@ static Res gcSegSplit(Seg seg, Seg segHi, AVER(mid < limit); AVER(SegBase(seg) == base); AVER(SegLimit(seg) == limit); - AVER(BoolCheck(withReservoirPermit)); + AVERT(Bool, withReservoirPermit); grey = SegGrey(seg); buf = gcseg->buffer; /* Look for buffer to reassign to segHi */ @@ -1648,7 +1648,7 @@ static Res gcSegDescribe(Seg seg, mps_lib_FILE *stream) Bool SegClassCheck(SegClass class) { - CHECKL(ProtocolClassCheck(&class->protocol)); + CHECKD(ProtocolClass, &class->protocol); CHECKL(class->name != NULL); /* Should be <= 6 char C identifier */ CHECKL(class->size >= sizeof(SegStruct)); CHECKL(FUNCHECK(class->init)); diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index d5ef0ca2491..21a8b8846ed 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -67,7 +67,7 @@ typedef struct AMSTStruct *AMST; static Bool AMSTCheck(AMST amst) { CHECKS(AMST, amst); - CHECKL(AMSCheck(AMST2AMS(amst))); + CHECKD_NOSIG(AMS, AMST2AMS(amst)); /* */ return TRUE; } @@ -104,7 +104,7 @@ typedef struct AMSTSegStruct { static Bool AMSTSegCheck(AMSTSeg amstseg) { CHECKS(AMSTSeg, amstseg); - CHECKL(AMSSegCheck(&amstseg->amsSegStruct)); + CHECKD_NOSIG(AMSSeg, &amstseg->amsSegStruct); /* */ /* don't bother to do other checks - this is a stress test */ return TRUE; } @@ -129,7 +129,7 @@ static Res amstSegInit(Seg seg, Pool pool, Addr base, Size size, amst = Pool2AMST(pool); AVERT(AMST, amst); /* no useful checks for base and size */ - AVER(BoolCheck(reservoirPermit)); + AVERT(Bool, reservoirPermit); /* Initialize the superclass fields first via next-method call */ super = SEG_SUPERCLASS(AMSTSegClass); @@ -311,7 +311,7 @@ static Res AMSTSegSizePolicy(Size *sizeReturn, AVER(sizeReturn != NULL); AVERT(Pool, pool); AVER(size > 0); - AVER(RankSetCheck(rankSet)); + AVERT(RankSet, rankSet); arena = PoolArena(pool); diff --git a/mps/code/splay.c b/mps/code/splay.c index 53e21db9fa8..610822fc74a 100644 --- a/mps/code/splay.c +++ b/mps/code/splay.c @@ -48,7 +48,7 @@ Bool SplayTreeCheck(SplayTree splay) CHECKL(FUNCHECK(splay->compare)); CHECKL(FUNCHECK(splay->nodeKey)); CHECKL(FUNCHECK(splay->updateNode)); - CHECKL(TreeCheck(splay->root)); + CHECKD_NOSIG(Tree, splay->root); return TRUE; } diff --git a/mps/code/than.c b/mps/code/than.c index 752ef3ed64c..a1dab12adc8 100644 --- a/mps/code/than.c +++ b/mps/code/than.c @@ -1,7 +1,7 @@ /* than.c: ANSI THREADS MANAGER * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * This is a single-threaded implementation of the threads manager. * Has stubs for thread suspension. @@ -30,7 +30,7 @@ Bool ThreadCheck(Thread thread) CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); - CHECKL(RingCheck(&thread->arenaRing)); + CHECKD_NOSIG(Ring, &thread->arenaRing); return TRUE; } @@ -146,7 +146,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/thix.c b/mps/code/thix.c index 7760a5e1349..cc380dd040f 100644 --- a/mps/code/thix.c +++ b/mps/code/thix.c @@ -1,7 +1,7 @@ /* thix.c: Threads Manager for Posix threads * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .purpose: This is a pthreads implementation of the threads manager. * This implements . @@ -61,7 +61,7 @@ Bool ThreadCheck(Thread thread) CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); - CHECKL(RingCheck(&thread->arenaRing)); + CHECKD_NOSIG(Ring, &thread->arenaRing); CHECKD(PThreadext, &thread->thrextStruct); return TRUE; } @@ -292,7 +292,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/thw3.c b/mps/code/thw3.c index e1e5c97841b..701ffc53cdd 100644 --- a/mps/code/thw3.c +++ b/mps/code/thw3.c @@ -1,7 +1,7 @@ /* thw3i3.c: WIN32 THREAD MANAGER * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * Implements thread registration, suspension, and stack * scanning. See . @@ -60,7 +60,7 @@ Bool ThreadCheck(Thread thread) CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); - CHECKL(RingCheck(&thread->arenaRing)); + CHECKD_NOSIG(Ring, &thread->arenaRing); return TRUE; } @@ -233,7 +233,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2002 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/thxc.c b/mps/code/thxc.c index 745669cfc47..9e6a6bd325c 100644 --- a/mps/code/thxc.c +++ b/mps/code/thxc.c @@ -1,7 +1,7 @@ /* thxc.c: OS X MACH THREADS MANAGER * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .design: See . * @@ -45,7 +45,7 @@ Bool ThreadCheck(Thread thread) CHECKS(Thread, thread); CHECKU(Arena, thread->arena); CHECKL(thread->serial < thread->arena->threadSerial); - CHECKL(RingCheck(&thread->arenaRing)); + CHECKD_NOSIG(Ring, &thread->arenaRing); CHECKL(MACH_PORT_VALID(thread->port)); return TRUE; } @@ -267,7 +267,7 @@ Res ThreadDescribe(Thread thread, mps_lib_FILE *stream) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/trace.c b/mps/code/trace.c index df258df17dc..924badcd541 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -64,9 +64,9 @@ void ScanStateInit(ScanState ss, TraceSet ts, Arena arena, TraceId ti; Trace trace; - AVER(TraceSetCheck(ts)); + AVERT(TraceSet, ts); AVERT(Arena, arena); - AVER(RankCheck(rank)); + AVERT(Rank, rank); /* white is arbitrary and can't be checked */ /* NOTE: We can only currently support scanning for a set of traces with @@ -504,9 +504,9 @@ static Res rootFlip(Root root, void *p) AVERT(Root, root); AVER(p != NULL); - AVER(TraceSetCheck(rf->ts)); + AVERT(TraceSet, rf->ts); AVERT(Arena, rf->arena); - AVER(RankCheck(rf->rank)); + AVERT(Rank, rf->rank); AVER(RootRank(root) <= RankEXACT); /* see .root.rank */ @@ -989,7 +989,7 @@ static Bool traceFindGrey(Seg *segReturn, Rank *rankReturn, Ring node, nextNode; AVER(segReturn != NULL); - AVER(TraceIdCheck(ti)); + AVERT(TraceId, ti); trace = ArenaTrace(arena, ti); @@ -1377,10 +1377,10 @@ void TraceScanSingleRef(TraceSet ts, Rank rank, Arena arena, { Res res; - AVER(TraceSetCheck(ts)); - AVER(RankCheck(rank)); + AVERT(TraceSet, ts); + AVERT(Rank, rank); AVERT(Arena, arena); - AVER(SegCheck(seg)); + AVERT(Seg, seg); AVER(refIO != NULL); res = traceScanSingleRefRes(ts, rank, arena, seg, refIO); diff --git a/mps/code/tract.c b/mps/code/tract.c index 69ae479cf1a..2468887bc17 100644 --- a/mps/code/tract.c +++ b/mps/code/tract.c @@ -1,7 +1,7 @@ /* tract.c: PAGE TABLES * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .ullagepages: Pages whose page index is < allocBase are recorded as * free but never allocated as alloc starts searching after the tables. @@ -113,7 +113,7 @@ Bool ChunkCheck(Chunk chunk) CHECKS(Chunk, chunk); CHECKU(Arena, chunk->arena); CHECKL(chunk->serial < chunk->arena->chunkSerial); - CHECKL(RingCheck(&chunk->chunkRing)); + CHECKD_NOSIG(Ring, &chunk->chunkRing); CHECKL(ChunkPagesToSize(chunk, 1) == ChunkPageSize(chunk)); CHECKL(ShiftCheck(ChunkPageShift(chunk))); @@ -128,7 +128,7 @@ Bool ChunkCheck(Chunk chunk) CHECKL(chunk->allocBase <= chunk->pages); CHECKL(chunk->allocBase >= chunk->pageTablePages); - CHECKL(chunk->allocTable != NULL); + CHECKD_NOSIG(BT, chunk->allocTable); /* check that allocTable is in the chunk overhead */ CHECKL((Addr)chunk->allocTable >= chunk->base); CHECKL(AddrAdd((Addr)chunk->allocTable, BTSize(chunk->pages)) @@ -671,7 +671,7 @@ void PageFree(Chunk chunk, Index pi) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/walk.c b/mps/code/walk.c index 0fcc37a151c..3f7f67f99e1 100644 --- a/mps/code/walk.c +++ b/mps/code/walk.c @@ -171,7 +171,7 @@ static Bool rootsStepClosureCheck(rootsStepClosure rsc) CHECKL(FUNCHECK(rsc->f)); /* p and s fields are arbitrary closures which cannot be checked */ if (rsc->root != NULL) { - CHECKL(RootCheck(rsc->root)); + CHECKD_NOSIG(Root, rsc->root); /* */ } return TRUE; } diff --git a/mps/design/check.txt b/mps/design/check.txt index c0d2a8a97b3..47d757d3945 100644 --- a/mps/design/check.txt +++ b/mps/design/check.txt @@ -95,17 +95,30 @@ type structure pointer, possibly invoking ``Check`` (depending on level; see `.level`_). It should be called with the child type and pointer. -_`.full-type`: ``CHECKS()``, ``CHECKD()``, ``CHECKU()``, all operate -only on fully fledged types. This means the type has to provide a -function ``Bool TypeCheck(Type type)`` where ``Type`` is substituted -for the name of the type (for example, ``PoolCheck()``), and the -expression ``obj->sig`` must be a valid value of type ``Sig`` whenever -``obj`` is a valid value of type ``Type``. +_`.full-type`: Use ``CHECKS()``, ``CHECKD()`` or ``CHECKU()`` on all +types that satisfy these three requirements: -_`.type.no-sig`: This tag is to be referenced in implementations -whenever the form ``CHECKL(ThingCheck(thing))`` is used instead of -``CHECK{U,D}(Thing, thing)`` because ``Thing`` is not a fully fledged -type (`.full-type`_). +_`.full-type.pointer`: The type is a pointer type. + +_`.full-type.check`: The type provides a function ``Bool TypeCheck(Type +type)`` where ``Type`` is substituted for the name of the type (for +example, ``PoolCheck()``). + +_`.full-type.sig`: The expression ``obj->sig`` is a valid value of +type ``Sig`` whenever ``obj`` is a valid value of type ``Type``. + +_`.partial-type`: Where the type satisfies `.full-type.pointer`_ and +`.full-type.check`_ but not `.full-type.sig`_ because the type lacks a +signature in order to save space (this applies to small structures +that are embedded many times in other structures, for example +``Ring``), use ``CHECKD_NOSIG()``. + +_`.hidden-type`: Where the type satisfies `.full-type.pointer`_ and +`.full-type.check`_ but not `.full-type.sig`_ because the structure +has a signature but the structure definition is not visible at point +of checking (for example ``Root``), use ``CHECKD_NOSIG()`` and +reference this tag. The structure could be considered for addition to +``mpmst.h``. Document History From 44b5c0d0c4c4787a60d06639f79d38fc24400b24 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 7 Apr 2014 00:27:31 +0100 Subject: [PATCH 22/24] Fix restructuredtext formatting. Copied from Perforce Change: 185266 ServerID: perforce.ravenbrook.com --- mps/design/type.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/design/type.txt b/mps/design/type.txt index e5f347d244b..6ce0da3c035 100644 --- a/mps/design/type.txt +++ b/mps/design/type.txt @@ -448,7 +448,7 @@ Root mode Description ``RootModePROTECTABLE_INNER`` Root is protectable: the MPS may place a barrier on any page completely covered by part of the root. -============================= ========================================== +============================= ========================================= _`.rootmode.const.unused`: ``RootModeCONSTANT`` has no effect. This mode was introduced in the hope of being able to maintain a From 0f445a4ea4cb87dc2f5ee13a99e0d69d0f474634 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 7 Apr 2014 00:29:09 +0100 Subject: [PATCH 23/24] Remove "todo: checkleveldeep asserts on arena creation with bootstrapping problems." -- this was fixed in change 184924. Copied from Perforce Change: 185267 ServerID: perforce.ravenbrook.com --- mps/code/check.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mps/code/check.h b/mps/code/check.h index 4ed2ba8b75a..825e15c7e48 100644 --- a/mps/code/check.h +++ b/mps/code/check.h @@ -1,7 +1,7 @@ /* check.h: ASSERTION INTERFACE * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * * .aver: This header defines a family of AVER and NOTREACHED macros. @@ -85,9 +85,6 @@ * * TODO: Should also allow the check level variable to come from an * environment variable. - * - * TODO: CheckLevelDEEP asserts on arena creation with bootstrapping - * problems. It clearly hasn't been tried for a while. RB 2012-09-01 */ enum { @@ -327,7 +324,7 @@ extern unsigned CheckLevel; /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited . + * Copyright (C) 2001-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * From f2776dc0b4ca560b8bd4d463a463c23830e8a31e Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 7 Apr 2014 10:14:40 +0100 Subject: [PATCH 24/24] Can't use checkd_nosig(tree, ...) because treeempty is null. arena->enabledMessageTypes might be NULL. Copied from Perforce Change: 185271 ServerID: perforce.ravenbrook.com --- mps/code/cbs.c | 3 ++- mps/code/global.c | 3 ++- mps/code/splay.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 456271a9e9b..176a15fef16 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -85,7 +85,8 @@ static Bool CBSBlockCheck(CBSBlock block) /* See .enter-leave.simple. */ UNUSED(block); /* Required because there is no signature */ CHECKL(block != NULL); - CHECKD_NOSIG(Tree, cbsBlockTree(block)); + /* Can't use CHECKD_NOSIG because TreeEMPTY is NULL. */ + CHECKL(TreeCheck(cbsBlockTree(block))); /* If the block is in the middle of being deleted, */ /* the pointers will be equal. */ diff --git a/mps/code/global.c b/mps/code/global.c index 072b21253ac..b43b888dc11 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -147,7 +147,8 @@ Bool GlobalsCheck(Globals arenaGlobals) arenaGlobals->rememberedSummaryIndex == 0); CHECKD_NOSIG(Ring, &arena->formatRing); CHECKD_NOSIG(Ring, &arena->messageRing); - CHECKD_NOSIG(BT, arena->enabledMessageTypes); + if (arena->enabledMessageTypes != NULL) + CHECKD_NOSIG(BT, arena->enabledMessageTypes); CHECKL(BoolCheck(arena->isFinalPool)); if (arena->isFinalPool) { CHECKD(Pool, arena->finalPool); diff --git a/mps/code/splay.c b/mps/code/splay.c index 610822fc74a..7e061cd14f4 100644 --- a/mps/code/splay.c +++ b/mps/code/splay.c @@ -48,7 +48,8 @@ Bool SplayTreeCheck(SplayTree splay) CHECKL(FUNCHECK(splay->compare)); CHECKL(FUNCHECK(splay->nodeKey)); CHECKL(FUNCHECK(splay->updateNode)); - CHECKD_NOSIG(Tree, splay->root); + /* Can't use CHECKD_NOSIG because TreeEMPTY is NULL. */ + CHECKL(TreeCheck(splay->root)); return TRUE; }