From a6f8e8a25d933b35140f73224512c691129b7b12 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 21 Mar 2014 14:48:25 +0000 Subject: [PATCH 01/65] Branching master to branch/2014-03-21/pellesc. Copied from Perforce Change: 184935 ServerID: perforce.ravenbrook.com From 4ef183e62a65f7bdb277d0d58dafb31107f0af0a Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 21 Mar 2014 18:28:39 +0000 Subject: [PATCH 02/65] Mps compiles and runs using pelles c. Merge code from Bruce Mitchener and from RB . Split call to EVENT_LIST so that event.c compiles. Remove useless call to va_end in seg.c. Copied from Perforce Change: 184948 ServerID: perforce.ravenbrook.com --- mps/code/event.c | 7 ++- mps/code/mps.c | 15 +++++++ mps/code/mpstd.h | 27 +++++++++++- mps/code/seg.c | 2 - mps/code/ssw3i3mv.c | 2 + mps/code/ssw3i3pc.c | 104 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 mps/code/ssw3i3pc.c diff --git a/mps/code/event.c b/mps/code/event.c index 8198319f26b..87715b25d9d 100644 --- a/mps/code/event.c +++ b/mps/code/event.c @@ -197,10 +197,13 @@ void EventInit(void) AVER((Bool)Event##name##Always == always); \ AVERT(Bool, always); \ AVER(0 <= Event##name##Kind); \ - AVER((EventKind)Event##name##Kind < EventKindLIMIT); \ + AVER((EventKind)Event##name##Kind < EventKindLIMIT); + +#define EVENT_CHECK_PARAMS(X, name, code, always, kind) \ EVENT_##name##_PARAMS(EVENT_PARAM_CHECK, name) - EVENT_LIST(EVENT_CHECK, X) + /*EVENT_LIST(EVENT_CHECK, X)*/ + /*EVENT_LIST(EVENT_CHECK_PARAMS, X)*/ /* Ensure that no event can be larger than the maximum event size. */ AVER(EventBufferSIZE <= EventSizeMAX); diff --git a/mps/code/mps.c b/mps/code/mps.c index ef2484eabdf..bcd6120de82 100644 --- a/mps/code/mps.c +++ b/mps/code/mps.c @@ -214,6 +214,21 @@ #include "spw3i6mv.c" /* Windows on 64-bit stack probe for Microsoft C */ #include "mpsiw3.c" /* Windows interface layer extras */ +/* Windows on 32-bit Intel with Pelles C */ + +#elif defined(MPS_PF_W3I3PC) + +#include "lockw3.c" /* Windows locks */ +#include "thw3.c" /* Windows threading */ +#include "thw3i3.c" /* Windows on 32-bit Intel thread stack scan */ +#include "vmw3.c" /* Windows virtual memory */ +#include "protw3.c" /* Windows protection */ +#include "proti3.c" /* 32-bit Intel mutator context decoding */ +#include "prmci3w3.c" /* Windows on 32-bit Intel mutator context */ +#include "ssw3i3pc.c" /* Windows on 32-bit stack scan for Pelles C */ +#include "spw3i3mv.c" /* Intel stack probe */ +#include "mpsiw3.c" /* Windows interface layer extras */ + #else #error "Unknown platform -- can't determine platform specific parts." diff --git a/mps/code/mpstd.h b/mps/code/mpstd.h index 88b4575155a..891d5979647 100644 --- a/mps/code/mpstd.h +++ b/mps/code/mpstd.h @@ -31,9 +31,12 @@ * Alignment of 4 would work, but the MS library uses 8 bytes for * doubles and __int64, so we choose that. The actual granularity of * VC malloc is 16! + * + * PellesC /Ze (Microsoft compatibility mode) defines _MSC_VER but + * isn't compatible enough for MPS purposes. */ -#if defined(_MSC_VER) && defined(_WIN32) && defined(_M_IX86) +#if defined(_MSC_VER) && defined(_WIN32) && defined(_M_IX86) && !defined(__POCC__) #if defined(CONFIG_PF_STRING) && ! defined(CONFIG_PF_W3I3MV) #error "specified CONFIG_PF_... inconsistent with detected w3i3mv" #endif @@ -58,7 +61,7 @@ * */ -#elif defined(_MSC_VER) && defined(_WIN32) && defined(_WIN64) && defined(_M_X64) +#elif defined(_MSC_VER) && defined(_WIN32) && defined(_WIN64) && defined(_M_X64) && !defined(__POCC__) #if defined(CONFIG_PF_STRING) && ! defined(CONFIG_PF_W3I6MV) #error "specified CONFIG_PF_... inconsistent with detected w3i6mv" #endif @@ -74,6 +77,26 @@ #define MPS_PF_ALIGN 16 +/* PellesC version 7.00.25 with /Ze option (Microsoft compatibility mode) + * Help node "Predefined preprocessor symbols (POCC)" + */ + +#elif defined(__POCC__) && defined(_WIN32) && defined(_M_IX86) +#if defined(CONFIG_PF_STRING) && ! defined(CONFIG_PF_W3I3PC) +#error "specified CONFIG_PF_... inconsistent with detected w3i3pc" +#endif +#define MPS_PF_W3I3PC +#define MPS_PF_STRING "w3i3pc" +#define MPS_OS_W3 +#define MPS_ARCH_I3 +#define MPS_BUILD_PC +#define MPS_T_WORD unsigned long +#define MPS_T_ULONGEST unsigned long +#define MPS_WORD_WIDTH 32 +#define MPS_WORD_SHIFT 5 +#define MPS_PF_ALIGN 8 + + /* GCC 4.0.1 (As supplied by Apple on Mac OS X 10.4.8 on an Intel Mac), * gcc -E -dM * And above for xcppgc. diff --git a/mps/code/seg.c b/mps/code/seg.c index 1ba5041d036..891c14296cf 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -571,7 +571,6 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi, Addr base, mid, limit; Arena arena; Res res; - va_list args; AVER(NULL != mergedSegReturn); AVERT(Seg, segLo); @@ -591,7 +590,6 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi, /* Invoke class-specific methods to do the merge */ res = class->merge(segLo, segHi, base, mid, limit, withReservoirPermit); - va_end(args); if (ResOK != res) goto failMerge; diff --git a/mps/code/ssw3i3mv.c b/mps/code/ssw3i3mv.c index ac0b09fd670..d879780734a 100644 --- a/mps/code/ssw3i3mv.c +++ b/mps/code/ssw3i3mv.c @@ -37,6 +37,8 @@ Res StackScan(ScanState ss, Addr *stackBot) AVER(sizeof(((_JUMP_BUFFER *)jb)->Esi) == sizeof(Addr)); AVER(sizeof(((_JUMP_BUFFER *)jb)->Ebx) == sizeof(Addr)); + /* Ensure that the callee-save registers will be found by + StackScanInner when it's passed the address of the Ebx field. */ AVER(offsetof(_JUMP_BUFFER, Edi) == offsetof(_JUMP_BUFFER, Ebx) + 4); AVER(offsetof(_JUMP_BUFFER, Esi) == offsetof(_JUMP_BUFFER, Ebx) + 8); diff --git a/mps/code/ssw3i3pc.c b/mps/code/ssw3i3pc.c new file mode 100644 index 00000000000..e03754c7eba --- /dev/null +++ b/mps/code/ssw3i3pc.c @@ -0,0 +1,104 @@ +/* ssw3i3pc.c: STACK SCANNING FOR WIN32 WITH PELLES C + * + * $Id$ + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. + * + * This scans the stack and fixes the registers which may contain roots. + * See . + * + * .assume.ms-compat: We rely on the fact that Pelles C's setjmp stores + * the callee-save registers in the jmp_buf and is compatible with Microsoft + * C. The Pelles C 7.00 setjmp.h header has a comment "MS compatible". See + * also "Is Pelles C's jmp_buf compatible with Microsoft C's?" + * + * + * REFERENCES + * + * "Argument Passing and Naming Conventions"; MSDN; Microsoft Corporation; + * . + * + * "Calling conventions for different C++ compilers and operating systems"; + * Agner Fog; Copenhagen University College of Engineering; 2012-02-29; + * . + */ + +#include "mpm.h" +#include + +SRCID(ssw3i3pc, "$Id$"); + + +/* This definition isn't in the Pelles C headers, so we reproduce it here. + * See .assume.ms-compat. */ + +typedef struct __JUMP_BUFFER { + unsigned long Ebp; + unsigned long Ebx; + unsigned long Edi; + unsigned long Esi; + unsigned long Esp; + unsigned long Eip; + unsigned long Registration; + unsigned long TryLevel; + unsigned long Cookie; + unsigned long UnwindFunc; + unsigned long UnwindData[6]; +} _JUMP_BUFFER; + + +Res StackScan(ScanState ss, Addr *stackBot) +{ + jmp_buf jb; + + /* .assume.ms-compat */ + (void)setjmp(jb); + + /* Ensure that the callee-save registers will be found by + StackScanInner when it's passed the address of the Ebx field. */ + AVER(offsetof(_JUMP_BUFFER, Edi) == offsetof(_JUMP_BUFFER, Ebx) + 4); + AVER(offsetof(_JUMP_BUFFER, Esi) == offsetof(_JUMP_BUFFER, Ebx) + 8); + + return StackScanInner(ss, stackBot, (Addr *)&((_JUMP_BUFFER *)jb)->Ebx, 3); +} + + +/* C. COPYRIGHT AND LICENSE + * + * Copyright (C) 2001-2014 Ravenbrook Limited . + * All rights reserved. This is an open source license. Contact + * Ravenbrook for commercial licensing options. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Redistributions in any form must be accompanied by information on how + * to obtain complete source code for this software and any accompanying + * software that uses this software. The source code must either be + * included in the distribution or be available for no more than the cost + * of distribution plus a nominal fee, and must be freely redistributable + * under reasonable conditions. For an executable file, complete source + * code means the source code for all modules it contains. It does not + * include source code for modules or files that typically accompany the + * major components of the operating system on which the executable file + * runs. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ From 831c86c47bc388fad5bbff45b8ec65c67785be1d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 21 Mar 2014 18:29:36 +0000 Subject: [PATCH 03/65] (very) draft makefile for pelles c. Copied from Perforce Change: 184949 ServerID: perforce.ravenbrook.com --- mps/code/w3i3pc.gmk | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 mps/code/w3i3pc.gmk diff --git a/mps/code/w3i3pc.gmk b/mps/code/w3i3pc.gmk new file mode 100644 index 00000000000..e1b832be7a2 --- /dev/null +++ b/mps/code/w3i3pc.gmk @@ -0,0 +1,5 @@ +%.obj: %.c + pocc /Ze $< + +amcss.exe: amcss.obj abq.obj arena.obj arenacl.obj arenavm.obj arg.obj boot.obj bt.obj buffer.obj cbs.obj dbgpool.obj dbgpooli.obj event.obj fmtdy.obj fmtdy.obj fmtdytst.obj fmthe.obj fmtno.obj fmtno.obj format.obj freelist.obj global.obj ld.obj lockw3.obj locus.obj message.obj meter.obj mpm.obj mpsi.obj mpsioan.obj mpsiw3.obj mpsliban.obj pool.obj poolabs.obj poolamc.obj poolams.obj poolamsi.obj poolawl.obj poollo.obj poolmfs.obj poolmrg.obj poolmv2.obj poolmv.obj poolmvff.obj pooln.obj poolsnc.obj proti3.obj prmci3w3.obj protocol.obj protw3.obj range.obj ref.obj reserv.obj ring.obj root.obj sa.obj sac.obj seg.obj shield.obj spw3i3mv.obj splay.obj ss.obj ssw3i3pc.obj table.obj testlib.obj thw3.obj thw3i3.obj trace.obj traceanc.obj tract.obj tree.obj version.obj vmw3.obj walk.obj + polink $^ /OUT:$@ From 9d5266c0cc32ea1e4abffa7d9763546c4ec02d1f Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 24 Mar 2014 18:23:29 +0000 Subject: [PATCH 04/65] Improved support for pelles c: * Refactor nmake files so that a compiler-specific makefile is included; move Microsoft Visual C-specific options to mv.nmk. * Add nmake files for Pelles (w3i3pc.nmk and pc.nmk). * Rename spw3i3mv.c to spw3i3.c and spw3i6mv.c to spw3i6.c since these are also used by Pelles C. * Make reasonable changes to the source code to avoid warnings from Pelles C: ** check results of function calls; ** avoid useless return values; ** undef max before defining it; ** ensure printf formats are checkable; ** move notreached() assertions to the end of blocks; ** suppress warnings in cases where the code shouldn't be changed ("Unreachable code", "Inline assembly code is not portable", "Structured Exception Handling is not portable"). Copied from Perforce Change: 184977 ServerID: perforce.ravenbrook.com --- mps/code/abq.c | 12 +-- mps/code/abqtest.c | 2 +- mps/code/amcss.c | 2 +- mps/code/amcsshe.c | 2 +- mps/code/amsss.c | 4 +- mps/code/amssshe.c | 4 +- mps/code/apss.c | 5 - mps/code/arena.c | 2 +- mps/code/arenavm.c | 2 +- mps/code/awlut.c | 2 +- mps/code/awluthe.c | 6 +- mps/code/bttest.c | 12 +-- mps/code/commpost.nmk | 10 +- mps/code/commpre.nmk | 19 ++-- mps/code/config.h | 13 ++- mps/code/event.c | 2 +- mps/code/event.h | 2 +- mps/code/eventcnv.c | 23 ++-- mps/code/eventtxt.c | 41 +++---- mps/code/exposet0.c | 2 +- mps/code/expt825.c | 8 +- mps/code/fbmtest.c | 16 +-- mps/code/finaltest.c | 8 +- mps/code/fmtdy.c | 6 +- mps/code/fotest.c | 5 - mps/code/locbwcss.c | 3 +- mps/code/lockutw3.c | 6 +- mps/code/locus.c | 2 +- mps/code/mpmss.c | 9 +- mps/code/mps.c | 10 +- mps/code/mpsi.c | 4 +- mps/code/mpsicv.c | 4 +- mps/code/mpsliban.c | 6 +- mps/code/mv.nmk | 74 +++++++++++++ mps/code/mv2test.c | 26 ++--- mps/code/pc.nmk | 59 +++++++++++ mps/code/poolmv2.c | 34 +++--- mps/code/protw3.c | 4 +- mps/code/qs.c | 7 +- mps/code/sacss.c | 6 +- mps/code/segsmss.c | 10 +- mps/code/splay.c | 6 +- mps/code/{spw3i3mv.c => spw3i3.c} | 9 +- mps/code/{spw3i6mv.c => spw3i6.c} | 2 +- mps/code/steptest.c | 5 +- mps/code/teletest.c | 5 +- mps/code/testlib.c | 14 +-- mps/code/testlib.h | 28 +++++ mps/code/w3i3mv.nmk | 9 +- mps/code/w3i3pc.gmk | 5 - mps/code/w3i3pc.nmk | 171 ++++++++++++++++++++++++++++++ mps/code/w3i6mv.nmk | 8 +- mps/code/walk.c | 3 +- mps/code/zcoll.c | 19 ++-- mps/code/zmess.c | 2 +- mps/tool/testrun.bat | 4 +- 56 files changed, 536 insertions(+), 228 deletions(-) create mode 100644 mps/code/mv.nmk create mode 100644 mps/code/pc.nmk rename mps/code/{spw3i3mv.c => spw3i3.c} (94%) rename mps/code/{spw3i6mv.c => spw3i6.c} (98%) delete mode 100644 mps/code/w3i3pc.gmk create mode 100644 mps/code/w3i3pc.nmk diff --git a/mps/code/abq.c b/mps/code/abq.c index 596921dd09a..b915bb42c9b 100644 --- a/mps/code/abq.c +++ b/mps/code/abq.c @@ -107,7 +107,7 @@ Bool ABQPush(ABQ abq, void *element) if (ABQIsFull(abq)) return FALSE; - mps_lib_memcpy(ABQElement(abq, abq->in), element, abq->elementSize); + (void)mps_lib_memcpy(ABQElement(abq, abq->in), element, abq->elementSize); abq->in = ABQNextIndex(abq, abq->in); AVERT(ABQ, abq); @@ -126,7 +126,7 @@ Bool ABQPop(ABQ abq, void *elementReturn) if (ABQIsEmpty(abq)) return FALSE; - mps_lib_memcpy(elementReturn, ABQElement(abq, abq->out), abq->elementSize); + (void)mps_lib_memcpy(elementReturn, ABQElement(abq, abq->out), abq->elementSize); abq->out = ABQNextIndex(abq, abq->out); @@ -146,7 +146,7 @@ Bool ABQPeek(ABQ abq, void *elementReturn) if (ABQIsEmpty(abq)) return FALSE; - mps_lib_memcpy(elementReturn, ABQElement(abq, abq->out), abq->elementSize); + (void)mps_lib_memcpy(elementReturn, ABQElement(abq, abq->out), abq->elementSize); /* Identical to pop, but don't increment out */ @@ -261,7 +261,7 @@ void ABQIterate(ABQ abq, ABQIterateMethod iterate, void *closureP, Size closureS AVERT(Bool, delete); if (!delete) { if (copy != index) - mps_lib_memcpy(ABQElement(abq, copy), element, abq->elementSize); + (void)mps_lib_memcpy(ABQElement(abq, copy), element, abq->elementSize); copy = ABQNextIndex(abq, copy); } index = ABQNextIndex(abq, index); @@ -272,8 +272,8 @@ void ABQIterate(ABQ abq, ABQIterateMethod iterate, void *closureP, Size closureS /* If any elements were deleted, need to copy remainder of queue. */ if (copy != index) { while (index != in) { - mps_lib_memcpy(ABQElement(abq, copy), ABQElement(abq, index), - abq->elementSize); + (void)mps_lib_memcpy(ABQElement(abq, copy), ABQElement(abq, index), + abq->elementSize); copy = ABQNextIndex(abq, copy); index = ABQNextIndex(abq, index); } diff --git a/mps/code/abqtest.c b/mps/code/abqtest.c index 350f0e89f86..4cff09f1745 100644 --- a/mps/code/abqtest.c +++ b/mps/code/abqtest.c @@ -130,7 +130,7 @@ static void step(void) DestroyTestBlock(a); break; default: - if (!deleted & (pushee > popee)) { + if (!deleted && (pushee > popee)) { TestBlock b; TestClosureStruct cl; deleted = (unsigned)abqRnd (pushee - popee) + popee; diff --git a/mps/code/amcss.c b/mps/code/amcss.c index bf0c6611174..1b32c849769 100644 --- a/mps/code/amcss.c +++ b/mps/code/amcss.c @@ -285,7 +285,7 @@ static void test(mps_arena_t arena) if (objs % 1024 == 0) { report(arena); putchar('.'); - fflush(stdout); + (void)fflush(stdout); } ++objs; diff --git a/mps/code/amcsshe.c b/mps/code/amcsshe.c index 5ad7c064f5d..248929240d0 100644 --- a/mps/code/amcsshe.c +++ b/mps/code/amcsshe.c @@ -236,7 +236,7 @@ static void *test(void *arg, size_t s) if (objs % 1024 == 0) { report(arena); putchar('.'); - fflush(stdout); + (void)fflush(stdout); } ++objs; diff --git a/mps/code/amsss.c b/mps/code/amsss.c index a0a1fe666e6..c678f26ff45 100644 --- a/mps/code/amsss.c +++ b/mps/code/amsss.c @@ -152,7 +152,7 @@ static void *test(void *arg, size_t haveAmbigous) lastStep = totalSize; printf("\nSize %"PRIuLONGEST" bytes, %lu objects.\n", (ulongest_t)totalSize, objs); - fflush(stdout); + (void)fflush(stdout); for(i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]), "all roots check"); @@ -184,7 +184,7 @@ static void *test(void *arg, size_t haveAmbigous) if (objs % 256 == 0) { printf("."); report(); - fflush(stdout); + (void)fflush(stdout); } } diff --git a/mps/code/amssshe.c b/mps/code/amssshe.c index 4787ef80e6f..37408340a00 100644 --- a/mps/code/amssshe.c +++ b/mps/code/amssshe.c @@ -111,7 +111,7 @@ static void *test(void *arg, size_t s) lastStep = totalSize; printf("\nSize %"PRIuLONGEST" bytes, %lu objects.\n", (ulongest_t)totalSize, objs); - fflush(stdout); + (void)fflush(stdout); for(i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]), "all roots check"); @@ -139,7 +139,7 @@ static void *test(void *arg, size_t s) ++objs; if (objs % 256 == 0) { printf("."); - fflush(stdout); + (void)fflush(stdout); } } diff --git a/mps/code/apss.c b/mps/code/apss.c index aaa5da0957b..8016f9b1aa5 100644 --- a/mps/code/apss.c +++ b/mps/code/apss.c @@ -111,11 +111,6 @@ allocFail: } -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1)) - - /* randomSizeAligned -- produce sizes both large and small, * aligned by platform alignment */ diff --git a/mps/code/arena.c b/mps/code/arena.c index 21ceea8c1e3..d5833c65441 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -155,7 +155,7 @@ Bool ArenaCheck(Arena arena) CHECKL(BoolCheck(arena->hasFreeCBS)); if (arena->hasFreeCBS) - CBSCheck(ArenaFreeCBS(arena)); + CHECKL(CBSCheck(ArenaFreeCBS(arena))); return TRUE; } diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 68753cd6e87..d37fb96c485 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -530,7 +530,7 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args) /* Copy the stack-allocated VM parameters into their home in the VMArena. */ AVER(sizeof(vmArena->vmParams) == sizeof(vmParams)); - mps_lib_memcpy(vmArena->vmParams, vmParams, sizeof(vmArena->vmParams)); + (void)mps_lib_memcpy(vmArena->vmParams, vmParams, sizeof(vmArena->vmParams)); /* */ vmArena->extendBy = userSize; diff --git a/mps/code/awlut.c b/mps/code/awlut.c index 8af4bcd4bbc..a8d96d930e0 100644 --- a/mps/code/awlut.c +++ b/mps/code/awlut.c @@ -216,7 +216,7 @@ static void test(mps_arena_t arena, } } - mps_arena_collect(arena); + die(mps_arena_collect(arena), "mps_arena_collect"); mps_arena_release(arena); for(i = 0; i < TABLE_SLOTS; ++i) { diff --git a/mps/code/awluthe.c b/mps/code/awluthe.c index 9fb1281dcc1..be07c7b48f6 100644 --- a/mps/code/awluthe.c +++ b/mps/code/awluthe.c @@ -221,7 +221,7 @@ static void test(mps_arena_t arena, } } - mps_arena_collect(arena); + die(mps_arena_collect(arena), "mps_arena_collect"); mps_arena_release(arena); for(i = 0; i < TABLE_SLOTS; ++i) { @@ -274,8 +274,8 @@ static void *setup(void *v, size_t s) die(mps_root_create_reg(&stack, arena, mps_rank_ambig(), 0, thr, mps_stack_scan_ambig, v, 0), "Root Create\n"); - EnsureHeaderFormat(&dylanfmt, arena); - EnsureHeaderWeakFormat(&dylanweakfmt, arena); + die(EnsureHeaderFormat(&dylanfmt, arena), "EnsureHeaderFormat"); + die(EnsureHeaderWeakFormat(&dylanweakfmt, arena), "EnsureHeaderWeakFormat"); MPS_ARGS_BEGIN(args) { /* Ask the leafpool to allocate in the nursery, as we're using it to test weaknesss and want things to die in it promptly. */ diff --git a/mps/code/bttest.c b/mps/code/bttest.c index 12a6bd8503f..d84ed688496 100644 --- a/mps/code/bttest.c +++ b/mps/code/bttest.c @@ -125,7 +125,7 @@ static void get(void) { if (argInRange(0)) { Bool b = (BTGet)(bt, args[0]); - printf(b ? "TRUE\n" : "FALSE\n"); + puts(b ? "TRUE" : "FALSE"); } } @@ -148,7 +148,7 @@ static void isSetRange(void) { if (checkDefaultRange(0)) { Bool b = BTIsSetRange(bt, args[0], args[1]); - printf(b ? "TRUE\n" : "FALSE\n"); + puts(b ? "TRUE" : "FALSE"); } } @@ -157,7 +157,7 @@ static void isResRange(void) { if (checkDefaultRange(0)) { Bool b = BTIsResRange(bt, args[0], args[1]); - printf(b ? "TRUE\n" : "FALSE\n"); + puts(b ? "TRUE" : "FALSE"); } } @@ -325,7 +325,7 @@ static void showBT(void) { i = 0; while((i < btSize) && (i < 50)) { if (i % 10 == 0) - c = (char)((i / 10) % 10) + '0'; + c = (char)(((i / 10) % 10) + '0'); else c = ' '; putchar(c); @@ -334,7 +334,7 @@ static void showBT(void) { putchar('\n'); i = 0; while((i < btSize) && (i < 50)) { - c = (char)(i % 10) +'0'; + c = (char)((i % 10) +'0'); putchar(c); ++ i; } @@ -374,7 +374,7 @@ extern int main(int argc, char *argv[]) while(1) { char input[100]; printf("bt test> "); - fflush(stdout); + (void)fflush(stdout); if (fgets(input, 100, stdin)) { obeyCommand(input); showBT(); diff --git a/mps/code/commpost.nmk b/mps/code/commpost.nmk index 021e37b89e4..f8ed8380799 100644 --- a/mps/code/commpost.nmk +++ b/mps/code/commpost.nmk @@ -96,8 +96,8 @@ $(PFM)\cool\mps.lib: \ $(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \ $(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ) $(ECHO) $@ - cl /c $(CFLAGS) /Fd$(PFM)\$(VARIETY)\ /Fo$(PFM)\$(VARIETY)\version.o version.c - $(LIBMAN) $(LIBFLAGS) /OUT:$@ $** $(PFM)\$(VARIETY)\version.o + $(CC) /c $(CFLAGS) /Fo$(PFM)\$(VARIETY)\version.obj version.c + $(LIBMAN) $(LIBFLAGS) /OUT:$@ $** $(PFM)\$(VARIETY)\version.obj # OTHER GENUINE TARGETS @@ -267,13 +267,13 @@ $(PFM)\$(VARIETY)\mpseventsql.obj: $(PFM)\$(VARIETY)\eventsql.obj $(ECHO) $@ @if not exist $(PFM) mkdir $(PFM) @if not exist $(PFM)\$(VARIETY) mkdir $(PFM)\$(VARIETY) - cl /c $(CFLAGS) /Fd$(PFM)\$(VARIETY)\ /Fo$@ $< + $(CC) /c $(CFLAGS) /Fo$@ $< $(PFM)\$(VARIETY)\sqlite3.obj: $(ECHO) $@ @if not exist $(PFM) mkdir $(PFM) @if not exist $(PFM)\$(VARIETY) mkdir $(PFM)\$(VARIETY) - cl /c $(CFLAGSSQL) /Fd$(PFM)\$(VARIETY)\ /Fo$@ sqlite3.c + $(CC) /c $(CFLAGSSQL) /Fo$@ sqlite3.c {}.asm{$(PFM)\$(VARIETY)}.obj: $(ECHO) $@ @@ -295,7 +295,7 @@ $(PFM)\$(VARIETY)\sqlite3.obj: {$(PFM)\$(VARIETY)}.obj{$(PFM)\$(VARIETY)}.exe: $(ECHO) $@ - $(LINKER) $(LINKFLAGS) /PDB:$*.pdb /OUT:$@ $(**) + $(LINKER) $(LINKFLAGS) /OUT:$@ $(**) # C. COPYRIGHT AND LICENSE diff --git a/mps/code/commpre.nmk b/mps/code/commpre.nmk index ec1685a8630..9edc9ef0937 100644 --- a/mps/code/commpre.nmk +++ b/mps/code/commpre.nmk @@ -219,20 +219,15 @@ ECHO = echo # C FLAGS -# /MD means compile for multi-threaded environment with separate C library DLL. -# /MT means compile for multi-threaded environment. -# /ML means compile for single-threaded environment. -# A 'd' at the end means compile for debugging. - CFLAGSTARGETPRE = CFLAGSTARGETPOST = -CRTFLAGSHOT = /MT -CRTFLAGSCOOL = /MTd -LINKFLAGSHOT = libcmt.lib -LINKFLAGSCOOL = libcmtd.lib +CRTFLAGSHOT = +CRTFLAGSCOOL = +LINKFLAGSHOT = +LINKFLAGSCOOL = CFLAGSSQLPRE = /nologo $(PFMDEFS) -CFLAGSCOMMONPRE = /nologo /W4 /WX $(PFMDEFS) $(CFLAGSTARGETPRE) +CFLAGSCOMMONPRE = /nologo $(PFMDEFS) $(CFLAGSTARGETPRE) CFLAGSSQLPOST = CFLAGSCOMMONPOST = $(CFLAGSTARGETPOST) @@ -247,7 +242,7 @@ CFLAGSHOT = /O2 /DNDEBUG # building a DLL, mpsdy.dll, the linker step will fail (error LNK2001: # unresolved external symbol __chkesp). See # http://support.microsoft.com/kb/q191669/ -CFLAGSCOOL = /Od +CFLAGSCOOL = CFLAGSINTERNAL = /Zi CFLAGSEXTERNAL = @@ -280,7 +275,7 @@ LFCOOL = $(LINKFLAGSCOOL) $(LINKFLAGSINTERNAL) # %%VARIETY: When adding a new variety, define a macro containing the flags # for the new variety LIBMAN = lib # can't call this LIB - it screws the environment -LIBFLAGSCOMMON = /nologo +LIBFLAGSCOMMON = LIBFLAGSRASH = LIBFLAGSHOT = diff --git a/mps/code/config.h b/mps/code/config.h index 4778b4b7552..0a1dc4a6a2e 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -172,7 +172,7 @@ /* "constant conditional" (MPS_END) */ #pragma warning(disable: 4127) -/* "unreachable code" (ASSERT, if cond is constantly true). */ +/* "unreachable code" (AVER, if cond is constantly true). */ #pragma warning(disable: 4702) /* "expression evaluates to a function which is missing an argument list" */ @@ -211,6 +211,17 @@ #endif /* MPS_BUILD_MV */ +/* Suppress Pelles C warnings at warning level 2 */ +/* Essentially the same settings are done in testlib.h. */ + +#ifdef MPS_BUILD_PC + +/* "Unreachable code" (AVER, if condition is constantly true). */ +#pragma warn(disable: 2154) + +#endif /* MPS_BUILD_PC */ + + /* EPVMDefaultSubsequentSegSIZE is a default for the alignment of * subsequent segments (non-initial at each save level) in EPVM. See * design.mps.poolepvm.arch.segment.size. diff --git a/mps/code/event.c b/mps/code/event.c index 374b55868f2..a650b63b958 100644 --- a/mps/code/event.c +++ b/mps/code/event.c @@ -419,7 +419,7 @@ void EventDump(mps_lib_FILE *stream) /* This can happen if there's a backtrace very early in the life of the MPS, and will cause an access violation if we continue. */ if (!eventInited) { - WriteF(stream, "No events\n", NULL); + (void)WriteF(stream, "No events\n", NULL); return; } diff --git a/mps/code/event.h b/mps/code/event.h index 3e1463527ba..11884d30d6c 100644 --- a/mps/code/event.h +++ b/mps/code/event.h @@ -87,7 +87,7 @@ extern Word EventKindControl; size = offsetof(Event##name##Struct, f1) + _string_len + sizeof('\0'); \ EVENT_BEGIN(name, size) \ _event->f0 = (p0); \ - mps_lib_memcpy(_event->f1, (string), _string_len); \ + (void)mps_lib_memcpy(_event->f1, (string), _string_len); \ _event->f1[_string_len] = '\0'; \ EVENT_END(name, size); \ END diff --git a/mps/code/eventcnv.c b/mps/code/eventcnv.c index 7cca6846a49..33375c45f4d 100644 --- a/mps/code/eventcnv.c +++ b/mps/code/eventcnv.c @@ -64,12 +64,12 @@ static const char *prog; /* program name */ static void fevwarn(const char *prefix, const char *format, va_list args) { - fflush(stdout); /* sync */ - fprintf(stderr, "%s: %s @", prog, prefix); - EVENT_CLOCK_PRINT(stderr, eventTime); - fprintf(stderr, " "); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); + (void)fflush(stdout); /* sync */ + (void)fprintf(stderr, "%s: %s @", prog, prefix); + (void)EVENT_CLOCK_PRINT(stderr, eventTime); + (void)fprintf(stderr, " "); + (void)vfprintf(stderr, format, args); + (void)fprintf(stderr, "\n"); } /* evwarn -- flush stdout, warn to stderr */ @@ -100,10 +100,9 @@ static void everror(const char *format, ...) static void usage(void) { - fprintf(stderr, - "Usage: %s [-f logfile] [-h]\n" - "See \"Telemetry\" in the reference manual for instructions.\n", - prog); + (void)fprintf(stderr, "Usage: %s [-f logfile] [-h]\n" + "See \"Telemetry\" in the reference manual for instructions.\n", + prog); } @@ -270,7 +269,7 @@ static void readLog(FILE *stream) break; } - EVENT_CLOCK_PRINT(stdout, eventTime); + (void)EVENT_CLOCK_PRINT(stdout, eventTime); printf(" %4X", (unsigned)code); switch (code) { @@ -286,7 +285,7 @@ static void readLog(FILE *stream) } putchar('\n'); - fflush(stdout); + (void)fflush(stdout); } /* while(!feof(input)) */ } diff --git a/mps/code/eventtxt.c b/mps/code/eventtxt.c index 3971d0e84da..4782e576a94 100644 --- a/mps/code/eventtxt.c +++ b/mps/code/eventtxt.c @@ -54,26 +54,24 @@ static void everror(const char *format, ...) { va_list args; - fflush(stdout); /* sync */ - fprintf(stderr, "%s: ", prog); + (void)fflush(stdout); /* sync */ + (void)fprintf(stderr, "%s: ", prog); va_start(args, format); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); + (void)vfprintf(stderr, format, args); + (void)fprintf(stderr, "\n"); va_end(args); exit(EXIT_FAILURE); } static void usage(void) { - fprintf(stderr, - "Usage: %s [-l ]\n", - prog); + (void)fprintf(stderr, "Usage: %s [-l ]\n", prog); } static void usageError(void) { - usage(); - everror("Bad usage"); + usage(); + everror("Bad usage"); } /* parseArgs -- parse command line arguments */ @@ -289,7 +287,7 @@ static void recordLabel(char *p) address = parseHex(&p); if (address > (Word)-1) { - printf("label address too large!"); + (void)printf("label address too large!"); return; } @@ -440,24 +438,27 @@ static void readLog(FILE *input) if ((major != EVENT_VERSION_MAJOR) || (median != EVENT_VERSION_MEDIAN) || (minor != EVENT_VERSION_MINOR)) { - fprintf(stderr, "Event log version does not match: %d.%d.%d vs %d.%d.%d\n", - (int)major, (int)median, (int)minor, - EVENT_VERSION_MAJOR, - EVENT_VERSION_MEDIAN, - EVENT_VERSION_MINOR); + (void)fprintf(stderr, "Event log version does not match: " + "%d.%d.%d vs %d.%d.%d\n", + (int)major, (int)median, (int)minor, + EVENT_VERSION_MAJOR, + EVENT_VERSION_MEDIAN, + EVENT_VERSION_MINOR); } if (maxCode > EventCodeMAX) { - fprintf(stderr, "Event log may contain unknown events with codes from %d to %d\n", - EventCodeMAX+1, (int)maxCode); + (void)fprintf(stderr, "Event log may contain unknown events " + "with codes from %d to %d\n", + EventCodeMAX+1, (int)maxCode); } if (wordWidth > MPS_WORD_WIDTH) { int newHexWordWidth = (int)((wordWidth + 3) / 4); if (newHexWordWidth > hexWordWidth) { - fprintf(stderr, - "Event log word width is greater than on current platform;" - "previous values may be printed too narrowly.\n"); + (void)fprintf(stderr, + "Event log word width is greater than on current " + "platform; previous values may be printed too " + "narrowly.\n"); } hexWordWidth = newHexWordWidth; } diff --git a/mps/code/exposet0.c b/mps/code/exposet0.c index 739ccac1e6a..a3eb7266e1a 100644 --- a/mps/code/exposet0.c +++ b/mps/code/exposet0.c @@ -231,7 +231,7 @@ static void *test(void *arg, size_t s) if (objs % 1024 == 0) { report(arena); putchar('.'); - fflush(stdout); + (void)fflush(stdout); } ++objs; diff --git a/mps/code/expt825.c b/mps/code/expt825.c index e18905061cf..8c8d1e79a3d 100644 --- a/mps/code/expt825.c +++ b/mps/code/expt825.c @@ -86,7 +86,7 @@ static void register_numbered_tree(mps_word_t tree, mps_arena_t arena) { /* don't finalize ints */ if ((tree & 1) == 0) { - mps_finalize(arena, (mps_addr_t *)&tree); + die(mps_finalize(arena, (mps_addr_t *)&tree), "mps_finalize"); register_numbered_tree(DYLAN_VECTOR_SLOT(tree, 0), arena); register_numbered_tree(DYLAN_VECTOR_SLOT(tree, 1), arena); } @@ -125,7 +125,7 @@ static void register_indirect_tree(mps_word_t tree, mps_arena_t arena) /* don't finalize ints */ if ((tree & 1) == 0) { mps_word_t indirect = DYLAN_VECTOR_SLOT(tree,2); - mps_finalize(arena, (mps_addr_t *)&indirect); + die(mps_finalize(arena, (mps_addr_t *)&indirect), "mps_finalize"); register_indirect_tree(DYLAN_VECTOR_SLOT(tree, 0), arena); register_indirect_tree(DYLAN_VECTOR_SLOT(tree, 1), arena); } @@ -186,7 +186,7 @@ static void *test(void *arg, size_t s) (mps_collections(arena) < collectionCOUNT)) { mps_word_t final_this_time = 0; printf("Collecting..."); - fflush(stdout); + (void)fflush(stdout); die(mps_arena_collect(arena), "collect"); printf(" Done.\n"); while (mps_message_poll(arena)) { @@ -227,7 +227,7 @@ static void *test(void *arg, size_t s) (mps_collections(arena) < collectionCOUNT)) { mps_word_t final_this_time = 0; printf("Collecting..."); - fflush(stdout); + (void)fflush(stdout); die(mps_arena_collect(arena), "collect"); printf(" Done.\n"); while (mps_message_poll(arena)) { diff --git a/mps/code/fbmtest.c b/mps/code/fbmtest.c index 905e90d0a93..e26c9f26224 100644 --- a/mps/code/fbmtest.c +++ b/mps/code/fbmtest.c @@ -83,13 +83,13 @@ static Index (indexOfAddr)(FBMState state, Addr a) static void describe(FBMState state) { switch (state->type) { case FBMTypeCBS: - CBSDescribe(state->the.cbs, mps_lib_get_stdout()); + die(CBSDescribe(state->the.cbs, mps_lib_get_stdout()), "CBSDescribe"); break; case FBMTypeFreelist: - FreelistDescribe(state->the.fl, mps_lib_get_stdout()); + die(FreelistDescribe(state->the.fl, mps_lib_get_stdout()), "FreelistDescribe"); break; default: - fail(); + cdie(0, "invalid state->type"); break; } } @@ -157,7 +157,7 @@ static void check(FBMState state) FreelistIterate(state->the.fl, checkFLCallback, (void *)&closure, 0); break; default: - fail(); + cdie(0, "invalid state->type"); return; } @@ -311,7 +311,7 @@ static void allocate(FBMState state, Addr base, Addr limit) res = FreelistDelete(&oldRange, state->the.fl, &range); break; default: - fail(); + cdie(0, "invalid state->type"); return; } @@ -387,7 +387,7 @@ static void deallocate(FBMState state, Addr base, Addr limit) res = FreelistInsert(&freeRange, state->the.fl, &range); break; default: - fail(); + cdie(0, "invalid state->type"); return; } @@ -467,7 +467,7 @@ static void find(FBMState state, Size size, Bool high, FindDelete findDelete) (&foundRange, &oldRange, state->the.fl, size * state->align, findDelete); break; default: - fail(); + cdie(0, "invalid state->type"); return; } @@ -538,7 +538,7 @@ static void test(FBMState state, unsigned n) { find(state, size, high, findDelete); break; default: - fail(); + cdie(0, "invalid state->type"); return; } if ((i + 1) % 1000 == 0) diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index 205cfefd5ad..a6c23aebfd1 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -77,7 +77,7 @@ static void register_numbered_tree(mps_word_t tree, mps_arena_t arena) /* don't finalize ints */ if ((tree & 1) == 0) { mps_addr_t tree_ref = (mps_addr_t)tree; - mps_finalize(arena, &tree_ref); + die(mps_finalize(arena, &tree_ref), "mps_finalize"); register_numbered_tree(DYLAN_VECTOR_SLOT(tree, 0), arena); register_numbered_tree(DYLAN_VECTOR_SLOT(tree, 1), arena); } @@ -117,7 +117,7 @@ static void register_indirect_tree(mps_word_t tree, mps_arena_t arena) if ((tree & 1) == 0) { mps_word_t indirect = DYLAN_VECTOR_SLOT(tree,2); mps_addr_t indirect_ref = (mps_addr_t)indirect; - mps_finalize(arena, &indirect_ref); + die(mps_finalize(arena, &indirect_ref), "mps_finalize"); register_indirect_tree(DYLAN_VECTOR_SLOT(tree, 0), arena); register_indirect_tree(DYLAN_VECTOR_SLOT(tree, 1), arena); } @@ -175,7 +175,7 @@ static void *test(void *arg, size_t s) (mps_collections(arena) < collectionCOUNT)) { mps_word_t final_this_time = 0; printf("Collecting..."); - fflush(stdout); + (void)fflush(stdout); die(mps_arena_collect(arena), "collect"); printf(" Done.\n"); while (mps_message_poll(arena)) { @@ -213,7 +213,7 @@ static void *test(void *arg, size_t s) (mps_collections(arena) < collectionCOUNT)) { mps_word_t final_this_time = 0; printf("Collecting..."); - fflush(stdout); + (void)fflush(stdout); die(mps_arena_collect(arena), "collect"); printf(" Done.\n"); while (mps_message_poll(arena)) { diff --git a/mps/code/fmtdy.c b/mps/code/fmtdy.c index f622bfe128c..498f8811635 100644 --- a/mps/code/fmtdy.c +++ b/mps/code/fmtdy.c @@ -470,8 +470,8 @@ extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) break; case 1: /* stretchy non-traceable */ - notreached(); /* Not used by DylanWorks yet */ p += vt + 1; + notreached(); /* Not used by DylanWorks yet */ break; case 2: /* non-stretchy traceable */ @@ -482,7 +482,6 @@ extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) break; case 3: /* stretchy traceable */ - notreached(); /* DW doesn't create them yet */ vl = *(mps_word_t *)p; /* vector length */ assert((vl & 3) == 1); /* check Dylan integer tag */ vl >>= 2; /* untag it */ @@ -490,6 +489,7 @@ extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) res = dylan_scan_contig(mps_ss, p, p + vl); if(res) return res; p += vt; /* skip to end of whole vector */ + notreached(); /* DW doesn't create them yet */ break; case 4: /* non-word */ @@ -500,11 +500,11 @@ extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) break; case 5: /* stretchy non-word */ - notreached(); /* DW doesn't create them yet */ es = (vh & 0xff) >> 3; vb = (vh >> 16) & 0xff; vt += vb; p += NONWORD_LENGTH(vt, es) + 1; + notreached(); /* DW doesn't create them yet */ break; default: diff --git a/mps/code/fotest.c b/mps/code/fotest.c index ada5f6dec67..4025d20a2c6 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -149,11 +149,6 @@ allocFail: } -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1)) - - /* randomSizeAligned -- produce sizes both large and small, * aligned by platform alignment */ diff --git a/mps/code/locbwcss.c b/mps/code/locbwcss.c index 5807d9c1f7b..3bc674c7d68 100644 --- a/mps/code/locbwcss.c +++ b/mps/code/locbwcss.c @@ -131,8 +131,7 @@ static void allocMultiple(PoolStat stat) static void reportResults(PoolStat stat, const char *name) { - printf("\nResults for "); - fputs(name, stdout); + printf("\nResults for %s\n", name); printf("\n"); printf(" Allocated %"PRIuLONGEST" objects\n", (ulongest_t)stat->aCount); printf(" Freed %"PRIuLONGEST" objects\n", (ulongest_t)stat->fCount); diff --git a/mps/code/lockutw3.c b/mps/code/lockutw3.c index da5070ecab7..6ba288521c5 100644 --- a/mps/code/lockutw3.c +++ b/mps/code/lockutw3.c @@ -84,8 +84,10 @@ int main(int argc, char *argv[]) for(i = 0; i < nTHREADS; i++) t[i] = CreateThread(NULL, 0, thread0, NULL, 0, &id); - for(i = 0; i < nTHREADS; i++) - WaitForSingleObject(t[i], INFINITE); + for(i = 0; i < nTHREADS; i++) { + cdie(WaitForSingleObject(t[i], INFINITE) == WAIT_OBJECT_0, + "WaitForSingleObject"); + } Insist(shared == nTHREADS*COUNT); diff --git a/mps/code/locus.c b/mps/code/locus.c index 11220210f52..f0ba7415cde 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -43,7 +43,7 @@ SegPref SegPrefDefault(void) void SegPrefInit(SegPref pref) { - mps_lib_memcpy(pref, &segPrefDefault, sizeof(SegPrefStruct)); + (void)mps_lib_memcpy(pref, &segPrefDefault, sizeof(SegPrefStruct)); } diff --git a/mps/code/mpmss.c b/mps/code/mpmss.c index 76fbf12c3fe..b2a48347382 100644 --- a/mps/code/mpmss.c +++ b/mps/code/mpmss.c @@ -92,11 +92,6 @@ static mps_res_t stress(mps_class_t class, size_t (*size)(int i), } -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1)) - - /* randomSize -- produce sizes both latge and small */ static size_t randomSize(int i) @@ -153,7 +148,7 @@ static mps_pool_debug_option_s fenceOptions = { /* testInArena -- test all the pool classes in the given arena */ -static int testInArena(mps_arena_t arena, mps_pool_debug_option_s *options) +static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options) { /* IWBN to test MVFFDebug, but the MPS doesn't support debugging */ /* cross-segment allocation (possibly MVFF ought not to). */ @@ -176,8 +171,6 @@ static int testInArena(mps_arena_t arena, mps_pool_debug_option_s *options) die(stress(mps_class_mv(), randomSize, arena, (size_t)65536, (size_t)32, (size_t)65536), "stress MV"); - - return 0; } diff --git a/mps/code/mps.c b/mps/code/mps.c index bcd6120de82..ce910bad927 100644 --- a/mps/code/mps.c +++ b/mps/code/mps.c @@ -194,8 +194,8 @@ #include "protw3.c" /* Windows protection */ #include "proti3.c" /* 32-bit Intel mutator context decoding */ #include "prmci3w3.c" /* Windows on 32-bit Intel mutator context */ -#include "ssw3i3mv.c" /* Windows on 32-bit stack scan for Microsoft C */ -#include "spw3i3mv.c" /* Windows on 32-bit stack probe for Microsoft C */ +#include "ssw3i3mv.c" /* Windows on 32-bit Intel stack scan for Microsoft C */ +#include "spw3i3.c" /* Windows on 32-bit Intel stack probe */ #include "mpsiw3.c" /* Windows interface layer extras */ /* Windows on 64-bit Intel with Microsoft Visual Studio */ @@ -210,8 +210,8 @@ #include "protw3.c" /* Windows protection */ #include "proti6.c" /* 64-bit Intel mutator context decoding */ #include "prmci6w3.c" /* Windows on 64-bit Intel mutator context */ -#include "ssw3i6mv.c" /* Windows on 64-bit stack scan for Microsoft C */ -#include "spw3i6mv.c" /* Windows on 64-bit stack probe for Microsoft C */ +#include "ssw3i6mv.c" /* Windows on 64-bit Intel stack scan for Microsoft C */ +#include "spw3i6.c" /* Windows on 64-bit Intel stack probe */ #include "mpsiw3.c" /* Windows interface layer extras */ /* Windows on 32-bit Intel with Pelles C */ @@ -226,7 +226,7 @@ #include "proti3.c" /* 32-bit Intel mutator context decoding */ #include "prmci3w3.c" /* Windows on 32-bit Intel mutator context */ #include "ssw3i3pc.c" /* Windows on 32-bit stack scan for Pelles C */ -#include "spw3i3mv.c" /* Intel stack probe */ +#include "spw3i3.c" /* 32-bit Intel stack probe */ #include "mpsiw3.c" /* Windows interface layer extras */ #else diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c index 1d52208be9a..38b8e62f56c 100644 --- a/mps/code/mpsi.c +++ b/mps/code/mpsi.c @@ -1737,12 +1737,12 @@ mps_word_t mps_telemetry_control(mps_word_t resetMask, mps_word_t flipMask) void mps_telemetry_set(mps_word_t setMask) { - EventControl((Word)setMask, (Word)setMask); + (void)EventControl((Word)setMask, (Word)setMask); } void mps_telemetry_reset(mps_word_t resetMask) { - EventControl((Word)resetMask, 0); + (void)EventControl((Word)resetMask, 0); } mps_word_t mps_telemetry_get(void) diff --git a/mps/code/mpsicv.c b/mps/code/mpsicv.c index 3f8d05b92e0..cba8a69f300 100644 --- a/mps/code/mpsicv.c +++ b/mps/code/mpsicv.c @@ -94,8 +94,6 @@ struct tlonglong { /* alignmentTest -- test default alignment is acceptable */ -#define max(a, b) (((a) > (b)) ? (a) : (b)) - static void alignmentTest(mps_arena_t arena) { mps_pool_t pool; @@ -404,7 +402,7 @@ static void *test(void *arg, size_t s) if (rnd() & 1) { printf("Using auto_header format.\n"); - EnsureHeaderFormat(&format, arena); + die(EnsureHeaderFormat(&format, arena), "EnsureHeaderFormat"); ap_headerSIZE = headerSIZE; /* from fmthe.h */ } else { printf("Using normal format (no implicit object header: client pointers point at start of storage).\n"); diff --git a/mps/code/mpsliban.c b/mps/code/mpsliban.c index e84b2aed00d..75a3d48d518 100644 --- a/mps/code/mpsliban.c +++ b/mps/code/mpsliban.c @@ -65,9 +65,9 @@ static void mps_lib_assert_fail_default(const char *file, unsigned line, const char *condition) { - fflush(stdout); /* synchronize */ - fprintf(stderr, "%s:%u: MPS ASSERTION FAILED: %s\n", file, line, condition); - fflush(stderr); /* make sure the message is output */ + (void)fflush(stdout); /* synchronize */ + (void)fprintf(stderr, "%s:%u: MPS ASSERTION FAILED: %s\n", file, line, condition); + (void)fflush(stderr); /* make sure the message is output */ ASSERT_ABORT(); /* see config.h */ } diff --git a/mps/code/mv.nmk b/mps/code/mv.nmk new file mode 100644 index 00000000000..e860552e793 --- /dev/null +++ b/mps/code/mv.nmk @@ -0,0 +1,74 @@ +# -*- makefile -*- +# +# mv.nmk: NMAKE FRAGMENT FOR MICROSOFT VISUAL C/C++ +# +# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/gc.gmk#1 $ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. +# +# This file is included by platform nmake files that use the Microsoft +# Visual C/C+ compiler. It defines the compiler-specific variables +# that the common nmake file fragment () requires. + +CC = cl +LIBMAN = lib +LINKER = link + +# /Gs appears to be necessary to suppress stack checks. Stack checks +# (if not suppressed) generate a dependency on the C library, __chkesp, +# which causes the linker step to fail when building the DLL, mpsdy.dll. +CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /W4 /WX /Gs /Fd$(PFM)\$(VARIETY) +LIBFLAGSCOMMON = $(LIBFLAGSCOMMON) /nologo + +# /MD means compile for multi-threaded environment with separate C library DLL. +# /MT means compile for multi-threaded environment. +# /ML means compile for single-threaded environment. +# A 'd' at the end means compile for debugging. +CRTFLAGSHOT = $(CRTFLAGSHOT) /MT +CRTFLAGSCOOL = $(CRTFLAGSCOOL) /MTd + +CFLAGSCOOL = $(CFLAGSCOOL) /Od + +LINKFLAGSCOMMON = $(LINKFLAGSCOMMON) /PDB:$*.pdb +LINKFLAGSHOT = $(LINKFLAGSHOT) libcmt.lib +LINKFLAGSCOOL = $(LINKFLAGSCOOL) libcmtd.lib + + +# C. COPYRIGHT AND LICENSE +# +# Copyright (C) 2014 Ravenbrook Limited . +# All rights reserved. This is an open source license. Contact +# Ravenbrook for commercial licensing options. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Redistributions in any form must be accompanied by information on how +# to obtain complete source code for this software and any accompanying +# software that uses this software. The source code must either be +# included in the distribution or be available for no more than the cost +# of distribution plus a nominal fee, and must be freely redistributable +# under reasonable conditions. For an executable file, complete source +# code means the source code for all modules it contains. It does not +# include source code for modules or files that typically accompany the +# major components of the operating system on which the executable file +# runs. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +# PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mps/code/mv2test.c b/mps/code/mv2test.c index bc276abfc26..37435dfc7fd 100644 --- a/mps/code/mv2test.c +++ b/mps/code/mv2test.c @@ -38,11 +38,9 @@ static double expdev(void) } -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -static size_t min; -static size_t mean; -static size_t max; +static size_t size_min; +static size_t size_mean; +static size_t size_max; static int verbose = 0; static mps_pool_t pool; @@ -50,8 +48,8 @@ static size_t randomSize(unsigned long i) { /* Distribution centered on mean. Verify that allocations below min and above max are handled correctly */ - size_t s = (max - mean)/4; - size_t m = mean; + size_t s = (size_max - size_mean)/4; + size_t m = size_mean; double r; double x; @@ -73,8 +71,6 @@ static size_t randomSize(unsigned long i) #define TEST_SET_SIZE 1234 #define TEST_LOOPS 27 -#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1)) - static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size) { mps_res_t res; @@ -182,14 +178,14 @@ static void stress_with_arena_class(mps_arena_class_t aclass, Bool zoned) "mps_arena_create"); } MPS_ARGS_END(args); - min = MPS_PF_ALIGN; - mean = 42; - max = 8192; + size_min = MPS_PF_ALIGN; + size_mean = 42; + size_max = 8192; MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_MIN_SIZE, min); - MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, mean); - MPS_ARGS_ADD(args, MPS_KEY_MAX_SIZE, max); + MPS_ARGS_ADD(args, MPS_KEY_MIN_SIZE, size_min); + MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, size_mean); + MPS_ARGS_ADD(args, MPS_KEY_MAX_SIZE, size_max); MPS_ARGS_ADD(args, MPS_KEY_MVT_RESERVE_DEPTH, TEST_SET_SIZE/2); MPS_ARGS_ADD(args, MPS_KEY_MVT_FRAG_LIMIT, 0.3); die(stress(mps_class_mvt(), arena, randomSize, args), "stress MVT"); diff --git a/mps/code/pc.nmk b/mps/code/pc.nmk new file mode 100644 index 00000000000..80ce471c544 --- /dev/null +++ b/mps/code/pc.nmk @@ -0,0 +1,59 @@ +# -*- makefile -*- +# +# pc.nmk: NMAKE FRAGMENT FOR PELLES C +# +# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/gc.gmk#1 $ +# Copyright (c) 2014 Ravenbrook Limited. See end of file for license. +# +# This file is included by platform nmake files that use the Pelles C +# compiler. It defines the compiler-specific variables that the common +# nmake file fragment () requires. + +CC = pocc +LIBMAN = polib +LINKER = polink + +CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /Ze /W2 +CRTFLAGSHOT = /MT +CRTFLAGSCOOL = /MT + + +# C. COPYRIGHT AND LICENSE +# +# Copyright (C) 2014 Ravenbrook Limited . +# All rights reserved. This is an open source license. Contact +# Ravenbrook for commercial licensing options. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Redistributions in any form must be accompanied by information on how +# to obtain complete source code for this software and any accompanying +# software that uses this software. The source code must either be +# included in the distribution or be available for no more than the cost +# of distribution plus a nominal fee, and must be freely redistributable +# under reasonable conditions. For an executable file, complete source +# code means the source code for all modules it contains. It does not +# include source code for modules or files that typically accompany the +# major components of the operating system on which the executable file +# runs. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +# PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index 6910de5e065..d244fe23043 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -278,7 +278,9 @@ static Res MVTInit(Pool pool, ArgList args) if (res != ResOK) goto failABQ; - FreelistInit(MVTFreelist(mvt), align); + res = FreelistInit(MVTFreelist(mvt), align); + if (res != ResOK) + goto failABQ; pool->alignment = align; mvt->reuseSize = reuseSize; @@ -757,9 +759,11 @@ static Bool MVTDeleteOverlapping(Bool *deleteReturn, void *element, /* MVTReserve -- add a range to the available range queue, and if the - * queue is full, return segments to the arena. + * queue is full, return segments to the arena. Return TRUE if it + * succeeded in adding the range to the queue, FALSE if the queue + * overflowed. */ -static Res MVTReserve(MVT mvt, Range range) +static Bool MVTReserve(MVT mvt, Range range) { AVERT(MVT, mvt); AVERT(Range, range); @@ -774,18 +778,18 @@ static Res MVTReserve(MVT mvt, Range range) SURELY(ABQPeek(MVTABQ(mvt), &oldRange)); AVERT(Range, &oldRange); if (!MVTReturnSegs(mvt, &oldRange, arena)) - goto failOverflow; + goto overflow; METER_ACC(mvt->returns, RangeSize(&oldRange)); if (!ABQPush(MVTABQ(mvt), range)) - goto failOverflow; + goto overflow; } - return ResOK; + return TRUE; -failOverflow: +overflow: mvt->abqOverflow = TRUE; METER_ACC(mvt->overflows, RangeSize(range)); - return ResFAIL; + return FALSE; } @@ -820,7 +824,7 @@ static Res MVTInsert(MVT mvt, Addr base, Addr limit) * are coalesced on the ABQ. */ ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, 0); - MVTReserve(mvt, &newRange); + (void)MVTReserve(mvt, &newRange); } return ResOK; @@ -875,11 +879,11 @@ static Res MVTDelete(MVT mvt, Addr base, Addr limit) */ RangeInit(&rangeLeft, RangeBase(&rangeOld), base); if (RangeSize(&rangeLeft) >= mvt->reuseSize) - MVTReserve(mvt, &rangeLeft); + (void)MVTReserve(mvt, &rangeLeft); RangeInit(&rangeRight, limit, RangeLimit(&rangeOld)); if (RangeSize(&rangeRight) >= mvt->reuseSize) - MVTReserve(mvt, &rangeRight); + (void)MVTReserve(mvt, &rangeRight); return ResOK; } @@ -1269,8 +1273,6 @@ static Bool MVTReturnSegs(MVT mvt, Range range, Arena arena) */ static Bool MVTRefillCallback(MVT mvt, Range range) { - Res res; - AVERT(ABQ, MVTABQ(mvt)); AVERT(Range, range); @@ -1278,11 +1280,7 @@ static Bool MVTRefillCallback(MVT mvt, Range range) return TRUE; METER_ACC(mvt->refillPushes, ABQDepth(MVTABQ(mvt))); - res = MVTReserve(mvt, range); - if (res != ResOK) - return FALSE; - - return TRUE; + return MVTReserve(mvt, range); } static Bool MVTCBSRefillCallback(CBS cbs, Range range, diff --git a/mps/code/protw3.c b/mps/code/protw3.c index 37d886644f6..43e0522c074 100644 --- a/mps/code/protw3.c +++ b/mps/code/protw3.c @@ -109,11 +109,13 @@ LONG WINAPI ProtSEHfilter(LPEXCEPTION_POINTERS info) void ProtSetup(void) { + void *handler; /* See "AddVectoredExceptionHandler function (Windows)" */ /* ProtSetup is called only once per process, not once per arena, so this exception handler is only installed once. */ - AddVectoredExceptionHandler(1uL, ProtSEHfilter); + handler = AddVectoredExceptionHandler(1uL, ProtSEHfilter); + AVER(handler != NULL); } diff --git a/mps/code/qs.c b/mps/code/qs.c index 40e290dceec..2e573d0840b 100644 --- a/mps/code/qs.c +++ b/mps/code/qs.c @@ -318,15 +318,14 @@ static void validate(void) for(i = 0; i < listl; ++i) { cdie(((QSCell)reg[1])->tag == QSInt, "validate int"); if((mps_word_t)((QSCell)reg[1])->value != list[i]) { - fprintf(stdout, - "mps_res_t: Element %"PRIuLONGEST" of the two lists do not match.\n", - (ulongest_t)i); + (void)fprintf(stdout, "mps_res_t: Element %"PRIuLONGEST" of the " + "two lists do not match.\n", (ulongest_t)i); return; } reg[1] = (mps_addr_t)((QSCell)reg[1])->tail; } cdie(reg[1] == (mps_word_t)0, "validate end"); - fprintf(stdout, "Note: Lists compare equal.\n"); + (void)fprintf(stdout, "Note: Lists compare equal.\n"); } diff --git a/mps/code/sacss.c b/mps/code/sacss.c index a5fc3734029..d48b41708d8 100644 --- a/mps/code/sacss.c +++ b/mps/code/sacss.c @@ -125,9 +125,6 @@ static mps_res_t stress(mps_class_t class, } -#define max(a, b) (((a) > (b)) ? (a) : (b)) - - /* randomSize8 -- produce sizes both latge and small */ static size_t randomSize8(int i) @@ -163,7 +160,7 @@ static mps_sac_classes_s classes8[4] = { {8, 1, 1}, {16, 1, 2}, {136, 9, 5}, static mps_sac_classes_s classes16[4] = { {16, 1, 1}, {32, 1, 2}, {144, 9, 5}, {topClassSIZE, 9, 4} }; -static int testInArena(mps_arena_t arena) +static void testInArena(mps_arena_t arena) { mps_pool_debug_option_s *debugOptions; mps_sac_classes_s *classes; @@ -183,7 +180,6 @@ static int testInArena(mps_arena_t arena) die(stress(mps_class_mv(), classCOUNT, classes, randomSize8, arena, (size_t)65536, (size_t)32, (size_t)65536), "stress MV"); - return 0; } diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index 06c6b7c01fb..ed25bf305ee 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -33,8 +33,8 @@ /* Forward declarations */ -static SegClass AMSTSegClassGet(void); -static PoolClass AMSTPoolClassGet(void); +extern SegClass AMSTSegClassGet(void); +extern PoolClass AMSTPoolClassGet(void); /* Start by defining the AMST pool (AMS Test pool) */ @@ -789,7 +789,7 @@ static void *test(void *arg, size_t s) &ambigRoots[0], ambigRootsCOUNT), "root_create_table(ambig)"); - fputs(indent, stdout); + (void)fputs(indent, stdout); /* create an ap, and leave it busy */ die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); @@ -801,7 +801,7 @@ static void *test(void *arg, size_t s) printf("\nSize %"PRIuLONGEST" bytes, %"PRIuLONGEST" objects.\n", (ulongest_t)totalSize, (ulongest_t)objs); printf("%s", indent); - fflush(stdout); + (void)fflush(stdout); for(i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]), "all roots check"); @@ -832,7 +832,7 @@ static void *test(void *arg, size_t s) ++objs; if (objs % 256 == 0) { printf("."); - fflush(stdout); + (void)fflush(stdout); } } diff --git a/mps/code/splay.c b/mps/code/splay.c index 9e2be1e98ad..53e21db9fa8 100644 --- a/mps/code/splay.c +++ b/mps/code/splay.c @@ -800,7 +800,7 @@ Bool SplayTreeDelete(SplayTree splay, Tree node) { TreeClearRight(node); SplayTreeSetRoot(splay, TreeLeft(node)); TreeClearLeft(node); - SplaySplay(splay, NULL, compareGreater); + (void)SplaySplay(splay, NULL, compareGreater); leftLast = SplayTreeRoot(splay); AVER(leftLast != TreeEMPTY); AVER(!TreeHasRight(leftLast)); @@ -856,7 +856,7 @@ static Tree SplayTreeSuccessor(SplayTree splay) { /* temporarily chop off the left half-tree, inclusive of root */ SplayTreeSetRoot(splay, TreeRight(oldRoot)); TreeSetRight(oldRoot, TreeEMPTY); - SplaySplay(splay, NULL, compareLess); + (void)SplaySplay(splay, NULL, compareLess); newRoot = SplayTreeRoot(splay); AVER(newRoot != TreeEMPTY); AVER(TreeLeft(newRoot) == TreeEMPTY); @@ -968,7 +968,7 @@ Tree SplayTreeFirst(SplayTree splay) { if (SplayTreeIsEmpty(splay)) return TreeEMPTY; - SplaySplay(splay, NULL, compareLess); + (void)SplaySplay(splay, NULL, compareLess); node = SplayTreeRoot(splay); AVER(node != TreeEMPTY); AVER(TreeLeft(node) == TreeEMPTY); diff --git a/mps/code/spw3i3mv.c b/mps/code/spw3i3.c similarity index 94% rename from mps/code/spw3i3mv.c rename to mps/code/spw3i3.c index 3bb8ce94d0f..1439d069c40 100644 --- a/mps/code/spw3i3mv.c +++ b/mps/code/spw3i3.c @@ -1,4 +1,4 @@ -/* spw3i3mv.c: STACK PROBE FOR 32-BIT WINDOWS +/* spw3i3.c: STACK PROBE FOR 32-BIT WINDOWS * * $Id$ * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. @@ -13,6 +13,13 @@ #include "mpm.h" +#ifdef MPS_BUILD_PC + +/* "[ISO] Inline assembly code is not portable." */ +#pragma warn(disable: 2007) + +#endif /* MPS_BUILD_PC */ + void StackProbe(Size depth) { diff --git a/mps/code/spw3i6mv.c b/mps/code/spw3i6.c similarity index 98% rename from mps/code/spw3i6mv.c rename to mps/code/spw3i6.c index 751e9680e4b..2c9ee5de389 100644 --- a/mps/code/spw3i6mv.c +++ b/mps/code/spw3i6.c @@ -1,4 +1,4 @@ -/* spw3i6mv.c: STACK PROBE FOR 64-BIT WINDOWS +/* spw3i6.c: STACK PROBE FOR 64-BIT WINDOWS * * $Id$ * Copyright (c) 2013 Ravenbrook Limited. See end of file for license. diff --git a/mps/code/steptest.c b/mps/code/steptest.c index 73cc730b790..b6e08995125 100644 --- a/mps/code/steptest.c +++ b/mps/code/steptest.c @@ -109,7 +109,8 @@ static double my_clock(void) { FILETIME ctime, etime, ktime, utime; double dk, du; - GetProcessTimes(currentProcess, &ctime, &etime, &ktime, &utime); + cdie(GetProcessTimes(currentProcess, &ctime, &etime, &ktime, &utime) != 0, + "GetProcessTimes"); dk = ktime.dwHighDateTime * 4096.0 * 1024.0 * 1024.0 + ktime.dwLowDateTime; dk /= 10.0; @@ -391,7 +392,7 @@ static void *test(void *arg, size_t s) if (collections > old_collections) { old_collections = collections; putchar('.'); - fflush(stdout); + (void)fflush(stdout); } } diff --git a/mps/code/teletest.c b/mps/code/teletest.c index 17002585133..1e0dca6a53e 100644 --- a/mps/code/teletest.c +++ b/mps/code/teletest.c @@ -209,13 +209,14 @@ extern int main(int argc, char *argv[]) while(1) { char input[INPUT_BUFFER_SIZE]; printf("telemetry test> "); - fflush(stdout); + (void)fflush(stdout); if (fgets(input, INPUT_BUFFER_SIZE , stdin)) { obeyCommand(input); } else { - doQuit(); + break; } } + doQuit(); return EXIT_SUCCESS; } diff --git a/mps/code/testlib.c b/mps/code/testlib.c index 8ef14ca3c78..d4cf0afc0f2 100644 --- a/mps/code/testlib.c +++ b/mps/code/testlib.c @@ -122,7 +122,7 @@ static unsigned long seed_verify_float = 1; static unsigned long rnd_verify_float(void) { double s; - s = seed_verify_float; + s = (double)seed_verify_float; s *= R_a_float; s = fmod(s, R_m_float); seed_verify_float = (unsigned long)s; @@ -285,7 +285,7 @@ void randomize(int argc, char *argv[]) argv[0], seed0); rnd_state_set(seed0); } - fflush(stdout); /* ensure seed is not lost in case of failure */ + (void)fflush(stdout); /* ensure seed is not lost in case of failure */ } unsigned long rnd_state(void) @@ -341,10 +341,10 @@ _mps_RES_ENUM(RES_STRINGS_ROW, X) void verror(const char *format, va_list args) { - fflush(stdout); /* synchronize */ - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); /* make sure the message is output */ + (void)fflush(stdout); /* synchronize */ + (void)vfprintf(stderr, format, args); + (void)fprintf(stderr, "\n"); + (void)fflush(stderr); /* make sure the message is output */ /* On Windows, the abort signal pops up a dialog box. This suspends * the test suite until a button is pressed, which is not acceptable * for offline testing, so if the MPS_TESTLIB_NOABORT environment @@ -413,7 +413,7 @@ void assert_die(const char *file, unsigned line, const char *condition) void testlib_init(int argc, char *argv[]) { - mps_lib_assert_fail_install(assert_die); + (void)mps_lib_assert_fail_install(assert_die); randomize(argc, argv); } diff --git a/mps/code/testlib.h b/mps/code/testlib.h index d36f26a275c..aff3c108351 100644 --- a/mps/code/testlib.h +++ b/mps/code/testlib.h @@ -69,6 +69,20 @@ #endif /* MPS_BUILD_MV */ +/* Suppress Pelles C warnings at warning level 2 */ +/* Some of these are also done in config.h. */ + +#ifdef MPS_BUILD_PC + +/* "Structured Exception Handling is not portable." (mps_tramp). */ +#pragma warn(disable: 2008) + +/* "Unreachable code" (AVER, if condition is constantly true). */ +#pragma warn(disable: 2154) + +#endif /* MPS_BUILD_PC */ + + /* ulongest_t -- longest unsigned integer type * * Define a longest unsigned integer type for testing, scanning, and @@ -119,6 +133,20 @@ typedef long longest_t; #define testlib_unused(v) ((void)(v)) +/* max -- return larger value + * + * Note: evaluates its arguments twice. + */ + +#undef max +#define max(a, b) (((a) > (b)) ? (a) : (b)) + + +/* alignUp -- align word to alignment */ + +#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1)) + + /* die -- succeed or die * * If the first argument is not ResOK then prints the second diff --git a/mps/code/w3i3mv.nmk b/mps/code/w3i3mv.nmk index 9bea83c3a25..afe2f9128bd 100644 --- a/mps/code/w3i3mv.nmk +++ b/mps/code/w3i3mv.nmk @@ -5,16 +5,13 @@ PFM = w3i3mv -# /Gs appears to be necessary to suppress stack checks. Stack checks -# (if not suppressed) generate a dependency on the C library, __chkesp, -# which causes the linker step to fail when building the DLL, mpsdy.dll. -PFMDEFS = /DCONFIG_PF_STRING="w3i3mv" /DCONFIG_PF_W3I3MV \ - /DWIN32 /D_WINDOWS /Gs +PFMDEFS = /DCONFIG_PF_STRING="w3i3mv" /DCONFIG_PF_W3I3MV /DWIN32 /D_WINDOWS !INCLUDE commpre.nmk +!INCLUDE mv.nmk # MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) +MPM = $(MPMCOMMON) diff --git a/mps/code/w3i3pc.gmk b/mps/code/w3i3pc.gmk deleted file mode 100644 index e1b832be7a2..00000000000 --- a/mps/code/w3i3pc.gmk +++ /dev/null @@ -1,5 +0,0 @@ -%.obj: %.c - pocc /Ze $< - -amcss.exe: amcss.obj abq.obj arena.obj arenacl.obj arenavm.obj arg.obj boot.obj bt.obj buffer.obj cbs.obj dbgpool.obj dbgpooli.obj event.obj fmtdy.obj fmtdy.obj fmtdytst.obj fmthe.obj fmtno.obj fmtno.obj format.obj freelist.obj global.obj ld.obj lockw3.obj locus.obj message.obj meter.obj mpm.obj mpsi.obj mpsioan.obj mpsiw3.obj mpsliban.obj pool.obj poolabs.obj poolamc.obj poolams.obj poolamsi.obj poolawl.obj poollo.obj poolmfs.obj poolmrg.obj poolmv2.obj poolmv.obj poolmvff.obj pooln.obj poolsnc.obj proti3.obj prmci3w3.obj protocol.obj protw3.obj range.obj ref.obj reserv.obj ring.obj root.obj sa.obj sac.obj seg.obj shield.obj spw3i3mv.obj splay.obj ss.obj ssw3i3pc.obj table.obj testlib.obj thw3.obj thw3i3.obj trace.obj traceanc.obj tract.obj tree.obj version.obj vmw3.obj walk.obj - polink $^ /OUT:$@ diff --git a/mps/code/w3i3pc.nmk b/mps/code/w3i3pc.nmk new file mode 100644 index 00000000000..bc428bc86a8 --- /dev/null +++ b/mps/code/w3i3pc.nmk @@ -0,0 +1,171 @@ +# w3i3pc.nmk: WINDOWS (IA-32) NMAKE FILE -*- makefile -*- +# +# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/w3i3pc.nmk#1 $ +# Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. + +PFM = w3i3pc + +# /Gs appears to be necessary to suppress stack checks. Stack checks +# (if not suppressed) generate a dependency on the C library, __chkesp, +# which causes the linker step to fail when building the DLL, mpsdy.dll. +PFMDEFS = /DCONFIG_PF_STRING="w3i3pc" /DCONFIG_PF_W3I3PC /DWIN32 /D_WINDOWS + +!INCLUDE commpre.nmk +!INCLUDE pc.nmk + +# MPM sources: core plus platform-specific. +MPM = $(MPMCOMMON) + + + +# Source to object file mappings and CFLAGS amalgamation +# +# %%VARIETY %%PART: When adding a new variety or part, add new macros which +# expand to the files included in the part for each variety +# +# %%VARIETY: When adding a new variety, add a CFLAGS macro which expands to +# the flags that that variety should use when compiling C. And a LINKFLAGS +# macro which expands to the flags that the variety should use when building +# executables. And a LIBFLAGS macro which expands to the flags that the +# variety should use when building libraries + +!IF "$(VARIETY)" == "hot" +CFLAGS=$(CFLAGSCOMMONPRE) $(CFHOT) $(CFLAGSCOMMONPOST) +CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) +LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) +LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) +MPMOBJ0 = $(MPM:<=w3i3pc\hot\) +PLINTHOBJ0 = $(PLINTH:<=w3i3pc\hot\) +AMSOBJ0 = $(AMS:<=w3i3pc\hot\) +AMCOBJ0 = $(AMC:<=w3i3pc\hot\) +AWLOBJ0 = $(AWL:<=w3i3pc\hot\) +LOOBJ0 = $(LO:<=w3i3pc\hot\) +SNCOBJ0 = $(SNC:<=w3i3pc\hot\) +MVFFOBJ0 = $(MVFF:<=w3i3pc\hot\) +DWOBJ0 = $(DW:<=w3i3pc\hot\) +FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\hot\) +POOLNOBJ0 = $(POOLN:<=w3i3pc\hot\) +TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\hot\) + +!ELSEIF "$(VARIETY)" == "cool" +CFLAGS=$(CFLAGSCOMMONPRE) $(CFCOOL) $(CFLAGSCOMMONPOST) +CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) +LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) +LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) +MPMOBJ0 = $(MPM:<=w3i3pc\cool\) +PLINTHOBJ0 = $(PLINTH:<=w3i3pc\cool\) +AMSOBJ0 = $(AMS:<=w3i3pc\cool\) +AMCOBJ0 = $(AMC:<=w3i3pc\cool\) +AWLOBJ0 = $(AWL:<=w3i3pc\cool\) +LOOBJ0 = $(LO:<=w3i3pc\cool\) +SNCOBJ0 = $(SNC:<=w3i3pc\cool\) +MVFFOBJ0 = $(MVFF:<=w3i3pc\cool\) +DWOBJ0 = $(DW:<=w3i3pc\cool\) +FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\cool\) +POOLNOBJ0 = $(POOLN:<=w3i3pc\cool\) +TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\cool\) + +!ELSEIF "$(VARIETY)" == "rash" +CFLAGS=$(CFLAGSCOMMONPRE) $(CFRASH) $(CFLAGSCOMMONPOST) +CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) +LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) +LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) +MPMOBJ0 = $(MPM:<=w3i3pc\rash\) +PLINTHOBJ0 = $(PLINTH:<=w3i3pc\rash\) +AMSOBJ0 = $(AMS:<=w3i3pc\rash\) +AMCOBJ0 = $(AMC:<=w3i3pc\rash\) +AWLOBJ0 = $(AWL:<=w3i3pc\rash\) +LOOBJ0 = $(LO:<=w3i3pc\rash\) +SNCOBJ0 = $(SNC:<=w3i3pc\rash\) +MVFFOBJ0 = $(MVFF:<=w3i3pc\rash\) +DWOBJ0 = $(DW:<=w3i3pc\rash\) +FMTTESTOBJ0 = $(FMTTEST:<=w3i3pc\rash\) +POOLNOBJ0 = $(POOLN:<=w3i3pc\rash\) +TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\rash\) + +#!ELSEIF "$(VARIETY)" == "cv" +#CFLAGS=$(CFLAGSCOMMON) $(CFCV) +#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV) +#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV) +#MPMOBJ0 = $(MPM:<=w3i3pc\cv\) +#MPMOBJ = $(MPMOBJ0:>=.obj) +#PLINTHOBJ0 = $(PLINTH:<=w3i3pc\cv\) +#PLINTHOBJ = $(PLINTHOBJ0:>=.obj) +#AMSOBJ0 = $(AMS:<=w3i3pc\cv\) +#AMSOBJ = $(AMSOBJ0:>=.obj) +#AMCOBJ0 = $(AMC:<=w3i3pc\cv\) +#AMCOBJ = $(AMCOBJ0:>=.obj) +#AWLOBJ0 = $(AWL:<=w3i3pc\cv\) +#AWLOBJ = $(AWLOBJ0:>=.obj) +#LOOBJ0 = $(LO:<=w3i3pc\cv\) +#LOOBJ = $(LOOBJ0:>=.obj) +#SNCOBJ0 = $(SNC:<=w3i3pc\cv\) +#SNCOBJ = $(SNCOBJ0:>=.obj) +#DWOBJ0 = $(DW:<=w3i3pc\cv\) +#DWOBJ = $(DWOBJ0:>=.obj) +#POOLNOBJ0 = $(POOLN:<=w3i3pc\cv\) +#POOLNOBJ = $(POOLNOBJ0:>=.obj) +#TESTLIBOBJ0 = $(TESTLIB:<=w3i3pc\cv\) +#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj) + +!ENDIF + +# %%PART: When adding a new part, add new macros which expand to the object +# files included in the part + +MPMOBJ = $(MPMOBJ0:>=.obj) +PLINTHOBJ = $(PLINTHOBJ0:>=.obj) +AMSOBJ = $(AMSOBJ0:>=.obj) +AMCOBJ = $(AMCOBJ0:>=.obj) +AWLOBJ = $(AWLOBJ0:>=.obj) +LOOBJ = $(LOOBJ0:>=.obj) +SNCOBJ = $(SNCOBJ0:>=.obj) +MVFFOBJ = $(MVFFOBJ0:>=.obj) +DWOBJ = $(DWOBJ0:>=.obj) +FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) +POOLNOBJ = $(POOLNOBJ0:>=.obj) +TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj) + + +!INCLUDE commpost.nmk + + +# C. COPYRIGHT AND LICENSE +# +# Copyright (C) 2001-2014 Ravenbrook Limited . +# All rights reserved. This is an open source license. Contact +# Ravenbrook for commercial licensing options. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Redistributions in any form must be accompanied by information on how +# to obtain complete source code for this software and any accompanying +# software that uses this software. The source code must either be +# included in the distribution or be available for no more than the cost +# of distribution plus a nominal fee, and must be freely redistributable +# under reasonable conditions. For an executable file, complete source +# code means the source code for all modules it contains. It does not +# include source code for modules or files that typically accompany the +# major components of the operating system on which the executable file +# runs. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +# PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mps/code/w3i6mv.nmk b/mps/code/w3i6mv.nmk index 2a4769a665f..4d69f6d4a65 100644 --- a/mps/code/w3i6mv.nmk +++ b/mps/code/w3i6mv.nmk @@ -5,15 +5,11 @@ PFM = w3i6mv -# /Gs appears to be necessary to suppress stack checks. Stack checks -# (if not suppressed) generate a dependency on the C library, __chkesp, -# which causes the linker step to fail when building the DLL, mpsdy.dll. -PFMDEFS = /DCONFIG_PF_STRING="w3i6mv" /DCONFIG_PF_W3I6MV \ - /DWIN32 /D_WINDOWS /Gs +PFMDEFS = /DCONFIG_PF_STRING="w3i6mv" /DCONFIG_PF_W3I6MV /DWIN32 /D_WINDOWS MASM = ml64 # MPM sources: core plus platform-specific. -MPM = $(MPMCOMMON) +MPM = $(MPMCOMMON) !INCLUDE commpre.nmk diff --git a/mps/code/walk.c b/mps/code/walk.c index b17540e4954..d08fd160eec 100644 --- a/mps/code/walk.c +++ b/mps/code/walk.c @@ -308,7 +308,8 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, if (SegFirst(&seg, arena)) { do { if ((SegPool(seg)->class->attr & AttrGC) != 0) { - TraceAddWhite(trace, seg); + res = TraceAddWhite(trace, seg); + AVER(res == ResOK); } } while (SegNext(&seg, arena, seg)); } diff --git a/mps/code/zcoll.c b/mps/code/zcoll.c index 639a323957a..9f8701ca1f5 100644 --- a/mps/code/zcoll.c +++ b/mps/code/zcoll.c @@ -119,12 +119,11 @@ static void showStatsAscii(size_t notcon, size_t con, size_t live, size_t alimit count = (a < 200) ? a + 1 : c; for(i = 0; i < count; i++) { - printf( (i == a) ? "A" - : (i < n) ? "n" - : (i < l) ? "L" - : (i < c) ? "_" - : " " - ); + putchar((i == a) ? 'A' + : (i < n) ? 'n' + : (i < l) ? 'L' + : (i < c) ? '_' + : ' '); } printf("\n"); } @@ -370,7 +369,7 @@ static void CatalogDo(mps_arena_t arena, mps_ap_t ap) myrootExact[CatalogRootIndex] = Catalog; get(arena); - fflush(stdout); + (void)fflush(stdout); CatalogCheck(); for(i = 0; i < CatalogVar; i += 1) { @@ -383,7 +382,7 @@ static void CatalogDo(mps_arena_t arena, mps_ap_t ap) get(arena); printf("Page %d: make articles\n", i); - fflush(stdout); + (void)fflush(stdout); for(j = 0; j < PageVar; j += 1) { die(make_dylan_vector(&v, ap, ArtFix + ArtVar), "Art"); @@ -405,7 +404,7 @@ static void CatalogDo(mps_arena_t arena, mps_ap_t ap) } } } - fflush(stdout); + (void)fflush(stdout); CatalogCheck(); } @@ -625,7 +624,7 @@ static void testscriptC(mps_arena_t arena, mps_ap_t ap, const char *script) script += sb; printf(" Collect\n"); stackwipe(); - mps_arena_collect(arena); + die(mps_arena_collect(arena), "mps_arena_collect"); mps_arena_release(arena); break; } diff --git a/mps/code/zmess.c b/mps/code/zmess.c index 1c87ac56cf2..e032b3f7620 100644 --- a/mps/code/zmess.c +++ b/mps/code/zmess.c @@ -242,7 +242,7 @@ static void testscriptC(mps_arena_t arena, const char *script) } case 'C': { printf(" Collect\n"); - mps_arena_collect(arena); + die(mps_arena_collect(arena), "mps_arena_collect"); break; } case 'F': { diff --git a/mps/tool/testrun.bat b/mps/tool/testrun.bat index 8bd44952bcd..88ad0779dff 100755 --- a/mps/tool/testrun.bat +++ b/mps/tool/testrun.bat @@ -59,9 +59,9 @@ set TEST_COUNT=0 set PASS_COUNT=0 set FAIL_COUNT=0 set SEPARATOR=---------------------------------------- -set LOGDIR=%TMP%\mps-%VARIETY%-log +set LOGDIR=%TMP%\mps-%PFM%-%VARIETY%-log echo Logging test output to %LOGDIR% -rmdir /q /s %LOGDIR% +rmdir /q /s %LOGDIR% 2> NUL mkdir %LOGDIR% if "%1"=="" call :run_tests %ALL_TEST_CASES% From 981dcb36e386d266d42907a65c4450252f2015d2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 24 Mar 2014 18:49:22 +0000 Subject: [PATCH 05/65] Ensure that windows.h is only included via mpswin.h, so that we always have the same set of definitions and pragmas in effect. Turn on WIN32_LEAN_AND_MEAN when including windows.h to improve compilation time. Copied from Perforce Change: 184979 ServerID: perforce.ravenbrook.com --- mps/code/clock.h | 2 +- mps/code/mpsw3.h | 2 +- mps/code/mpswin.h | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mps/code/clock.h b/mps/code/clock.h index 5e103ff4393..a027f4af07a 100644 --- a/mps/code/clock.h +++ b/mps/code/clock.h @@ -49,7 +49,7 @@ typedef union EventClockUnion { using Microsoft Visual Studio 6 because of support for CodeView debugging information. */ -#include /* KILL IT WITH FIRE! */ +#include "mpswin.h" /* KILL IT WITH FIRE! */ #define EVENT_CLOCK(lvalue) \ BEGIN \ diff --git a/mps/code/mpsw3.h b/mps/code/mpsw3.h index 2f543ddc0f8..f32b7a09831 100644 --- a/mps/code/mpsw3.h +++ b/mps/code/mpsw3.h @@ -11,7 +11,7 @@ #define mpsw3_h #include "mps.h" /* needed for mps_tramp_t */ -#include /* needed for SEH filter */ +#include "mpswin.h" /* needed for SEH filter */ extern LONG mps_SEH_filter(LPEXCEPTION_POINTERS, void **, size_t *); diff --git a/mps/code/mpswin.h b/mps/code/mpswin.h index 99317fb790a..1e25267c4ee 100644 --- a/mps/code/mpswin.h +++ b/mps/code/mpswin.h @@ -16,6 +16,9 @@ #pragma warning(disable: 4115 4201 4209 4214) #endif +/* Speed up the build process by excluding parts of windows.h that we + * don't use. See */ +#define WIN32_LEAN_AND_MEAN #include #ifdef MPS_BUILD_MV From a7c94b08451d04409fb5198ad70f330938ba611b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 24 Mar 2014 18:53:23 +0000 Subject: [PATCH 06/65] Need to include for malloc and _alloca. Copied from Perforce Change: 184980 ServerID: perforce.ravenbrook.com --- mps/code/lockutw3.c | 2 ++ mps/code/spw3i6.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mps/code/lockutw3.c b/mps/code/lockutw3.c index 6ba288521c5..43f486799df 100644 --- a/mps/code/lockutw3.c +++ b/mps/code/lockutw3.c @@ -4,6 +4,8 @@ * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. */ +#include /* malloc */ + #include "mpm.h" #include "testlib.h" #include "mpslib.h" diff --git a/mps/code/spw3i6.c b/mps/code/spw3i6.c index 2c9ee5de389..10404d4559e 100644 --- a/mps/code/spw3i6.c +++ b/mps/code/spw3i6.c @@ -16,8 +16,9 @@ * to be entered recursively. */ +#include /* _alloca */ + #include "mpm.h" -#include void StackProbe(Size depth) { From 23446b9efe48d3028be0a30b9afae9288ced53a2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 24 Mar 2014 20:36:57 +0000 Subject: [PATCH 07/65] Update file types: add +k (keyword expansion). Copied from Perforce Change: 184984 ServerID: perforce.ravenbrook.com --- mps/code/mv.nmk | 2 +- mps/code/pc.nmk | 2 +- mps/code/w3i3pc.nmk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/code/mv.nmk b/mps/code/mv.nmk index e860552e793..d07478a4d7e 100644 --- a/mps/code/mv.nmk +++ b/mps/code/mv.nmk @@ -2,7 +2,7 @@ # # mv.nmk: NMAKE FRAGMENT FOR MICROSOFT VISUAL C/C++ # -# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/gc.gmk#1 $ +# $Id$ # Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # This file is included by platform nmake files that use the Microsoft diff --git a/mps/code/pc.nmk b/mps/code/pc.nmk index 80ce471c544..e52addfba4c 100644 --- a/mps/code/pc.nmk +++ b/mps/code/pc.nmk @@ -2,7 +2,7 @@ # # pc.nmk: NMAKE FRAGMENT FOR PELLES C # -# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/gc.gmk#1 $ +# $Id$ # Copyright (c) 2014 Ravenbrook Limited. See end of file for license. # # This file is included by platform nmake files that use the Pelles C diff --git a/mps/code/w3i3pc.nmk b/mps/code/w3i3pc.nmk index bc428bc86a8..ce7358df2ab 100644 --- a/mps/code/w3i3pc.nmk +++ b/mps/code/w3i3pc.nmk @@ -1,6 +1,6 @@ # w3i3pc.nmk: WINDOWS (IA-32) NMAKE FILE -*- makefile -*- # -# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/w3i3pc.nmk#1 $ +# $Id$ # Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. PFM = w3i3pc From 4efa0dd942ccc7a87549f46c2f3a3662a8c079e2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 24 Mar 2014 20:56:06 +0000 Subject: [PATCH 08/65] Update manual to record the platform code pelles c (and also note that we don't support it). Copied from Perforce Change: 184986 ServerID: perforce.ravenbrook.com --- mps/manual/build.txt | 6 +++--- mps/manual/source/topic/platform.rst | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mps/manual/build.txt b/mps/manual/build.txt index c10763ec761..c97a01af418 100644 --- a/mps/manual/build.txt +++ b/mps/manual/build.txt @@ -151,9 +151,9 @@ Platform OS Architecture Compiler Makefile Historically, the MPS worked on a much wider variety of platforms, and still could: IRIX, OSF/1 (Tru64), Solaris, SunOS, Classic Mac OS; MIPS, PowerPC, ALPHA, SPARC v8, SPARC v9; Metrowerks Codewarrior, -SunPro C, Digital C, EGCS. If you are interested in support on any of -these platforms or any new platforms, please contact Ravenbrook at -`mps-questions@ravenbrook.com `_. +SunPro C, Digital C, EGCS, Pelles C. If you are interested in support +on any of these platforms or any new platforms, please contact +Ravenbrook at `mps-questions@ravenbrook.com `_. Running make diff --git a/mps/manual/source/topic/platform.rst b/mps/manual/source/topic/platform.rst index 0fbc4d59890..c9a1cb12b69 100644 --- a/mps/manual/source/topic/platform.rst +++ b/mps/manual/source/topic/platform.rst @@ -300,6 +300,7 @@ Formerly supported compiler toolchains: ``gp`` GCC with profiling ``MPS_BUILD_GP`` ``lc`` LCC ``MPS_BUILD_LC`` ``mw`` Metrowerks CodeWarrior ``MPS_BUILD_MW`` +``pc`` Pelles C ``MPS_BUILD_PC`` ``sc`` SunPro C ``MPS_BUILD_SC`` ====== ======================================= ================ @@ -348,7 +349,9 @@ Platform Status ``w3almv`` *Not supported* ``w3i3m9`` *Not supported* ``w3i3mv`` Supported +``w3i3pc`` *Not supported* ``w3i6mv`` Supported +``w3i6pc`` *Not supported* ``w3ppmv`` *Not supported* ``xci3gc`` *Not supported* ``xci3ll`` Supported From 00ee0bfcc5f291da747e867988f9180f5110c9fd Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 25 Mar 2014 10:59:09 +0000 Subject: [PATCH 09/65] 64-bit support for pelles c: * New nmake file w3i6pc.nmk. * New stack scanner ssw3i6pc.c supplies missing jump buffer definition. * Some platform tests change from defined(MPS_PF_W3I6MV) to defined(MPS_OS_w3) && defined(MPS_ARCH_I6). * Make reasonable changes to the source code to avoid warnings from Pelles C: ** Ensure that printf formats are consistent with arguments by using PRIuLONGEST and casting to ulongest_t. ** Use size_t for loop variables that index into arrays. ** Suppress "Consider changing type to 'size_t' for loop variable" warnings for the MPS core. Copied from Perforce Change: 184996 ServerID: perforce.ravenbrook.com --- mps/code/amcss.c | 3 +- mps/code/amcsshe.c | 3 +- mps/code/apss.c | 8 +- mps/code/awlut.c | 11 ++- mps/code/awluthe.c | 9 +-- mps/code/config.h | 5 +- mps/code/eventrep.c | 2 +- mps/code/exposet0.c | 3 +- mps/code/expt825.c | 12 ++- mps/code/fbmtest.c | 12 ++- mps/code/finalcv.c | 3 +- mps/code/finaltest.c | 6 +- mps/code/fmtdy.c | 12 +-- mps/code/locbwcss.c | 2 +- mps/code/locusss.c | 2 +- mps/code/mpmss.c | 8 +- mps/code/mps.c | 15 ++++ mps/code/mpstd.h | 21 ++++++ mps/code/qs.c | 2 +- mps/code/replay.c | 2 +- mps/code/sacss.c | 6 +- mps/code/spw3i6.c | 2 +- mps/code/ssw3i6pc.c | 143 +++++++++++++++++++++++++++++++++++ mps/code/steptest.c | 12 +-- mps/code/teletest.c | 18 ++--- mps/code/testlib.h | 2 +- mps/code/w3i6pc.nmk | 175 +++++++++++++++++++++++++++++++++++++++++++ mps/code/zcoll.c | 23 +++--- mps/code/zmess.c | 5 +- 29 files changed, 445 insertions(+), 82 deletions(-) create mode 100644 mps/code/ssw3i6pc.c create mode 100644 mps/code/w3i6pc.nmk diff --git a/mps/code/amcss.c b/mps/code/amcss.c index 1b32c849769..3f9afba4e82 100644 --- a/mps/code/amcss.c +++ b/mps/code/amcss.c @@ -196,7 +196,8 @@ static void test(mps_arena_t arena) collections = c; report(arena); - printf("%lu objects (mps_collections says: %lu)\n", objs, c); + printf("%lu objects (mps_collections says: %"PRIuLONGEST")\n", objs, + (ulongest_t)c); /* test mps_arena_has_addr */ { diff --git a/mps/code/amcsshe.c b/mps/code/amcsshe.c index 248929240d0..15dd342336c 100644 --- a/mps/code/amcsshe.c +++ b/mps/code/amcsshe.c @@ -173,7 +173,8 @@ static void *test(void *arg, size_t s) if (collections != c) { collections = c; - printf("\nCollection %lu, %lu objects.\n", c, objs); + printf("\nCollection %"PRIuLONGEST", %lu objects.\n", + (ulongest_t)c, objs); report(arena); for (r = 0; r < exactRootsCOUNT; ++r) { if (exactRoots[r] != objNULL) diff --git a/mps/code/apss.c b/mps/code/apss.c index 8016f9b1aa5..04818600510 100644 --- a/mps/code/apss.c +++ b/mps/code/apss.c @@ -43,14 +43,14 @@ static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size) /* stress -- create a pool of the requested type and allocate in it */ -static mps_res_t stress(mps_class_t class, size_t (*size)(unsigned long i), +static mps_res_t stress(mps_class_t class, size_t (*size)(size_t i), mps_arena_t arena, ...) { mps_res_t res = MPS_RES_OK; mps_pool_t pool; mps_ap_t ap; va_list arg; - unsigned long i, k; + size_t i, k; int *ps[testSetSIZE]; size_t ss[testSetSIZE]; @@ -78,7 +78,7 @@ static mps_res_t stress(mps_class_t class, size_t (*size)(unsigned long i), for (k=0; k */ cdie(root[objind] == NULL, "finalized live"); cdie(state[objind] == finalizableSTATE, "finalized dead"); diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index a6c23aebfd1..ee7a55ee3e7 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -188,7 +188,8 @@ static void *test(void *arg, size_t s) ++ final_this_time; } finals += final_this_time; - printf("%lu objects finalized: total %lu of %lu\n", + printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST + " of %"PRIuLONGEST"\n", final_this_time, finals, object_count); } @@ -226,7 +227,8 @@ static void *test(void *arg, size_t s) ++ final_this_time; } finals += final_this_time; - printf("%lu objects finalized: total %lu of %lu\n", + printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST + " of %"PRIuLONGEST"\n", final_this_time, finals, object_count); } diff --git a/mps/code/fmtdy.c b/mps/code/fmtdy.c index 498f8811635..758a7f4ebbb 100644 --- a/mps/code/fmtdy.c +++ b/mps/code/fmtdy.c @@ -493,15 +493,15 @@ extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) break; case 4: /* non-word */ - es = (vh & 0xff) >> 3; - vb = (vh >> 16) & 0xff; + es = (unsigned)(vh & 0xff) >> 3; + vb = (unsigned)((vh >> 16) & 0xff); vt += vb; p += NONWORD_LENGTH(vt, es); break; case 5: /* stretchy non-word */ - es = (vh & 0xff) >> 3; - vb = (vh >> 16) & 0xff; + es = (unsigned)(vh & 0xff) >> 3; + vb = (unsigned)((vh >> 16) & 0xff); vt += vb; p += NONWORD_LENGTH(vt, es) + 1; notreached(); /* DW doesn't create them yet */ @@ -678,8 +678,8 @@ static mps_addr_t dylan_skip(mps_addr_t object) if((vf & 6) == 4) /* non-word */ { - es = (vh & 0xff) >> 3; - vb = (vh >> 16) & 0xff; + es = (unsigned)(vh & 0xff) >> 3; + vb = (unsigned)((vh >> 16) & 0xff); vt += vb; p += NONWORD_LENGTH(vt, es); } diff --git a/mps/code/locbwcss.c b/mps/code/locbwcss.c index 3bc674c7d68..e37f59cbc30 100644 --- a/mps/code/locbwcss.c +++ b/mps/code/locbwcss.c @@ -110,7 +110,7 @@ static void poolStatInit(PoolStat stat, mps_pool_t pool, size_t objSize) static void allocMultiple(PoolStat stat) { mps_addr_t objects[allocsPerIteration]; - int i; + size_t i; /* allocate a few objects, and record stats for them */ for (i = 0; i < allocsPerIteration; i++) { diff --git a/mps/code/locusss.c b/mps/code/locusss.c index b399e58e8da..22a35ab6e4e 100644 --- a/mps/code/locusss.c +++ b/mps/code/locusss.c @@ -110,7 +110,7 @@ static void poolStatInit(PoolStat stat, mps_pool_t pool, size_t objSize) static mps_res_t allocMultiple(PoolStat stat) { mps_addr_t objects[contigAllocs]; - int i; + size_t i; /* allocate a few objects, and record stats for them */ for (i = 0; i < contigAllocs; i++) { diff --git a/mps/code/mpmss.c b/mps/code/mpmss.c index b2a48347382..9e592a7513c 100644 --- a/mps/code/mpmss.c +++ b/mps/code/mpmss.c @@ -30,13 +30,13 @@ extern mps_class_t PoolClassMFS(void); /* stress -- create a pool of the requested type and allocate in it */ -static mps_res_t stress(mps_class_t class, size_t (*size)(int i), +static mps_res_t stress(mps_class_t class, size_t (*size)(size_t i), mps_arena_t arena, ...) { mps_res_t res; mps_pool_t pool; va_list arg; - int i, k; + size_t i, k; int *ps[testSetSIZE]; size_t ss[testSetSIZE]; @@ -94,7 +94,7 @@ static mps_res_t stress(mps_class_t class, size_t (*size)(int i), /* randomSize -- produce sizes both latge and small */ -static size_t randomSize(int i) +static size_t randomSize(size_t i) { /* Make the range large enough to span three pages in the segment table: */ /* 160 segments/page, page size max 0x2000. */ @@ -106,7 +106,7 @@ static size_t randomSize(int i) /* randomSize8 -- produce sizes both latge and small, 8-byte aligned */ -static size_t randomSize8(int i) +static size_t randomSize8(size_t i) { size_t maxSize = 2 * 160 * 0x2000; /* Reduce by a factor of 2 every 10 cycles. Total allocation about 40 MB. */ diff --git a/mps/code/mps.c b/mps/code/mps.c index ce910bad927..0a8f29be9ba 100644 --- a/mps/code/mps.c +++ b/mps/code/mps.c @@ -229,6 +229,21 @@ #include "spw3i3.c" /* 32-bit Intel stack probe */ #include "mpsiw3.c" /* Windows interface layer extras */ +/* Windows on 64-bit Intel with Pelles C */ + +#elif defined(MPS_PF_W3I6PC) + +#include "lockw3.c" /* Windows locks */ +#include "thw3.c" /* Windows threading */ +#include "thw3i6.c" /* Windows on 64-bit Intel thread stack scan */ +#include "vmw3.c" /* Windows virtual memory */ +#include "protw3.c" /* Windows protection */ +#include "proti6.c" /* 64-bit Intel mutator context decoding */ +#include "prmci6w3.c" /* Windows on 64-bit Intel mutator context */ +#include "ssw3i6pc.c" /* Windows on 64-bit stack scan for Pelles C */ +#include "spw3i6.c" /* 64-bit Intel stack probe */ +#include "mpsiw3.c" /* Windows interface layer extras */ + #else #error "Unknown platform -- can't determine platform specific parts." diff --git a/mps/code/mpstd.h b/mps/code/mpstd.h index 891d5979647..1306281224b 100644 --- a/mps/code/mpstd.h +++ b/mps/code/mpstd.h @@ -97,6 +97,27 @@ #define MPS_PF_ALIGN 8 +/* PellesC version 7.00.25 with /Ze option (Microsoft compatibility mode) + * and /Tarm64-coff (Create a COFF object file for a X64 processor). + * Help node "Predefined preprocessor symbols (POCC)" + */ + +#elif defined(__POCC__) && defined(_WIN32) && defined(_WIN64) && defined(_M_X64) +#if defined(CONFIG_PF_STRING) && ! defined(CONFIG_PF_W3I6PC) +#error "specified CONFIG_PF_... inconsistent with detected w3i6pc" +#endif +#define MPS_PF_W3I6PC +#define MPS_PF_STRING "w3i6pc" +#define MPS_OS_W3 +#define MPS_ARCH_I6 +#define MPS_BUILD_PC +#define MPS_T_WORD unsigned __int64 +#define MPS_T_ULONGEST unsigned __int64 +#define MPS_WORD_WIDTH 64 +#define MPS_WORD_SHIFT 6 +#define MPS_PF_ALIGN 16 + + /* GCC 4.0.1 (As supplied by Apple on Mac OS X 10.4.8 on an Intel Mac), * gcc -E -dM * And above for xcppgc. diff --git a/mps/code/qs.c b/mps/code/qs.c index 2e573d0840b..2ccc9423184 100644 --- a/mps/code/qs.c +++ b/mps/code/qs.c @@ -186,7 +186,7 @@ static void swap(void) static void makerndlist(unsigned l) { - unsigned i; + size_t i; mps_word_t r; mps_addr_t addr; diff --git a/mps/code/replay.c b/mps/code/replay.c index 974ce5dcd07..0069e7415c1 100644 --- a/mps/code/replay.c +++ b/mps/code/replay.c @@ -21,7 +21,7 @@ #include "mpstd.h" -#ifdef MPS_PF_W3I6MV +#if defined(MPS_OS_W3) && defined(MPS_ARCH_I6) #define PRIuLONGEST "llu" #define PRIXPTR "016llX" typedef unsigned long long ulongest_t; diff --git a/mps/code/sacss.c b/mps/code/sacss.c index d48b41708d8..bfb0725ed47 100644 --- a/mps/code/sacss.c +++ b/mps/code/sacss.c @@ -47,13 +47,13 @@ static mps_res_t make(mps_addr_t *p, mps_sac_t sac, size_t size) static mps_res_t stress(mps_class_t class, size_t classes_count, mps_sac_classes_s *classes, - size_t (*size)(int i), mps_arena_t arena, ...) + size_t (*size)(size_t i), mps_arena_t arena, ...) { mps_res_t res; mps_pool_t pool; mps_sac_t sac; va_list arg; - int i, k; + size_t i, k; int *ps[testSetSIZE]; size_t ss[testSetSIZE]; @@ -127,7 +127,7 @@ static mps_res_t stress(mps_class_t class, /* randomSize8 -- produce sizes both latge and small */ -static size_t randomSize8(int i) +static size_t randomSize8(size_t i) { size_t maxSize = 2 * 160 * 0x2000; size_t size; diff --git a/mps/code/spw3i6.c b/mps/code/spw3i6.c index 10404d4559e..29b1f8b8dcf 100644 --- a/mps/code/spw3i6.c +++ b/mps/code/spw3i6.c @@ -22,7 +22,7 @@ void StackProbe(Size depth) { - _alloca(depth*sizeof(Word)); + (void)_alloca(depth*sizeof(Word)); } diff --git a/mps/code/ssw3i6pc.c b/mps/code/ssw3i6pc.c new file mode 100644 index 00000000000..c58e88f846a --- /dev/null +++ b/mps/code/ssw3i6pc.c @@ -0,0 +1,143 @@ +/* ssw3i6pc.c: STACK SCANNING FOR WIN32 WITH PELLES C + * + * $Id$ + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. + * + * This scans the stack and fixes the registers which may contain roots. + * See . + * + * .assume.ms-compat: We rely on the fact that Pelles C's setjmp stores + * the callee-save registers in the jmp_buf and is compatible with Microsoft + * C. The Pelles C 7.00 setjmp.h header has a comment "MS compatible". See + * also "Is Pelles C's jmp_buf compatible with Microsoft C's?" + * + * + * REFERENCES + * + * "Overview of x64 Calling Conventions"; MSDN; Microsoft Corporation; + * . + * + * "Caller/Callee Saved Registers"; MSDN; Microsoft Corporation; + * . + * + * "Register Usage"; MSDN; Microsoft Corporation; + * . + * + * "Calling conventions for different C++ compilers and operating systems"; + * Agner Fog; Copenhagen University College of Engineering; 2012-02-29; + * . + */ + +#include "mpm.h" +#include + +SRCID(ssw3i6pc, "$Id$"); + + +/* This definition isn't in the Pelles C headers, so we reproduce it here. + * See .assume.ms-compat. */ + +typedef /* _CRT_ALIGN(16) */ struct _SETJMP_FLOAT128 { + unsigned __int64 Part[2]; +} SETJMP_FLOAT128; + +typedef struct _JUMP_BUFFER { + unsigned __int64 Frame; + unsigned __int64 Rbx; + unsigned __int64 Rsp; + unsigned __int64 Rbp; + unsigned __int64 Rsi; + unsigned __int64 Rdi; + unsigned __int64 R12; + unsigned __int64 R13; + unsigned __int64 R14; + unsigned __int64 R15; + unsigned __int64 Rip; + unsigned __int64 Spare; + + SETJMP_FLOAT128 Xmm6; + SETJMP_FLOAT128 Xmm7; + SETJMP_FLOAT128 Xmm8; + SETJMP_FLOAT128 Xmm9; + SETJMP_FLOAT128 Xmm10; + SETJMP_FLOAT128 Xmm11; + SETJMP_FLOAT128 Xmm12; + SETJMP_FLOAT128 Xmm13; + SETJMP_FLOAT128 Xmm14; + SETJMP_FLOAT128 Xmm15; +} _JUMP_BUFFER; + + +Res StackScan(ScanState ss, Addr *stackBot) +{ + jmp_buf jb; + + /* We rely on the fact that Pelles C's setjmp stores the callee-save + registers in the jmp_buf. */ + (void)setjmp(jb); + + /* These checks will just serve to warn us at compile-time if the + setjmp.h header changes to indicate that the registers we want aren't + saved any more. */ + AVER(sizeof(((_JUMP_BUFFER *)jb)->Rdi) == sizeof(Addr)); + AVER(sizeof(((_JUMP_BUFFER *)jb)->Rsi) == sizeof(Addr)); + AVER(sizeof(((_JUMP_BUFFER *)jb)->Rbp) == sizeof(Addr)); + AVER(sizeof(((_JUMP_BUFFER *)jb)->R12) == sizeof(Addr)); + AVER(sizeof(((_JUMP_BUFFER *)jb)->R13) == sizeof(Addr)); + AVER(sizeof(((_JUMP_BUFFER *)jb)->R14) == sizeof(Addr)); + AVER(sizeof(((_JUMP_BUFFER *)jb)->R15) == sizeof(Addr)); + + /* The layout of the jmp_buf forces us to harmlessly scan Rsp as well. */ + AVER(offsetof(_JUMP_BUFFER, Rsp) == offsetof(_JUMP_BUFFER, Rbx) + 8); + AVER(offsetof(_JUMP_BUFFER, Rbp) == offsetof(_JUMP_BUFFER, Rbx) + 16); + AVER(offsetof(_JUMP_BUFFER, Rsi) == offsetof(_JUMP_BUFFER, Rbx) + 24); + AVER(offsetof(_JUMP_BUFFER, Rdi) == offsetof(_JUMP_BUFFER, Rbx) + 32); + AVER(offsetof(_JUMP_BUFFER, R12) == offsetof(_JUMP_BUFFER, Rbx) + 40); + AVER(offsetof(_JUMP_BUFFER, R13) == offsetof(_JUMP_BUFFER, Rbx) + 48); + AVER(offsetof(_JUMP_BUFFER, R14) == offsetof(_JUMP_BUFFER, Rbx) + 56); + AVER(offsetof(_JUMP_BUFFER, R15) == offsetof(_JUMP_BUFFER, Rbx) + 64); + + return StackScanInner(ss, stackBot, (Addr *)&((_JUMP_BUFFER *)jb)->Rbx, 9); +} + + +/* C. COPYRIGHT AND LICENSE + * + * Copyright (C) 2001-2014 Ravenbrook Limited . + * All rights reserved. This is an open source license. Contact + * Ravenbrook for commercial licensing options. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Redistributions in any form must be accompanied by information on how + * to obtain complete source code for this software and any accompanying + * software that uses this software. The source code must either be + * included in the distribution or be available for no more than the cost + * of distribution plus a nominal fee, and must be freely redistributable + * under reasonable conditions. For an executable file, complete source + * code means the source code for all modules it contains. It does not + * include source code for modules or files that typically accompany the + * major components of the operating system on which the executable file + * runs. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/mps/code/steptest.c b/mps/code/steptest.c index b6e08995125..4d6353e78df 100644 --- a/mps/code/steptest.c +++ b/mps/code/steptest.c @@ -420,8 +420,8 @@ static void *test(void *arg, size_t s) printf("Collection statistics:\n"); printf(" %"PRIuLONGEST" collections\n", (ulongest_t)collections); printf(" %"PRIuLONGEST" bytes condemned.\n", (ulongest_t)condemned); - printf(" %lu bytes not condemned.\n", - (unsigned long)not_condemned); + printf(" %"PRIuLONGEST" bytes not condemned.\n", + (ulongest_t)not_condemned); printf(" %"PRIuLONGEST" bytes survived.\n", (ulongest_t)live); if (condemned) { printf(" Mortality %5.2f%%.\n", @@ -430,10 +430,10 @@ static void *test(void *arg, size_t s) ((double)condemned/(condemned + not_condemned)) * 100.0); } if (collections) { - printf(" Condemned per collection %lu bytes.\n", - (unsigned long)condemned/collections); - printf(" Reclaimed per collection %lu bytes.\n", - (unsigned long)(condemned - live)/collections); + printf(" Condemned per collection %"PRIuLONGEST" bytes.\n", + (ulongest_t)condemned/collections); + printf(" Reclaimed per collection %"PRIuLONGEST" bytes.\n", + (ulongest_t)(condemned - live)/collections); } printf("Allocation statistics:\n"); diff --git a/mps/code/teletest.c b/mps/code/teletest.c index 1e0dca6a53e..312237f5251 100644 --- a/mps/code/teletest.c +++ b/mps/code/teletest.c @@ -19,19 +19,10 @@ SRCID(teletest, "$Id$"); static mps_arena_t arena; - +#define WORD_FORMAT "%" PRIwWORD PRIuLONGEST #define MAX_ARGS 3 #define INPUT_BUFFER_SIZE 512 -#if (MPS_WORD_WIDTH == 32) -#define WORD_FORMAT "0x%08lx" -#elif (MPS_WORD_WIDTH == 64) -#define WORD_FORMAT "0x%016lx" -#else -#error "Unrecognized word width" -#endif - - static mps_word_t args[MAX_ARGS]; static char *stringArg; static Count argCount; @@ -43,7 +34,8 @@ static void callControl(mps_word_t reset, mps_word_t flip) old = mps_telemetry_control(reset, flip); new = mps_telemetry_control((mps_word_t)0, (mps_word_t)0); - (void)printf(WORD_FORMAT " -> " WORD_FORMAT "\n", old, new); + (void)printf(WORD_FORMAT " -> " WORD_FORMAT "\n", + (ulongest_t)old, (ulongest_t)new); } @@ -58,7 +50,7 @@ static void doRead(void) mps_word_t old; old = mps_telemetry_control((mps_word_t)0, (mps_word_t)0); - (void)printf(WORD_FORMAT "\n", old); + (void)printf(WORD_FORMAT "\n", (ulongest_t)old); } @@ -85,7 +77,7 @@ static void doIntern(void) mps_word_t id; id = mps_telemetry_intern(stringArg); - (void)printf(WORD_FORMAT "\n", id); + (void)printf(WORD_FORMAT "\n", (ulongest_t)id); } static void doLabel(void) diff --git a/mps/code/testlib.h b/mps/code/testlib.h index aff3c108351..6dea9beae75 100644 --- a/mps/code/testlib.h +++ b/mps/code/testlib.h @@ -101,7 +101,7 @@ #error "How many beans make five?" #endif -#ifdef MPS_PF_W3I6MV +#if defined(MPS_OS_W3) && defined(MPS_ARCH_I6) #define PRIuLONGEST "llu" #define SCNuLONGEST "llu" #define SCNXLONGEST "llX" diff --git a/mps/code/w3i6pc.nmk b/mps/code/w3i6pc.nmk new file mode 100644 index 00000000000..fd3f798a9b5 --- /dev/null +++ b/mps/code/w3i6pc.nmk @@ -0,0 +1,175 @@ +# -*- makefile -*- +# +# w3i6pc.nmk: NMAKE FILE FOR WINDOWS/x64/PELLES C +# +# $Id: //info.ravenbrook.com/project/mps/branch/2014-03-21/pellesc/code/w3i6pc.nmk#1 $ +# Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. + +PFM = w3i6pc + +# /Gs appears to be necessary to suppress stack checks. Stack checks +# (if not suppressed) generate a dependency on the C library, __chkesp, +# which causes the linker step to fail when building the DLL, mpsdy.dll. +PFMDEFS = /DCONFIG_PF_STRING="w3i6pc" /DCONFIG_PF_W3I6PC /DWIN32 /D_WINDOWS + +!INCLUDE commpre.nmk +!INCLUDE pc.nmk + +CFLAGSCOMMONPRE = $(CFLAGSCOMMONPRE) /Tamd64-coff + +# MPM sources: core plus platform-specific. +MPM = $(MPMCOMMON) + + + +# Source to object file mappings and CFLAGS amalgamation +# +# %%VARIETY %%PART: When adding a new variety or part, add new macros which +# expand to the files included in the part for each variety +# +# %%VARIETY: When adding a new variety, add a CFLAGS macro which expands to +# the flags that that variety should use when compiling C. And a LINKFLAGS +# macro which expands to the flags that the variety should use when building +# executables. And a LIBFLAGS macro which expands to the flags that the +# variety should use when building libraries + +!IF "$(VARIETY)" == "hot" +CFLAGS=$(CFLAGSCOMMONPRE) $(CFHOT) $(CFLAGSCOMMONPOST) +CFLAGSSQL=$(CFLAGSSQLPRE) $(CFHOT) $(CFLAGSSQLPOST) +LINKFLAGS=$(LINKFLAGSCOMMON) $(LFHOT) +LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSHOT) +MPMOBJ0 = $(MPM:<=w3i6pc\hot\) +PLINTHOBJ0 = $(PLINTH:<=w3i6pc\hot\) +AMSOBJ0 = $(AMS:<=w3i6pc\hot\) +AMCOBJ0 = $(AMC:<=w3i6pc\hot\) +AWLOBJ0 = $(AWL:<=w3i6pc\hot\) +LOOBJ0 = $(LO:<=w3i6pc\hot\) +SNCOBJ0 = $(SNC:<=w3i6pc\hot\) +MVFFOBJ0 = $(MVFF:<=w3i6pc\hot\) +DWOBJ0 = $(DW:<=w3i6pc\hot\) +FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\hot\) +POOLNOBJ0 = $(POOLN:<=w3i6pc\hot\) +TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\hot\) + +!ELSEIF "$(VARIETY)" == "cool" +CFLAGS=$(CFLAGSCOMMONPRE) $(CFCOOL) $(CFLAGSCOMMONPOST) +CFLAGSSQL=$(CFLAGSSQLPRE) $(CFCOOL) $(CFLAGSSQLPOST) +LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCOOL) +LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCOOL) +MPMOBJ0 = $(MPM:<=w3i6pc\cool\) +PLINTHOBJ0 = $(PLINTH:<=w3i6pc\cool\) +AMSOBJ0 = $(AMS:<=w3i6pc\cool\) +AMCOBJ0 = $(AMC:<=w3i6pc\cool\) +AWLOBJ0 = $(AWL:<=w3i6pc\cool\) +LOOBJ0 = $(LO:<=w3i6pc\cool\) +SNCOBJ0 = $(SNC:<=w3i6pc\cool\) +MVFFOBJ0 = $(MVFF:<=w3i6pc\cool\) +DWOBJ0 = $(DW:<=w3i6pc\cool\) +FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\cool\) +POOLNOBJ0 = $(POOLN:<=w3i6pc\cool\) +TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\cool\) + +!ELSEIF "$(VARIETY)" == "rash" +CFLAGS=$(CFLAGSCOMMONPRE) $(CFRASH) $(CFLAGSCOMMONPOST) +CFLAGSSQL=$(CFLAGSSQLPRE) $(CFRASH) $(CFLAGSSQLPOST) +LINKFLAGS=$(LINKFLAGSCOMMON) $(LFRASH) +LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSRASH) +MPMOBJ0 = $(MPM:<=w3i6pc\rash\) +PLINTHOBJ0 = $(PLINTH:<=w3i6pc\rash\) +AMSOBJ0 = $(AMS:<=w3i6pc\rash\) +AMCOBJ0 = $(AMC:<=w3i6pc\rash\) +AWLOBJ0 = $(AWL:<=w3i6pc\rash\) +LOOBJ0 = $(LO:<=w3i6pc\rash\) +SNCOBJ0 = $(SNC:<=w3i6pc\rash\) +MVFFOBJ0 = $(MVFF:<=w3i6pc\rash\) +DWOBJ0 = $(DW:<=w3i6pc\rash\) +FMTTESTOBJ0 = $(FMTTEST:<=w3i6pc\rash\) +POOLNOBJ0 = $(POOLN:<=w3i6pc\rash\) +TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\rash\) + +#!ELSEIF "$(VARIETY)" == "cv" +#CFLAGS=$(CFLAGSCOMMON) $(CFCV) +#LINKFLAGS=$(LINKFLAGSCOMMON) $(LFCV) +#LIBFLAGS=$(LIBFLAGSCOMMON) $(LIBFLAGSCV) +#MPMOBJ0 = $(MPM:<=w3i6pc\cv\) +#MPMOBJ = $(MPMOBJ0:>=.obj) +#PLINTHOBJ0 = $(PLINTH:<=w3i6pc\cv\) +#PLINTHOBJ = $(PLINTHOBJ0:>=.obj) +#AMSOBJ0 = $(AMS:<=w3i6pc\cv\) +#AMSOBJ = $(AMSOBJ0:>=.obj) +#AMCOBJ0 = $(AMC:<=w3i6pc\cv\) +#AMCOBJ = $(AMCOBJ0:>=.obj) +#AWLOBJ0 = $(AWL:<=w3i6pc\cv\) +#AWLOBJ = $(AWLOBJ0:>=.obj) +#LOOBJ0 = $(LO:<=w3i6pc\cv\) +#LOOBJ = $(LOOBJ0:>=.obj) +#SNCOBJ0 = $(SNC:<=w3i6pc\cv\) +#SNCOBJ = $(SNCOBJ0:>=.obj) +#DWOBJ0 = $(DW:<=w3i6pc\cv\) +#DWOBJ = $(DWOBJ0:>=.obj) +#POOLNOBJ0 = $(POOLN:<=w3i6pc\cv\) +#POOLNOBJ = $(POOLNOBJ0:>=.obj) +#TESTLIBOBJ0 = $(TESTLIB:<=w3i6pc\cv\) +#TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj) + +!ENDIF + +# %%PART: When adding a new part, add new macros which expand to the object +# files included in the part + +MPMOBJ = $(MPMOBJ0:>=.obj) +PLINTHOBJ = $(PLINTHOBJ0:>=.obj) +AMSOBJ = $(AMSOBJ0:>=.obj) +AMCOBJ = $(AMCOBJ0:>=.obj) +AWLOBJ = $(AWLOBJ0:>=.obj) +LOOBJ = $(LOOBJ0:>=.obj) +SNCOBJ = $(SNCOBJ0:>=.obj) +MVFFOBJ = $(MVFFOBJ0:>=.obj) +DWOBJ = $(DWOBJ0:>=.obj) +FMTTESTOBJ = $(FMTTESTOBJ0:>=.obj) +POOLNOBJ = $(POOLNOBJ0:>=.obj) +TESTLIBOBJ = $(TESTLIBOBJ0:>=.obj) + + +!INCLUDE commpost.nmk + + +# C. COPYRIGHT AND LICENSE +# +# Copyright (C) 2001-2014 Ravenbrook Limited . +# All rights reserved. This is an open source license. Contact +# Ravenbrook for commercial licensing options. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Redistributions in any form must be accompanied by information on how +# to obtain complete source code for this software and any accompanying +# software that uses this software. The source code must either be +# included in the distribution or be available for no more than the cost +# of distribution plus a nominal fee, and must be freely redistributable +# under reasonable conditions. For an executable file, complete source +# code means the source code for all modules it contains. It does not +# include source code for modules or files that typically accompany the +# major components of the operating system on which the executable file +# runs. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +# PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mps/code/zcoll.c b/mps/code/zcoll.c index 9f8701ca1f5..646d8c7d30a 100644 --- a/mps/code/zcoll.c +++ b/mps/code/zcoll.c @@ -196,8 +196,8 @@ static void get(mps_arena_t arena) switch(type) { case mps_message_type_gc_start(): { mclockBegin = mps_message_clock(arena, message); - printf(" %5lu: (%5lu)", - mclockBegin, mclockBegin - mclockEnd); + printf(" %5"PRIuLONGEST": (%5"PRIuLONGEST")", + (ulongest_t)mclockBegin, (ulongest_t)(mclockBegin - mclockEnd)); printf(" Coll Begin (%s)\n", mps_message_gc_start_why(arena, message)); break; @@ -211,8 +211,8 @@ static void get(mps_arena_t arena) mclockEnd = mps_message_clock(arena, message); - printf(" %5lu: (%5lu)", - mclockEnd, mclockEnd - mclockBegin); + printf(" %5"PRIuLONGEST": (%5"PRIuLONGEST")", + (ulongest_t)mclockEnd, (ulongest_t)(mclockEnd - mclockBegin)); printf(" Coll End "); showStatsText(notcon, con, live); if(rnd()==0) showStatsAscii(notcon, con, live, alimit); @@ -222,7 +222,8 @@ static void get(mps_arena_t arena) mps_message_finalization_ref(&objaddr, arena, message); obj = objaddr; objind = DYLAN_INT_INT(DYLAN_VECTOR_SLOT(obj, 0)); - printf(" Finalization for object %lu at %p\n", objind, objaddr); + printf(" Finalization for object %"PRIuLONGEST" at %p\n", + (ulongest_t)objind, objaddr); break; } default: { @@ -301,7 +302,7 @@ static void CatalogCheck(void) mps_word_t w; void *Catalog, *Page, *Art, *Poly; unsigned long Catalogs = 0, Pages = 0, Arts = 0, Polys = 0; - int i, j, k; + size_t i, j, k; /* retrieve Catalog from root */ Catalog = myrootExact[CatalogRootIndex]; @@ -359,7 +360,7 @@ static void CatalogDo(mps_arena_t arena, mps_ap_t ap) { mps_word_t v; void *Catalog, *Page, *Art, *Poly; - int i, j, k; + size_t i, j, k; die(make_dylan_vector(&v, ap, CatalogFix + CatalogVar), "Catalog"); DYLAN_VECTOR_SLOT(v, 0) = DYLAN_INT(CatalogSig); @@ -381,7 +382,7 @@ static void CatalogDo(mps_arena_t arena, mps_ap_t ap) DYLAN_VECTOR_SLOT(Catalog, CatalogFix + i) = (mps_word_t)Page; get(arena); - printf("Page %d: make articles\n", i); + printf("Page %"PRIuLONGEST": make articles\n", (ulongest_t)i); (void)fflush(stdout); for(j = 0; j < PageVar; j += 1) { @@ -531,7 +532,7 @@ static void Make(mps_arena_t arena, mps_ap_t ap, unsigned randm, unsigned keep1i static void Rootdrop(char rank_char) { - unsigned i; + size_t i; if(rank_char == 'A') { for(i = 0; i < myrootAmbigCOUNT; ++i) { @@ -550,7 +551,7 @@ static void Rootdrop(char rank_char) #define stackwipedepth 50000 static void stackwipe(void) { - unsigned iw; + size_t iw; unsigned long aw[stackwipedepth]; /* Do some pointless work that the compiler won't optimise away, so that @@ -734,7 +735,7 @@ static void *testscriptB(void *arg, size_t s) mps_fmt_t fmt; mps_chain_t chain; mps_pool_t amc; - int i; + size_t i; mps_root_t root_table_Ambig; mps_root_t root_table_Exact; mps_ap_t ap; diff --git a/mps/code/zmess.c b/mps/code/zmess.c index e032b3f7620..2b6d533dfde 100644 --- a/mps/code/zmess.c +++ b/mps/code/zmess.c @@ -179,7 +179,8 @@ static void report(mps_arena_t arena, const char *pm, Bool discard) mps_message_finalization_ref(&objaddr, arena, message); obj = objaddr; objind = DYLAN_INT_INT(DYLAN_VECTOR_SLOT(obj, 0)); - printf(" Finalization for object %lu at %p\n", objind, objaddr); + printf(" Finalization for object %"PRIuLONGEST" at %p\n", + (ulongest_t)objind, objaddr); cdie(myroot[objind] == NULL, "finalized live"); cdie(state[objind] == finalizableSTATE, "not finalizable"); state[objind] = finalizedSTATE; @@ -308,7 +309,7 @@ static void *testscriptB(void *arg, size_t s) mps_root_t root_table; mps_ap_t ap; mps_root_t root_stackreg; - int i; + size_t i; int N = myrootCOUNT - 1; void *stack_starts_here; /* stack scanning starts here */ From d799a993a2a098562f799fcc412f316e4cd58498 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 25 Mar 2014 11:05:09 +0000 Subject: [PATCH 10/65] Support for stackprobe on w3i3pc and w3i6pc. Copied from Perforce Change: 184998 ServerID: perforce.ravenbrook.com --- mps/code/config.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mps/code/config.h b/mps/code/config.h index c785cf7f949..d66487e1684 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -341,12 +341,10 @@ /* Stack configuration */ -/* Currently StackProbe has a useful implementation only on - * Intel platforms and only when using Microsoft build tools (builder.mv) - */ -#if defined(MPS_ARCH_I3) && defined(MPS_BUILD_MV) +/* Currently StackProbe has a useful implementation only on Windows. */ +#if defined(MPS_OS_W3) && defined(MPS_ARCH_I3) #define StackProbeDEPTH ((Size)500) -#elif defined(MPS_PF_W3I6MV) +#elif defined(MPS_OS_W3) && defined(MPS_ARCH_I6) #define StackProbeDEPTH ((Size)500) #else #define StackProbeDEPTH ((Size)0) From 629278c469385046ecf0bd26a73241927be1e368 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 25 Mar 2014 11:08:06 +0000 Subject: [PATCH 11/65] Fixedsize function needs to take a size_t as argument. Copied from Perforce Change: 184999 ServerID: perforce.ravenbrook.com --- mps/code/mpmss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mps/code/mpmss.c b/mps/code/mpmss.c index 9e592a7513c..547f3d746b6 100644 --- a/mps/code/mpmss.c +++ b/mps/code/mpmss.c @@ -62,7 +62,7 @@ static mps_res_t stress(mps_class_t class, size_t (*size)(size_t i), for (k=0; k Date: Tue, 25 Mar 2014 15:12:33 +0000 Subject: [PATCH 12/65] Uncomment event_list calls. Copied from Perforce Change: 185011 ServerID: perforce.ravenbrook.com --- mps/code/event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mps/code/event.c b/mps/code/event.c index a650b63b958..131f0552f25 100644 --- a/mps/code/event.c +++ b/mps/code/event.c @@ -202,8 +202,8 @@ void EventInit(void) #define EVENT_CHECK_PARAMS(X, name, code, always, kind) \ EVENT_##name##_PARAMS(EVENT_PARAM_CHECK, name) - /*EVENT_LIST(EVENT_CHECK, X)*/ - /*EVENT_LIST(EVENT_CHECK_PARAMS, X)*/ + EVENT_LIST(EVENT_CHECK, X); + EVENT_LIST(EVENT_CHECK_PARAMS, X); /* Ensure that no event can be larger than the maximum event size. */ AVER(EventBufferSIZE <= EventSizeMAX); From 028ec084ffb485de16418864647f792efd701132 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 25 Mar 2014 15:37:27 +0000 Subject: [PATCH 13/65] Fix case of mps_os_w3, spotted by rb. Copied from Perforce Change: 185013 ServerID: perforce.ravenbrook.com --- mps/code/eventrep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/code/eventrep.c b/mps/code/eventrep.c index 66988cf2e24..c2364529cf1 100644 --- a/mps/code/eventrep.c +++ b/mps/code/eventrep.c @@ -31,7 +31,7 @@ #include "mpstd.h" -#if defined(MPS_OS_w3) && defined(MPS_ARCH_I6) +#if defined(MPS_OS_W3) && defined(MPS_ARCH_I6) #define PRIuLONGEST "llu" #define PRIXPTR "016llX" typedef unsigned long long ulongest_t; From 9aef4157fdd83cc16674dd359fb4aee31ea6a925 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 26 Mar 2014 12:27:35 +0000 Subject: [PATCH 14/65] Fix review comments from dl . Add __attribute__((__format__(printf))) to functions that take a printf-compatible format string (when building using GCC or Clang), so that format string mistakes can be detected statically. Copied from Perforce Change: 185021 ServerID: perforce.ravenbrook.com --- mps/code/awlut.c | 6 ++++-- mps/code/awluthe.c | 8 +++++--- mps/code/config.h | 17 +++++++++++++++++ mps/code/eventcnv.c | 3 +++ mps/code/eventrep.c | 1 + mps/code/eventsql.c | 13 ++++++++----- mps/code/eventtxt.c | 1 + mps/code/mpswin.h | 1 + mps/code/poolmv2.c | 4 +++- mps/code/replay.c | 1 + mps/code/teletest.c | 2 +- mps/code/testlib.c | 2 ++ mps/code/testlib.h | 19 +++++++++++++++++++ mps/code/w3i3pc.nmk | 3 --- mps/code/w3i6pc.nmk | 3 --- 15 files changed, 66 insertions(+), 18 deletions(-) diff --git a/mps/code/awlut.c b/mps/code/awlut.c index e5dbd64a47e..927d16add46 100644 --- a/mps/code/awlut.c +++ b/mps/code/awlut.c @@ -221,11 +221,13 @@ static void test(mps_arena_t arena, for(i = 0; i < TABLE_SLOTS; ++i) { if (preserve[i] == 0) { if (table_slot(weaktable, i)) { - error("Strongly unreachable weak table entry found, slot %lu.\n", i); + error("Strongly unreachable weak table entry found, " + "slot %"PRIuLONGEST".\n", (ulongest_t)i); } else { if (table_slot(exacttable, i) != 0) { error("Weak table entry deleted, but corresponding " - "exact table entry not deleted, slot %lu.\n", i); + "exact table entry not deleted, slot %"PRIuLONGEST".\n", + (ulongest_t)i); } } } diff --git a/mps/code/awluthe.c b/mps/code/awluthe.c index fa883a30487..257b4142723 100644 --- a/mps/code/awluthe.c +++ b/mps/code/awluthe.c @@ -121,7 +121,7 @@ static mps_word_t *alloc_string(const char *s, mps_ap_t ap) * .assume.dylan-obj */ -static mps_word_t *alloc_table(unsigned long n, mps_ap_t ap) +static mps_word_t *alloc_table(size_t n, mps_ap_t ap) { size_t objsize; void *p; @@ -226,11 +226,13 @@ static void test(mps_arena_t arena, for(i = 0; i < TABLE_SLOTS; ++i) { if (preserve[i] == 0) { if (table_slot(weaktable, i)) { - error("Strongly unreachable weak table entry found, slot %lu.\n", i); + error("Strongly unreachable weak table entry found, " + "slot %"PRIuLONGEST".\n", (ulongest_t)i); } else { if (table_slot(exacttable, i) != 0) { error("Weak table entry deleted, but corresponding " - "exact table entry not deleted, slot %lu.\n", i); + "exact table entry not deleted, slot %"PRIuLONGEST".\n", + (ulongest_t)i); } } } diff --git a/mps/code/config.h b/mps/code/config.h index d66487e1684..cfca6ab01b6 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -225,6 +225,23 @@ #endif /* MPS_BUILD_PC */ +/* Function attributes */ +/* These are also defined in testlib.h */ + +#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL) + +/* GCC: + * Clang: + */ +#define ATTRIBUTE_FORMAT(ARGLIST) __attribute__((__format__ ARGLIST)) + +#else + +#define ATTRIBUTE_FORMAT(ARGLIST) + +#endif + + /* EPVMDefaultSubsequentSegSIZE is a default for the alignment of * subsequent segments (non-initial at each save level) in EPVM. See * design.mps.poolepvm.arch.segment.size. diff --git a/mps/code/eventcnv.c b/mps/code/eventcnv.c index 33375c45f4d..3464605cf1e 100644 --- a/mps/code/eventcnv.c +++ b/mps/code/eventcnv.c @@ -62,6 +62,7 @@ static const char *prog; /* program name */ /* fevwarn -- flush stdout, write message to stderr */ +ATTRIBUTE_FORMAT((printf, 2, 0)) static void fevwarn(const char *prefix, const char *format, va_list args) { (void)fflush(stdout); /* sync */ @@ -74,6 +75,7 @@ static void fevwarn(const char *prefix, const char *format, va_list args) /* evwarn -- flush stdout, warn to stderr */ +ATTRIBUTE_FORMAT((printf, 1, 2)) static void evwarn(const char *format, ...) { va_list args; @@ -85,6 +87,7 @@ static void evwarn(const char *format, ...) /* everror -- flush stdout, message to stderr, exit */ +ATTRIBUTE_FORMAT((printf, 1, 2)) static void everror(const char *format, ...) { va_list args; diff --git a/mps/code/eventrep.c b/mps/code/eventrep.c index c2364529cf1..375d793c13f 100644 --- a/mps/code/eventrep.c +++ b/mps/code/eventrep.c @@ -116,6 +116,7 @@ typedef struct apRepStruct *apRep; /* error -- error signalling */ +ATTRIBUTE_FORMAT((printf, 1, 2)) static void error(const char *format, ...) { va_list args; diff --git a/mps/code/eventsql.c b/mps/code/eventsql.c index 0fa36dea739..74aaad92b31 100644 --- a/mps/code/eventsql.c +++ b/mps/code/eventsql.c @@ -113,6 +113,7 @@ unsigned int verbosity = 0; #define LOG_SELDOM 3 #define LOG_RARELY 4 +ATTRIBUTE_FORMAT((printf, 2, 0)) static void vlog(unsigned int level, const char *format, va_list args) { if (level <= verbosity) { @@ -123,6 +124,7 @@ static void vlog(unsigned int level, const char *format, va_list args) } } +ATTRIBUTE_FORMAT((printf, 2, 3)) static void evlog(unsigned int level, const char *format, ...) { va_list args; @@ -131,6 +133,7 @@ static void evlog(unsigned int level, const char *format, ...) va_end(args); } +ATTRIBUTE_FORMAT((printf, 1, 2)) static void error(const char *format, ...) { va_list args; @@ -452,7 +455,7 @@ static void registerLogFile(sqlite3 *db, name = sqlite3_column_text(statement, 0); logSerial = sqlite3_column_int64(statement, 1); completed = sqlite3_column_int64(statement, 2); - evlog(force ? LOG_OFTEN : LOG_ALWAYS, "Log file matching '%s' already in event_log, named \"%s\" (serial %lu, completed %lu).", + evlog(force ? LOG_OFTEN : LOG_ALWAYS, "Log file matching '%s' already in event_log, named \"%s\" (serial %llu, completed %llu).", filename, name, logSerial, completed); if (force) { evlog(LOG_OFTEN, "Continuing anyway because -f specified."); @@ -486,7 +489,7 @@ static void registerLogFile(sqlite3 *db, if (res != SQLITE_DONE) sqlite_error(res, db, "insert into event_log failed."); logSerial = sqlite3_last_insert_rowid(db); - evlog(LOG_SOMETIMES, "Log file %s added to event_log with serial %lu", + evlog(LOG_SOMETIMES, "Log file %s added to event_log with serial %llu", filename, logSerial); finalizeStatement(db, statement); } @@ -508,7 +511,7 @@ static void logFileCompleted(sqlite3 *db, res = sqlite3_step(statement); if (res != SQLITE_DONE) sqlite_error(res, db, "insert into event_log failed."); - evlog(LOG_SOMETIMES, "Marked in event_log: %lu events", completed); + evlog(LOG_SOMETIMES, "Marked in event_log: %llu events", completed); finalizeStatement(db, statement); } @@ -864,7 +867,7 @@ static int64 readLog(FILE *input, /* this macro sets statement and last_index */ EVENT_LIST(EVENT_TYPE_WRITE_SQL, X); default: - error("Event %llu has Unknown event code %d", eventCount, code); + error("Event %llu has Unknown event code %ld", eventCount, code); } /* bind the fields we store for every event */ \ res = sqlite3_bind_int64(statement, last_index+1, logSerial); @@ -951,7 +954,7 @@ int main(int argc, char *argv[]) makeTables(db); fillGlueTables(db); count = writeEventsToSQL(db); - evlog(LOG_ALWAYS, "Imported %llu events from %s to %s, serial %lu.", + evlog(LOG_ALWAYS, "Imported %llu events from %s to %s, serial %llu.", count, logFileName, databaseName, logSerial); if (runTests) { diff --git a/mps/code/eventtxt.c b/mps/code/eventtxt.c index 4782e576a94..4e81a8b06c4 100644 --- a/mps/code/eventtxt.c +++ b/mps/code/eventtxt.c @@ -50,6 +50,7 @@ static const char *logFileName = NULL; /* everror -- error signalling */ +ATTRIBUTE_FORMAT((printf, 1, 2)) static void everror(const char *format, ...) { va_list args; diff --git a/mps/code/mpswin.h b/mps/code/mpswin.h index 1e25267c4ee..8d54f5c90a4 100644 --- a/mps/code/mpswin.h +++ b/mps/code/mpswin.h @@ -20,6 +20,7 @@ * don't use. See */ #define WIN32_LEAN_AND_MEAN #include +#undef WIN32_LEAN_AND_MEAN #ifdef MPS_BUILD_MV #pragma warning(default: 4115 4201 4209 4214) diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index d244fe23043..d9d063dc39e 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -280,7 +280,7 @@ static Res MVTInit(Pool pool, ArgList args) res = FreelistInit(MVTFreelist(mvt), align); if (res != ResOK) - goto failABQ; + goto failFreelist; pool->alignment = align; mvt->reuseSize = reuseSize; @@ -345,6 +345,8 @@ static Res MVTInit(Pool pool, ArgList args) reserveDepth, fragLimit); return ResOK; +failFreelist: + ABQFinish(arena, MVTABQ(mvt)); failABQ: CBSFinish(MVTCBS(mvt)); failCBS: diff --git a/mps/code/replay.c b/mps/code/replay.c index 0069e7415c1..9f761119c4f 100644 --- a/mps/code/replay.c +++ b/mps/code/replay.c @@ -47,6 +47,7 @@ static Word eventTime = 0; /* current event time */ /* error -- error signalling */ +ATTRIBUTE_FORMAT((printf, 1, 2)) static void error(const char *format, ...) { va_list args; diff --git a/mps/code/teletest.c b/mps/code/teletest.c index 312237f5251..07d2948513c 100644 --- a/mps/code/teletest.c +++ b/mps/code/teletest.c @@ -19,7 +19,7 @@ SRCID(teletest, "$Id$"); static mps_arena_t arena; -#define WORD_FORMAT "%" PRIwWORD PRIuLONGEST +#define WORD_FORMAT "0x%0" PRIwWORD PRIuLONGEST #define MAX_ARGS 3 #define INPUT_BUFFER_SIZE 512 diff --git a/mps/code/testlib.c b/mps/code/testlib.c index d4cf0afc0f2..6f5a6dd2ff6 100644 --- a/mps/code/testlib.c +++ b/mps/code/testlib.c @@ -339,6 +339,7 @@ _mps_RES_ENUM(RES_STRINGS_ROW, X) /* verror -- die with message */ +ATTRIBUTE_FORMAT((printf, 1, 0)) void verror(const char *format, va_list args) { (void)fflush(stdout); /* synchronize */ @@ -360,6 +361,7 @@ void verror(const char *format, va_list args) /* error -- die with message */ +ATTRIBUTE_FORMAT((printf, 1, 2)) void error(const char *format, ...) { va_list args; diff --git a/mps/code/testlib.h b/mps/code/testlib.h index 6dea9beae75..252fb5167a3 100644 --- a/mps/code/testlib.h +++ b/mps/code/testlib.h @@ -83,6 +83,23 @@ #endif /* MPS_BUILD_PC */ +/* Function attributes */ +/* These are also defined in config.h */ + +#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL) + +/* GCC: + * Clang: + */ +#define ATTRIBUTE_FORMAT(ARGLIST) __attribute__((__format__ ARGLIST)) + +#else + +#define ATTRIBUTE_FORMAT(ARGLIST) + +#endif + + /* ulongest_t -- longest unsigned integer type * * Define a longest unsigned integer type for testing, scanning, and @@ -195,7 +212,9 @@ void assert_die(const char *file, unsigned line, const char *condition); /* error, verror -- die with message */ +ATTRIBUTE_FORMAT((printf, 1, 2)) extern void error(const char *format, ...); +ATTRIBUTE_FORMAT((printf, 1, 0)) extern void verror(const char *format, va_list args); diff --git a/mps/code/w3i3pc.nmk b/mps/code/w3i3pc.nmk index ce7358df2ab..d6d424b669d 100644 --- a/mps/code/w3i3pc.nmk +++ b/mps/code/w3i3pc.nmk @@ -5,9 +5,6 @@ PFM = w3i3pc -# /Gs appears to be necessary to suppress stack checks. Stack checks -# (if not suppressed) generate a dependency on the C library, __chkesp, -# which causes the linker step to fail when building the DLL, mpsdy.dll. PFMDEFS = /DCONFIG_PF_STRING="w3i3pc" /DCONFIG_PF_W3I3PC /DWIN32 /D_WINDOWS !INCLUDE commpre.nmk diff --git a/mps/code/w3i6pc.nmk b/mps/code/w3i6pc.nmk index fd3f798a9b5..1decdde0083 100644 --- a/mps/code/w3i6pc.nmk +++ b/mps/code/w3i6pc.nmk @@ -7,9 +7,6 @@ PFM = w3i6pc -# /Gs appears to be necessary to suppress stack checks. Stack checks -# (if not suppressed) generate a dependency on the C library, __chkesp, -# which causes the linker step to fail when building the DLL, mpsdy.dll. PFMDEFS = /DCONFIG_PF_STRING="w3i6pc" /DCONFIG_PF_W3I6PC /DWIN32 /D_WINDOWS !INCLUDE commpre.nmk From fe68bfac839c7fba357e4009eb0042377265f9ea Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 26 Mar 2014 13:44:02 +0000 Subject: [PATCH 15/65] Avoid expanding __file__ in aver in pelles c -- the compiler somehow loses its definition for __file__ in deeply nested macro expansions. Copied from Perforce Change: 185025 ServerID: perforce.ravenbrook.com --- mps/code/check.h | 2 +- mps/code/config.h | 16 ++++++++++++++++ mps/code/event.c | 5 +---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/mps/code/check.h b/mps/code/check.h index d4abc0fd80a..4ed2ba8b75a 100644 --- a/mps/code/check.h +++ b/mps/code/check.h @@ -52,7 +52,7 @@ #define ASSERT(cond, condstring) \ BEGIN \ if (cond) NOOP; else \ - mps_lib_assert_fail(__FILE__ , __LINE__, (condstring)); \ + mps_lib_assert_fail(MPS_FILE, __LINE__, (condstring)); \ END #define ASSERT_TYPECHECK(type, val) \ diff --git a/mps/code/config.h b/mps/code/config.h index cfca6ab01b6..5d4eb20779c 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -225,6 +225,22 @@ #endif /* MPS_BUILD_PC */ +/* MPS_FILE -- expands to __FILE__ in nested macros */ + +#ifdef MPS_BUILD_PC + +/* Pelles C loses definition of __FILE__ in deeply nested macro + * expansions. See + */ +#define MPS_FILE "<__FILE__ unavailable in " MPS_PF_STRING ">" + +#else + +#define MPS_FILE __FILE__ + +#endif + + /* Function attributes */ /* These are also defined in testlib.h */ diff --git a/mps/code/event.c b/mps/code/event.c index 131f0552f25..2e7468c3752 100644 --- a/mps/code/event.c +++ b/mps/code/event.c @@ -197,13 +197,10 @@ void EventInit(void) AVER((Bool)Event##name##Always == always); \ AVERT(Bool, always); \ AVER(0 <= Event##name##Kind); \ - AVER((EventKind)Event##name##Kind < EventKindLIMIT); - -#define EVENT_CHECK_PARAMS(X, name, code, always, kind) \ + AVER((EventKind)Event##name##Kind < EventKindLIMIT); \ EVENT_##name##_PARAMS(EVENT_PARAM_CHECK, name) EVENT_LIST(EVENT_CHECK, X); - EVENT_LIST(EVENT_CHECK_PARAMS, X); /* Ensure that no event can be larger than the maximum event size. */ AVER(EventBufferSIZE <= EventSizeMAX); From d6273ee2eac7891d978f0c91acb62e13f3828044 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 27 Mar 2014 21:31:08 +0000 Subject: [PATCH 16/65] Document amc and amcz support for ambiguous interior references. Copied from Perforce Change: 185065 ServerID: perforce.ravenbrook.com --- mps/manual/source/pool/intro.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mps/manual/source/pool/intro.rst b/mps/manual/source/pool/intro.rst index ea2a03ce562..a27a33380e1 100644 --- a/mps/manual/source/pool/intro.rst +++ b/mps/manual/source/pool/intro.rst @@ -121,8 +121,8 @@ Blocks are automatically managed? [10]_ yes yes yes yes yes Blocks are promoted between generations yes yes no no no --- --- --- --- --- Blocks are manually managed? [10]_ no no no no no yes yes yes yes yes Blocks are scanned? [11]_ yes no yes yes no no no no no yes -Blocks support base pointers only? [12]_ yes yes yes yes yes --- --- --- --- yes -Blocks support internal pointers? [12]_ no no no no no --- --- --- --- no +Blocks support base pointers only? [12]_ no no yes yes yes --- --- --- --- yes +Blocks support internal pointers? [12]_ yes yes no no no --- --- --- --- no Blocks may be protected by barriers? yes no yes yes yes no no no no yes Blocks may move? yes yes no no no no no no no no Blocks may be finalized? yes yes yes yes yes no no no no no From 1572cacd63c4e3b905f7ccff08dad99cbc4fcc80 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 28 Mar 2014 12:45:11 +0000 Subject: [PATCH 17/65] Avoid spurious output from rmdir when running "nmake clean". Copied from Perforce Change: 185069 ServerID: perforce.ravenbrook.com --- mps/code/commpost.nmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/code/commpost.nmk b/mps/code/commpost.nmk index 021e37b89e4..240eadd150e 100644 --- a/mps/code/commpost.nmk +++ b/mps/code/commpost.nmk @@ -27,7 +27,7 @@ $(ALL_TARGETS) $(OPTIONAL_TARGETS): clean: $(ECHO) $(PFM): $@ - -echo y | rmdir/s $(PFM) + if exist $(PFM) rmdir /q /s $(PFM) # target target # %%VARIETY: When adding a new variety, optionally, add a recursive make From d04344de11a556cebea31f53029141dc941453dc Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 28 Mar 2014 12:59:38 +0000 Subject: [PATCH 18/65] Explicit instructions for users compiling for 64-bit windows. Copied from Perforce Change: 185070 ServerID: perforce.ravenbrook.com --- mps/manual/build.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mps/manual/build.txt b/mps/manual/build.txt index c10763ec761..b21a1e1bf2b 100644 --- a/mps/manual/build.txt +++ b/mps/manual/build.txt @@ -190,9 +190,10 @@ You will need to switch your build environment between 32-bit and 64-bit using Microsoft's ``setenv`` command, for example, ``setenv /x86`` or ``setenv /x64``. -To build just one target, run the command:: +To build just one target, run one of these commands:: - nmake /f w3i3mv.nmk + nmake /f w3i3mv.nmk (32-bit) + nmake /f w3i6mv.nmk (64-bit) On Mac OS X, you can build from the command line with:: @@ -264,6 +265,7 @@ this program, you need to install the SQLite3 development resources. it contains files named ``sqlite3.c`` and ``sqlite3.h``. Copy these two files into the ``code`` directory in the MPS Kit. Then in the "Visual Studio Command Prompt", visit the ``code`` directory and run - the command:: + one of these commands:: - nmake /f w3i3mv.nmk mpseventsql.exe + nmake /f w3i3mv.nmk mpseventsql.exe (32-bit) + nmake /f w3i6mv.nmk mpseventsql.exe (64-bit) From 68edf84c3b26f21a7d51e39bcf4a9273c9e885e5 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 28 Mar 2014 13:09:14 +0000 Subject: [PATCH 19/65] Remove #pragma warning(disable: ...) for microsoft visual c/c++ warnings that are no longer generated by the code, so that we get the maximum checking from this compiler. Copied from Perforce Change: 185072 ServerID: perforce.ravenbrook.com --- mps/code/bttest.c | 10 ---------- mps/code/commpre.nmk | 9 ++++++--- mps/code/config.h | 45 +++----------------------------------------- mps/code/eventcnv.c | 10 ++-------- mps/code/eventsql.c | 7 ++----- mps/code/eventtxt.c | 10 ++-------- mps/code/fmtdy.c | 8 ++------ mps/code/fmtdytst.c | 10 ++-------- mps/code/fmtno.c | 20 ++------------------ mps/code/mpswin.h | 19 ++----------------- mps/code/testlib.c | 13 ------------- mps/code/testlib.h | 37 +----------------------------------- mps/code/zcoll.c | 9 +-------- 13 files changed, 25 insertions(+), 182 deletions(-) diff --git a/mps/code/bttest.c b/mps/code/bttest.c index 12a6bd8503f..531e3150445 100644 --- a/mps/code/bttest.c +++ b/mps/code/bttest.c @@ -312,11 +312,6 @@ static void obeyCommand(const char *command) } -#ifdef MPS_BUILD_MV -/* disable "conversion from int to char" */ -#pragma warning(disable: 4244) -#endif - static void showBT(void) { Index i; char c; @@ -353,11 +348,6 @@ static void showBT(void) { putchar('\n'); } -#ifdef MPS_BUILD_MV -/* disable "conversion from int to char" */ -#pragma warning(default: 4244) -#endif - #define testArenaSIZE (((size_t)64)<<20) diff --git a/mps/code/commpre.nmk b/mps/code/commpre.nmk index ec1685a8630..71fcd97c56b 100644 --- a/mps/code/commpre.nmk +++ b/mps/code/commpre.nmk @@ -1,7 +1,7 @@ # commpre.nmk: FIRST COMMON FRAGMENT FOR PLATFORMS USING NMAKE -*- makefile -*-1 # # $Id$ -# Copyright (c) 2001 Ravenbrook Limited. See end of file for license. +# Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. # # DESCRIPTION # @@ -219,12 +219,15 @@ ECHO = echo # C FLAGS +# /D_CRT_SECURE_NO_WARNINGS suppresses "This function or variable may +# be unsafe" warnings for standard C library functions fopen, getenv, +# snprintf, sscanf, strcpy, and so on. # /MD means compile for multi-threaded environment with separate C library DLL. # /MT means compile for multi-threaded environment. # /ML means compile for single-threaded environment. # A 'd' at the end means compile for debugging. -CFLAGSTARGETPRE = +CFLAGSTARGETPRE = /D_CRT_SECURE_NO_WARNINGS CFLAGSTARGETPOST = CRTFLAGSHOT = /MT CRTFLAGSCOOL = /MTd @@ -299,7 +302,7 @@ LIBFLAGSCOOL = # 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/config.h b/mps/code/config.h index 4778b4b7552..e4735881b5d 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -1,7 +1,7 @@ /* config.h: MPS CONFIGURATION * * $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 @@ -161,53 +161,14 @@ #include "mpstd.h" /* Suppress Visual C warnings at warning level 4, */ -/* see mail.richard.1997-09-25.13-26. */ +/* see mail.richard.1997-09-25.13-26 and job003715. */ /* Essentially the same settings are done in testlib.h. */ #ifdef MPS_BUILD_MV -/* "unreferenced inline function has been removed" (windows.h) */ -#pragma warning(disable: 4514) - /* "constant conditional" (MPS_END) */ #pragma warning(disable: 4127) -/* "unreachable code" (ASSERT, if cond is constantly true). */ -#pragma warning(disable: 4702) - -/* "expression evaluates to a function which is missing an argument list" */ -#pragma warning(disable: 4550) - -/* "local variable is initialized but not referenced" */ -#pragma warning(disable: 4189) - -/* "not all control paths return a value" */ -#pragma warning(disable: 4715) - -/* MSVC 2.0 generates a warning when using NOCHECK or UNUSED */ -#ifdef _MSC_VER -#if _MSC_VER < 1000 -#pragma warning(disable: 4705) -#endif -#else /* _MSC_VER */ -#error "Expected _MSC_VER to be defined for builder.mv" -#endif /* _MSC_VER */ - - -/* Non-checking varieties give many spurious warnings because parameters - * are suddenly unused, etc. We aren't interested in these - */ - -#if defined(AVER_AND_CHECK_NONE) - -/* "unreferenced formal parameter" */ -#pragma warning(disable: 4100) - -/* "unreferenced local function has been removed" */ -#pragma warning(disable: 4505) - -#endif /* AVER_AND_CHECK_NONE */ - #endif /* MPS_BUILD_MV */ @@ -547,7 +508,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. * diff --git a/mps/code/eventcnv.c b/mps/code/eventcnv.c index 7cca6846a49..5095a871ea1 100644 --- a/mps/code/eventcnv.c +++ b/mps/code/eventcnv.c @@ -1,5 +1,5 @@ /* eventcnv.c: Simple event log converter - * 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 a command-line tool that converts a binary format telemetry output * stream from the MPS into a more-portable textual format. @@ -46,12 +46,6 @@ #include /* for strcmp */ #include "mpstd.h" -#ifdef MPS_BUILD_MV -/* MSVC warning 4996 = stdio / C runtime 'unsafe' */ -/* Objects to: strncpy, sscanf, fopen. See job001934. */ -#pragma warning( disable : 4996 ) -#endif - #define DEFAULT_TELEMETRY_FILENAME "mpsio.log" #define TELEMETRY_FILENAME_ENVAR "MPS_TELEMETRY_FILENAME" @@ -332,7 +326,7 @@ int main(int argc, char *argv[]) /* 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/eventsql.c b/mps/code/eventsql.c index 0fa36dea739..9215899273e 100644 --- a/mps/code/eventsql.c +++ b/mps/code/eventsql.c @@ -2,7 +2,7 @@ * * $Id$ * - * Copyright (c) 2012-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2012-2014 Ravenbrook Limited. See end of file for license. * * This is a command-line tool that imports events from a text-format * MPS telemetry file into a SQLite database file. @@ -86,9 +86,6 @@ #define DEFAULT_DATABASE_NAME "mpsevent.db" #ifdef MPS_BUILD_MV -/* MSVC warning 4996 = stdio / C runtime 'unsafe' */ -/* Objects to: getenv, sprintf. See job001934. */ -#pragma warning( disable : 4996 ) #define strtoll _strtoi64 #endif @@ -965,7 +962,7 @@ int main(int argc, char *argv[]) /* COPYRIGHT AND LICENSE * - * Copyright (c) 2012-2013 Ravenbrook Limited . + * Copyright (c) 2012-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/eventtxt.c b/mps/code/eventtxt.c index 3971d0e84da..68c37fa3de5 100644 --- a/mps/code/eventtxt.c +++ b/mps/code/eventtxt.c @@ -2,7 +2,7 @@ * * $Id$ * - * Copyright (c) 2012-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2012-2014 Ravenbrook Limited. See end of file for license. * * This is a command-line tool that converts events from a text-format * MPS telemetry file into a more human-readable format. @@ -39,12 +39,6 @@ #include #include -#ifdef MPS_BUILD_MV -/* MSVC warning 4996 = stdio / C runtime 'unsafe' */ -/* Objects to: strncpy, sscanf, fopen. See job001934. */ -#pragma warning( disable : 4996 ) -#endif - static const char *prog; /* program name */ static const char *logFileName = NULL; @@ -500,7 +494,7 @@ int main(int argc, char *argv[]) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2012-2013 Ravenbrook Limited . + * Copyright (C) 2012-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * diff --git a/mps/code/fmtdy.c b/mps/code/fmtdy.c index f622bfe128c..3d689519c65 100644 --- a/mps/code/fmtdy.c +++ b/mps/code/fmtdy.c @@ -1,7 +1,7 @@ /* fmtdy.c: DYLAN OBJECT FORMAT 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. * Portions copyright (c) 2002 Global Graphics Software. * * .readership: MPS developers, Dylan developers @@ -69,10 +69,6 @@ /* MPS_END causes "constant conditional" warnings. */ #pragma warning(disable: 4127) -/* windows.h causes warnings about "unreferenced inline function */ -/* has been removed". */ -#pragma warning(disable: 4514) - #endif /* _MSC_VER */ @@ -844,7 +840,7 @@ mps_res_t dylan_fmt_weak(mps_fmt_t *mps_fmt_o, mps_arena_t arena) /* 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/fmtdytst.c b/mps/code/fmtdytst.c index 790840f5491..376c43aa7df 100644 --- a/mps/code/fmtdytst.c +++ b/mps/code/fmtdytst.c @@ -1,7 +1,7 @@ /* fmtdytst.c: DYLAN FORMAT TEST CODE * * $Id$ - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * .readership: MPS developers, Dylan developers. */ @@ -17,12 +17,6 @@ #define unused(param) ((void)param) -#ifdef MPS_BUILD_MV -/* windows.h causes warnings about "unreferenced inline function */ -/* has been removed". */ -#pragma warning(disable: 4514) -#endif /* MPS_BUILD_MV */ - static mps_word_t *ww = NULL; static mps_word_t *tvw; @@ -222,7 +216,7 @@ mps_bool_t dylan_check(mps_addr_t 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/fmtno.c b/mps/code/fmtno.c index 6c632fef06b..05f84651bdf 100644 --- a/mps/code/fmtno.c +++ b/mps/code/fmtno.c @@ -1,7 +1,7 @@ /* fmtno.c: NULL OBJECT FORMAT 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. * * .readership: MPS developers */ @@ -17,22 +17,6 @@ #define notreached() assert(0) #define unused(param) ((void)param) -#ifdef MPS_BUILD_MV - -/* MSVC 2.0 generates a warning for unused(). */ -#ifdef _MSC_VER -#if _MSC_VER < 1000 -#pragma warning(disable: 4705) -#endif -#else /* _MSC_VER */ -#error "Expected _MSC_VER to be defined for builder.mv" -#endif /* _MSC_VER */ - -/* windows.h causes warnings about "unreferenced inline function */ -/* has been removed". */ -#pragma warning(disable: 4514) - -#endif /* MPS_BUILD_MV */ #define ALIGN sizeof(mps_word_t) @@ -137,7 +121,7 @@ mps_res_t no_fmt(mps_fmt_t *mps_fmt_o, mps_arena_t arena) /* 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/mpswin.h b/mps/code/mpswin.h index 99317fb790a..e2128f4e8a0 100644 --- a/mps/code/mpswin.h +++ b/mps/code/mpswin.h @@ -1,7 +1,7 @@ /* mpswin.h: RAVENBROOK MEMORY POOL SYSTEM WINDOWS.H 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. * * .readership: For MPS client application developers, MPS developers. * @@ -11,29 +11,14 @@ #ifndef mpswin_h #define mpswin_h -/* Suppress Visual C warnings from windows.h at warning level 4. */ -#ifdef MPS_BUILD_MV -#pragma warning(disable: 4115 4201 4209 4214) -#endif - #include -#ifdef MPS_BUILD_MV -#pragma warning(default: 4115 4201 4209 4214) -/* windows.h might also cause warnings about "unreferenced inline - * function has been removed". In Visual C, these can be turned off: - * #pragma warning(disable: 4514) - * But they are generated at the end of the compilation, so you have - * to turn them off permanently. - */ -#endif - #endif /* mpswin_h */ /* 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/testlib.c b/mps/code/testlib.c index 8ef14ca3c78..728e02b8d66 100644 --- a/mps/code/testlib.c +++ b/mps/code/testlib.c @@ -19,19 +19,6 @@ struct itimerspec; /* stop complaints from time.h */ #endif #include -#ifdef MPS_BUILD_MV -/* MSVC warning 4702 = unreachable code - * - * job000605: believed needed to prevent VC7 warning - * for error() below, in which va_end is mandated by - * ISO C (C99:7.15.1) even though it is unreachable. - */ -#pragma warning(disable: 4702) -/* MSVC warning 4996 = stdio / C runtime 'unsafe' */ -/* Objects to: sscanf. See job001934. */ -#pragma warning( disable : 4996 ) -#endif - /* fail -- like assert, but (notionally) returns a value, so usable in an expression */ diff --git a/mps/code/testlib.h b/mps/code/testlib.h index d36f26a275c..05ec5e260e5 100644 --- a/mps/code/testlib.h +++ b/mps/code/testlib.h @@ -23,49 +23,14 @@ /* Suppress Visual C warnings at warning level 4, */ -/* see mail.richard.1997-09-25.13-26. */ +/* see mail.richard.1997-09-25.13-26 and job003715. */ /* Essentially the same settings are done in config.h. */ #ifdef MPS_BUILD_MV -/* "unreferenced inline function has been removed" (windows.h) */ -#pragma warning(disable: 4514) - /* "constant conditional" (MPS_END) */ #pragma warning(disable: 4127) -/* MSVC 2.0 generates a warning when using NOCHECK or UNUSED */ -#ifdef _MSC_VER -#if _MSC_VER < 1000 -#pragma warning(disable: 4705) -#endif -#else /* _MSC_VER */ -#error "Expected _MSC_VER to be defined for builder.mv" -#endif /* _MSC_VER */ - - -/* MSVC 10.00 on PowerPC generates erroneous warnings about */ -/* uninitialized local variables, if you take their address. */ -#ifdef MPS_ARCH_PP -#pragma warning(disable: 4701) -#endif - - -/* Non-checking varieties give many spurious warnings because parameters - * are suddenly unused, etc. We aren't interested in these. - */ - -#if defined(AVER_AND_CHECK_NONE) - -/* "unreferenced formal parameter" */ -#pragma warning(disable: 4100) - -/* "unreferenced local function has been removed" */ -#pragma warning(disable: 4505) - -#endif - - #endif /* MPS_BUILD_MV */ diff --git a/mps/code/zcoll.c b/mps/code/zcoll.c index 639a323957a..d30e9fb5568 100644 --- a/mps/code/zcoll.c +++ b/mps/code/zcoll.c @@ -69,13 +69,6 @@ #include /* clock */ -#ifdef MPS_BUILD_MV -/* MSVC warning 4996 = stdio / C runtime 'unsafe' */ -/* Objects to: sscanf. See job001934. */ -#pragma warning( disable : 4996 ) -#endif - - /* testChain -- generation parameters for the test */ #define genCOUNT 2 static mps_gen_param_s testChain[genCOUNT] = { @@ -937,7 +930,7 @@ int main(int argc, char *argv[]) /* C. COPYRIGHT AND LICENSE * - * Copyright (c) 2001-2014 Ravenbrook Limited . + * Copyright (c) 2008-2014 Ravenbrook Limited . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. * From 56149eaf27139e3ba85f98c5476bb63d2bc0bdab Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 28 Mar 2014 14:27:21 +0000 Subject: [PATCH 20/65] Preserve the first table entry, so as to avoid false positives when this is kept alive by a register or stack-local variable. Copied from Perforce Change: 185077 ServerID: perforce.ravenbrook.com --- mps/code/awlut.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mps/code/awlut.c b/mps/code/awlut.c index 927d16add46..b8e14a0db7d 100644 --- a/mps/code/awlut.c +++ b/mps/code/awlut.c @@ -193,11 +193,12 @@ static void test(mps_arena_t arena, for(i = 0; i < TABLE_SLOTS; ++i) { mps_word_t *string; - /* Ensure that the last entry in the table is preserved, so that - * we don't get a false positive due to the local variable - * 'string' keeping this entry alive (see job003436). + /* Ensure that the first and last entries in the table are + * preserved, so that we don't get false positives due to the + * local variables 'weak_table' and 'string' keeping these entries + * alive (see job003436). */ - if (rnd() % 2 == 0 || i + 1 == TABLE_SLOTS) { + if (rnd() % 2 == 0 || i == 0 || i + 1 == TABLE_SLOTS) { string = alloc_string("iamalive", leafap); preserve[i] = string; } else { From 9ef67883992af9e1b4c2ad4eade34d6aa13210f8 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 28 Mar 2014 14:27:44 +0000 Subject: [PATCH 21/65] Avoid spurious output from rmdir. Copied from Perforce Change: 185078 ServerID: perforce.ravenbrook.com --- mps/tool/testrun.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/tool/testrun.bat b/mps/tool/testrun.bat index 7ac1db072a7..255ecf23e51 100755 --- a/mps/tool/testrun.bat +++ b/mps/tool/testrun.bat @@ -61,7 +61,7 @@ set FAIL_COUNT=0 set SEPARATOR=---------------------------------------- set LOGDIR=%TMP%\mps-%PFM%-%VARIETY%-log echo Logging test output to %LOGDIR% -rmdir /q /s %LOGDIR% 2> NUL +if exists %LOGDIR% rmdir /q /s %LOGDIR% mkdir %LOGDIR% if "%1"=="" call :run_tests %ALL_TEST_CASES% From 608720178ba66e7686ce75cea156e7380550aecc Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 29 Mar 2014 17:24:28 +0000 Subject: [PATCH 22/65] Fix header comment for ssw3i6*.c -- win64 not win32. Copied from Perforce Change: 185086 ServerID: perforce.ravenbrook.com --- mps/code/ssw3i6mv.c | 6 +++--- mps/code/ssw3i6pc.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mps/code/ssw3i6mv.c b/mps/code/ssw3i6mv.c index 807577a89a2..16c33e3fb74 100644 --- a/mps/code/ssw3i6mv.c +++ b/mps/code/ssw3i6mv.c @@ -1,7 +1,7 @@ -/* ssw3i6mv.c: STACK SCANNING FOR WIN32 WITH MICROSOFT C +/* ssw3i6mv.c: STACK SCANNING FOR WIN64 WITH MICROSOFT C * * $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 scans the stack and fixes the registers which may contain roots. * See . It's unlikely that the callee-save @@ -64,7 +64,7 @@ Res StackScan(ScanState ss, Addr *stackBot) /* 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/ssw3i6pc.c b/mps/code/ssw3i6pc.c index c58e88f846a..89fbbeac420 100644 --- a/mps/code/ssw3i6pc.c +++ b/mps/code/ssw3i6pc.c @@ -1,4 +1,4 @@ -/* ssw3i6pc.c: STACK SCANNING FOR WIN32 WITH PELLES C +/* ssw3i6pc.c: STACK SCANNING FOR WIN64 WITH PELLES C * * $Id$ * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. From f025b00534da55572e3252801e1ab66971020669 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 30 Mar 2014 14:26:02 +0100 Subject: [PATCH 23/65] Turn on -wunreachable-code for gcc and clang. Remove unreachable code: * No need to have different debug options or structured allocation classes for different platforms. * Don't use STATISTIC_BEGIN, use STATISTIC_STAT. * #ifdef away the unused code in zmess.c for testing ControlAlloc failure. * Remove unused code from the example Scheme interpreter. Copied from Perforce Change: 185089 ServerID: perforce.ravenbrook.com --- mps/code/apss.c | 18 ++----- mps/code/gc.gmk | 26 ++++++--- mps/code/ll.gmk | 27 +++++++--- mps/code/mpm.h | 7 --- mps/code/mpmss.c | 16 ++---- mps/code/mps.xcodeproj/project.pbxproj | 75 +++++++++++--------------- mps/code/poolamc.c | 24 ++++----- mps/code/sacss.c | 30 ++++------- mps/code/trace.c | 11 ++-- mps/code/zmess.c | 9 +++- mps/example/scheme/scheme-advanced.c | 4 -- mps/example/scheme/scheme-boehm.c | 6 +-- mps/example/scheme/scheme-malloc.c | 6 +-- mps/example/scheme/scheme.c | 4 -- 14 files changed, 115 insertions(+), 148 deletions(-) diff --git a/mps/code/apss.c b/mps/code/apss.c index 04818600510..6e4c7f3a71b 100644 --- a/mps/code/apss.c +++ b/mps/code/apss.c @@ -122,16 +122,9 @@ static size_t randomSizeAligned(size_t i) } -static mps_pool_debug_option_s bothOptions8 = { - /* .fence_template = */ (const void *)"postpost", - /* .fence_size = */ 8, - /* .free_template = */ (const void *)"DEAD", - /* .free_size = */ 4 -}; - -static mps_pool_debug_option_s bothOptions16 = { +static mps_pool_debug_option_s bothOptions = { /* .fence_template = */ (const void *)"postpostpostpost", - /* .fence_size = */ 16, + /* .fence_size = */ MPS_PF_ALIGN, /* .free_template = */ (const void *)"DEAD", /* .free_size = */ 4 }; @@ -181,9 +174,6 @@ static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options) int main(int argc, char *argv[]) { mps_arena_t arena; - mps_pool_debug_option_s *bothOptions; - - bothOptions = MPS_PF_ALIGN == 8 ? &bothOptions8 : &bothOptions16; testlib_init(argc, argv); @@ -200,7 +190,7 @@ int main(int argc, char *argv[]) die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); - testInArena(arena, bothOptions); + testInArena(arena, &bothOptions); mps_arena_destroy(arena); MPS_ARGS_BEGIN(args) { @@ -210,7 +200,7 @@ int main(int argc, char *argv[]) die(mps_arena_create_k(&arena, mps_arena_class_cl(), args), "mps_arena_create"); } MPS_ARGS_END(args); - testInArena(arena, bothOptions); + testInArena(arena, &bothOptions); mps_arena_destroy(arena); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); diff --git a/mps/code/gc.gmk b/mps/code/gc.gmk index 8ff258c9cf3..e6bd343f11b 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -3,7 +3,7 @@ # gc.gmk: GNUMAKEFILE FRAGMENT FOR GNU CC # # $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 file is included by platform makefiles that use the GNU CC # compiler. It defines the compiler-specific variables that the @@ -12,11 +12,23 @@ CC = gcc CFLAGSDEBUG = -O -g3 CFLAGSOPT = -O2 -g3 -CFLAGSCOMPILER := -Wall -Wextra -Werror -Wpointer-arith \ - -Wstrict-prototypes -Wmissing-prototypes \ - -Winline -Waggregate-return -Wnested-externs \ - -Wcast-qual -Wshadow -Wwrite-strings # -Wstrict-aliasing=2 -CFLAGSCOMPILERSTRICT := -ansi -pedantic -Wshadow +CFLAGSCOMPILER := \ + -pedantic \ + -Waggregate-return \ + -Wall \ + -Wcast-qual \ + -Werror \ + -Wextra \ + -Winline \ + -Wmissing-prototypes \ + -Wnested-externs \ + -Wpointer-arith \ + -Wshadow \ + -Wstrict-aliasing=2 \ + -Wstrict-prototypes \ + -Wunreachable-code \ + -Wwrite-strings +CFLAGSCOMPILERSTRICT := -ansi # A different set of compiler flags for less strict compilation, for # instance when we need to #include a third-party header file that @@ -38,7 +50,7 @@ endef # 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/ll.gmk b/mps/code/ll.gmk index fd91e62fe42..dc2595c511f 100644 --- a/mps/code/ll.gmk +++ b/mps/code/ll.gmk @@ -3,7 +3,7 @@ # ll.gmk: GNUMAKEFILE FRAGMENT FOR CLANG/LLVM # # $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 file is included by platform makefiles that use the Clang/LLVM # compiler. It defines the compiler-specific variables that the @@ -12,11 +12,24 @@ CC = clang CFLAGSDEBUG = -O -g3 CFLAGSOPT = -O2 -g3 -CFLAGSCOMPILER := -Wall -Werror -Wpointer-arith \ - -Wstrict-prototypes -Wmissing-prototypes \ - -Winline -Waggregate-return -Wnested-externs \ - -Wcast-qual -Wshadow # -Wstrict-aliasing=2 -CFLAGSCOMPILERSTRICT := -pedantic -Wno-extended-offsetof +CFLAGSCOMPILER := \ + -pedantic \ + -Waggregate-return \ + -Wall \ + -Wcast-qual \ + -Werror \ + -Wextra \ + -Winline \ + -Wmissing-prototypes \ + -Wnested-externs \ + -Wno-extended-offsetof \ + -Wpointer-arith \ + -Wshadow \ + -Wstrict-aliasing=2 \ + -Wstrict-prototypes \ + -Wunreachable-code \ + -Wwrite-strings +CFLAGSCOMPILERSTRICT := # A different set of compiler flags for less strict compilation, for # instance when we need to #include a third-party header file that @@ -38,7 +51,7 @@ endef # 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 46dcd74b880..da45d9aedd2 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -1008,9 +1008,6 @@ extern void StackProbe(Size depth); * STATISTIC_WRITE is inserted in WriteF arguments to output the values * of statistic fields. * - * STATISTIC_BEGIN and STATISTIC_END can be used around a block of - * statements. - * * .statistic.whitehot: The implementation of STATISTIC for * non-statistical varieties passes the parameter to DISCARD to ensure * the parameter is syntactically an expression. The parameter is @@ -1022,16 +1019,12 @@ extern void StackProbe(Size depth); #define STATISTIC(gather) BEGIN (gather); END #define STATISTIC_STAT(gather) BEGIN gather; END #define STATISTIC_WRITE(format, arg) (format), (arg), -#define STATISTIC_BEGIN BEGIN -#define STATISTIC_END END #elif defined(STATISTICS_NONE) #define STATISTIC(gather) DISCARD(((gather), 0)) #define STATISTIC_STAT DISCARD_STAT #define STATISTIC_WRITE(format, arg) -#define STATISTIC_BEGIN BEGIN if (0) { -#define STATISTIC_END } END #else /* !defined(STATISTICS) && !defined(STATISTICS_NONE) */ diff --git a/mps/code/mpmss.c b/mps/code/mpmss.c index 547f3d746b6..9dd25574417 100644 --- a/mps/code/mpmss.c +++ b/mps/code/mpmss.c @@ -125,16 +125,9 @@ static size_t fixedSize(size_t i) } -static mps_pool_debug_option_s bothOptions8 = { - /* .fence_template = */ (const void *)"postpost", - /* .fence_size = */ 8, - /* .free_template = */ (const void *)"DEAD", - /* .free_size = */ 4 -}; - -static mps_pool_debug_option_s bothOptions16 = { +static mps_pool_debug_option_s bothOptions = { /* .fence_template = */ (const void *)"postpostpostpost", - /* .fence_size = */ 16, + /* .fence_size = */ MPS_PF_ALIGN, /* .free_template = */ (const void *)"DEAD", /* .free_size = */ 4 }; @@ -177,15 +170,12 @@ static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options) int main(int argc, char *argv[]) { mps_arena_t arena; - mps_pool_debug_option_s *bothOptions; - - bothOptions = MPS_PF_ALIGN == 8 ? &bothOptions8 : &bothOptions16; testlib_init(argc, argv); die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "mps_arena_create"); - testInArena(arena, bothOptions); + testInArena(arena, &bothOptions); mps_arena_destroy(arena); die(mps_arena_create(&arena, mps_arena_class_vm(), smallArenaSIZE), diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj index d7865d3d4a6..d9ce4fdd401 100644 --- a/mps/code/mps.xcodeproj/project.pbxproj +++ b/mps/code/mps.xcodeproj/project.pbxproj @@ -4609,29 +4609,24 @@ GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ( - "-pedantic", - "-Wall", - "-Wextra", - "-Wwrite-strings", - "-Wno-extended-offsetof", - ); SDKROOT = macosx; SYMROOT = xc; WARNING_CFLAGS = ( "-pedantic", - "-Wpointer-arith", - "-Wstrict-prototypes", - "-Wmissing-prototypes", - "-Winline", "-Waggregate-return", - "-Wnested-externs", - "-Wcast-qual", - "-Wshadow", "-Wall", + "-Wcast-qual", "-Wextra", - "-Wwrite-strings", + "-Winline", + "-Wmissing-prototypes", + "-Wnested-externs", "-Wno-extended-offsetof", + "-Wpointer-arith", + "-Wshadow", + "-Wstrict-aliasing=2", + "-Wstrict-prototypes", + "-Wunreachable-code", + "-Wwrite-strings", ); }; name = RASH; @@ -5053,29 +5048,24 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.4; ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = ( - "-pedantic", - "-Wall", - "-Wextra", - "-Wwrite-strings", - "-Wno-extended-offsetof", - ); SDKROOT = macosx; SYMROOT = xc; WARNING_CFLAGS = ( "-pedantic", - "-Wpointer-arith", - "-Wstrict-prototypes", - "-Wmissing-prototypes", - "-Winline", "-Waggregate-return", - "-Wnested-externs", - "-Wcast-qual", - "-Wshadow", "-Wall", + "-Wcast-qual", "-Wextra", - "-Wwrite-strings", + "-Winline", + "-Wmissing-prototypes", + "-Wnested-externs", "-Wno-extended-offsetof", + "-Wpointer-arith", + "-Wshadow", + "-Wstrict-aliasing=2", + "-Wstrict-prototypes", + "-Wunreachable-code", + "-Wwrite-strings", ); }; name = Debug; @@ -5111,29 +5101,24 @@ GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ( - "-pedantic", - "-Wall", - "-Wextra", - "-Wwrite-strings", - "-Wno-extended-offsetof", - ); SDKROOT = macosx; SYMROOT = xc; WARNING_CFLAGS = ( "-pedantic", - "-Wpointer-arith", - "-Wstrict-prototypes", - "-Wmissing-prototypes", - "-Winline", "-Waggregate-return", - "-Wnested-externs", - "-Wcast-qual", - "-Wshadow", "-Wall", + "-Wcast-qual", "-Wextra", - "-Wwrite-strings", + "-Winline", + "-Wmissing-prototypes", + "-Wnested-externs", "-Wno-extended-offsetof", + "-Wpointer-arith", + "-Wshadow", + "-Wstrict-aliasing=2", + "-Wstrict-prototypes", + "-Wunreachable-code", + "-Wwrite-strings", ); }; name = Release; diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index d7d8e0cbfd1..4e479266b7d 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -2242,18 +2242,18 @@ static void AMCTraceEnd(Pool pool, Trace trace) ti = trace->ti; AVER(TraceIdCheck(ti)); - STATISTIC_BEGIN { - Count pRetMin = 100; - PageRetStruct *pr = &amc->pageretstruct[ti]; - if(pr->pRet >= pRetMin) { - EVENT21(AMCTraceEnd, ArenaEpoch(pool->arena), (EventFU)trace->why, - ArenaAlign(pool->arena), AMCLargeSegPAGES, pRetMin, pr->pCond, - pr->pRet, pr->pCS, pr->pRS, pr->sCM, pr->pCM, pr->sRM, pr->pRM, - pr->pRM1, pr->pRMrr, pr->pRMr1, pr->sCL, pr->pCL, pr->sRL, - pr->pRL, pr->pRLr); - } - *pr = pageretstruct_Zero; - } STATISTIC_END; + STATISTIC_STAT ({ + Count pRetMin = 100; + PageRetStruct *pr = &amc->pageretstruct[ti]; + if(pr->pRet >= pRetMin) { + EVENT21(AMCTraceEnd, ArenaEpoch(pool->arena), (EventFU)trace->why, + ArenaAlign(pool->arena), AMCLargeSegPAGES, pRetMin, pr->pCond, + pr->pRet, pr->pCS, pr->pRS, pr->sCM, pr->pCM, pr->sRM, pr->pRM, + pr->pRM1, pr->pRMrr, pr->pRMr1, pr->sCL, pr->pCL, pr->sRL, + pr->pRL, pr->pRLr); + } + *pr = pageretstruct_Zero; + }); } diff --git a/mps/code/sacss.c b/mps/code/sacss.c index bfb0725ed47..d2300de1898 100644 --- a/mps/code/sacss.c +++ b/mps/code/sacss.c @@ -140,41 +140,29 @@ static size_t randomSize8(size_t i) /* testInArena -- test all the pool classes in the given arena */ -static mps_pool_debug_option_s debugOptions8 = { - /* .fence_template = */ (const void *)"postpost", - /* .fence_size = */ 8, - /* .free_template = */ (const void *)"DEAD", - /* .free_size = */ 4 -}; - -static mps_pool_debug_option_s debugOptions16 = { +static mps_pool_debug_option_s debugOptions = { /* .fence_template = */ (const void *)"postpostpostpost", - /* .fence_size = */ 16, + /* .fence_size = */ MPS_PF_ALIGN, /* .free_template = */ (const void *)"DEAD", /* .free_size = */ 4 }; -static mps_sac_classes_s classes8[4] = { {8, 1, 1}, {16, 1, 2}, {136, 9, 5}, - {topClassSIZE, 9, 4} }; - -static mps_sac_classes_s classes16[4] = { {16, 1, 1}, {32, 1, 2}, {144, 9, 5}, - {topClassSIZE, 9, 4} }; +static mps_sac_classes_s classes[4] = { + {MPS_PF_ALIGN, 1, 1}, + {MPS_PF_ALIGN * 2, 1, 2}, + {128 + MPS_PF_ALIGN, 9, 5}, + {topClassSIZE, 9, 4} +}; static void testInArena(mps_arena_t arena) { - mps_pool_debug_option_s *debugOptions; - mps_sac_classes_s *classes; - - debugOptions = MPS_PF_ALIGN == 8 ? &debugOptions8 : &debugOptions16; - classes = MPS_PF_ALIGN == 8 ? classes8 : classes16; - printf("MVFF\n\n"); die(stress(mps_class_mvff(), classCOUNT, classes, randomSize8, arena, (size_t)65536, (size_t)32, (mps_align_t)MPS_PF_ALIGN, TRUE, TRUE, TRUE), "stress MVFF"); printf("MV debug\n\n"); die(stress(mps_class_mv_debug(), classCOUNT, classes, randomSize8, arena, - debugOptions, (size_t)65536, (size_t)32, (size_t)65536), + &debugOptions, (size_t)65536, (size_t)32, (size_t)65536), "stress MV debug"); printf("MV\n\n"); die(stress(mps_class_mv(), classCOUNT, classes, randomSize8, arena, diff --git a/mps/code/trace.c b/mps/code/trace.c index e77f93cd483..b394ed95e80 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1,7 +1,7 @@ /* trace.c: GENERIC TRACER IMPLEMENTATION * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. + * Copyright (c) 2001-2014 Ravenbrook Limited. * See end of file for license. * Portions copyright (C) 2002 Global Graphics Software. * @@ -1641,11 +1641,12 @@ Res TraceStart(Trace trace, double mortality, double finishingTime) } while (SegNext(&seg, arena, seg)); } - STATISTIC_BEGIN { + STATISTIC_STAT ({ /* @@ */ /* Iterate over all chains, all GenDescs within a chain, */ /* (and all PoolGens within a GenDesc). */ - Ring node, nextNode; + Ring node; + Ring nextNode; Index i; RING_FOR(node, &arena->chainRing, nextNode) { @@ -1658,7 +1659,7 @@ Res TraceStart(Trace trace, double mortality, double finishingTime) /* Now do topgen GenDesc (and all PoolGens within it). */ TraceStartPoolGen(NULL, &arena->topGen, TRUE, 0); - } STATISTIC_END; + }); res = RootsIterate(ArenaGlobals(arena), rootGrey, (void *)trace); AVER(res == ResOK); @@ -1900,7 +1901,7 @@ failStart: /* 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/zmess.c b/mps/code/zmess.c index 2b6d533dfde..a97c10ea8f1 100644 --- a/mps/code/zmess.c +++ b/mps/code/zmess.c @@ -442,6 +442,9 @@ static void testscriptA(const char *script) * * TIMCA_remote returns a Bool, true for let "ControlAlloc succeed". */ + +#ifdef TEST_CONTROLALLOC_FAILURE + static const char *TIMCA_str = ""; static int TIMCA_done = 0; static void TIMCA_setup(const char *string) @@ -481,6 +484,8 @@ Bool TIMCA_remote(void) return succeed; } +#endif /* TEST_CONTROLALLOC_FAILURE */ + /* main -- runs various test scripts * @@ -535,7 +540,8 @@ int main(int argc, char *argv[]) * * See . */ - if(0) { +#if TEST_CONTROLALLOC_FAILURE + { /* ArenaCreate unable to pre-allocate: THESE SHOULD FAIL */ /* manually edit if(0) -> if(1) to test these */ if(0) { @@ -562,6 +568,7 @@ int main(int argc, char *argv[]) TIMCA_setup(""); /* must reset it! */ } +#endif printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; diff --git a/mps/example/scheme/scheme-advanced.c b/mps/example/scheme/scheme-advanced.c index 22009cf2323..476b790f0a4 100644 --- a/mps/example/scheme/scheme-advanced.c +++ b/mps/example/scheme/scheme-advanced.c @@ -2011,8 +2011,6 @@ static obj_t entry_do(obj_t env, obj_t op_env, obj_t operator, obj_t operands) return result; } } - error("%s: unimplemented", operator->operator.name); - return obj_error; } @@ -4007,7 +4005,6 @@ static mps_res_t obj_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit) assert(0); fprintf(stderr, "Unexpected object on the heap\n"); abort(); - return MPS_RES_FAIL; } } } MPS_SCAN_END(ss); @@ -4078,7 +4075,6 @@ static mps_addr_t obj_skip(mps_addr_t base) assert(0); fprintf(stderr, "Unexpected object on the heap\n"); abort(); - return NULL; } return base; } diff --git a/mps/example/scheme/scheme-boehm.c b/mps/example/scheme/scheme-boehm.c index 839f1a56fd3..8d039433bb4 100644 --- a/mps/example/scheme/scheme-boehm.c +++ b/mps/example/scheme/scheme-boehm.c @@ -1,6 +1,6 @@ /* scheme.c -- SCHEME INTERPRETER EXAMPLE FOR THE MEMORY POOL SYSTEM * - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * TO DO * - unbounded integers, other number types. @@ -1728,8 +1728,6 @@ static obj_t entry_do(obj_t env, obj_t op_env, obj_t operator, obj_t operands) return result; } } - error("%s: unimplemented", operator->operator.name); - return obj_error; } @@ -3638,7 +3636,7 @@ int main(int argc, char *argv[]) /* 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/example/scheme/scheme-malloc.c b/mps/example/scheme/scheme-malloc.c index 799e7db66cf..1333ce73aef 100644 --- a/mps/example/scheme/scheme-malloc.c +++ b/mps/example/scheme/scheme-malloc.c @@ -1,6 +1,6 @@ /* scheme.c -- SCHEME INTERPRETER EXAMPLE FOR THE MEMORY POOL SYSTEM * - * Copyright (c) 2001-2013 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * TO DO * - unbounded integers, other number types. @@ -1728,8 +1728,6 @@ static obj_t entry_do(obj_t env, obj_t op_env, obj_t operator, obj_t operands) return result; } } - error("%s: unimplemented", operator->operator.name); - return obj_error; } @@ -3635,7 +3633,7 @@ int main(int argc, char *argv[]) /* 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/example/scheme/scheme.c b/mps/example/scheme/scheme.c index 4b2b36797c5..8a8dcf48ed7 100644 --- a/mps/example/scheme/scheme.c +++ b/mps/example/scheme/scheme.c @@ -2037,8 +2037,6 @@ static obj_t entry_do(obj_t env, obj_t op_env, obj_t operator, obj_t operands) return result; } } - error("%s: unimplemented", operator->operator.name); - return obj_error; } @@ -3994,7 +3992,6 @@ static mps_res_t obj_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit) assert(0); fprintf(stderr, "Unexpected object on the heap\n"); abort(); - return MPS_RES_FAIL; } } } MPS_SCAN_END(ss); @@ -4071,7 +4068,6 @@ static mps_addr_t obj_skip(mps_addr_t base) assert(0); fprintf(stderr, "Unexpected object on the heap\n"); abort(); - return NULL; } return base; } From d92687e06339f611c7e363532d3011c1042de58c Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 30 Mar 2014 17:00:50 +0100 Subject: [PATCH 24/65] Turn off -wunreachable-code in gcc: too many false positives. Copied from Perforce Change: 185091 ServerID: perforce.ravenbrook.com --- mps/code/gc.gmk | 1 - 1 file changed, 1 deletion(-) diff --git a/mps/code/gc.gmk b/mps/code/gc.gmk index e6bd343f11b..3b7f0e664b9 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -26,7 +26,6 @@ CFLAGSCOMPILER := \ -Wshadow \ -Wstrict-aliasing=2 \ -Wstrict-prototypes \ - -Wunreachable-code \ -Wwrite-strings CFLAGSCOMPILERSTRICT := -ansi From b2ec897e6bfae239ad016e9b33154a131b47987f Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 30 Mar 2014 18:51:53 +0100 Subject: [PATCH 25/65] Support the clang address sanitizer. Copied from Perforce Change: 185096 ServerID: perforce.ravenbrook.com --- mps/code/config.h | 21 +++++++++++++++------ mps/code/trace.c | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/mps/code/config.h b/mps/code/config.h index 6878d51b153..4ebed1a9d6d 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -203,19 +203,28 @@ /* Function attributes */ -/* These are also defined in testlib.h */ +/* Some of these are also defined in testlib.h */ -#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL) - -/* GCC: +/* Attribute for functions that take a printf-like format argument, so + * that the compiler can check the format specifiers against the types + * of the arguments. + * GCC: * Clang: */ +#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL) #define ATTRIBUTE_FORMAT(ARGLIST) __attribute__((__format__ ARGLIST)) - #else - #define ATTRIBUTE_FORMAT(ARGLIST) +#endif +/* Attribute for functions that should not be instrumented by Clang's + * address sanitizer. + * + */ +#if defined(MPS_BUILD_LL) && __has_feature(address_sanitizer) +#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((__no_sanitize_address__)) +#else +#define ATTRIBUTE_NO_SANITIZE_ADDRESS #endif diff --git a/mps/code/trace.c b/mps/code/trace.c index b394ed95e80..6fb666925b2 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1462,6 +1462,7 @@ Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit) * This is as TraceScanArea except words are only fixed if they are zero * when masked with a mask. */ +ATTRIBUTE_NO_SANITIZE_ADDRESS Res TraceScanAreaMasked(ScanState ss, Addr *base, Addr *limit, Word mask) { Res res; From 5edd5c5ef8046fa0de648e4e723d3d4121d77bb9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 31 Mar 2014 11:37:46 +0100 Subject: [PATCH 26/65] Bring .p4ignore up to date so that p4 status is clean. Copied from Perforce Change: 185101 ServerID: perforce.ravenbrook.com --- mps/.p4ignore | 2 ++ mps/code/.p4ignore | 1 + mps/manual/.p4ignore | 1 + 3 files changed, 4 insertions(+) diff --git a/mps/.p4ignore b/mps/.p4ignore index ba720759d8c..fb2e5c024e5 100644 --- a/mps/.p4ignore +++ b/mps/.p4ignore @@ -16,3 +16,5 @@ TAGS *.dSYM code/*/*/*.d *.pyc +test/test/log +test/test/obj diff --git a/mps/code/.p4ignore b/mps/code/.p4ignore index 7a9dfb599a8..dcda2b9ad09 100644 --- a/mps/code/.p4ignore +++ b/mps/code/.p4ignore @@ -9,6 +9,7 @@ lii6ll w3i3mv w3i6mv xci3gc +xci6ll # Visual Studio junk Debug Release diff --git a/mps/manual/.p4ignore b/mps/manual/.p4ignore index 3902ee8b103..ef6464692c9 100644 --- a/mps/manual/.p4ignore +++ b/mps/manual/.p4ignore @@ -1,2 +1,3 @@ doctrees converted +html From 9a523d0ccb578aaadedc75a4f9cff78c82ab53c4 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 31 Mar 2014 13:01:40 +0100 Subject: [PATCH 27/65] Fix compilation on lii6gc: * Don't test __has_feature unless we know we are on MPS_BUILD_LL. * Fix type-punned pointer aliasing in expt825.c. Copied from Perforce Change: 185104 ServerID: perforce.ravenbrook.com --- mps/code/config.h | 6 +++++- mps/code/expt825.c | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mps/code/config.h b/mps/code/config.h index 4ebed1a9d6d..f4cd43a54da 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -221,11 +221,15 @@ * address sanitizer. * */ -#if defined(MPS_BUILD_LL) && __has_feature(address_sanitizer) +#if defined(MPS_BUILD_LL) +#if __has_feature(address_sanitizer) #define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((__no_sanitize_address__)) #else #define ATTRIBUTE_NO_SANITIZE_ADDRESS #endif +#else +#define ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif /* EPVMDefaultSubsequentSegSIZE is a default for the alignment of diff --git a/mps/code/expt825.c b/mps/code/expt825.c index 459452bc722..5947a0cff68 100644 --- a/mps/code/expt825.c +++ b/mps/code/expt825.c @@ -86,7 +86,8 @@ static void register_numbered_tree(mps_word_t tree, mps_arena_t arena) { /* don't finalize ints */ if ((tree & 1) == 0) { - die(mps_finalize(arena, (mps_addr_t *)&tree), "mps_finalize"); + mps_addr_t addr = (void *)tree; + die(mps_finalize(arena, &addr), "mps_finalize"); register_numbered_tree(DYLAN_VECTOR_SLOT(tree, 0), arena); register_numbered_tree(DYLAN_VECTOR_SLOT(tree, 1), arena); } @@ -124,8 +125,8 @@ static void register_indirect_tree(mps_word_t tree, mps_arena_t arena) { /* don't finalize ints */ if ((tree & 1) == 0) { - mps_word_t indirect = DYLAN_VECTOR_SLOT(tree,2); - die(mps_finalize(arena, (mps_addr_t *)&indirect), "mps_finalize"); + mps_addr_t indirect = (void *)DYLAN_VECTOR_SLOT(tree,2); + die(mps_finalize(arena, &indirect), "mps_finalize"); register_indirect_tree(DYLAN_VECTOR_SLOT(tree, 0), arena); register_indirect_tree(DYLAN_VECTOR_SLOT(tree, 1), arena); } From 9ec2dfb001d9dbc8d448c49f93422cf2eb392056 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 31 Mar 2014 16:58:05 +0100 Subject: [PATCH 28/65] Fix typo: "if exists" should be "if exist". Copied from Perforce Change: 185108 ServerID: perforce.ravenbrook.com --- mps/tool/testrun.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/tool/testrun.bat b/mps/tool/testrun.bat index 255ecf23e51..e2b16a00260 100755 --- a/mps/tool/testrun.bat +++ b/mps/tool/testrun.bat @@ -61,7 +61,7 @@ set FAIL_COUNT=0 set SEPARATOR=---------------------------------------- set LOGDIR=%TMP%\mps-%PFM%-%VARIETY%-log echo Logging test output to %LOGDIR% -if exists %LOGDIR% rmdir /q /s %LOGDIR% +if exist %LOGDIR% rmdir /q /s %LOGDIR% mkdir %LOGDIR% if "%1"=="" call :run_tests %ALL_TEST_CASES% From d190a9221c3b9e78b9d8df0c5f07acab16f94669 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 31 Mar 2014 19:03:32 +0100 Subject: [PATCH 29/65] Fixed rb's review comments Copied from Perforce Change: 185111 ServerID: perforce.ravenbrook.com --- mps/code/bt.c | 14 +++++-- mps/code/nailboard.c | 91 +++++++++++++++++++++++++++++++--------- mps/code/nailboard.h | 7 ++++ mps/design/nailboard.txt | 5 ++- 4 files changed, 92 insertions(+), 25 deletions(-) diff --git a/mps/code/bt.c b/mps/code/bt.c index a58e501ee52..cc2db93ce2d 100644 --- a/mps/code/bt.c +++ b/mps/code/bt.c @@ -10,6 +10,12 @@ * DESIGN * * .design: see + * + * .aver.critical: The function BTIsResRange (and anything it calls) + * is on the critical path because it is + * called by NailboardIsResRange, which is called for every object in + * a nailboarded segment when the segment is scanned or reclaimed; see + * . */ #include "bt.h" @@ -90,7 +96,9 @@ SRCID(bt, "$Id$"); } else { \ Index actInnerBase = BTIndexAlignUp((base)); \ if (actInnerBase > (limit)) { /* no inner range */ \ - AVER((base) < (limit)); /* caught by small range case */ \ + /* Must have base < limit otherwise caught by small range case */ \ + /* And see .aver.critical. */ \ + AVER_CRITICAL((base) < (limit)); \ bits_action(BTWordIndex((base)), \ BTBitIndex((base)), \ BTBitIndex((limit))); \ @@ -311,8 +319,8 @@ void BTSetRange(BT t, Index base, Index limit) Bool BTIsResRange(BT bt, Index base, Index limit) { - AVER(BTCheck(bt)); - AVER(base < limit); + AVER_CRITICAL(BTCheck(bt)); /* See .aver.critical */ + AVER_CRITICAL(base < limit); /* Can't check range of base or limit */ #define SINGLE_IS_RES_RANGE(i) \ diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index 69adde5a6c3..39ebb843d05 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -13,22 +13,29 @@ SRCID(nailboard, "$Id$"); + +/* Log2 of scale factor between levels. See . */ #define LEVEL_SHIFT MPS_WORD_SHIFT + /* nailboardLevels -- return the number of levels in a nailboard with * the given number of nails. */ + static Count nailboardLevels(Count nails) { return SizeRoundUp(SizeFloorLog2(nails) + 1, LEVEL_SHIFT) / LEVEL_SHIFT; } + /* nailboardLevelBits -- return the number of bits in the bit table * for the given level. */ + static Count nailboardLevelBits(Nailboard board, Index level) { - /* Don't AVER(level < board->levels): see .check.levels */ + /* Use <= rather than < because of .check.levels. */ + AVER(level <= board->levels); return RangeSize(&board->range) >> (board->alignShift + level * LEVEL_SHIFT); } @@ -48,19 +55,23 @@ Bool NailboardCheck(Nailboard board) return TRUE; } + /* nailboardStructSize -- return the size of the nailboard structure, * plus the array of pointers to levels. */ + static Size nailboardStructSize(Count levels) { return offsetof(NailboardStruct, level) + sizeof(BT *) * levels; } + /* nailboardSize -- return the total size of the nailboard * * This is the size of the nailboard structure plus the combined sizes * of the bit tables. */ + static Size nailboardSize(Count nails, Count levels) { Index i; @@ -73,6 +84,7 @@ static Size nailboardSize(Count nails, Count levels) return size; } + /* NailboardCreate -- allocate a nailboard * * Allocate a nailboard in the control pool for arena, to cover the @@ -83,6 +95,7 @@ static Size nailboardSize(Count nails, Count levels) * alignment specifies the granularity of the nails: that is, the * number of bytes covered by each nail. */ + Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, Addr base, Addr limit) { @@ -111,21 +124,22 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, board->alignShift = SizeLog2(alignment); board->newNails = FALSE; - p = AddrAdd(p, nailboardStructSize(levels)); + p = (char *)p + nailboardStructSize(levels); for (i = 0; i < levels; ++i) { AVER(nails > 0); board->level[i] = p; BTResRange(board->level[i], 0, nails); - p = AddrAdd(p, BTSize(nails)); + p = (char *)p + BTSize(nails); nails >>= LEVEL_SHIFT; } - + board->sig = NailboardSig; AVERT(Nailboard, board); *boardReturn = board; return ResOK; } + /* NailboardDestroy -- destroy a nailboard */ void NailboardDestroy(Nailboard board, Arena arena) @@ -146,43 +160,51 @@ void NailboardDestroy(Nailboard board, Arena arena) void (NailboardClearNewNails)(Nailboard board) { AVERT(Nailboard, board); - board->newNails = FALSE; + NailboardClearNewNails(board); } + /* NailboardNewNails -- return the "new nails" flag * * Return TRUE if any new nails have been set in the nailboard since * the last call to NailboardClearNewNails (or since the nailboard was * created, if there have never been any such calls), FALSE otherwise. */ + Bool (NailboardNewNails)(Nailboard board) { AVERT(Nailboard, board); - return board->newNails; + return NailboardNewNails(board); } + /* nailboardIndex -- return the index of the nail corresponding to * addr in the given level. */ + static Index nailboardIndex(Nailboard board, Index level, Addr addr) { return AddrOffset(RangeBase(&board->range), addr) >> (board->alignShift + level * LEVEL_SHIFT); } + /* nailboardAddr -- return the address corresponding to the index in * the given level. */ + static Addr nailboardAddr(Nailboard board, Index level, Index index) { return AddrAdd(RangeBase(&board->range), index << (board->alignShift + level * LEVEL_SHIFT)); } + /* nailboardIndexRange -- update *ibaseReturn and *ilimitReturn to be * the indexes of the nail corresponding to base and limit * respectively, in the given level. See .impl.isresrange.alignment. */ + static void nailboardIndexRange(Index *ibaseReturn, Index *ilimitReturn, Nailboard board, Index level, Addr base, Addr limit) @@ -191,12 +213,14 @@ static void nailboardIndexRange(Index *ibaseReturn, Index *ilimitReturn, *ilimitReturn = nailboardIndex(board, level, AddrSub(limit, 1)) + 1; } + /* NailboardGet -- return nail corresponding to address * * Return the nail in the nailboard corresponding to the address addr. * It is an error if addr does not lie in the range of addresses * covered by the nailboard. */ + Bool NailboardGet(Nailboard board, Addr addr) { AVERT(Nailboard, board); @@ -204,12 +228,17 @@ Bool NailboardGet(Nailboard board, Addr addr) return BTGet(board->level[0], nailboardIndex(board, 0, addr)); } + /* NailboardSet -- set nail corresponding to address * * Set the nail in the nailboard corresponding to the address addr. * Return the old nail at that position. It is an error if addr does * not lie in the range of addresses covered by the nailboard. + * + * This function is on the critical path because it is called for + * every fix of an ambiguous reference to an address in an AMC pool. */ + Bool NailboardSet(Nailboard board, Addr addr) { Index i, j; @@ -232,12 +261,14 @@ Bool NailboardSet(Nailboard board, Addr addr) return FALSE; } + /* NailboardSetRange -- set all nails in range * * Set all nails in the nailboard corresponding to the range between * base and limit. It is an error if any part of the range is not * covered by the nailboard, or if any nail in the range is set. */ + void NailboardSetRange(Nailboard board, Addr base, Addr limit) { Index i, ibase, ilimit; @@ -250,14 +281,18 @@ void NailboardSetRange(Nailboard board, Addr base, Addr limit) } } + /* NailboardIsSetRange -- test if all nails are set in a range * * Return TRUE if all nails are set in the range between base and * limit, or FALSE if any nail is unset. It is an error if any part of * the range is not covered by the nailboard. * - * This function is not expected to be efficient. + * This function is not expected to be efficient because it is only + * used in an AVER in AMCWhiten to check that the unused part of the + * buffer for a nailboarded segment has in fact been nailed. */ + Bool NailboardIsSetRange(Nailboard board, Addr base, Addr limit) { Index ibase, ilimit; @@ -266,6 +301,7 @@ Bool NailboardIsSetRange(Nailboard board, Addr base, Addr limit) return BTIsSetRange(board->level[0], ibase, ilimit); } + /* NailboardIsResRange -- test if all nails are reset in a range * * Return TRUE if no nails are set in the range between base and @@ -276,8 +312,9 @@ Bool NailboardIsSetRange(Nailboard board, Addr base, Addr limit) * object in every nailed segment. It must take time that is no more * than logarithmic in the size of the range. * - * See . + * See . */ + Bool NailboardIsResRange(Nailboard board, Addr base, Addr limit) { Index i, ibase, ilimit; @@ -286,19 +323,32 @@ Bool NailboardIsResRange(Nailboard board, Addr base, Addr limit) AVERT_CRITICAL(Nailboard, board); - for (i = board->levels - 1;; --i) { + /* Descend levels until ibase and ilimit are two or more bits apart: + * that is, until there is an "inner" part to the range. */ + i = board->levels; + do { + -- i; nailboardIndexRange(&ibase, &ilimit, board, i, base, limit); if (BTIsResRange(board->level[i], ibase, ilimit)) - return TRUE; /* */ + /* The entire range was clear. This is expected to be the common + * case. */ + return TRUE; if (i == 0) - return FALSE; /* */ - if (ibase + 1 < ilimit - 1) { - if (BTIsResRange(board->level[i], ibase + 1, ilimit - 1)) - break; - else - return FALSE; /* */ - } - } + /* At level 0 there is only one nail per bit so the set bit is known + * to be within the range. */ + return FALSE; + } while (ibase + 1 >= ilimit - 1); + + /* At this point we know there is an "inner" part. Are there any + * bits set in it? */ + if (!BTIsResRange(board->level[i], ibase + 1, ilimit - 1)) + return FALSE; + + /* At this point we know that in level i, there is is a bit set at + * ibase or at ilimit - 1 (or both), and everything between them is + * reset. */ + AVER_CRITICAL(BTGet(board->level[i], ibase) + || BTGet(board->level[i], ilimit - 1)); /* Left splinter */ for (j = i, jbase = ibase;;) { @@ -308,7 +358,7 @@ Bool NailboardIsResRange(Nailboard board, Addr base, Addr limit) -- j; nailboardIndexRange(&jbase, &jlimit, board, j, base, leftLimit); if (jbase + 1 < jlimit && !BTIsResRange(board->level[j], jbase + 1, jlimit)) - return FALSE; /* */ + return FALSE; /* */ if (!BTGet(board->level[j], jbase)) break; if (j == 0) @@ -323,7 +373,7 @@ Bool NailboardIsResRange(Nailboard board, Addr base, Addr limit) -- j; nailboardIndexRange(&jbase, &jlimit, board, j, rightBase, limit); if (jbase < jlimit - 1 && !BTIsResRange(board->level[j], jbase, jlimit - 1)) - return FALSE; /* */ + return FALSE; /* */ if (!BTGet(board->level[j], jlimit - 1)) break; if (j == 0) @@ -333,6 +383,7 @@ Bool NailboardIsResRange(Nailboard board, Addr base, Addr limit) return TRUE; } + Res NailboardDescribe(Nailboard board, mps_lib_FILE *stream) { Index i, j; diff --git a/mps/code/nailboard.h b/mps/code/nailboard.h index 0763ef405c0..66141067f5f 100644 --- a/mps/code/nailboard.h +++ b/mps/code/nailboard.h @@ -14,6 +14,13 @@ typedef struct NailboardStruct *Nailboard; +/* NOTE: we could reduce the size of this structure using bitfields. + * levels can be at most MPS_WORD_WIDTH / LEVEL_SHIFT + 1, which is 11 + * on 64-bit, so it would fit in 4 bits. (Or it could be recalculated + * from range each time it's needed.) alignShift is at most + * MPS_WORD_SHIFT so would fit in 3 bits. (Or it could be supplied in + * each function call by the owner.) newNails would fit in 1 bit. + */ typedef struct NailboardStruct { Sig sig; RangeStruct range; /* range of addresses covered by nailboard */ diff --git a/mps/design/nailboard.txt b/mps/design/nailboard.txt index 8c8bca594af..498654d6890 100644 --- a/mps/design/nailboard.txt +++ b/mps/design/nailboard.txt @@ -80,7 +80,7 @@ corresponding word in the level *k*\−1 table is set). _`.impl.scale`: Here ``scale`` is an arbitrary scale factor that must be a power of 2. It could in future be supplied as a parameter when creating a nailboard, but in the current implementation it is always -:c:macro:`MPS_WORD_WIDTH`. +``MPS_WORD_WIDTH``. _`.impl.table.last`: The last bit table is one word long or shorter. @@ -113,7 +113,8 @@ it is reclaimed. _`.impl.isresrange.strategy`: The strategy for testing to see if any nails are set in a range is to handle the cases that are expected to be common first. In particular, we expect that there will only be few -nails in a nailboard, so most calls to :c:func:`NailboardIsResRange` will return ``TRUE``. +nails in a nailboard, so most calls to ``NailboardIsResRange()`` will +return ``TRUE``. _`.impl.isresrange.alignment`: When testing a range against a level of a nailboard, the base and limit of the range will typically not align From 5f2d39da6b09816d2f67a942397d6524dfbbd783 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 31 Mar 2014 19:14:53 +0100 Subject: [PATCH 30/65] Add release notes entry for nailboard improvement. Copied from Perforce Change: 185112 ServerID: perforce.ravenbrook.com --- mps/manual/source/release.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 3e6f650e146..0ff400cc154 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -3,6 +3,26 @@ Release notes ============= +.. _release-notes-1.114: + +Release 1.114.0 +--------------- + + +Other changes +............. + +#. Ambiguous :term:`interior pointers` now keep objects in + :ref:`pool-amc` and :ref:`pool-amcz` pools alive. This means that + if the compiler optimizes away a pointer to the base of an object, + leaving an interior pointer as the only reference keeping the + object alive, this does not cause the object to be incorrectly + collected. Or, if writing your own compiler, you can now perform + such an optimization. See job003359_. + + .. _job003359: https://www.ravenbrook.com/project/mps/issue/job003359/ + + .. _release-notes-1.113: Release 1.113.0 From 3bbde3766b30e4fd5f7c6007e146e2cf592d6694 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 12:11:06 +0100 Subject: [PATCH 31/65] Generate dependencies for fmtscheme.c. Copied from Perforce Change: 185120 ServerID: perforce.ravenbrook.com --- mps/code/comm.gmk | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk index ffef57e63fa..04e4a742f18 100644 --- a/mps/code/comm.gmk +++ b/mps/code/comm.gmk @@ -206,9 +206,11 @@ TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d) FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o) FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o) +FMTDYTSTDEP = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d) FMTHETSTOBJ = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.o) FMTHETSTDEP = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.d) -FMTSCMTSTOBJ = $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.o) +FMTSCMOBJ = $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.o) +FMTSCMDEP = $(FMTSCM:%.c=$(PFM)/$(VARIETY)/%.d) PLINTHOBJ = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.o) PLINTHDEP = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.d) EVENTPROCOBJ = $(EVENTPROC:%.c=$(PFM)/$(VARIETY)/%.o) @@ -372,7 +374,7 @@ $(PFM)/$(VARIETY)/abqtest: $(PFM)/$(VARIETY)/abqtest.o \ $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a $(PFM)/$(VARIETY)/airtest: $(PFM)/$(VARIETY)/airtest.o \ - $(FMTSCMTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a + $(FMTSCMOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a $(PFM)/$(VARIETY)/amcss: $(PFM)/$(VARIETY)/amcss.o \ $(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a @@ -567,9 +569,20 @@ include $(PFM)/$(VARIETY)/mps.d else # %%PART: When adding a new part, add the dependency file macro for the new # part here. -include $(MPMDEP) $(AMSDEP) $(AMCDEP) $(LODEP) \ - $(AWLDEP) $(POOLNDEP) $(TESTLIBDEP) $(FMTDYDEP) $(FMTHETSTDEP) \ - $(PLINTHDEP) $(EVENTPROCDEP) +include \ + $(MPMDEP) \ + $(AMCDEP) \ + $(AMSDEP) \ + $(AWLDEP) \ + $(EVENTPROCDEP) \ + $(FMTDYDEP) \ + $(FMTDYTSTDEP) \ + $(FMTHETSTDEP) \ + $(FMTSCMDEP) \ + $(LODEP) \ + $(PLINTHDEP) \ + $(POOLNDEP) \ + $(TESTLIBDEP) endif endif From 4ee6bdd356c31f3e434eee701b47053113da04fc Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 13:32:42 +0100 Subject: [PATCH 32/65] Explain why the last level in the nailboard might be tiny (to avoid special cases for small nailboards). Copied from Perforce Change: 185122 ServerID: perforce.ravenbrook.com --- mps/code/nailboard.c | 2 ++ mps/design/nailboard.txt | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index 39ebb843d05..ce628093dfe 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -20,6 +20,8 @@ SRCID(nailboard, "$Id$"); /* nailboardLevels -- return the number of levels in a nailboard with * the given number of nails. + * + * See */ static Count nailboardLevels(Count nails) diff --git a/mps/design/nailboard.txt b/mps/design/nailboard.txt index 498654d6890..5e22f774121 100644 --- a/mps/design/nailboard.txt +++ b/mps/design/nailboard.txt @@ -82,7 +82,12 @@ be a power of 2. It could in future be supplied as a parameter when creating a nailboard, but in the current implementation it is always ``MPS_WORD_WIDTH``. -_`.impl.table.last`: The last bit table is one word long or shorter. +_`.impl.table.last`: The last bit table is always shorter than one +word. This is slightly wasteful in some cases (for example, a +nailboard with 64 nails and ``scale`` 64 will have two levels, the +second level having just one bit), but allows the code to support +small nailboards without special cases in the code (consider the case +of a nailboard with just one nail). _`.impl.size`: The size of the level *i* bit table is the ceiling of From 1fc2bbe52b0b90af9b6a7d43606015f309ffc961 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 17:02:00 +0100 Subject: [PATCH 33/65] Fixed dl's review comments . Copied from Perforce Change: 185127 ServerID: perforce.ravenbrook.com --- mps/code/airtest.c | 95 +++++++++++++++++++++++++++-- mps/code/config.h | 25 ++++---- mps/code/fmtscheme.c | 68 --------------------- mps/code/fmtscheme.h | 3 +- mps/code/mps.h | 3 + mps/code/nailboard.c | 16 +++-- mps/code/nailboardtest.c | 4 +- mps/code/pool.c | 1 + mps/code/poolamc.c | 67 +++++++++++++------- mps/design/nailboard.txt | 17 +++++- mps/manual/source/pool/amc.rst | 8 ++- mps/manual/source/release.rst | 24 +++++--- mps/manual/source/topic/keyword.rst | 1 + mps/tool/testrun.sh | 1 + 14 files changed, 202 insertions(+), 131 deletions(-) diff --git a/mps/code/airtest.c b/mps/code/airtest.c index 4d4219f7f5c..a5d289f6aeb 100644 --- a/mps/code/airtest.c +++ b/mps/code/airtest.c @@ -10,17 +10,24 @@ * * If any of these objects are finalized, then this means that the * ambiguous interior references has failed to keep the object alive. + * + * The test is then repeated with MPS_KEY_INTERIOR=FALSE; in this case + * we expect most of the vectors to be finalized. */ #include "mps.h" -#include "fmtscheme.h" +#include "mpsavm.h" +#include "mpscamc.h" +#include "mpslib.h" #include "testlib.h" +#include "fmtscheme.h" #define OBJ_LEN (1u << 4) #define OBJ_COUNT 10 -void test_main(void) +static void test_air(int interior) { + size_t n_finalized = 0; size_t i, j; obj_t *s[OBJ_COUNT]; mps_message_type_enable(scheme_arena, mps_message_type_finalization()); @@ -41,12 +48,89 @@ void test_main(void) mps_arena_release(scheme_arena); if (mps_message_get(&msg, scheme_arena, mps_message_type_finalization())) { mps_addr_t ref; - obj_t o; mps_message_finalization_ref(&ref, scheme_arena, msg); - o = ref; - error("wrongly finalized vector %ld at %p", o->vector.vector[0]->integer.integer, o); + ++ n_finalized; + if (interior) { + obj_t o; + o = ref; + error("wrongly finalized vector %ld at %p", o->vector.vector[0]->integer.integer, o); + } } } + if (!interior && n_finalized + 1 < OBJ_COUNT) { + error("only finalized %"PRIuLONGEST" out of %"PRIuLONGEST" vectors.", + (ulongest_t)n_finalized, (ulongest_t)OBJ_COUNT); + } +} + +static mps_gen_param_s obj_gen_params[] = { + { 150, 0.85 }, + { 170, 0.45 } +}; + +static void test_main(int interior) +{ + mps_res_t res; + mps_chain_t obj_chain; + mps_fmt_t obj_fmt; + mps_thr_t thread; + mps_root_t reg_root; + void *marker = ▮ + + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 1 << 20); + MPS_ARGS_DONE(args); + res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), args); + } MPS_ARGS_END(args); + if (res != MPS_RES_OK) error("Couldn't create arena"); + + res = mps_chain_create(&obj_chain, scheme_arena, + sizeof(obj_gen_params) / sizeof(*obj_gen_params), + obj_gen_params); + if (res != MPS_RES_OK) error("Couldn't create obj chain"); + + scheme_fmt(&obj_fmt); + + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, obj_chain); + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, obj_fmt); + MPS_ARGS_ADD(args, MPS_KEY_INTERIOR, interior); + MPS_ARGS_DONE(args); + die(mps_pool_create_k(&obj_pool, scheme_arena, mps_class_amc(), args), + "mps_pool_create_k"); + } MPS_ARGS_END(args); + + res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none); + if (res != MPS_RES_OK) error("Couldn't create obj allocation point"); + + res = mps_thread_reg(&thread, scheme_arena); + if (res != MPS_RES_OK) error("Couldn't register thread"); + + res = mps_root_create_reg(®_root, scheme_arena, mps_rank_ambig(), 0, + thread, mps_stack_scan_ambig, marker, 0); + if (res != MPS_RES_OK) error("Couldn't create root"); + + test_air(interior); + + mps_arena_park(scheme_arena); + mps_root_destroy(reg_root); + mps_thread_dereg(thread); + mps_ap_destroy(obj_ap); + mps_pool_destroy(obj_pool); + mps_chain_destroy(obj_chain); + mps_fmt_destroy(obj_fmt); + mps_arena_destroy(scheme_arena); +} + +int main(int argc, char *argv[]) +{ + testlib_init(argc, argv); + + test_main(TRUE); + test_main(FALSE); + + printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); + return 0; } @@ -90,4 +174,3 @@ void test_main(void) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - diff --git a/mps/code/config.h b/mps/code/config.h index f4cd43a54da..e29127c153c 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -262,6 +262,13 @@ #define FMT_CLASS_DEFAULT (&FormatDefaultClass) +/* Pool AMC Configuration -- see */ + +#define AMC_INTERIOR_DEFAULT TRUE +/* AMC treats segments of this many pages (or more) as "Large" */ +#define AMCLargeSegPAGES ((Count)8) + + /* Pool AMS Configuration -- see */ #define AMS_SUPPORT_AMBIGUOUS_DEFAULT FALSE @@ -271,6 +278,10 @@ /* Pool AWL Configuration -- see */ #define AWL_GEN_DEFAULT 0 +#define AWL_HAVE_SEG_SA_LIMIT TRUE +#define AWL_SEG_SA_LIMIT 200 /* TODO: Improve guesswork with measurements */ +#define AWL_HAVE_TOTAL_SA_LIMIT FALSE +#define AWL_TOTAL_SA_LIMIT 0 /* Pool LO Configuration -- see */ @@ -534,20 +545,6 @@ #define ARENA_INIT_SPARE_COMMIT_LIMIT ((Size)10uL*1024uL*1024uL) -/* Pool Class AMC configuration */ - -/* AMC treats segments of this many pages (or more) as "Large" */ -#define AMCLargeSegPAGES ((Count)8) - - -/* Pool Class AWL configuration -- see poolawl.c for usage */ - -#define AWL_HAVE_SEG_SA_LIMIT TRUE -#define AWL_SEG_SA_LIMIT 200 /* TODO: Improve guesswork with measurements */ -#define AWL_HAVE_TOTAL_SA_LIMIT FALSE -#define AWL_TOTAL_SA_LIMIT 0 - - /* Default chain for GC pools * * TODO: The default should be to measure liveness and make sensible diff --git a/mps/code/fmtscheme.c b/mps/code/fmtscheme.c index 97c76483402..04a29a061fd 100644 --- a/mps/code/fmtscheme.c +++ b/mps/code/fmtscheme.c @@ -6,10 +6,6 @@ #include -#include "mpsavm.h" -#include "mpscamc.h" -#include "mpslib.h" - #include "fmtscheme.h" #include "testlib.h" @@ -467,70 +463,6 @@ void scheme_fmt(mps_fmt_t *fmt) if (res != MPS_RES_OK) error("Couldn't create obj format"); } -static mps_gen_param_s obj_gen_params[] = { - { 150, 0.85 }, - { 170, 0.45 } -}; - -int main(int argc, char *argv[]) -{ - mps_res_t res; - mps_chain_t obj_chain; - mps_fmt_t obj_fmt; - mps_thr_t thread; - mps_root_t reg_root; - void *marker = ▮ - - randomize(argc, argv); - mps_lib_assert_fail_install(assert_die); - - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 1 << 20); - MPS_ARGS_DONE(args); - res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), args); - } MPS_ARGS_END(args); - if (res != MPS_RES_OK) error("Couldn't create arena"); - - res = mps_chain_create(&obj_chain, scheme_arena, - sizeof(obj_gen_params) / sizeof(*obj_gen_params), - obj_gen_params); - if (res != MPS_RES_OK) error("Couldn't create obj chain"); - - scheme_fmt(&obj_fmt); - - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, obj_chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, obj_fmt); - MPS_ARGS_DONE(args); - die(mps_pool_create_k(&obj_pool, scheme_arena, mps_class_amc(), args), - "mps_pool_create_k"); - } MPS_ARGS_END(args); - - res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none); - if (res != MPS_RES_OK) error("Couldn't create obj allocation point"); - - res = mps_thread_reg(&thread, scheme_arena); - if (res != MPS_RES_OK) error("Couldn't register thread"); - - res = mps_root_create_reg(®_root, scheme_arena, mps_rank_ambig(), 0, - thread, mps_stack_scan_ambig, marker, 0); - if (res != MPS_RES_OK) error("Couldn't create root"); - - test_main(); - - mps_arena_park(scheme_arena); - mps_root_destroy(reg_root); - mps_thread_dereg(thread); - mps_ap_destroy(obj_ap); - mps_pool_destroy(obj_pool); - mps_chain_destroy(obj_chain); - mps_fmt_destroy(obj_fmt); - mps_arena_destroy(scheme_arena); - - printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); - return 0; -} - /* C. COPYRIGHT AND LICENSE * diff --git a/mps/code/fmtscheme.h b/mps/code/fmtscheme.h index 6b2f10f202d..fbbbddf8ccd 100644 --- a/mps/code/fmtscheme.h +++ b/mps/code/fmtscheme.h @@ -183,7 +183,8 @@ extern obj_t scheme_make_table(size_t length, hash_t hashf, cmp_t cmpf); extern void scheme_fmt(mps_fmt_t *fmt); extern mps_arena_t scheme_arena; -extern void test_main(void); +extern mps_pool_t obj_pool; +extern mps_ap_t obj_ap; #endif /* fmtscheme_h */ diff --git a/mps/code/mps.h b/mps/code/mps.h index 299684b781e..b948a5f8d7d 100644 --- a/mps/code/mps.h +++ b/mps/code/mps.h @@ -191,6 +191,9 @@ extern const struct mps_key_s _mps_key_align; extern const struct mps_key_s _mps_key_cbs_extend_by; #define MPS_KEY_CBS_EXTEND_BY (&_mps_key_cbs_extend_by) #define MPS_KEY_CBS_EXTEND_BY_FIELD size +extern const struct mps_key_s _mps_key_interior; +#define MPS_KEY_INTERIOR (&_mps_key_interior) +#define MPS_KEY_INTERIOR_FIELD b extern const struct mps_key_s _mps_key_vmw3_top_down; #define MPS_KEY_VMW3_TOP_DOWN (&_mps_key_vmw3_top_down) diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index ce628093dfe..e6ca658f1a1 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -103,6 +103,7 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, { void *p; Nailboard board; + Shift alignShift; Count nails, levels; Index i; Res res; @@ -114,7 +115,8 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, AVER(AddrIsAligned(base, alignment)); AVER(AddrIsAligned(limit, alignment)); - nails = AddrOffset(base, limit) / alignment; + alignShift = SizeLog2((Size)alignment); + nails = AddrOffset(base, limit) >> alignShift; levels = nailboardLevels(nails); res = ControlAlloc(&p, arena, nailboardSize(nails, levels), FALSE); if (res != ResOK) @@ -123,7 +125,7 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, board = p; RangeInit(&board->range, base, limit); board->levels = levels; - board->alignShift = SizeLog2(alignment); + board->alignShift = alignShift; board->newNails = FALSE; p = (char *)p + nailboardStructSize(levels); @@ -146,17 +148,20 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, void NailboardDestroy(Nailboard board, Arena arena) { + Count nails; Size size; AVERT(Nailboard, board); AVERT(Arena, arena); - size = nailboardSize(nailboardLevelBits(board, 0), board->levels); + nails = nailboardLevelBits(board, 0); + size = nailboardSize(nails, board->levels); board->sig = SigInvalid; ControlFree(arena, board, size); } + /* NailboardClearNewNails -- clear the "new nails" flag */ void (NailboardClearNewNails)(Nailboard board) @@ -203,8 +208,9 @@ static Addr nailboardAddr(Nailboard board, Index level, Index index) /* nailboardIndexRange -- update *ibaseReturn and *ilimitReturn to be - * the indexes of the nail corresponding to base and limit - * respectively, in the given level. See .impl.isresrange.alignment. + * the interval of indexes of nails in the given level, corresponding + * to the interval of addresses base and limit. See + * . */ static void nailboardIndexRange(Index *ibaseReturn, Index *ilimitReturn, diff --git a/mps/code/nailboardtest.c b/mps/code/nailboardtest.c index c2baaad210f..a78ba4b3b9e 100644 --- a/mps/code/nailboardtest.c +++ b/mps/code/nailboardtest.c @@ -53,8 +53,8 @@ int main(int argc, char **argv) { mps_arena_t arena; - randomize(argc, argv); - mps_lib_assert_fail_install(assert_die); + testlib_init(argc, argv); + die(mps_arena_create(&arena, mps_arena_class_vm(), 1024 * 1024), "mps_arena_create"); diff --git a/mps/code/pool.c b/mps/code/pool.c index 0524d69525c..90b9955f01a 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -118,6 +118,7 @@ ARG_DEFINE_KEY(min_size, Size); ARG_DEFINE_KEY(mean_size, Size); ARG_DEFINE_KEY(max_size, Size); ARG_DEFINE_KEY(align, Align); +ARG_DEFINE_KEY(interior, Bool); /* PoolInit -- initialize a pool diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index e9ed4ce7d67..681d201ed2e 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -21,6 +21,10 @@ typedef struct AMCStruct *AMC; /* amcGen typedef */ typedef struct amcGenStruct *amcGen; +/* Function returning TRUE if block in nailboarded segment is pinned. */ +typedef Bool (*amcPinnedMethod)(AMC amc, Nailboard board, Addr base, Addr limit); + + /* forward declarations */ static Bool amcSegHasNailboard(Seg seg); @@ -456,6 +460,7 @@ typedef struct AMCStruct { /* */ amcGen afterRampGen; /* the generation after rampGen */ unsigned rampCount; /* */ int rampMode; /* */ + amcPinnedMethod pinned; /* function determining if block is pinned */ /* page retention in an in-progress trace */ STATISTIC_DECL(PageRetStruct pageretstruct[TraceLIMIT]); @@ -742,6 +747,26 @@ static Res amcSegCreateNailboard(Seg seg, Pool pool) } +/* amcPinnedInterior -- block is pinned by any nail */ + +static Bool amcPinnedInterior(AMC amc, Nailboard board, Addr base, Addr limit) +{ + Size headerSize = AMC2Pool(amc)->format->headerSize; + return !NailboardIsResRange(board, AddrSub(base, headerSize), + AddrSub(limit, headerSize)); +} + + +/* amcPinnedBase -- block is pinned only if base is nailed */ + +static Bool amcPinnedBase(AMC amc, Nailboard board, Addr base, Addr limit) +{ + UNUSED(amc); + UNUSED(limit); + return NailboardGet(board, base); +} + + /* amcVarargs -- decode obsolete varargs */ static void AMCVarargs(ArgStruct args[MPS_ARGS_MAX], va_list varargs) @@ -770,6 +795,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) Index i; size_t genArraySize; size_t genCount; + Bool interior = AMC_INTERIOR_DEFAULT; ArgStruct arg; /* Suppress a warning about this structure not being used when there @@ -793,6 +819,8 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) amc->chain = arg.val.chain; else amc->chain = ArenaGlobals(arena)->defaultChain; + if (ArgPick(&arg, args, MPS_KEY_INTERIOR)) + interior = arg.val.b; AVERT(Format, pool->format); AVERT(Chain, amc->chain); @@ -821,6 +849,12 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) pool->fix = AMCHeaderFix; } + if (interior) { + amc->pinned = amcPinnedInterior; + } else { + amc->pinned = amcPinnedBase; + } + amc->sig = AMCSig; AVERT(AMC, amc); @@ -1278,29 +1312,18 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg) } -/* amcNailboardIsResClientRange -- wrapper for NailboardIsResRange, - * except that the addresses are client addresses for objects with the - * given header size. - */ -static Bool amcNailboardIsResClientRange(Nailboard board, Size headerSize, - Addr base, Addr limit) -{ - return NailboardIsResRange(board, AddrSub(base, headerSize), - AddrSub(limit, headerSize)); -} - - /* amcScanNailedRange -- make one scanning pass over a range of * addresses in a nailed segment. */ static Res amcScanNailedRange(Bool *totalReturn, Bool *moreReturn, Size *bytesScanned, ScanState ss, - Pool pool, Nailboard board, + AMC amc, Nailboard board, Addr base, Addr limit) { Format format; Size headerSize; Addr p, clientLimit; + Pool pool = AMC2Pool(amc); format = pool->format; headerSize = format->headerSize; p = AddrAdd(base, headerSize); @@ -1308,7 +1331,7 @@ static Res amcScanNailedRange(Bool *totalReturn, Bool *moreReturn, while (p < clientLimit) { Addr q; q = (*format->skip)(p); - if (!amcNailboardIsResClientRange(board, headerSize, p, q)) { + if ((*amc->pinned)(amc, board, p, q)) { Res res; res = (*format->scan)(&ss->ss_s, p, q); if(res != ResOK) { @@ -1338,7 +1361,7 @@ static Res amcScanNailedRange(Bool *totalReturn, Bool *moreReturn, * nailboard. */ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn, - ScanState ss, Pool pool, Seg seg, AMC amc) + ScanState ss, Seg seg, AMC amc) { Addr p, limit; Size bytesScanned = 0; @@ -1359,7 +1382,7 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn, goto returnGood; } res = amcScanNailedRange(totalReturn, moreReturn, &bytesScanned, - ss, pool, board, p, limit); + ss, amc, board, p, limit); if (res != ResOK) return res; p = limit; @@ -1368,7 +1391,7 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn, limit = SegLimit(seg); /* @@@@ Shouldn't p be set to BufferLimit here?! */ res = amcScanNailedRange(totalReturn, moreReturn, &bytesScanned, - ss, pool, board, p, limit); + ss, amc, board, p, limit); if (res != ResOK) return res; @@ -1392,7 +1415,7 @@ static Res amcScanNailed(Bool *totalReturn, ScanState ss, Pool pool, do { Res res; - res = amcScanNailedOnce(&total, &moreScanning, ss, pool, seg, amc); + res = amcScanNailedOnce(&total, &moreScanning, ss, seg, amc); if(res != ResOK) { *totalReturn = FALSE; return res; @@ -1653,7 +1676,7 @@ static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) /* If object is nailed already then we mustn't copy it: */ if (SegNailed(seg) != TraceSetEMPTY && !(amcSegHasNailboard(seg) - && NailboardIsResRange(amcSegNailboard(seg), ref, clientQ))) + && !(*amc->pinned)(amc, amcSegNailboard(seg), ref, clientQ))) { /* Segment only needs greying if there are new traces for */ /* which we are nailing. */ @@ -1800,8 +1823,7 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) /* If object is nailed already then we mustn't copy it: */ if (SegNailed(seg) != TraceSetEMPTY && !(amcSegHasNailboard(seg) - && amcNailboardIsResClientRange(amcSegNailboard(seg), - headerSize, ref, clientQ))) + && !(*amc->pinned)(amc, amcSegNailboard(seg), ref, clientQ))) { /* Segment only needs greying if there are new traces for */ /* which we are nailing. */ @@ -1917,8 +1939,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg) q = AddrSub(clientQ, headerSize); length = AddrOffset(p, q); if(amcSegHasNailboard(seg)) { - preserve = !amcNailboardIsResClientRange(amcSegNailboard(seg), headerSize, - clientP, clientQ); + preserve = (*amc->pinned)(amc, amcSegNailboard(seg), clientP, clientQ); } else { /* There's no nailboard, so preserve everything that hasn't been * forwarded. In this case, preservedInPlace* become somewhat diff --git a/mps/design/nailboard.txt b/mps/design/nailboard.txt index 5e22f774121..0bb39fdfa9c 100644 --- a/mps/design/nailboard.txt +++ b/mps/design/nailboard.txt @@ -6,7 +6,7 @@ Nailboards for ambiguously referenced segments :Tag: design.mps.nailboard :Author: Gareth Rees :Date: 2014-01-15 -:Status: incomplete design +:Status: complete design :Revision: $Id$ :Copyright: See section `Copyright and License`_. :Index terms: pair: nailboard; design @@ -176,6 +176,21 @@ one-sided: that is, we don't need to look at the right splinter of a left splinter or vice versa, because we know that it is empty. +Future +------ + +_`.future.tune`: The implementation makes heavy use of +``BTIsResRange``, but this function is not well tuned for scanning +small arrays (which we expect to be the common case for nailboards). +Performance might be improved by special-casing the small levels. + +_`.future.limit`: In C and C++, a pointer to the address beyond the +end of an object (the limit of the object in our terminalogy) is a +valid pointer. There might be users that require nailboards to support +these limit pointers, so that they can be recorded in the nailboard, +and so that they retain objects. + + Document History ---------------- diff --git a/mps/manual/source/pool/amc.rst b/mps/manual/source/pool/amc.rst index 37d03f263eb..4f326b9f78f 100644 --- a/mps/manual/source/pool/amc.rst +++ b/mps/manual/source/pool/amc.rst @@ -113,12 +113,18 @@ AMC interface method`, a :term:`forward method`, an :term:`is-forwarded method` and a :term:`padding method`. - It accepts one optional keyword argument: + It accepts two optional keyword arguments: * :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies the :term:`generation chain` for the pool. If not specified, the pool will use the arena's default chain. + * :c:macro:`MPS_KEY_INTERIOR` (type :c:type:`mps_bool_t`, default + ``TRUE``) specifies whether :term:`ambiguous ` :term:`interior pointers` to blocks in the pool keep + objects alive. If this is ``FALSE``, then only :term:`client + pointers` keep objects alive. + For example:: MPS_ARGS_BEGIN(args) { diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 0ff400cc154..ad9bbae930c 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -8,19 +8,23 @@ Release notes Release 1.114.0 --------------- +New features +............ -Other changes -............. +#. :term:`Ambiguous ` :term:`interior pointers` + now keep objects in :ref:`pool-amc` and :ref:`pool-amcz` pools + alive. -#. Ambiguous :term:`interior pointers` now keep objects in - :ref:`pool-amc` and :ref:`pool-amcz` pools alive. This means that - if the compiler optimizes away a pointer to the base of an object, - leaving an interior pointer as the only reference keeping the - object alive, this does not cause the object to be incorrectly - collected. Or, if writing your own compiler, you can now perform - such an optimization. See job003359_. + This means that if the compiler optimizes away a pointer to the + base of an object, leaving an interior pointer as the only + reference keeping the object alive, this does not cause the object + to be incorrectly collected. Or, if you are writing your own + compiler, you can now perform such an optimization safely. - .. _job003359: https://www.ravenbrook.com/project/mps/issue/job003359/ + If you require the old behaviour (in which ambiguous interior + pointers were ignored) then you can set the + :c:macro:`MPS_KEY_INTERIOR` keyword argument to ``FALSE`` when + calling :c:func:`mps_pool_create_k`. .. _release-notes-1.113: diff --git a/mps/manual/source/topic/keyword.rst b/mps/manual/source/topic/keyword.rst index 5f804a63847..665daa91e64 100644 --- a/mps/manual/source/topic/keyword.rst +++ b/mps/manual/source/topic/keyword.rst @@ -104,6 +104,7 @@ now :c:macro:`MPS_KEY_ARGS_END`. :c:macro:`MPS_KEY_FMT_SKIP` :c:type:`mps_fmt_skip_t` ``fmt_skip`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FORMAT` :c:type:`mps_fmt_t` ``format`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` , :c:func:`mps_class_snc` :c:macro:`MPS_KEY_GEN` :c:type:`unsigned` ``u`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` + :c:macro:`MPS_KEY_INTERIOR` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz` :c:macro:`MPS_KEY_MAX_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv` :c:macro:`MPS_KEY_MEAN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`, :c:func:`mps_class_mvt`, :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_MFS_UNIT_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs` diff --git a/mps/tool/testrun.sh b/mps/tool/testrun.sh index 5b4d44f72de..4d0b1040942 100755 --- a/mps/tool/testrun.sh +++ b/mps/tool/testrun.sh @@ -16,6 +16,7 @@ ALL_TEST_CASES=" abqtest + airtest amcss amcsshe amcssth From 64c94ff8bea3a6ef68f3f70243fdb708fb2ca2ce Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 17:13:47 +0100 Subject: [PATCH 34/65] Document mps_key_interior for amcz, and mention it in the pool introduction. Copied from Perforce Change: 185128 ServerID: perforce.ravenbrook.com --- mps/manual/source/pool/amcz.rst | 8 +++++++- mps/manual/source/pool/intro.rst | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/mps/manual/source/pool/amcz.rst b/mps/manual/source/pool/amcz.rst index 70d38ffa6ab..61555fd180a 100644 --- a/mps/manual/source/pool/amcz.rst +++ b/mps/manual/source/pool/amcz.rst @@ -68,12 +68,18 @@ AMCZ interface method`, an :term:`is-forwarded method` and a :term:`padding method`. - It accepts one optional keyword argument: + It accepts two optional keyword arguments: * :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies the :term:`generation chain` for the pool. If not specified, the pool will use the arena's default chain. + * :c:macro:`MPS_KEY_INTERIOR` (type :c:type:`mps_bool_t`, default + ``TRUE``) specifies whether :term:`ambiguous ` :term:`interior pointers` to blocks in the pool keep + objects alive. If this is ``FALSE``, then only :term:`client + pointers` keep objects alive. + For example:: MPS_ARGS_BEGIN(args) { diff --git a/mps/manual/source/pool/intro.rst b/mps/manual/source/pool/intro.rst index a27a33380e1..ed8f83b8d4a 100644 --- a/mps/manual/source/pool/intro.rst +++ b/mps/manual/source/pool/intro.rst @@ -193,6 +193,10 @@ Blocks may use :term:`in-band headers`? yes yes yes yes yes just past the end of the header) is considered to be a reference to the block. + Pools that support internal pointers can be switched to + base pointers only, by setting the optional keyword + argument :c:macro:`MPS_KEY_INTERIOR` to ``FALSE`` when + calling :c:func:`mps_pool_create_k`. .. index:: single: pool class; writing From fe837568b94d8ee34b13b20484ad60b2fad50355 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 21:12:58 +0100 Subject: [PATCH 35/65] Cast pointer to void * for the benefit of gcc. Copied from Perforce Change: 185133 ServerID: perforce.ravenbrook.com --- mps/code/airtest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mps/code/airtest.c b/mps/code/airtest.c index a5d289f6aeb..4fc1548281a 100644 --- a/mps/code/airtest.c +++ b/mps/code/airtest.c @@ -53,7 +53,8 @@ static void test_air(int interior) if (interior) { obj_t o; o = ref; - error("wrongly finalized vector %ld at %p", o->vector.vector[0]->integer.integer, o); + error("wrongly finalized vector %ld at %p", + o->vector.vector[0]->integer.integer, (void *)o); } } } From a29c01d416c61d0688292360dd631af58086703c Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 22:07:48 +0100 Subject: [PATCH 36/65] Clang can compile eventsql.c with -pedantic but gcc cannot. Copied from Perforce Change: 185137 ServerID: perforce.ravenbrook.com --- mps/code/gc.gmk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mps/code/gc.gmk b/mps/code/gc.gmk index 3b7f0e664b9..608ced354b0 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -13,7 +13,6 @@ CC = gcc CFLAGSDEBUG = -O -g3 CFLAGSOPT = -O2 -g3 CFLAGSCOMPILER := \ - -pedantic \ -Waggregate-return \ -Wall \ -Wcast-qual \ @@ -27,7 +26,7 @@ CFLAGSCOMPILER := \ -Wstrict-aliasing=2 \ -Wstrict-prototypes \ -Wwrite-strings -CFLAGSCOMPILERSTRICT := -ansi +CFLAGSCOMPILERSTRICT := -ansi -pedantic # A different set of compiler flags for less strict compilation, for # instance when we need to #include a third-party header file that From feaa22a74fb4cdb43acf53d7870553032f779c7a Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 22:43:58 +0100 Subject: [PATCH 37/65] 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 66bb75c5d727dd54ccd93e023ce1a5b16a379cc4 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 3 Apr 2014 16:57:26 +0100 Subject: [PATCH 38/65] Add reference to c99 as requested by rb in . Copied from Perforce Change: 185214 ServerID: perforce.ravenbrook.com --- mps/design/nailboard.txt | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mps/design/nailboard.txt b/mps/design/nailboard.txt index 0bb39fdfa9c..d54a58cf03c 100644 --- a/mps/design/nailboard.txt +++ b/mps/design/nailboard.txt @@ -184,11 +184,22 @@ _`.future.tune`: The implementation makes heavy use of small arrays (which we expect to be the common case for nailboards). Performance might be improved by special-casing the small levels. -_`.future.limit`: In C and C++, a pointer to the address beyond the -end of an object (the limit of the object in our terminalogy) is a -valid pointer. There might be users that require nailboards to support -these limit pointers, so that they can be recorded in the nailboard, -and so that they retain objects. +_`.future.limit`: In C and C++, a pointer to "one past the last +element of an array object" (the limit of the object in our +terminology) is a valid pointer and can be used in pointer arithmetic. +See §6.5.6.8–9 of [C1999]. So in theory a programmer could have such +as pointer as the only reference keeping an object alive, and still +expect to be able to subtract from it to get back to the object. The +current nailboard implementation does not support this use case. + + +References +---------- + +.. [C1999] + International Standard ISO/IEC 9899:1999; + "Programming languages — C"; + Document History From 3f07e913b71c0fd00388e165bf7777473ea45c19 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 10:30:45 +0100 Subject: [PATCH 39/65] Fix airtest to use its own ambiguous root instead of relying on references to disappear from the c stack (which they don't on lii6ll). Copied from Perforce Change: 185218 ServerID: perforce.ravenbrook.com --- mps/code/airtest.c | 66 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/mps/code/airtest.c b/mps/code/airtest.c index 4fc1548281a..367a4464390 100644 --- a/mps/code/airtest.c +++ b/mps/code/airtest.c @@ -3,16 +3,28 @@ * $Id: //info.ravenbrook.com/project/mps/branch/2014-01-15/nailboard/code/fotest.c#1 $ * Copyright (c) 2014 Ravenbrook Limited. See end of file for license. * - * This test case creates a bunch of vectors, registers them for - * finalization, and then discards the base pointers to those objects, - * keeping only ambiguous interior references to the vector entries in - * the stack-allocated table s. + * .overview: This test case creates a bunch of vectors, registers + * them for finalization, and then discards the base pointers to those + * objects, keeping only ambiguous interior references to the vector + * entries in the stack-allocated table s. * - * If any of these objects are finalized, then this means that the - * ambiguous interior references has failed to keep the object alive. + * .options: The test has two options: * - * The test is then repeated with MPS_KEY_INTERIOR=FALSE; in this case - * we expect most of the vectors to be finalized. + * 'interior' is the value passed as MPS_KEY_INTERIOR when creating + * the AMC pool. If TRUE, interior pointers must keep objects alive, + * and so if any of these objects are finalized, the test fails. If + * FALSE, interior pointers do not keep objects alive, so it is likely + * that all the objects will be finalized. + * + * 'stack' is TRUE if the C stack is registered as a root. (If FALSE, + * we register the table of interior pointers as an ambiguous root.) + * + * .fail.lii6ll: The test case passes on most platforms with + * interior=FALSE and stack=TRUE (that is, all vectors get finalized), + * but fails on lii6ll in variety HOT. Rather than struggle to defeat + * the Clang optimizer, we choose not to test in this configuration. + * In any case, the MPS does not guarantee anything about timely + * finalization (see ). */ #include "mps.h" @@ -23,13 +35,19 @@ #include "fmtscheme.h" #define OBJ_LEN (1u << 4) -#define OBJ_COUNT 10 +#define OBJ_COUNT 1 -static void test_air(int interior) +static void test_air(int interior, int stack) { size_t n_finalized = 0; size_t i, j; - obj_t *s[OBJ_COUNT]; + obj_t *s[OBJ_COUNT] = {0}; + mps_root_t root; + if (!stack) { + mps_addr_t *p = (void *)s; + die(mps_root_create_table(&root, scheme_arena, mps_rank_ambig(), 0, p, + OBJ_COUNT), "mps_root_create_table"); + } mps_message_type_enable(scheme_arena, mps_message_type_finalization()); for (j = 0; j < OBJ_COUNT; ++j) { obj_t n = scheme_make_integer((long)j); @@ -58,10 +76,13 @@ static void test_air(int interior) } } } - if (!interior && n_finalized + 1 < OBJ_COUNT) { + if (!interior && n_finalized < OBJ_COUNT) { error("only finalized %"PRIuLONGEST" out of %"PRIuLONGEST" vectors.", (ulongest_t)n_finalized, (ulongest_t)OBJ_COUNT); } + if (!stack) { + mps_root_destroy(root); + } } static mps_gen_param_s obj_gen_params[] = { @@ -69,7 +90,7 @@ static mps_gen_param_s obj_gen_params[] = { { 170, 0.45 } }; -static void test_main(int interior) +static void test_main(int interior, int stack) { mps_res_t res; mps_chain_t obj_chain; @@ -107,14 +128,17 @@ static void test_main(int interior) res = mps_thread_reg(&thread, scheme_arena); if (res != MPS_RES_OK) error("Couldn't register thread"); - res = mps_root_create_reg(®_root, scheme_arena, mps_rank_ambig(), 0, - thread, mps_stack_scan_ambig, marker, 0); - if (res != MPS_RES_OK) error("Couldn't create root"); + if (stack) { + res = mps_root_create_reg(®_root, scheme_arena, mps_rank_ambig(), 0, + thread, mps_stack_scan_ambig, marker, 0); + if (res != MPS_RES_OK) error("Couldn't create root"); + } - test_air(interior); + test_air(interior, stack); mps_arena_park(scheme_arena); - mps_root_destroy(reg_root); + if (stack) + mps_root_destroy(reg_root); mps_thread_dereg(thread); mps_ap_destroy(obj_ap); mps_pool_destroy(obj_pool); @@ -127,8 +151,10 @@ int main(int argc, char *argv[]) { testlib_init(argc, argv); - test_main(TRUE); - test_main(FALSE); + test_main(TRUE, TRUE); + test_main(TRUE, FALSE); + /* not test_main(FALSE, TRUE) -- see .fail.lii6ll. */ + test_main(FALSE, FALSE); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; From 6ef4b6e0c6a94da7e9512abf160ea4bd24a4e19d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 4 Apr 2014 11:49:19 +0100 Subject: [PATCH 40/65] 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 41/65] 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 42/65] 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 43/65] 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 44/65] 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 45/65] 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 46/65] 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 47/65] 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 48/65] 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 49/65] 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 50/65] 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 51/65] 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 52/65] 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 53/65] 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 54/65] 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 55/65] 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 56/65] 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 31154ac728fd68d1e23eae74cf31d5cf62822fda Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 17:35:57 +0100 Subject: [PATCH 57/65] Avoid calling sizeroundup when the result needs to be a count. Use PointerAdd instead of casting to (char *) and back again. Copied from Perforce Change: 185256 ServerID: perforce.ravenbrook.com --- mps/code/nailboard.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index e6ca658f1a1..8744514662b 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -26,7 +26,7 @@ SRCID(nailboard, "$Id$"); static Count nailboardLevels(Count nails) { - return SizeRoundUp(SizeFloorLog2(nails) + 1, LEVEL_SHIFT) / LEVEL_SHIFT; + return (SizeFloorLog2((Size)nails) + LEVEL_SHIFT) / LEVEL_SHIFT; } @@ -128,12 +128,12 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, board->alignShift = alignShift; board->newNails = FALSE; - p = (char *)p + nailboardStructSize(levels); + p = PointerAdd(p, nailboardStructSize(levels)); for (i = 0; i < levels; ++i) { AVER(nails > 0); board->level[i] = p; BTResRange(board->level[i], 0, nails); - p = (char *)p + BTSize(nails); + p = PointerAdd(p, BTSize(nails)); nails >>= LEVEL_SHIFT; } From 116021aef09b1d63766aa5181f9e99e7e053feb2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 6 Apr 2014 20:00:31 +0100 Subject: [PATCH 58/65] 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 59/65] 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 60/65] 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 61/65] 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 62/65] 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 63/65] 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; } From b7c3b0ae84b9f2a827b057ac7d7d302d16aa7dab Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 7 Apr 2014 13:22:21 +0100 Subject: [PATCH 64/65] Can't can't checkd_nosig(ring, &arenaring) because &arenaring is never null and gcc will warn about a constant comparison. Copied from Perforce Change: 185279 ServerID: perforce.ravenbrook.com --- mps/code/global.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mps/code/global.c b/mps/code/global.c index b43b888dc11..22326aa391f 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -213,7 +213,9 @@ Bool GlobalsCheck(Globals arenaGlobals) /* we also check the statics now. */ CHECKL(BoolCheck(arenaRingInit)); - CHECKD_NOSIG(Ring, &arenaRing); + /* Can't CHECKD_NOSIG here because &arenaRing is never NULL and GCC + * will warn about a constant comparison. */ + CHECKL(RingCheck(&arenaRing)); CHECKL(BoolCheck(arena->emergency)); From a51ebd62eaf52e89c4b8a19ae53b9b5e42c9fce6 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 7 Apr 2014 15:35:17 +0100 Subject: [PATCH 65/65] Add default case to switch statement so that it compiles with gcc -wswitch-default. Copied from Perforce Change: 185293 ServerID: perforce.ravenbrook.com --- mps/code/fmtscheme.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mps/code/fmtscheme.c b/mps/code/fmtscheme.c index 04a29a061fd..5299c8f3525 100644 --- a/mps/code/fmtscheme.c +++ b/mps/code/fmtscheme.c @@ -415,8 +415,9 @@ static mps_addr_t obj_isfwd(mps_addr_t addr) return obj->fwd2.fwd; case TYPE_FWD: return obj->fwd.fwd; + default: + return NULL; } - return NULL; } static void obj_fwd(mps_addr_t old, mps_addr_t new)