From 00901670bef25dae4201f8968ea2021bcb4c41f8 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 8 Apr 2014 18:29:25 +0100 Subject: [PATCH 01/75] The alignment of an awl pool is now set to the format alignment, as documented. the alignment restriction on pointers is now based on sizeof(void *), not mps_pf_align. Copied from Perforce Change: 185357 ServerID: perforce.ravenbrook.com --- mps/code/poolawl.c | 16 +++++++++------- mps/manual/source/pool/awl.rst | 9 ++++----- mps/manual/source/release.rst | 10 ++++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 6332a91b7cd..edcae788e3c 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -558,6 +558,7 @@ static Res AWLInit(Pool pool, ArgList args) AVERT(Format, format); pool->format = format; + pool->alignment = format->alignment; AVER(FUNCHECK(findDependent)); awl->findDependent = findDependent; @@ -570,7 +571,7 @@ static Res AWLInit(Pool pool, ArgList args) if (res != ResOK) goto failGenInit; - awl->alignShift = SizeLog2(pool->alignment); + awl->alignShift = SizeLog2(PoolAlignment(pool)); awl->size = (Size)0; awl->succAccesses = 0; @@ -937,7 +938,7 @@ static Res awlScanSinglePass(Bool *anyScannedReturn, i = awlIndexOfAddr(base, awl, p); if (!BTGet(awlseg->alloc, i)) { - p = AddrAdd(p, pool->alignment); + p = AddrAdd(p, PoolAlignment(pool)); continue; } hp = AddrAdd(p, format->headerSize); @@ -954,7 +955,8 @@ static Res awlScanSinglePass(Bool *anyScannedReturn, } objectLimit = AddrSub(objectLimit, format->headerSize); AVER(p < objectLimit); - p = AddrAlignUp(objectLimit, pool->alignment); + AVER(AddrIsAligned(objectLimit, PoolAlignment(pool))); + p = objectLimit; } AVER(p == limit); @@ -1051,7 +1053,7 @@ static Res AWLFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) switch(ss->rank) { case RankAMBIG: /* not a real pointer if not aligned or not allocated */ - if (!AddrIsAligned(base, pool->alignment) || !BTGet(awlseg->alloc, i)) + if (!AddrIsAligned(base, sizeof(void *)) || !BTGet(awlseg->alloc, i)) return ResOK; /* falls through */ case RankEXACT: @@ -1125,7 +1127,7 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg) } q = format->skip(AddrAdd(p, format->headerSize)); q = AddrSub(q, format->headerSize); - q = AddrAlignUp(q, pool->alignment); + AVER(AddrIsAligned(q, PoolAlignment(pool))); j = awlIndexOfAddr(base, awl, q); AVER(j <= awlseg->grains); if(BTGet(awlseg->mark, i)) { @@ -1243,13 +1245,13 @@ static void AWLWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f, i = awlIndexOfAddr(base, awl, object); if (!BTGet(awlseg->alloc, i)) { /* This grain is free */ - object = AddrAdd(object, pool->alignment); + object = AddrAdd(object, PoolAlignment(pool)); continue; } object = AddrAdd(object, format->headerSize); next = format->skip(object); next = AddrSub(next, format->headerSize); - next = AddrAlignUp(next, pool->alignment); + AVER(AddrIsAligned(next, PoolAlignment(pool))); if (BTGet(awlseg->mark, i) && BTGet(awlseg->scanned, i)) (*f)(object, pool->format, pool, p, s); object = next; diff --git a/mps/manual/source/pool/awl.rst b/mps/manual/source/pool/awl.rst index 4128339227a..79df0258804 100644 --- a/mps/manual/source/pool/awl.rst +++ b/mps/manual/source/pool/awl.rst @@ -282,11 +282,10 @@ the format of objects allocated in it: that it does not look like an aligned pointer. "Aligned pointer" means a word whose numeric value (that is, its - value when treated as an unsigned integer) is a multiple of the - architecture's :term:`natural alignment` (see - :c:macro:`MPS_PF_ALIGN`). If you're using a 32-bit architecture, - that means that an aligned pointer is a multiple of 4 and its bottom - two bits are both zero. + value when treated as an unsigned integer) is a multiple of the size + of a pointer. For you're using a 32-bit architecture, that means + that an aligned pointer is a multiple of 4 and its bottom two bits + are both zero. The bottom line is that references from an object in an AWL pool must be untagged and aligned, and integers must be tagged with a diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 294b6545b91..83e23aea3c3 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -27,6 +27,16 @@ New features calling :c:func:`mps_pool_create_k`. +Other changes +............. + +#. The alignment of :ref:`pool-awl` pools is now configurable via the + object format, as documented, and is no longer always + :c:macro:`MPS_PF_ALIGN`. See job003745_. + + .. _job003745: https://www.ravenbrook.com/project/mps/issue/job003745/ + + .. _release-notes-1.113: Release 1.113.0 From dbaf43f32e86628a9239e1293887dd0b6a200326 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 8 Apr 2014 20:52:40 +0100 Subject: [PATCH 02/75] No need to put "branch/" in the branches index: just use date/task. Turn jobs into links in the description. Copied from Perforce Change: 185364 ServerID: perforce.ravenbrook.com --- mps/tool/branch | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mps/tool/branch b/mps/tool/branch index f60eccae235..faf69ffb0bc 100755 --- a/mps/tool/branch +++ b/mps/tool/branch @@ -46,9 +46,9 @@ CHILD_RE = r'(?:{}|{})$'.format(TASK_BRANCH_RE, VERSION_BRANCH_RE) TASK_BRANCH_ENTRY = ''' - {child} + {date}/{task} Changes - {description} + {desc_html} In development (diffs). @@ -60,7 +60,7 @@ VERSION_BRANCH_ENTRY = ''' None. {parent}/...@{changelevel} - {description} + {desc_html} base
@@ -161,6 +161,9 @@ def main(argv): if not args.description: args.description = fmt("Branching {parent} to {child}.") print(fmt("description={description}")) + args.desc_html = re.sub(r'\b(job\d{6})\b', + fmt(r'. - * 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/testlib.h b/mps/code/testlib.h index 0912373031d..9c197cae839 100644 --- a/mps/code/testlib.h +++ b/mps/code/testlib.h @@ -28,13 +28,10 @@ /* Suppress Pelles C warnings at warning level 2 */ -/* Some of these are also done in config.h. */ +/* This is 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) From c4767b5a3106b60440a382d2516e29f2bfe0f079 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 12:24:49 +0100 Subject: [PATCH 04/75] Correct the nailboard level sizes; add assertion to nailboardindex checking this. Copied from Perforce Change: 185421 ServerID: perforce.ravenbrook.com --- mps/code/nailboard.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index 8744514662b..dc669a67ef7 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -30,26 +30,36 @@ static Count nailboardLevels(Count nails) } +/* nailboardNails -- return the total number of nails in the board */ + +static Count nailboardNails(Nailboard board) +{ + return RangeSize(&board->range) >> board->alignShift; +} + + /* nailboardLevelBits -- return the number of bits in the bit table * for the given level. */ -static Count nailboardLevelBits(Nailboard board, Index level) +static Count nailboardLevelBits(Count nails, Index level) { - /* Use <= rather than < because of .check.levels. */ - AVER(level <= board->levels); - return RangeSize(&board->range) >> (board->alignShift + level * LEVEL_SHIFT); + Shift shift = level * LEVEL_SHIFT; + return (nails + (1 << shift) - 1) >> shift; } Bool NailboardCheck(Nailboard board) { Index i; + Count nails; CHECKS(Nailboard, board); CHECKL(RangeCheck(&board->range)); CHECKL(0 < board->levels); - CHECKL(board->levels == nailboardLevels(nailboardLevelBits(board, 0))); - CHECKL(nailboardLevelBits(board, board->levels - 1) != 0); - CHECKL(nailboardLevelBits(board, board->levels) == 0); /* .check.levels */ + nails = nailboardNails(board); + CHECKL(board->levels == nailboardLevels(nails)); + CHECKL(nails == nailboardLevelBits(nails, 0)); + CHECKL(nailboardLevelBits(nails, board->levels - 1) != 0); + CHECKL(nailboardLevelBits(nails, board->levels) == 1); CHECKL(BoolCheck(board->newNails)); for (i = 0; i < board->levels; ++i) { CHECKL(board->level[i] != NULL); @@ -80,8 +90,7 @@ static Size nailboardSize(Count nails, Count levels) Size size; size = nailboardStructSize(levels); for (i = 0; i < levels; ++i) { - size += BTSize(nails); - nails >>= LEVEL_SHIFT; + size += BTSize(nailboardLevelBits(nails, i)); } return size; } @@ -130,11 +139,11 @@ Res NailboardCreate(Nailboard *boardReturn, Arena arena, Align alignment, p = PointerAdd(p, nailboardStructSize(levels)); for (i = 0; i < levels; ++i) { - AVER(nails > 0); + Count levelBits = nailboardLevelBits(nails, i); + AVER(levelBits > 0); board->level[i] = p; - BTResRange(board->level[i], 0, nails); - p = PointerAdd(p, BTSize(nails)); - nails >>= LEVEL_SHIFT; + BTResRange(board->level[i], 0, levelBits); + p = PointerAdd(p, BTSize(levelBits)); } board->sig = NailboardSig; @@ -154,7 +163,7 @@ void NailboardDestroy(Nailboard board, Arena arena) AVERT(Nailboard, board); AVERT(Arena, arena); - nails = nailboardLevelBits(board, 0); + nails = nailboardNails(board); size = nailboardSize(nails, board->levels); board->sig = SigInvalid; @@ -191,8 +200,10 @@ Bool (NailboardNewNails)(Nailboard board) static Index nailboardIndex(Nailboard board, Index level, Addr addr) { - return AddrOffset(RangeBase(&board->range), addr) + Index i = AddrOffset(RangeBase(&board->range), addr) >> (board->alignShift + level * LEVEL_SHIFT); + AVER_CRITICAL(i < nailboardLevelBits(nailboardNails(board), level)); + return i; } @@ -414,7 +425,7 @@ Res NailboardDescribe(Nailboard board, mps_lib_FILE *stream) return res; for(i = 0; i < board->levels; ++i) { - Count levelNails = nailboardLevelBits(board, i); + Count levelNails = nailboardLevelBits(nailboardNails(board), i); Count resetNails = BTCountResRange(board->level[i], 0, levelNails); res = WriteF(stream, " Level $U ($U bits, $U set): ", i, levelNails, levelNails - resetNails, NULL); From 58f7a40cbf58671e8c29d76190e12898c7ec6149 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 12:37:48 +0100 Subject: [PATCH 05/75] Document that the arena must be parked in order for mps_arena_formatted_objects_walk to visit all objects. Copied from Perforce Change: 185424 ServerID: perforce.ravenbrook.com --- mps/manual/source/topic/format.rst | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/mps/manual/source/topic/format.rst b/mps/manual/source/topic/format.rst index 91ac7ae6462..b9bbdae61bb 100644 --- a/mps/manual/source/topic/format.rst +++ b/mps/manual/source/topic/format.rst @@ -468,22 +468,27 @@ Object format introspection Each :term:`pool class` determines for which objects the stepper function is called. Typically, all validly formatted objects are - visited. During a :term:`trace` this will in general be only the - :term:`black` objects, though the :ref:`pool-lo` pool, for - example, will walk all objects since they are validly formatted - whether they are black or :term:`white`. :term:`Padding objects` - may be visited at the pool class's discretion: the :term:`client - program` should handle this case. - - .. seealso:: - - :ref:`topic-arena`. + visited. :term:`Padding objects` may be visited at the pool + class's discretion: the stepper function must handle this + case. .. note:: This function is intended for heap analysis, tuning, and debugging, not for frequent use in production. + .. warning:: + + If a garbage collection is currently in progress (that is, if + the arena is in the :term:`clamped ` or + :term:`unclamped state`), then only objects that are known to + be currently valid are visited. + + For the most reliable results, ensure the arena is in the + :term:`parked state` by calling :c:func:`mps_arena_park` + before calling this function (and release it by calling + :c:func:`mps_arena_release` afterwards, if desired). + .. c:type:: void (*mps_formatted_objects_stepper_t)(mps_addr_t addr, mps_fmt_t fmt, mps_pool_t pool, void *p, size_t s) @@ -515,10 +520,6 @@ Object format introspection It must not access other memory managed by the MPS. - .. seealso:: - - :ref:`topic-arena`. - Obsolete interface ------------------ From e30fc43dd4b0cbc8c813ee23628d13d76c07081b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 15:06:58 +0100 Subject: [PATCH 06/75] Fix amcssth -- don't try to test two incompatible features at the same time (see job003561). Set the commit limit in amcss and amcsshe so that we test that the MPS can live in a tight memory limit. Don't try to detect when the MPS has made a "dynamic" collection. This is not reliable or maintainable. Copied from Perforce Change: 185430 ServerID: perforce.ravenbrook.com --- mps/code/amcss.c | 21 +--------------- mps/code/amcsshe.c | 20 ++-------------- mps/code/amcssth.c | 58 +++++++++++++++++++++++++++++---------------- mps/code/exposet0.c | 6 ----- 4 files changed, 41 insertions(+), 64 deletions(-) diff --git a/mps/code/amcss.c b/mps/code/amcss.c index 20f4dae3740..48892a45830 100644 --- a/mps/code/amcss.c +++ b/mps/code/amcss.c @@ -78,19 +78,6 @@ static void report(mps_arena_t arena) printf(" not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned); printf(" clock: %"PRIuLONGEST"\n", (ulongest_t)mps_message_clock(arena, message)); printf("}\n"); - - if(condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) { - /* When condemned size is larger than could happen in a gen 2 - * collection (discounting ramps, natch), guess that was a dynamic - * collection, and reset the commit limit, so it doesn't run out. - * - * GDR 2013-03-12: Fiddling with the commit limit was causing - * the test to fail sometimes (see job003440), so I've commented - * out this feature. - */ - /* die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); */ - } - } else { cdie(0, "unknown message type"); break; @@ -98,8 +85,6 @@ static void report(mps_arena_t arena) mps_message_discard(arena, message); } - - return; } @@ -310,11 +295,7 @@ int main(int argc, char *argv[]) "arena_create"); mps_message_type_enable(arena, mps_message_type_gc()); mps_message_type_enable(arena, mps_message_type_gc_start()); - /* GDR 2013-03-12: Fiddling with the commit limit was causing - * the test to fail sometimes (see job003440), so I've commented - * out this feature. - */ - /*die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit");*/ + die(mps_arena_commit_limit_set(arena, 2*testArenaSIZE), "set limit"); die(mps_thread_reg(&thread, arena), "thread_reg"); test(arena, mps_class_amc(), exactRootsCOUNT); test(arena, mps_class_amcz(), 0); diff --git a/mps/code/amcsshe.c b/mps/code/amcsshe.c index 11a5950f497..8b3a0c65e36 100644 --- a/mps/code/amcsshe.c +++ b/mps/code/amcsshe.c @@ -91,18 +91,6 @@ static void report(mps_arena_t arena) printf("not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned); mps_message_discard(arena, message); - - if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) { - /* When condemned size is larger than could happen in a gen 2 - * collection (discounting ramps, natch), guess that was a dynamic - * collection, and reset the commit limit, so it doesn't run out. - * - * GDR 2013-03-07: Fiddling with the commit limit was causing - * the test to fail sometimes (see job003432), so I've commented - * out this feature. - */ - /*die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");*/ - } } } @@ -257,14 +245,10 @@ int main(int argc, char *argv[]) testlib_init(argc, argv); - die(mps_arena_create(&arena, mps_arena_class_vm(), 3*testArenaSIZE), + die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), "arena_create\n"); mps_message_type_enable(arena, mps_message_type_gc()); - /* GDR 2013-03-07: Fiddling with the commit limit was causing - * the test to fail sometimes (see job003432), so I've commented - * out this feature. - */ - /*die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit");*/ + die(mps_arena_commit_limit_set(arena, 2*testArenaSIZE), "set limit"); die(mps_thread_reg(&thread, arena), "thread_reg"); test(arena, mps_class_amc(), exactRootsCOUNT); test(arena, mps_class_amcz(), 0); diff --git a/mps/code/amcssth.c b/mps/code/amcssth.c index 79eff570b0b..2f17f97ca09 100644 --- a/mps/code/amcssth.c +++ b/mps/code/amcssth.c @@ -4,11 +4,20 @@ * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * Portions copyright (c) 2002 Global Graphics Software. * - * .posix: This is Posix only. + * .mode: This test case has two modes: + * + * .mode.walk: In this mode, the main thread parks the arena half way + * through the test case and runs mps_arena_formatted_objects_walk(). + * This checks that walking works while the other threads continue to + * allocate in the background. + * + * .mode.commit: In this mode, the arena's commit limit is set. This + * checks that the MPS can make progress inside a tight limit in the + * presence of allocation on multiple threads. But this is + * incompatible with .mode.walk: if the arena is parked, then the + * arena has no chance to make progress. */ -#define _POSIX_C_SOURCE 199309L - #include "fmtdy.h" #include "fmtdytst.h" #include "testlib.h" @@ -19,6 +28,11 @@ #include /* fflush, printf, putchar */ +enum { + ModeWALK = 0, /* .mode.walk */ + ModeCOMMIT = 1 /* .mode.commit */ +}; + /* These values have been tuned in the hope of getting one dynamic collection. */ #define testArenaSIZE ((size_t)1000*1024) @@ -65,12 +79,6 @@ static void report(mps_arena_t arena) printf("not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned); mps_message_discard(arena, message); - - if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) - /* When condemned size is larger than could happen in a gen 2 - * collection (discounting ramps, natch), guess that was a dynamic - * collection, and reset the commit limit, so it doesn't run out. */ - die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); } } @@ -210,7 +218,7 @@ static void *kid_thread(void *arg) /* test -- the body of the test */ -static void *test(mps_class_t pool_class, size_t roots_count) +static void *test_pool(mps_class_t pool_class, size_t roots_count, int mode) { size_t i; mps_word_t collections, rampSwitch; @@ -221,6 +229,7 @@ static void *test(mps_class_t pool_class, size_t roots_count) mps_pool_t pool; testthr_t kids[10]; closure_s cl; + int walked = FALSE, ramped = FALSE; die(mps_pool_create(&pool, arena, pool_class, format, chain), "pool_create(amc)"); @@ -250,21 +259,23 @@ static void *test(mps_class_t pool_class, size_t roots_count) if (collections != c) { collections = c; - printf("\nCollection %lu started, %lu objects.\n", c, objs); + printf("\nCollection %lu started, %lu objects, committed=%lu.\n", + c, objs, (unsigned long)mps_arena_committed(arena)); report(arena); for (i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]), "all roots check"); - if (collections == collectionsCOUNT / 2) { + if (mode == ModeWALK && collections >= collectionsCOUNT / 2 && !walked) { unsigned long object_count = 0; mps_arena_park(arena); mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); mps_arena_release(arena); printf("stepped on %lu objects.\n", object_count); + walked = TRUE; } - if (collections == rampSwitch) { + if (collections >= rampSwitch && !ramped) { int begin_ramp = !ramping || /* Every other time, switch back immediately. */ (collections & 1); @@ -289,6 +300,7 @@ static void *test(mps_class_t pool_class, size_t roots_count) ramping = 1; } } + ramped = TRUE; } churn(ap, roots_count); @@ -317,31 +329,37 @@ static void *test(mps_class_t pool_class, size_t roots_count) return NULL; } -int main(int argc, char *argv[]) +static void test_arena(int mode) { mps_thr_t thread; mps_root_t reg_root; void *marker = ▮ - testlib_init(argc, argv); - die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "arena_create"); + if (mode == ModeCOMMIT) + die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); mps_message_type_enable(arena, mps_message_type_gc()); init(); die(mps_thread_reg(&thread, arena), "thread_reg"); die(mps_root_create_reg(®_root, arena, mps_rank_ambig(), 0, thread, - mps_stack_scan_ambig, marker, 0), "root_create"); + mps_stack_scan_ambig, marker, 0), "root_create"); - test(mps_class_amc(), exactRootsCOUNT); - test(mps_class_amcz(), 0); + test_pool(mps_class_amc(), exactRootsCOUNT, mode); + test_pool(mps_class_amcz(), 0, mode); mps_root_destroy(reg_root); mps_thread_dereg(thread); - finish(); report(arena); mps_arena_destroy(arena); +} + +int main(int argc, char *argv[]) +{ + testlib_init(argc, argv); + test_arena(ModeWALK); + test_arena(ModeCOMMIT); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; diff --git a/mps/code/exposet0.c b/mps/code/exposet0.c index f471dd2a3bc..21f2567cbaa 100644 --- a/mps/code/exposet0.c +++ b/mps/code/exposet0.c @@ -72,12 +72,6 @@ static void report(mps_arena_t arena) printf("not_condemned %"PRIuLONGEST"\n", (ulongest_t)not_condemned); mps_message_discard(arena, message); - - if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) - /* When condemned size is larger than could happen in a gen 2 - * collection (discounting ramps, natch), guess that was a dynamic - * collection, and reset the commit limit, so it doesn't run out. */ - die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); } } From 8da860f464254ee717da9daa107dac112f1b86a8 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 15:36:51 +0100 Subject: [PATCH 07/75] Document the constraints on the mean and maximum size arguments to the mv pool class. remove documentation from poolmv.h: this is in the manual now. Copied from Perforce Change: 185432 ServerID: perforce.ravenbrook.com --- mps/code/poolmv.h | 37 ++++++----------------------------- mps/manual/source/pool/mv.rst | 20 ++++++++++--------- 2 files changed, 17 insertions(+), 40 deletions(-) diff --git a/mps/code/poolmv.h b/mps/code/poolmv.h index 098cd3eaa2e..8e6885254bc 100644 --- a/mps/code/poolmv.h +++ b/mps/code/poolmv.h @@ -1,41 +1,16 @@ /* poolmv.h: 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 the interface to the manual-variable pool class. * - * .mv: Manual-variable pools manage variably-sized blocks of memory in a - * flexible manner. They have higher overheads than a fixed-size pool. + * .mv: Manual-variable pools manage variably-sized blocks of memory + * in a flexible manner. They have higher overheads than a fixed-size + * pool. * - * .init: This class adds the following arguments to PoolCreate: - * - * Size extendBy - * - * extendBy is the default number of bytes reserved by the pool at a time. - * A large size will make allocation cheaper but have a higher resource - * overhead. A typical value might be 65536. See note 2. - * - * Size avgSize - * - * avgSize is an estimate of the average size of an allocation, and is used - * to choose the size of internal tables. An accurate estimate will - * improve the efficiency of the pool. A low estimate will make the pool - * less space efficient. A high estimate will make the pool less time - * efficient. A typical value might be 32. avgSize must not be less than - * extendBy. - * - * Size maxSize - * - * maxSize is an estimate of the maximum total size that the pool will - * reach. Setting this parameter does not actually contrain the pool, but - * an accurate estimate will improve the efficiency of the pool. maxSize - * must not be less than extendBy. - * - * Notes - * 2. The documentation could suggest a segment size according to the - * distribution of allocation size requests. richard 1994-11-08 + * .design: See */ #ifndef poolmv_h @@ -59,7 +34,7 @@ extern Bool MVCheck(MV mv); /* 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/manual/source/pool/mv.rst b/mps/manual/source/pool/mv.rst index 433525f7362..361cd41c0b5 100644 --- a/mps/manual/source/pool/mv.rst +++ b/mps/manual/source/pool/mv.rst @@ -75,17 +75,19 @@ MV interface When creating an MV pool, :c:func:`mps_pool_create_k` may take three :term:`keyword arguments`: - * :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`, default 65536) is the - :term:`size` of segment that the pool will request from the - :term:`arena`. + * :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`, + default 65536) is the :term:`size` of segment that the pool will + request from the :term:`arena`. - * :c:macro:`MPS_KEY_MEAN_SIZE` (type :c:type:`size_t`, default 32) is the - predicted mean size of blocks that will be allocated from the - pool. + * :c:macro:`MPS_KEY_MEAN_SIZE` (type :c:type:`size_t`, default 32) + is the predicted mean size of blocks that will be allocated from + the pool. This value must be smaller than, or equal to, the + value for :c:macro:`MPS_KEY_EXTEND_BY`. - * :c:macro:`MPS_KEY_MAX_SIZE` (type :c:type:`size_t`, default 65536) is the - predicted maximum size of blocks that will be allocated from the - pool. + * :c:macro:`MPS_KEY_MAX_SIZE` (type :c:type:`size_t`, + default 65536) is the predicted maximum size of blocks that will + be allocated from the pool. This value must be larger than, or + equal to, the value for :c:macro:`MPS_KEY_EXTEND_BY`. The mean and maximum sizes are *hints* to the MPS: the pool will be less efficient if these are wrong, but nothing will break. From 4e30c7d2b830d4987497d2b60fd204387c4e77f3 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 18:16:29 +0100 Subject: [PATCH 08/75] Don't turn on the alloctable in amsbufferempty when it's shared with nonwhitetable and the colour tables are in use -- this will turn any grey grains in the segment invalid. Add more checking to AMS, including the table use invariant. Copied from Perforce Change: 185434 ServerID: perforce.ravenbrook.com --- mps/code/poolams.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/mps/code/poolams.c b/mps/code/poolams.c index c67a2efd684..7d090b2470b 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -74,6 +74,11 @@ Bool AMSSegCheck(AMSSeg amsseg) CHECKD_NOSIG(BT, amsseg->nongreyTable); CHECKD_NOSIG(BT, amsseg->nonwhiteTable); + /* If tables are shared, they mustn't both be in use. */ + CHECKL(!(amsseg->ams->shareAllocTable + && amsseg->allocTableInUse + && amsseg->colourTablesInUse)); + return TRUE; } @@ -167,6 +172,10 @@ static Res amsCreateTables(AMS ams, BT *allocReturn, goto failWhite; } + /* Invalidate the colour tables in checking varieties. */ + AVER((BTResRange(nongreyTable, 0, length), TRUE)); + AVER((BTSetRange(nonwhiteTable, 0, length), TRUE)); + *allocReturn = allocTable; *nongreyReturn = nongreyTable; *nonwhiteReturn = nonwhiteTable; @@ -1023,7 +1032,8 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit) AVER(limitIndex <= amsseg->firstFree); if (limitIndex == amsseg->firstFree) /* is it at the end? */ { amsseg->firstFree = initIndex; - } else { /* start using allocTable */ + } else if (!ams->shareAllocTable || !amsseg->colourTablesInUse) { + /* start using allocTable */ amsseg->allocTableInUse = TRUE; BTSetRange(amsseg->allocTable, 0, amsseg->firstFree); if (amsseg->firstFree < amsseg->grains) @@ -1415,16 +1425,20 @@ static Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) /* doing that here (this can be called from RootScan, during flip). */ clientRef = *refIO; + AVER_CRITICAL(SegBase(seg) <= clientRef); + AVER_CRITICAL(clientRef < SegLimit(seg)); /* see .ref-limit */ base = AddrSub((Addr)clientRef, format->headerSize); /* can get an ambiguous reference too close to the base of the * segment, so when we subtract the header we are not in the * segment any longer. This isn't a real reference, * so we can just skip it. */ if (base < SegBase(seg)) { - return ResOK; + AVER_CRITICAL(ss->rank == RankAMBIG); + return ResOK; } i = AMS_ADDR_INDEX(seg, base); + AVER_CRITICAL(i < amsseg->grains); AVER_CRITICAL(!AMS_IS_INVALID_COLOUR(seg, i)); ss->wasMarked = TRUE; From 988997f69c14147400bdaf175b6c7f436ab5c93b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 19:17:42 +0100 Subject: [PATCH 09/75] Add release note for job001549. Copied from Perforce Change: 185436 ServerID: perforce.ravenbrook.com --- mps/manual/source/release.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 83e23aea3c3..b93ffc786f5 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -30,6 +30,14 @@ New features Other changes ............. +#. The :ref:`pool-ams` pool class no longer triggers the assertion + ``!AMS_IS_INVALID_COLOUR(seg, i)`` under rare circumstances + (namely, detaching an :term:`allocation point` from a :term:`grey` + segment when :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` is + ``FALSE``). See job001549_. + + .. _job001549: https://www.ravenbrook.com/project/mps/issue/job001549/ + #. The alignment of :ref:`pool-awl` pools is now configurable via the object format, as documented, and is no longer always :c:macro:`MPS_PF_ALIGN`. See job003745_. From c6c46536c2e64b335834941f69e081c6c7e46ffb Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 10 Apr 2014 19:40:42 +0100 Subject: [PATCH 10/75] Must ensure the consistency of a segment even if we are just about to free it, because the segment must pass the segcheck inside segfree. Copied from Perforce Change: 185440 ServerID: perforce.ravenbrook.com --- mps/code/poolams.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 7d090b2470b..d769630f009 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -1598,12 +1598,13 @@ static void AMSReclaim(Pool pool, Trace trace, Seg seg) /* preservedInPlaceCount is updated on fix */ trace->preservedInPlaceSize += (grains - amsseg->free) << ams->grainShift; + /* Ensure consistency of segment even if are just about to free it */ + amsseg->colourTablesInUse = FALSE; + SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace)); + if (amsseg->free == grains && SegBuffer(seg) == NULL) { /* No survivors */ SegFree(seg); - } else { - amsseg->colourTablesInUse = FALSE; - SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace)); } } From 9c8713f51b76d3c2380e4c39558dccb10a2b14e7 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 00:26:48 +0100 Subject: [PATCH 11/75] Fix problems found by coverity. see for full analysis. Copied from Perforce Change: 185445 ServerID: perforce.ravenbrook.com --- mps/code/abq.c | 20 +++------- mps/code/airtest.c | 2 +- mps/code/arenavm.c | 3 +- mps/code/cbs.c | 3 +- mps/code/djbench.c | 1 + mps/code/eventcnv.c | 6 +++ mps/code/gcbench.c | 10 ++--- mps/code/meter.h | 11 ++++-- mps/code/mpm.c | 8 ++-- mps/code/mpm.h | 6 ++- mps/code/poolmv2.c | 93 +++++++++++++++------------------------------ mps/code/sac.c | 15 +++++--- mps/code/trace.c | 3 +- mps/code/vman.c | 10 ++--- mps/code/vmix.c | 8 ++-- mps/code/vmw3.c | 7 ++-- 16 files changed, 92 insertions(+), 114 deletions(-) diff --git a/mps/code/abq.c b/mps/code/abq.c index b915bb42c9b..22286354c77 100644 --- a/mps/code/abq.c +++ b/mps/code/abq.c @@ -1,7 +1,7 @@ /* abq.c: QUEUE 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: A fixed-length FIFO queue. * @@ -185,18 +185,10 @@ Res ABQDescribe(ABQ abq, ABQDescribeElement describeElement, mps_lib_FILE *strea if(res != ResOK) return res; - res = METER_WRITE(abq->push, stream); - if(res != ResOK) - return res; - res = METER_WRITE(abq->pop, stream); - if(res != ResOK) - return res; - res = METER_WRITE(abq->peek, stream); - if(res != ResOK) - return res; - res = METER_WRITE(abq->delete, stream); - if(res != ResOK) - return res; + METER_WRITE(abq->push, stream); + METER_WRITE(abq->pop, stream); + METER_WRITE(abq->peek, stream); + METER_WRITE(abq->delete, stream); res = WriteF(stream, "}\n", NULL); if(res != ResOK) @@ -311,7 +303,7 @@ static void *ABQElement(ABQ abq, Index index) { /* 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/airtest.c b/mps/code/airtest.c index 31932bb4286..9da2c768f84 100644 --- a/mps/code/airtest.c +++ b/mps/code/airtest.c @@ -35,7 +35,7 @@ #include "fmtscheme.h" #define OBJ_LEN (1u << 4) -#define OBJ_COUNT 1 +#define OBJ_COUNT 10 static void test_air(int interior, int stack) { diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 1bcc6272f35..15b79bbed51 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -593,6 +593,8 @@ static void VMArenaFinish(Arena arena) AVERT(VMArena, vmArena); arenaVM = vmArena->vm; + EVENT1(ArenaDestroy, vmArena); + /* destroy all chunks, including the primary */ arena->primary = NULL; RING_FOR(node, &arena->chunkRing, next) { @@ -612,7 +614,6 @@ static void VMArenaFinish(Arena arena) VMUnmap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM)); VMDestroy(arenaVM); - EVENT1(ArenaDestroy, vmArena); } diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 176a15fef16..118d226a603 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -1077,8 +1077,7 @@ Res CBSDescribe(CBS cbs, mps_lib_FILE *stream) res = SplayTreeDescribe(cbsSplay(cbs), stream, &cbsSplayNodeDescribe); if (res != ResOK) return res; - res = METER_WRITE(cbs->treeSearch, stream); - if (res != ResOK) return res; + METER_WRITE(cbs->treeSearch, stream); res = WriteF(stream, "}\n", NULL); return res; diff --git a/mps/code/djbench.c b/mps/code/djbench.c index 59f05130cf2..c1f37f412b2 100644 --- a/mps/code/djbench.c +++ b/mps/code/djbench.c @@ -56,6 +56,7 @@ static mps_bool_t zoned = TRUE; /* arena allocates using zones */ \ for (k = 0; k < nblocks; ++k) { \ blocks[k].p = NULL; \ + blocks[k].s = 0; \ } \ \ for (j = 0; j < npass; ++j) { \ diff --git a/mps/code/eventcnv.c b/mps/code/eventcnv.c index 355b6efa2a2..7b7e060470f 100644 --- a/mps/code/eventcnv.c +++ b/mps/code/eventcnv.c @@ -197,6 +197,12 @@ static Res eventRead(Bool *eofOut, EventUnion *event, FILE *stream) return ResIO; } + if (event->any.size < sizeof(event->any)) + return ResFAIL; /* invalid size: too small */ + + if (event->any.size > sizeof(*event)) + return ResFAIL; /* invalid size: too large */ + /* Read the rest of the event. */ rest = event->any.size - sizeof(event->any); if (rest > 0) { diff --git a/mps/code/gcbench.c b/mps/code/gcbench.c index 80c68d7f711..2a18d1a7d10 100644 --- a/mps/code/gcbench.c +++ b/mps/code/gcbench.c @@ -318,8 +318,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; /* fall through */ - case 'M': cap *= 1024; /* fall through */ + case 'G': cap <<= 20; p++; break; + case 'M': cap <<= 10; p++; break; case 'K': p++; break; default: cap = 0; break; } @@ -340,9 +340,9 @@ int main(int argc, char *argv[]) { char *p; arenasize = (unsigned)strtoul(optarg, &p, 10); switch(toupper(*p)) { - case 'G': arenasize *= 1024; - case 'M': arenasize *= 1024; - case 'K': arenasize *= 1024; break; + case 'G': arenasize <<= 30; break; + case 'M': arenasize <<= 20; break; + case 'K': arenasize <<= 10; break; case '\0': break; default: fprintf(stderr, "Bad arena size %s\n", optarg); diff --git a/mps/code/meter.h b/mps/code/meter.h index 7a7f8266e87..f1731400e42 100644 --- a/mps/code/meter.h +++ b/mps/code/meter.h @@ -1,7 +1,7 @@ /* meter.h: METER 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. * * .sources: mps.design.metrics. * @@ -45,9 +45,12 @@ extern void MeterEmit(Meter meter); #define METER_ACC(meter, delta) \ STATISTIC(MeterAccumulate(&(meter), delta)) #if defined(STATISTICS) -#define METER_WRITE(meter, stream) MeterWrite(&(meter), stream) +#define METER_WRITE(meter, stream) BEGIN \ + Res _res = MeterWrite(&(meter), (stream)); \ + if (_res != ResOK) return _res; \ + END #elif defined(STATISTICS_NONE) -#define METER_WRITE(meter, stream) (ResOK) +#define METER_WRITE(meter, stream) NOOP #else #error "No statistics configured." #endif @@ -59,7 +62,7 @@ extern void MeterEmit(Meter meter); /* 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.c b/mps/code/mpm.c index f544acca401..a46fdf5fb10 100644 --- a/mps/code/mpm.c +++ b/mps/code/mpm.c @@ -174,16 +174,16 @@ Word (WordAlignDown)(Word word, Align alignment) /* SizeIsP2 -- test whether a size is a power of two */ -Bool SizeIsP2(Size size) +Bool (SizeIsP2)(Size size) { - return WordIsP2((Word)size); + return SizeIsP2(size); } /* WordIsP2 -- tests whether a word is a power of two */ -Bool WordIsP2(Word word) +Bool (WordIsP2)(Word word) { - return word > 0 && (word & (word - 1)) == 0; + return WordIsP2(word); } diff --git a/mps/code/mpm.h b/mps/code/mpm.h index d830674512f..3423ffdb03c 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -143,11 +143,13 @@ extern Bool ResIsAllocFailure(Res res); * SizeFloorLog2 returns the floor of the logarithm in base 2 of size. * size can be any positive non-zero value. */ -extern Bool SizeIsP2(Size size); +extern Bool (SizeIsP2)(Size size); +#define SizeIsP2(size) WordIsP2((Word)size) extern Shift SizeLog2(Size size); extern Shift SizeFloorLog2(Size size); -extern Bool WordIsP2(Word word); +extern Bool (WordIsP2)(Word word); +#define WordIsP2(word) ((word) > 0 && ((word) & ((word) - 1)) == 0) /* Formatted Output -- see , */ diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index b2903481b45..51b346e9f43 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -1050,68 +1050,37 @@ static Res MVTDescribe(Pool pool, mps_lib_FILE *stream) res = FreelistDescribe(MVTFreelist(mvt), stream); if(res != ResOK) return res; - res = METER_WRITE(mvt->segAllocs, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->segFrees, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->bufferFills, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->bufferEmpties, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->poolFrees, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->poolSize, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->poolAllocated, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->poolAvailable, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->poolUnavailable, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->poolUtilization, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->finds, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->overflows, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->underflows, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->refills, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->refillPushes, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->returns, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->perfectFits, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->firstFits, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->secondFits, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->failures, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->emergencyContingencies, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->fragLimitContingencies, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->contingencySearches, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->contingencyHardSearches, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->splinters, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->splintersUsed, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->splintersDropped, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->sawdust, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->exceptions, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->exceptionSplinters, stream); - if (res != ResOK) return res; - res = METER_WRITE(mvt->exceptionReturns, stream); - if (res != ResOK) return res; + METER_WRITE(mvt->segAllocs, stream); + METER_WRITE(mvt->segFrees, stream); + METER_WRITE(mvt->bufferFills, stream); + METER_WRITE(mvt->bufferEmpties, stream); + METER_WRITE(mvt->poolFrees, stream); + METER_WRITE(mvt->poolSize, stream); + METER_WRITE(mvt->poolAllocated, stream); + METER_WRITE(mvt->poolAvailable, stream); + METER_WRITE(mvt->poolUnavailable, stream); + METER_WRITE(mvt->poolUtilization, stream); + METER_WRITE(mvt->finds, stream); + METER_WRITE(mvt->overflows, stream); + METER_WRITE(mvt->underflows, stream); + METER_WRITE(mvt->refills, stream); + METER_WRITE(mvt->refillPushes, stream); + METER_WRITE(mvt->returns, stream); + METER_WRITE(mvt->perfectFits, stream); + METER_WRITE(mvt->firstFits, stream); + METER_WRITE(mvt->secondFits, stream); + METER_WRITE(mvt->failures, stream); + METER_WRITE(mvt->emergencyContingencies, stream); + METER_WRITE(mvt->fragLimitContingencies, stream); + METER_WRITE(mvt->contingencySearches, stream); + METER_WRITE(mvt->contingencyHardSearches, stream); + METER_WRITE(mvt->splinters, stream); + METER_WRITE(mvt->splintersUsed, stream); + METER_WRITE(mvt->splintersDropped, stream); + METER_WRITE(mvt->sawdust, stream); + METER_WRITE(mvt->exceptions, stream); + METER_WRITE(mvt->exceptionSplinters, stream); + METER_WRITE(mvt->exceptionReturns, stream); res = WriteF(stream, "}\n", NULL); return res; diff --git a/mps/code/sac.c b/mps/code/sac.c index 435988cf867..3caf9ab893f 100644 --- a/mps/code/sac.c +++ b/mps/code/sac.c @@ -48,18 +48,20 @@ static Bool SACCheck(SAC sac) CHECKL(esac->_middle > 0); /* check classes above middle */ prevSize = esac->_middle; - for (j = sac->middleIndex + 1, i = 0; - j <= sac->classesCount; ++j, i += 2) { + for (j = sac->middleIndex + 1, i = 0; j < sac->classesCount; ++j, i += 2) { CHECKL(prevSize < esac->_freelists[i]._size); b = sacFreeListBlockCheck(&(esac->_freelists[i])); if (!b) return b; prevSize = esac->_freelists[i]._size; } /* check overlarge class */ - CHECKL(esac->_freelists[i-2]._size == SizeMAX); - CHECKL(esac->_freelists[i-2]._count == 0); - CHECKL(esac->_freelists[i-2]._count_max == 0); - CHECKL(esac->_freelists[i-2]._blocks == NULL); + CHECKL(prevSize < esac->_freelists[i]._size); + b = sacFreeListBlockCheck(&(esac->_freelists[i])); + if (!b) return b; + CHECKL(esac->_freelists[i]._size == SizeMAX); + CHECKL(esac->_freelists[i]._count == 0); + CHECKL(esac->_freelists[i]._count_max == 0); + CHECKL(esac->_freelists[i]._blocks == NULL); /* check classes below middle */ prevSize = esac->_middle; for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) { @@ -69,6 +71,7 @@ static Bool SACCheck(SAC sac) prevSize = esac->_freelists[i]._size; } /* check smallest class */ + CHECKL(prevSize > esac->_freelists[i]._size); CHECKL(esac->_freelists[i]._size == 0); b = sacFreeListBlockCheck(&(esac->_freelists[i])); return b; diff --git a/mps/code/trace.c b/mps/code/trace.c index 924badcd541..c726d8b8597 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -797,10 +797,11 @@ void TraceDestroy(Trace trace) (TraceStatReclaim, trace, trace->reclaimCount, trace->reclaimSize)); + EVENT1(TraceDestroy, trace); + trace->sig = SigInvalid; trace->arena->busyTraces = TraceSetDel(trace->arena->busyTraces, trace); trace->arena->flippedTraces = TraceSetDel(trace->arena->flippedTraces, trace); - EVENT1(TraceDestroy, trace); } diff --git a/mps/code/vman.c b/mps/code/vman.c index db7795c9f2e..6ba3d0b9dff 100644 --- a/mps/code/vman.c +++ b/mps/code/vman.c @@ -1,7 +1,7 @@ /* vman.c: ANSI VM: MALLOC-BASED PSEUDO MEMORY MAPPING * * $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" @@ -117,13 +117,13 @@ void VMDestroy(VM vm) AVER(vm->mapped == (Size)0); AVER(vm->reserved == AddrOffset(vm->base, vm->limit)); + EVENT1(VMDestroy, vm); + memset((void *)vm->base, VMJunkBYTE, AddrOffset(vm->base, vm->limit)); free(vm->block); vm->sig = SigInvalid; - free(vm); - - EVENT1(VMDestroy, vm); + free(vm); } @@ -215,7 +215,7 @@ void VMUnmap(VM vm, Addr base, Addr 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/vmix.c b/mps/code/vmix.c index 01a0919b820..0903a031a2c 100644 --- a/mps/code/vmix.c +++ b/mps/code/vmix.c @@ -1,7 +1,7 @@ /* vmix.c: VIRTUAL MEMORY MAPPING FOR UNIX (ISH) * * $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 the implementation of the virtual memory mapping * interface (vm.h) for Unix-like operating systems. It was created @@ -186,6 +186,8 @@ void VMDestroy(VM vm) AVERT(VM, vm); AVER(vm->mapped == (Size)0); + EVENT1(VMDestroy, vm); + /* This appears to be pretty pointless, since the descriptor */ /* page is about to vanish completely. However, munmap might fail */ /* for some reason, and this would ensure that it was still */ @@ -197,8 +199,6 @@ void VMDestroy(VM vm) r = munmap((void *)vm, (size_t)SizeAlignUp(sizeof(VMStruct), vm->align)); AVER(r == 0); - - EVENT1(VMDestroy, vm); } @@ -304,7 +304,7 @@ void VMUnmap(VM vm, Addr base, Addr 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/vmw3.c b/mps/code/vmw3.c index e82f14ccd51..5be8153c73c 100644 --- a/mps/code/vmw3.c +++ b/mps/code/vmw3.c @@ -1,7 +1,7 @@ /* vmw3.c: VIRTUAL MEMORY MAPPING FOR WIN32 * * $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: See . * @@ -191,6 +191,8 @@ void VMDestroy(VM vm) AVERT(VM, vm); AVER(vm->mapped == 0); + EVENT1(VMDestroy, vm); + /* This appears to be pretty pointless, since the vm descriptor page * is about to vanish completely. However, the VirtualFree might * fail and it would be nice to have a dead sig there. */ @@ -201,7 +203,6 @@ void VMDestroy(VM vm) b = VirtualFree((LPVOID)vm, (SIZE_T)0, MEM_RELEASE); AVER(b != 0); - EVENT1(VMDestroy, vm); } @@ -303,7 +304,7 @@ void VMUnmap(VM vm, Addr base, Addr 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. * From 1a9dd526d9e3698f99ee068cd5bdd2e3e4718196 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 12:06:28 +0100 Subject: [PATCH 12/75] Add -wconversion to options for gcc and clang. Ensure that the MPS builds with this option with Clang. Copied from Perforce Change: 185457 ServerID: perforce.ravenbrook.com --- mps/code/gc.gmk | 1 + mps/code/ll.gmk | 1 + mps/code/nailboard.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mps/code/gc.gmk b/mps/code/gc.gmk index 826cb0ef659..d3716ca9f18 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -16,6 +16,7 @@ CFLAGSCOMPILER := \ -Waggregate-return \ -Wall \ -Wcast-qual \ + -Wconversion \ -Werror \ -Wextra \ -Winline \ diff --git a/mps/code/ll.gmk b/mps/code/ll.gmk index dc2595c511f..6a8c96e6731 100644 --- a/mps/code/ll.gmk +++ b/mps/code/ll.gmk @@ -17,6 +17,7 @@ CFLAGSCOMPILER := \ -Waggregate-return \ -Wall \ -Wcast-qual \ + -Wconversion \ -Werror \ -Wextra \ -Winline \ diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index dc669a67ef7..709fd915121 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -44,7 +44,7 @@ static Count nailboardNails(Nailboard board) static Count nailboardLevelBits(Count nails, Index level) { - Shift shift = level * LEVEL_SHIFT; + Shift shift = (Shift)(level * LEVEL_SHIFT); return (nails + (1 << shift) - 1) >> shift; } From c5bf5d492393455dedf5fc645f56ffc798ab7e38 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 12:17:39 +0100 Subject: [PATCH 13/75] Not ready for gcc -wconversion. Copied from Perforce Change: 185459 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 d3716ca9f18..826cb0ef659 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -16,7 +16,6 @@ CFLAGSCOMPILER := \ -Waggregate-return \ -Wall \ -Wcast-qual \ - -Wconversion \ -Werror \ -Wextra \ -Winline \ From 3a36920e400a77154eda74d48cc737d063d18881 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 12:42:26 +0100 Subject: [PATCH 14/75] Fix the build for gcc on os x: gcc warns about the missing return in protcatchthread, but we don't want to add one because that would be unreachable code. so use __attribute__((__noreturn__)) instead. Copied from Perforce Change: 185461 ServerID: perforce.ravenbrook.com --- mps/code/config.h | 10 ++++++++++ mps/code/protxc.c | 1 + 2 files changed, 11 insertions(+) diff --git a/mps/code/config.h b/mps/code/config.h index e29127c153c..b781f1da591 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -231,6 +231,16 @@ #define ATTRIBUTE_NO_SANITIZE_ADDRESS #endif +/* Attribute for functions that do not return. + * GCC: + * Clang: + */ +#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL) +#define ATTRIBUTE_NORETURN __attribute__((__noreturn__)) +#else +#define ATTRIBUTE_NORETURN +#endif + /* EPVMDefaultSubsequentSegSIZE is a default for the alignment of * subsequent segments (non-initial at each save level) in EPVM. See diff --git a/mps/code/protxc.c b/mps/code/protxc.c index 8f62bb3a5df..58dee81a179 100644 --- a/mps/code/protxc.c +++ b/mps/code/protxc.c @@ -282,6 +282,7 @@ static void protCatchOne(void) * handler won't cause a deadlock. */ +ATTRIBUTE_NORETURN static void *protCatchThread(void *p) { UNUSED(p); for (;;) From 93a79ac8a614b5eafbc3300bd0101e1b9f09ded1 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 14:25:15 +0100 Subject: [PATCH 15/75] Add -wconversion to the options for gcc. ensure that the mps builds. Copied from Perforce Change: 185463 ServerID: perforce.ravenbrook.com --- mps/code/buffer.c | 6 +++--- mps/code/eventcom.h | 10 +++++++--- mps/code/fbmtest.c | 2 +- mps/code/fotest.c | 4 ++-- mps/code/gc.gmk | 1 + mps/code/global.c | 2 +- mps/code/misc.h | 15 +++++++++++++-- mps/code/mpm.h | 8 ++++---- mps/code/mpmst.h | 8 ++++---- mps/code/mpmtypes.h | 2 +- mps/code/nailboard.c | 2 +- mps/code/poolmfs.c | 2 +- mps/code/poolmvff.c | 2 +- mps/code/seg.c | 12 ++++++------ mps/code/trace.c | 2 +- 15 files changed, 47 insertions(+), 31 deletions(-) diff --git a/mps/code/buffer.c b/mps/code/buffer.c index baa553a19a2..90aec0b7a45 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -1075,7 +1075,7 @@ static Res bufferTrivInit(Buffer buffer, Pool pool, ArgList args) AVERT(Buffer, buffer); AVERT(Pool, pool); UNUSED(args); - EVENT3(BufferInit, buffer, pool, buffer->isMutator); + EVENT3(BufferInit, buffer, pool, BOOL(buffer->isMutator)); return ResOK; } @@ -1288,7 +1288,7 @@ static Res segBufInit(Buffer buffer, Pool pool, ArgList args) segbuf->rankSet = RankSetEMPTY; AVERT(SegBuf, segbuf); - EVENT3(BufferInitSeg, buffer, pool, buffer->isMutator); + EVENT3(BufferInitSeg, buffer, pool, BOOL(buffer->isMutator)); return ResOK; } @@ -1515,7 +1515,7 @@ static Res rankBufInit(Buffer buffer, Pool pool, ArgList args) BufferSetRankSet(buffer, RankSetSingle(rank)); /* There's nothing to check that the superclass doesn't, so no AVERT. */ - EVENT4(BufferInitRank, buffer, pool, buffer->isMutator, rank); + EVENT4(BufferInitRank, buffer, pool, BOOL(buffer->isMutator), rank); return ResOK; } diff --git a/mps/code/eventcom.h b/mps/code/eventcom.h index 6114b045d48..d2c43a31c60 100644 --- a/mps/code/eventcom.h +++ b/mps/code/eventcom.h @@ -1,6 +1,6 @@ /* -- Event Logging Common Definitions * - * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * $Id$ * * .sources: mps.design.telemetry @@ -89,7 +89,11 @@ typedef Word EventFW; /* word */ typedef unsigned EventFU; /* unsigned integer */ typedef char EventFS[EventStringLengthMAX + sizeof('\0')]; /* string */ typedef double EventFD; /* double */ -typedef int EventFB; /* boolean */ +/* EventFB must be unsigned (even though Bool is a typedef for int) + * because it used as the type of a bitfield with width 1, and we need + * the legals values of the field to be 0 and 1 (not 0 and -1 which + * would be the case for int : 1). */ +typedef unsigned EventFB; /* Boolean */ /* Event packing bitfield specifiers */ #define EventFP_BITFIELD @@ -133,7 +137,7 @@ typedef union EventUnion { /* 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/fbmtest.c b/mps/code/fbmtest.c index 9f3754b3496..231d02482a7 100644 --- a/mps/code/fbmtest.c +++ b/mps/code/fbmtest.c @@ -560,7 +560,7 @@ extern int main(int argc, char *argv[]) Align align; testlib_init(argc, argv); - align = (1 << rnd() % 4) * MPS_PF_ALIGN; + align = sizeof(void *) << (rnd() % 4); NAllocateTried = NAllocateSucceeded = NDeallocateTried = NDeallocateSucceeded = 0; diff --git a/mps/code/fotest.c b/mps/code/fotest.c index 9dab6650ede..2e63d4e121b 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "mps_arena_create"); - alignment = (1 << (rnd() % 4)) * MPS_PF_ALIGN; + alignment = sizeof(void *) << (rnd() % 4); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, (64 + rnd() % 64) * 1024); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, (1 + rnd() % 8) * 8); @@ -190,7 +190,7 @@ int main(int argc, char *argv[]) die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "mps_arena_create"); - alignment = (1 << (rnd() % 4)) * MPS_PF_ALIGN; + alignment = sizeof(void *) << (rnd() % 4); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ALIGN, alignment); MPS_ARGS_ADD(args, MPS_KEY_MIN_SIZE, (1 + rnd() % 4) * 4); diff --git a/mps/code/gc.gmk b/mps/code/gc.gmk index 826cb0ef659..d3716ca9f18 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -16,6 +16,7 @@ CFLAGSCOMPILER := \ -Waggregate-return \ -Wall \ -Wcast-qual \ + -Wconversion \ -Werror \ -Wextra \ -Winline \ diff --git a/mps/code/global.c b/mps/code/global.c index 22326aa391f..da97184130c 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -1131,7 +1131,7 @@ void ArenaSetEmergency(Arena arena, Bool emergency) AVERT(Arena, arena); AVERT(Bool, emergency); - EVENT2(ArenaSetEmergency, arena, emergency); + EVENT2(ArenaSetEmergency, arena, BOOL(emergency)); arena->emergency = emergency; } diff --git a/mps/code/misc.h b/mps/code/misc.h index 6ba4be5f49d..444df857317 100644 --- a/mps/code/misc.h +++ b/mps/code/misc.h @@ -1,7 +1,7 @@ /* misc.h: MISCELLANEOUS DEFINITIONS * * $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) 2001 Global Graphics Software. * * Small general things which are useful for C but aren't part of the @@ -170,6 +170,16 @@ typedef const struct SrcIdStruct { ((type *)(void *)((char *)(p) - offsetof(type, field))) +/* BITFIELD -- coerce a value into a bitfield + * + * This coerces value to the given width and type in a way that avoids + * warnings from gcc -Wconversion about possible loss of data. + */ + +#define BITFIELD(type, value, width) ((type)value & (((type)1 << (width)) - 1)) +#define BOOL(v) BITFIELD(unsigned, (v), 1) + + /* Bit Sets -- sets of integers in [0,N-1]. * * Can be used on any unsigned integral type, ty. These definitions @@ -191,6 +201,7 @@ typedef const struct SrcIdStruct { #define BS_SUB(s1, s2) BS_SUPER((s2), (s1)) #define BS_IS_SINGLE(s) ( ((s) != 0) && (((s) & ((s)-1)) == 0) ) #define BS_SYM_DIFF(s1, s2) ((s1) ^ (s2)) +#define BS_BITFIELD(ty, s) BITFIELD(ty ## Set, (s), ty ## LIMIT) #endif /* misc_h */ @@ -198,7 +209,7 @@ typedef const struct SrcIdStruct { /* 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/mpm.h b/mps/code/mpm.h index 3423ffdb03c..0cbad2b0f1c 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -711,10 +711,10 @@ extern Addr (SegLimit)(Seg seg); #define SegSummary(seg) (((GCSeg)(seg))->summary) -#define SegSetPM(seg, mode) ((void)((seg)->pm = (mode))) -#define SegSetSM(seg, mode) ((void)((seg)->sm = (mode))) -#define SegSetDepth(seg, d) ((void)((seg)->depth = (d))) -#define SegSetNailed(seg, ts) ((void)((seg)->nailed = (ts))) +#define SegSetPM(seg, mode) ((void)((seg)->pm = BS_BITFIELD(Access, (mode)))) +#define SegSetSM(seg, mode) ((void)((seg)->sm = BS_BITFIELD(Access, (mode)))) +#define SegSetDepth(seg, d) ((void)((seg)->depth = BITFIELD(unsigned, (d), ShieldDepthWIDTH))) +#define SegSetNailed(seg, ts) ((void)((seg)->nailed = BS_BITFIELD(Trace, (ts)))) /* Buffer Interface -- see */ diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 85e95a78ec1..5d38f3a3319 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -1,7 +1,7 @@ /* mpmst.h: MEMORY POOL MANAGER DATA STRUCTURES * * $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) 2001 Global Graphics Software. * * .design: This header file crosses module boundaries. The relevant @@ -275,8 +275,8 @@ typedef struct SegStruct { /* segment structure */ RingStruct poolRing; /* link in list of segs in pool */ Addr limit; /* limit of segment */ unsigned depth : ShieldDepthWIDTH; /* see */ - AccessSet pm : AccessSetWIDTH; /* protection mode, */ - AccessSet sm : AccessSetWIDTH; /* shield mode, */ + AccessSet pm : AccessLIMIT; /* protection mode, */ + AccessSet sm : AccessLIMIT; /* shield mode, */ TraceSet grey : TraceLIMIT; /* traces for which seg is grey */ TraceSet white : TraceLIMIT; /* traces for which seg is white */ TraceSet nailed : TraceLIMIT; /* traces for which seg has nailed objects */ @@ -738,7 +738,7 @@ typedef struct AllocPatternStruct { /* 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/mpmtypes.h b/mps/code/mpmtypes.h index 693a2262247..e22e77d8f69 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -271,7 +271,7 @@ typedef struct TraceMessageStruct *TraceMessage; /* trace end */ #define AccessSetEMPTY ((AccessSet)0) /* */ #define AccessREAD ((AccessSet)(1<<0)) #define AccessWRITE ((AccessSet)(1<<1)) -#define AccessSetWIDTH (2) +#define AccessLIMIT (2) #define RefSetEMPTY BS_EMPTY(RefSet) #define RefSetUNIV BS_UNIV(RefSet) #define ZoneSetEMPTY BS_EMPTY(ZoneSet) diff --git a/mps/code/nailboard.c b/mps/code/nailboard.c index 709fd915121..852c98949e7 100644 --- a/mps/code/nailboard.c +++ b/mps/code/nailboard.c @@ -45,7 +45,7 @@ static Count nailboardNails(Nailboard board) static Count nailboardLevelBits(Count nails, Index level) { Shift shift = (Shift)(level * LEVEL_SHIFT); - return (nails + (1 << shift) - 1) >> shift; + return (nails + ((Count)1 << shift) - 1) >> shift; } Bool NailboardCheck(Nailboard board) diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index fbb125a71f2..214b2b232d3 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -136,7 +136,7 @@ static Res MFSInit(Pool pool, ArgList args) mfs->sig = MFSSig; AVERT(MFS, mfs); - EVENT5(PoolInitMFS, pool, arena, extendBy, extendSelf, unitSize); + EVENT5(PoolInitMFS, pool, arena, extendBy, BOOL(extendSelf), unitSize); return ResOK; } diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index 201d2047104..fc4307d50a2 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -610,7 +610,7 @@ static Res MVFFInit(Pool pool, ArgList args) mvff->sig = MVFFSig; AVERT(MVFF, mvff); EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align, - slotHigh, arenaHigh, firstFit); + BOOL(slotHigh), BOOL(arenaHigh), BOOL(firstFit)); return ResOK; failInit: diff --git a/mps/code/seg.c b/mps/code/seg.c index 069b2c50049..31dd0759ff9 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -593,7 +593,7 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi, if (ResOK != res) goto failMerge; - EVENT3(SegMerge, segLo, segHi, withReservoirPermit); + EVENT3(SegMerge, segLo, segHi, BOOL(withReservoirPermit)); /* Deallocate segHi object */ ControlFree(arena, segHi, class->size); AVERT(Seg, segLo); @@ -1200,7 +1200,7 @@ static void gcSegSetGreyInternal(Seg seg, TraceSet oldGrey, TraceSet grey) /* Internal method. Parameters are checked by caller */ gcseg = SegGCSeg(seg); arena = PoolArena(SegPool(seg)); - seg->grey = grey; + seg->grey = BS_BITFIELD(Trace, grey); /* If the segment is now grey and wasn't before, add it to the */ /* appropriate grey list so that TraceFindGrey can locate it */ @@ -1313,11 +1313,11 @@ static void gcSegSetWhite(Seg seg, TraceSet white) AVERT_CRITICAL(Tract, tract); AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg)); - TractSetWhite(tract, white); + TractSetWhite(tract, BS_BITFIELD(Trace, white)); } AVER(addr == limit); - seg->white = white; + seg->white = BS_BITFIELD(Trace, white); } @@ -1350,7 +1350,7 @@ static void gcSegSetRankSet(Seg seg, RankSet rankSet) arena = PoolArena(SegPool(seg)); oldRankSet = seg->rankSet; - seg->rankSet = rankSet; + seg->rankSet = BS_BITFIELD(Rank, rankSet); if (oldRankSet == RankSetEMPTY) { if (rankSet != RankSetEMPTY) { @@ -1427,7 +1427,7 @@ static void gcSegSetRankSummary(Seg seg, RankSet rankSet, RefSet summary) wasShielded = (seg->rankSet != RankSetEMPTY && gcseg->summary != RefSetUNIV); willbeShielded = (rankSet != RankSetEMPTY && summary != RefSetUNIV); - seg->rankSet = rankSet; + seg->rankSet = BS_BITFIELD(Rank, rankSet); gcseg->summary = summary; if (willbeShielded && !wasShielded) { diff --git a/mps/code/trace.c b/mps/code/trace.c index c726d8b8597..61e9d396155 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1570,7 +1570,7 @@ static void TraceStartPoolGen(Chain chain, GenDesc desc, Bool top, Index i) Ring n, nn; RING_FOR(n, &desc->locusRing, nn) { PoolGen gen = RING_ELT(PoolGen, genRing, n); - EVENT11(TraceStartPoolGen, chain, top, i, desc, + EVENT11(TraceStartPoolGen, chain, BOOL(top), i, desc, desc->capacity, desc->mortality, desc->zones, gen->pool, gen->nr, gen->totalSize, gen->newSizeAtCreate); From da307afb8181412dff5459d37a5ac6f58c7269f8 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 15:17:20 +0100 Subject: [PATCH 16/75] Turn on -wduplicate-enum and -wmissing-variable-declarations options for clang. ensure the mps compiles with these options. Copied from Perforce Change: 185466 ServerID: perforce.ravenbrook.com --- mps/code/amcssth.c | 10 +++++----- mps/code/arg.h | 5 +++-- mps/code/buffer.c | 4 ++-- mps/code/event.c | 4 ++-- mps/code/eventcom.h | 3 ++- mps/code/eventtxt.c | 2 +- mps/code/fmtscheme.c | 10 ++-------- mps/code/global.c | 1 + mps/code/ll.gmk | 2 ++ mps/code/lockut.c | 2 +- mps/code/misc.h | 1 + mps/code/poolawl.c | 4 ++++ mps/code/qs.c | 2 +- mps/code/steptest.c | 26 +++++++++++++------------- mps/code/version.c | 2 ++ 15 files changed, 42 insertions(+), 36 deletions(-) diff --git a/mps/code/amcssth.c b/mps/code/amcssth.c index 2f17f97ca09..2f91edee93e 100644 --- a/mps/code/amcssth.c +++ b/mps/code/amcssth.c @@ -83,11 +83,11 @@ static void report(mps_arena_t arena) } -mps_arena_t arena; -mps_fmt_t format; -mps_chain_t chain; -mps_root_t exactRoot, ambigRoot; -unsigned long objs = 0; +static mps_arena_t arena; +static mps_fmt_t format; +static mps_chain_t chain; +static mps_root_t exactRoot, ambigRoot; +static unsigned long objs = 0; /* make -- create one new object */ diff --git a/mps/code/arg.h b/mps/code/arg.h index dd458efe7b7..bb184dddad9 100644 --- a/mps/code/arg.h +++ b/mps/code/arg.h @@ -1,7 +1,7 @@ /* arg.h: Keyword 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 . */ @@ -28,6 +28,7 @@ typedef struct mps_key_s { } KeyStruct; #define ARG_DEFINE_KEY(id, type) \ + extern const KeyStruct _mps_key_##id; \ const KeyStruct _mps_key_##id = {KeySig, #id, ArgCheck##type} #define argsNone mps_args_none @@ -62,7 +63,7 @@ extern Bool ArgCheckPool(Arg arg); /* 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/buffer.c b/mps/code/buffer.c index 90aec0b7a45..27314924600 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -980,14 +980,14 @@ Bool BufferIsTrappedByMutator(Buffer buffer) * * Just represent the two patterns by two different pointers to dummies. */ -AllocPatternStruct AllocPatternRampStruct = {'\0'}; +static AllocPatternStruct AllocPatternRampStruct = {'\0'}; AllocPattern AllocPatternRamp(void) { return &AllocPatternRampStruct; } -AllocPatternStruct AllocPatternRampCollectAllStruct = {'\0'}; +static AllocPatternStruct AllocPatternRampCollectAllStruct = {'\0'}; AllocPattern AllocPatternRampCollectAll(void) { diff --git a/mps/code/event.c b/mps/code/event.c index 2e7468c3752..d2166dbba2d 100644 --- a/mps/code/event.c +++ b/mps/code/event.c @@ -44,13 +44,13 @@ char EventBuffer[EventKindLIMIT][EventBufferSIZE]; char *EventLast[EventKindLIMIT]; /* Pointers to the last even written out of each buffer. */ -char *EventWritten[EventKindLIMIT]; +static char *EventWritten[EventKindLIMIT]; EventControlSet EventKindControl; /* Bit set used to control output. */ /* A single event structure output once per buffer flush. */ -EventEventClockSyncStruct eventClockSyncStruct; +static EventEventClockSyncStruct eventClockSyncStruct; /* eventClockSync -- Populate and write the clock sync event. */ diff --git a/mps/code/eventcom.h b/mps/code/eventcom.h index d2c43a31c60..931c975596d 100644 --- a/mps/code/eventcom.h +++ b/mps/code/eventcom.h @@ -56,7 +56,8 @@ ENUM_DECLARE(EventKind) enum EventDefinitionsEnum { EVENT_LIST(EVENT_ENUM, X) - EventEnumWarningSuppressor /* suppress comma-at-end-of-enum warning */ + /* suppress comma-at-end-of-enum warning */ + EventEnumWarningSuppressor = USHRT_MAX }; diff --git a/mps/code/eventtxt.c b/mps/code/eventtxt.c index 5b7f7ab1312..692aa348296 100644 --- a/mps/code/eventtxt.c +++ b/mps/code/eventtxt.c @@ -171,7 +171,7 @@ static double parseDouble(char **pInOut) #define MAX_STRING_LENGTH 1024 -char strBuf[MAX_STRING_LENGTH]; +static char strBuf[MAX_STRING_LENGTH]; static char *parseString(char **pInOut) { diff --git a/mps/code/fmtscheme.c b/mps/code/fmtscheme.c index 5299c8f3525..11900130a71 100644 --- a/mps/code/fmtscheme.c +++ b/mps/code/fmtscheme.c @@ -12,14 +12,8 @@ /* special objects */ -obj_t obj_empty; /* (), the empty list */ -obj_t obj_eof; /* end of file */ -obj_t obj_error; /* error indicator */ -obj_t obj_true; /* #t, boolean true */ -obj_t obj_false; /* #f, boolean false */ -obj_t obj_undefined; /* undefined result indicator */ -obj_t obj_tail; /* tail recursion indicator */ -obj_t obj_deleted; /* deleted key in hashtable */ +static obj_t obj_true; /* #t, boolean true */ +static obj_t obj_false; /* #f, boolean false */ /* MPS globals */ diff --git a/mps/code/global.c b/mps/code/global.c index da97184130c..9bfe9c20dc0 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -617,6 +617,7 @@ void ArenaLeaveRecursive(Arena arena) * version. The format is platform-specific. We won't necessarily * publish this. */ +extern MutatorFaultContext mps_exception_info; MutatorFaultContext mps_exception_info = NULL; diff --git a/mps/code/ll.gmk b/mps/code/ll.gmk index 6a8c96e6731..24dd32b9efe 100644 --- a/mps/code/ll.gmk +++ b/mps/code/ll.gmk @@ -18,10 +18,12 @@ CFLAGSCOMPILER := \ -Wall \ -Wcast-qual \ -Wconversion \ + -Wduplicate-enum \ -Werror \ -Wextra \ -Winline \ -Wmissing-prototypes \ + -Wmissing-variable-declarations \ -Wnested-externs \ -Wno-extended-offsetof \ -Wpointer-arith \ diff --git a/mps/code/lockut.c b/mps/code/lockut.c index ec22369bc13..8b8e677b382 100644 --- a/mps/code/lockut.c +++ b/mps/code/lockut.c @@ -15,7 +15,7 @@ #define nTHREADS 4 static Lock lock; -unsigned long shared, tmp; +static unsigned long shared, tmp; static void incR(unsigned long i) diff --git a/mps/code/misc.h b/mps/code/misc.h index 444df857317..809fd7e954a 100644 --- a/mps/code/misc.h +++ b/mps/code/misc.h @@ -50,6 +50,7 @@ typedef const struct SrcIdStruct { #define SRCID(id, scmid) \ static SrcIdStruct id ## FileSrcIdStruct = \ {__FILE__, (scmid), __DATE__, __TIME__}; \ + extern SrcId id ## SrcId; \ SrcId id ## SrcId = &id ## FileSrcIdStruct diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index edcae788e3c..cbece0b41fe 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -305,10 +305,14 @@ DEFINE_SEG_CLASS(AWLSegClass, class) * it's possible to tweak them in a debugger. */ +extern Count AWLSegSALimit; Count AWLSegSALimit = AWL_SEG_SA_LIMIT; +extern Bool AWLHaveSegSALimit; Bool AWLHaveSegSALimit = AWL_HAVE_SEG_SA_LIMIT; +extern Count AWLTotalSALimit; Count AWLTotalSALimit = AWL_TOTAL_SA_LIMIT; +extern Bool AWLHaveTotalSALimit; Bool AWLHaveTotalSALimit = AWL_HAVE_TOTAL_SA_LIMIT; diff --git a/mps/code/qs.c b/mps/code/qs.c index 4d78fc6bcb8..50fe8c48723 100644 --- a/mps/code/qs.c +++ b/mps/code/qs.c @@ -50,7 +50,7 @@ static mps_addr_t isMoved(mps_addr_t object); static void copy(mps_addr_t object, mps_addr_t to); static void pad(mps_addr_t base, size_t size); -struct mps_fmt_A_s fmt_A_s = +static struct mps_fmt_A_s fmt_A_s = { (mps_align_t)4, scan, skip, copy, diff --git a/mps/code/steptest.c b/mps/code/steptest.c index c1af5b01089..deee85fef2e 100644 --- a/mps/code/steptest.c +++ b/mps/code/steptest.c @@ -71,19 +71,19 @@ static mps_addr_t ambigRoots[ambigRootsCOUNT]; /* Things we want to measure. Times are all in microseconds. */ -double alloc_time; /* Time spent allocating */ -double max_alloc_time; /* Max time taken to allocate one object */ -double step_time; /* Time spent in mps_arena_step returning 1 */ -double max_step_time; /* Max time of mps_arena_step returning 1 */ -double no_step_time; /* Time spent in mps_arena_step returning 0 */ -double max_no_step_time; /* Max time of mps_arena_step returning 0 */ +static double alloc_time; /* Time spent allocating */ +static double max_alloc_time; /* Max time taken to allocate one object */ +static double step_time; /* Time spent in mps_arena_step returning 1 */ +static double max_step_time; /* Max time of mps_arena_step returning 1 */ +static double no_step_time; /* Time spent in mps_arena_step returning 0 */ +static double max_no_step_time; /* Max time of mps_arena_step returning 0 */ -double total_clock_time; /* Time spent reading the clock */ -long clock_reads; /* Number of times clock is read */ -long steps; /* # of mps_arena_step calls returning 1 */ -long no_steps; /* # of mps_arena_step calls returning 0 */ -size_t alloc_bytes; /* # of bytes allocated */ -long commit_failures; /* # of times mps_commit fails */ +static double total_clock_time; /* Time spent reading the clock */ +static long clock_reads; /* Number of times clock is read */ +static long steps; /* # of mps_arena_step calls returning 1 */ +static long no_steps; /* # of mps_arena_step calls returning 0 */ +static size_t alloc_bytes; /* # of bytes allocated */ +static long commit_failures; /* # of times mps_commit fails */ /* Operating-system dependent timing. Defines two functions, void @@ -151,7 +151,7 @@ static double my_clock(void) * on thrush.ravenbrook.com on 2002-06-28, clock_time goes from 5.43 * us near process start to 7.45 us later). */ -double clock_time; /* current estimate of time to read the clock */ +static double clock_time; /* current estimate of time to read the clock */ /* take at least this many microseconds to set the clock */ #define CLOCK_TIME_SET 10000 diff --git a/mps/code/version.c b/mps/code/version.c index 9f8d644e47a..4771c8a7c69 100644 --- a/mps/code/version.c +++ b/mps/code/version.c @@ -47,6 +47,7 @@ SRCID(version, "$Id$"); * (assuming we've made any substantial changes to the library this year). */ +extern char MPSCopyrightNotice[]; char MPSCopyrightNotice[] = "Portions copyright (c) 2010-2014 Ravenbrook Limited and Global Graphics Software."; @@ -59,6 +60,7 @@ char MPSCopyrightNotice[] = * see also guide.mps.version. */ +extern char MPSVersionString[]; char MPSVersionString[] = "@(#)Ravenbrook MPS, " "product." MPS_PROD_STRING ", " MPS_RELEASE ", platform." MPS_PF_STRING From 55273fd68b66f325382919d6893c9f000b4cdb64 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 15:28:03 +0100 Subject: [PATCH 17/75] Turn -wconversion off again. (the mps builds with this option with gcc 4.8 but not with gcc 4.6.3 on the travis buildbots.) Copied from Perforce Change: 185467 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 d3716ca9f18..826cb0ef659 100644 --- a/mps/code/gc.gmk +++ b/mps/code/gc.gmk @@ -16,7 +16,6 @@ CFLAGSCOMPILER := \ -Waggregate-return \ -Wall \ -Wcast-qual \ - -Wconversion \ -Werror \ -Wextra \ -Winline \ From 2f50660fcf23a3456d843714470567160440eced Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 20:37:42 +0100 Subject: [PATCH 18/75] Exclude coverage data files from perforce. Copied from Perforce Change: 185470 ServerID: perforce.ravenbrook.com --- mps/.p4ignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mps/.p4ignore b/mps/.p4ignore index fb2e5c024e5..b640360caf6 100644 --- a/mps/.p4ignore +++ b/mps/.p4ignore @@ -18,3 +18,5 @@ code/*/*/*.d *.pyc test/test/log test/test/obj +....gcda +....gcno \ No newline at end of file From 2ef0e22c550092d62a21db01fc40cf151e1a2dfc Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 21:15:09 +0100 Subject: [PATCH 19/75] Default value for mps_key_arena_size makes it easier to create arenas. Copied from Perforce Change: 185472 ServerID: perforce.ravenbrook.com --- mps/code/arenavm.c | 6 +++--- mps/code/config.h | 2 ++ mps/manual/source/topic/arena.rst | 31 ++++++++++++++++--------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 15b79bbed51..81e0684c436 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -480,7 +480,7 @@ ARG_DEFINE_KEY(arena_contracted, Fun); static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args) { - Size userSize; /* size requested by user */ + Size userSize = VM_ARENA_SIZE_DEFAULT; /* size requested by user */ Size chunkSize; /* size actually created */ Size vmArenaSize; /* aligned size of VMArenaStruct */ Res res; @@ -495,8 +495,8 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args) AVER(class == VMArenaClassGet()); AVERT(ArgList, args); - ArgRequire(&arg, args, MPS_KEY_ARENA_SIZE); - userSize = arg.val.size; + if (ArgPick(&arg, args, MPS_KEY_ARENA_SIZE)) + userSize = arg.val.size; AVER(userSize > 0); diff --git a/mps/code/config.h b/mps/code/config.h index b781f1da591..0afa66c06bb 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -366,6 +366,8 @@ pool to be very heavily used. */ #define CONTROL_EXTEND_BY 4096 +#define VM_ARENA_SIZE_DEFAULT ((Size)1 << 20) + /* Stack configuration */ diff --git a/mps/manual/source/topic/arena.rst b/mps/manual/source/topic/arena.rst index 5220ece4007..1925117cc84 100644 --- a/mps/manual/source/topic/arena.rst +++ b/mps/manual/source/topic/arena.rst @@ -233,18 +233,18 @@ Virtual memory arenas more efficient. When creating a virtual memory arena, :c:func:`mps_arena_create_k` - requires one :term:`keyword argument`: + accepts one :term:`keyword argument` on all platforms: - * :c:macro:`MPS_KEY_ARENA_SIZE` (type :c:type:`size_t`). is the - initial amount of virtual address space, in :term:`bytes (1)`, - that the arena will reserve (this space is initially reserved so - that the arena can subsequently use it without interference from - other parts of the program, but most of it is not committed, so - it doesn't require any RAM or backing store). The arena may - allocate more virtual address space beyond this initial - reservation as and when it deems it necessary. The MPS is most - efficient if you reserve an address space that is several times - larger than your peak memory usage. + * :c:macro:`MPS_KEY_ARENA_SIZE` (type :c:type:`size_t`, default + 2\ :superscript:`20`) is the initial amount of virtual address + space, in :term:`bytes (1)`, that the arena will reserve (this + space is initially reserved so that the arena can subsequently + use it without interference from other parts of the program, but + most of it is not committed, so it doesn't require any RAM or + backing store). The arena may allocate more virtual address + space beyond this initial reservation as and when it deems it + necessary. The MPS is most efficient if you reserve an address + space that is several times larger than your peak memory usage. .. note:: @@ -252,8 +252,8 @@ Virtual memory arenas more times it has to extend its address space, the less efficient garbage collection will become. - An optional :term:`keyword argument` may be passed, but is - only used on the Windows operating system: + A second optional :term:`keyword argument` may be passed, but it + only has any effect on the Windows operating system: * :c:macro:`MPS_KEY_VMW3_TOP_DOWN` (type :c:type:`mps_bool_t`). If true, the arena will allocate address space starting at the @@ -273,8 +273,9 @@ Virtual memory arenas If the MPS fails to allocate memory for the internal arena structures, :c:func:`mps_arena_create_k` returns - :c:macro:`MPS_RES_MEMORY`. Either ``size`` was far too small or - the operating system refused to provide enough memory. + :c:macro:`MPS_RES_MEMORY`. Either :c:macro:`MPS_KEY_ARENA_SIZE` + was far too small or the operating system refused to provide + enough memory. For example:: From b033a145645696b2b29873ec3a7218659fd2ded2 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 21:18:23 +0100 Subject: [PATCH 20/75] Ensure that mpseventsql compiles with gcc -wmissing-variable-declarations. Copied from Perforce Change: 185473 ServerID: perforce.ravenbrook.com --- mps/code/eventsql.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/code/eventsql.c b/mps/code/eventsql.c index 46bfa688a9b..e1c9ea22381 100644 --- a/mps/code/eventsql.c +++ b/mps/code/eventsql.c @@ -102,7 +102,7 @@ typedef sqlite3_int64 int64; * and for reporting errors. */ -unsigned int verbosity = 0; +static unsigned int verbosity = 0; #define LOG_ALWAYS 0 #define LOG_OFTEN 1 @@ -533,7 +533,7 @@ static void logFileCompleted(sqlite3 *db, /* An array of table-creation statement strings. */ -const char *createStatements[] = { +static const char *createStatements[] = { "CREATE TABLE IF NOT EXISTS event_kind (name TEXT," " description TEXT," " enum INTEGER PRIMARY KEY)", @@ -571,7 +571,7 @@ static void makeTables(sqlite3 *db) } } -const char *glueTables[] = { +static const char *glueTables[] = { "event_kind", "event_type", "event_param", From 03c4de821bd73be06ad6f516af3ff12e3552a926 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 11 Apr 2014 21:27:31 +0100 Subject: [PATCH 21/75] Use the mps to manage memory in test cases, not malloc! Copied from Perforce Change: 185474 ServerID: perforce.ravenbrook.com --- mps/code/abqtest.c | 23 ++++++++++++++--------- mps/code/airtest.c | 6 +----- mps/code/lockcov.c | 29 ++++++++++++++++++++++++----- mps/code/lockut.c | 21 +++++++++++++++++++-- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/mps/code/abqtest.c b/mps/code/abqtest.c index 49d285c761f..367bafe730b 100644 --- a/mps/code/abqtest.c +++ b/mps/code/abqtest.c @@ -7,16 +7,16 @@ #include "abq.h" #include "mps.h" #include "mpsavm.h" +#include "mpscmfs.h" #include "mpstd.h" #include "testlib.h" -#include /* free, malloc */ #include /* printf */ SRCID(abqtest, "$Id$"); - +static mps_pool_t pool; static ABQStruct abq; /* the ABQ which we will use */ static Size abqSize; /* the size of the current ABQ */ @@ -51,9 +51,12 @@ static TestBlock testBlocks = NULL; static TestBlock CreateTestBlock(unsigned no) { - TestBlock b = malloc(sizeof(TestBlockStruct)); - cdie(b != NULL, "malloc"); + TestBlock b; + mps_addr_t p; + die(mps_alloc(&p, pool, sizeof(TestBlockStruct)), "alloc"); + + b = p; b->next = testBlocks; b->id = no; b->base = 0; @@ -79,7 +82,7 @@ static void DestroyTestBlock(TestBlock b) } } - free(b); + mps_free(pool, b, sizeof(TestBlockStruct)); } typedef struct TestClosureStruct *TestClosure; @@ -147,9 +150,6 @@ static void step(void) } } - -#define testArenaSIZE (((size_t)4)<<20) - extern int main(int argc, char *argv[]) { mps_arena_t arena; @@ -159,9 +159,14 @@ extern int main(int argc, char *argv[]) abqSize = 0; - die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), + die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none), "mps_arena_create"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, sizeof(TestBlockStruct)); + die(mps_pool_create_k(&pool, arena, mps_class_mfs(), args), "pool_create"); + } MPS_ARGS_END(args); + die(ABQInit((Arena)arena, &abq, NULL, ABQ_SIZE, sizeof(TestBlock)), "ABQInit"); diff --git a/mps/code/airtest.c b/mps/code/airtest.c index 9da2c768f84..946e585bc2f 100644 --- a/mps/code/airtest.c +++ b/mps/code/airtest.c @@ -99,11 +99,7 @@ static void test_main(int interior, int stack) mps_root_t reg_root = NULL; 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); + res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), mps_args_none); if (res != MPS_RES_OK) error("Couldn't create arena"); res = mps_chain_create(&obj_chain, scheme_arena, diff --git a/mps/code/lockcov.c b/mps/code/lockcov.c index a7289dca9ce..75ded6f202a 100644 --- a/mps/code/lockcov.c +++ b/mps/code/lockcov.c @@ -4,21 +4,37 @@ * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. */ +#include "mps.h" +#include "mpsavm.h" +#include "mpscmfs.h" #include "mpm.h" #include "testlib.h" #include "mpslib.h" #include /* printf */ -#include /* free, malloc */ int main(int argc, char *argv[]) { - Lock a = malloc(LockSize()); - Lock b = malloc(LockSize()); + mps_arena_t arena; + mps_pool_t pool; + mps_addr_t p; + Lock a, b; testlib_init(argc, argv); + die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none), + "arena_create"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, LockSize()); + die(mps_pool_create_k(&pool, arena, mps_class_mfs(), args), "pool_create"); + } MPS_ARGS_END(args); + + die(mps_alloc(&p, pool, LockSize()), "alloc a"); + a = p; + die(mps_alloc(&p, pool, LockSize()), "alloc b"); + b = p; + Insist(a != NULL); Insist(b != NULL); @@ -46,8 +62,11 @@ int main(int argc, char *argv[]) LockReleaseMPM(a); LockFinish(a); LockReleaseGlobalRecursive(); - free(a); - free(b); + + mps_free(pool, a, LockSize()); + mps_free(pool, b, LockSize()); + mps_pool_destroy(pool); + mps_arena_destroy(arena); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; diff --git a/mps/code/lockut.c b/mps/code/lockut.c index 8b8e677b382..e93bdea6815 100644 --- a/mps/code/lockut.c +++ b/mps/code/lockut.c @@ -4,12 +4,14 @@ * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. */ +#include "mps.h" +#include "mpsavm.h" +#include "mpscmfs.h" #include "mpm.h" #include "testlib.h" #include "testthr.h" #include /* printf */ -#include /* malloc */ #define nTHREADS 4 @@ -63,12 +65,23 @@ static void *thread0(void *p) int main(int argc, char *argv[]) { + mps_arena_t arena; + mps_pool_t pool; + mps_addr_t p; testthr_t t[10]; unsigned i; testlib_init(argc, argv); - lock = malloc(LockSize()); + die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none), + "arena_create"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, LockSize()); + die(mps_pool_create_k(&pool, arena, mps_class_mfs(), args), "pool_create"); + } MPS_ARGS_END(args); + + die(mps_alloc(&p, pool, LockSize()), "alloc"); + lock = p; Insist(lock != NULL); LockInit(lock); @@ -86,6 +99,10 @@ int main(int argc, char *argv[]) LockFinish(lock); + mps_free(pool, lock, LockSize()); + mps_pool_destroy(pool); + mps_arena_destroy(arena); + printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; } From 27d16fc322928028dd187cd340ec665549a4f0d9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 12 Apr 2014 15:34:43 +0100 Subject: [PATCH 22/75] Eventtxt no longer reports an error if there are multiple labels associated with an address. instead, it store all the labels encountered, and prints the one that was in force at the time of each event. Use the MPS to manage memory, not malloc/free. Recommend sort before mpseventtxt and not afterwards (data is smaller; labelling is more accurate). Copied from Perforce Change: 185477 ServerID: perforce.ravenbrook.com --- mps/code/eventtxt.c | 188 +++++++++++++++++++------- mps/manual/source/topic/telemetry.rst | 2 +- 2 files changed, 142 insertions(+), 48 deletions(-) diff --git a/mps/code/eventtxt.c b/mps/code/eventtxt.c index 692aa348296..70962450d9f 100644 --- a/mps/code/eventtxt.c +++ b/mps/code/eventtxt.c @@ -29,15 +29,19 @@ * $Id$ */ +#include "mps.h" +#include "mpsavm.h" +#include "mpscmvff.h" #include "config.h" #include "eventdef.h" #include "eventcom.h" #include "table.h" #include "testlib.h" /* for ulongest_t and associated print formats */ +#include #include -#include -#include +#include /* exit, EXIT_FAILURE, EXIT_SUCCESS */ +#include /* strcpy, strlen */ static const char *prog; /* program name */ static const char *logFileName = NULL; @@ -106,15 +110,19 @@ static void parseArgs(int argc, char *argv[]) static void *tableAlloc(void *closure, size_t size) { - UNUSED(closure); - return malloc(size); + mps_pool_t pool = closure; + mps_addr_t p; + mps_res_t res; + res = mps_alloc(&p, pool, size); + if (res != MPS_RES_OK) + everror("allocation failed: %d", res); + return p; } static void tableFree(void *closure, void *p, size_t size) { - UNUSED(closure); - UNUSED(size); - free(p); + mps_pool_t pool = closure; + mps_free(pool, p, size); } /* Printing routines */ @@ -215,21 +223,21 @@ static Table internTable; /* dictionary of intern ids to strings */ static Table labelTable; /* dictionary of addrs to intern ids */ -static void createTables(void) +static void createTables(mps_pool_t pool) { Res res; /* MPS intern IDs are serials from zero up, so we can use -1 * and -2 as specials. */ res = TableCreate(&internTable, (size_t)1<<4, - tableAlloc, tableFree, NULL, + tableAlloc, tableFree, pool, (Word)-1, (Word)-2); if (res != ResOK) everror("Couldn't make intern table."); /* We assume that 0 and 1 are invalid as Addrs. */ res = TableCreate(&labelTable, (size_t)1<<7, - tableAlloc, tableFree, NULL, + tableAlloc, tableFree, pool, 0, 1); if (res != ResOK) everror("Couldn't make label table."); @@ -238,19 +246,19 @@ static void createTables(void) /* recordIntern -- record an interned string in the table. a copy of * the string from the parsed buffer into a newly-allocated block. */ -static void recordIntern(char *p) +static void recordIntern(mps_pool_t pool, char *p) { ulongest_t stringId; char *string; - char *copy; + mps_addr_t copy; size_t len; Res res; stringId = parseHex(&p); string = parseString(&p); len = strlen(string); - copy = malloc(len+1); - if (copy == NULL) + res = mps_alloc(©, pool, len + 1); + if (res != MPS_RES_OK) everror("Couldn't allocate space for a string."); (void)strcpy(copy, string); res = TableDefine(internTable, (Word)stringId, (void *)copy); @@ -258,12 +266,55 @@ static void recordIntern(char *p) everror("Couldn't create an intern mapping."); } -/* recordLabel records a label (an association between an address and - * a string ID). Note that the event log may have been generated on a - * platform with addresses larger than Word on the current platform. - * If that happens then we are scuppered because our Table code uses - * Word as the key type: there's nothing we can do except detect this - * bad case (see also the EventInit handling and warning code). +/* Over time there may be multiple labels associated with an address, + * so we keep a list, recording for each label the clock when the + * association was made. This means that printAddr can select the + * label that was in force at the time of the event. + */ + +typedef struct LabelStruct *Label; +typedef struct LabelStruct { + ulongest_t clock; /* clock of this label */ + ulongest_t id; /* string id of this label */ +} LabelStruct; + +typedef struct LabelListStruct *LabelList; +typedef struct LabelListStruct { + size_t n; /* number of labels in array */ + Label labels; /* labels, sorted in order by clock */ +} LabelListStruct; + +/* labelFind returns the index of the first entry in list with a clock + * value that's greater than 'clock', or list->n if there is no such + * label. The list is assumed to be sorted. + */ + +static size_t labelFind(LabelList list, ulongest_t clock) +{ + size_t low = 0, high = list->n; + while (low < high) { + size_t mid = (low + high) / 2; + assert(0 <= mid && mid < list->n); + if (list->labels[mid].clock > clock) { + high = mid; + } else { + low = mid + 1; + } + } + assert(0 <= low && low <= list->n); + assert(low == list->n || list->labels[low].clock > clock); + return low; +} + +/* recordLabel records a label: an association (made at the time given + * by 'clock') between an address and a string ID. These are encoded + * as two hexadecimal numbers in the string pointed to by 'p'. + * + * Note that the event log may have been generated on a platform with + * addresses larger than Word on the current platform. If that happens + * then we are scuppered because our Table code uses Word as the key + * type: there's nothing we can do except detect this bad case (see + * also the EventInit handling and warning code). * * We can and do handle the case where string IDs (which are Words on * the MPS platform) are larger than void* on the current platform. @@ -274,25 +325,50 @@ static void recordIntern(char *p) * probably a bad idea and maybe doomed to failure. */ -static void recordLabel(char *p) +static void recordLabel(mps_pool_t pool, ulongest_t clock, char *p) { ulongest_t address; - ulongest_t *stringIdP; + LabelList list; + Label newlabels; + mps_addr_t tmp; + size_t pos; Res res; - + address = parseHex(&p); if (address > (Word)-1) { (void)printf("label address too large!"); return; } - - stringIdP = malloc(sizeof(ulongest_t)); - if (stringIdP == NULL) - everror("Can't allocate space for a string's ID"); - *stringIdP = parseHex(&p); - res = TableDefine(labelTable, (Word)address, (void *)stringIdP); + + if (TableLookup(&tmp, labelTable, address)) { + list = tmp; + } else { + /* First label for this address */ + res = mps_alloc(&tmp, pool, sizeof(LabelListStruct)); + if (res != MPS_RES_OK) + everror("Can't allocate space for a label list"); + list = tmp; + list->n = 0; + res = TableDefine(labelTable, (Word)address, list); + if (res != ResOK) + everror("Couldn't create a label mapping."); + } + + res = mps_alloc(&tmp, pool, sizeof(LabelStruct) * (list->n + 1)); if (res != ResOK) - everror("Couldn't create an intern mapping."); + everror("Couldn't allocate space for list of labels."); + newlabels = tmp; + + pos = labelFind(list, clock); + memcpy(newlabels, list->labels, sizeof(LabelStruct) * pos); + newlabels[pos].clock = clock; + newlabels[pos].id = parseHex(&p); + memcpy(newlabels + pos + 1, list->labels + pos, + sizeof(LabelStruct) * (list->n - pos)); + if (list->n > 0) + mps_free(pool, list->labels, sizeof(LabelStruct) * list->n); + list->labels = newlabels; + ++ list->n; } /* output code */ @@ -308,20 +384,23 @@ static int hexWordWidth = (MPS_WORD_WIDTH+3)/4; /* printAddr -- output a ulongest_t in hex, with the interned string * if the value is in the label table */ -static void printAddr(ulongest_t addr, const char *ident) +static void printAddr(ulongest_t clock, ulongest_t addr, const char *ident) { - ulongest_t label; - void *alias; + void *tmp; printf("%s:%0*" PRIXLONGEST, ident, hexWordWidth, addr); - if (TableLookup(&alias, labelTable, addr)) { - label = *(ulongest_t*)alias; - putchar('['); - if (TableLookup(&alias, internTable, label)) - printStr((char *)alias); - else - printf("unknown label %" PRIuLONGEST, label); - putchar(']'); + if (TableLookup(&tmp, labelTable, addr)) { + LabelList list = tmp; + size_t pos = labelFind(list, clock); + if (pos > 0) { + putchar('['); + ulongest_t id = list->labels[pos - 1].id; + if (TableLookup(&tmp, internTable, id)) + printStr((char *)tmp); + else + printf("unknown label %" PRIXLONGEST, id); + putchar(']'); + } } putchar(' '); } @@ -332,7 +411,7 @@ static void printAddr(ulongest_t addr, const char *ident) #define processParamA(ident) \ val_hex = parseHex(&p); \ - printAddr(val_hex, #ident); + printAddr(clock, val_hex, #ident); #define processParamP processParamA #define processParamW processParamA @@ -375,7 +454,7 @@ static const char *eventName[EventCodeMAX+EventCodeMAX]; /* readLog -- read and parse log. Returns the number of events written. */ -static void readLog(FILE *input) +static void readLog(mps_pool_t pool, FILE *input) { int i; @@ -415,9 +494,9 @@ static void readLog(FILE *input) /* for a few particular codes, we do local processing. */ if (code == EventInternCode) { - recordIntern(q); + recordIntern(pool, q); } else if (code == EventLabelCode) { - recordLabel(q); + recordLabel(pool, clock, q); } else if (code == EventEventInitCode) { ulongest_t major, median, minor, maxCode, maxNameLen, wordWidth, clocksPerSec; major = parseHex(&q); /* EVENT_VERSION_MAJOR */ @@ -476,6 +555,9 @@ static void readLog(FILE *input) int main(int argc, char *argv[]) { + mps_arena_t arena; + mps_pool_t pool; + mps_res_t res; FILE *input; parseArgs(argc, argv); @@ -488,8 +570,20 @@ int main(int argc, char *argv[]) everror("unable to open %s", logFileName); } - createTables(); - readLog(input); + res = mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none); + if (res != MPS_RES_OK) + everror("failed to create arena: %d", res); + + res = mps_pool_create_k(&pool, arena, mps_class_mvff(), mps_args_none); + if (res != MPS_RES_OK) + everror("failed to create pool: %d", res); + + createTables(pool); + readLog(pool, input); + + mps_pool_destroy(pool); + mps_arena_destroy(arena); + (void)fclose(input); return 0; } diff --git a/mps/manual/source/topic/telemetry.rst b/mps/manual/source/topic/telemetry.rst index f33de3516ce..a665aaf4b07 100644 --- a/mps/manual/source/topic/telemetry.rst +++ b/mps/manual/source/topic/telemetry.rst @@ -110,7 +110,7 @@ The MPS writes the telemetry to the log in an encoded form for speed. It can be decoded using the :ref:`mpseventcnv ` and :ref:`mpseventtxt ` programs:: - (gdb) shell mpseventcnv | mpseventtxt | sort > mpsio.txt + (gdb) shell mpseventcnv | sort | mpseventtxt > mpsio.txt The ``sort`` is useful because the events are not necessarily written to the telemetry file in time order, but each event starts with a From fc91f6d89f4b890b5f97f76ec17b33e5bbe063ff Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 12 Apr 2014 16:22:20 +0100 Subject: [PATCH 23/75] Release notes for job003747 and job003756. Copied from Perforce Change: 185479 ServerID: perforce.ravenbrook.com --- mps/manual/source/release.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index b93ffc786f5..4a57665a23b 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -27,6 +27,15 @@ New features calling :c:func:`mps_pool_create_k`. +Interface changes +................. + +#. There is now a default value (currently 1 \ :term:`megabyte`) for + the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument to + :c:func:`mps_arena_create_k` when creating a virtual memory arena. + See :c:func:`mps_arena_class_vm`. + + Other changes ............. @@ -44,6 +53,13 @@ Other changes .. _job003745: https://www.ravenbrook.com/project/mps/issue/job003745/ +#. :program:`mpseventtxt` now successfully processes a telemetry log + containing multiple labels associated with the same address. See + job003756_. + + .. _job003756: https://www.ravenbrook.com/project/mps/issue/job003756/ + + .. _release-notes-1.113: From 14c18c9e4497452b8f833121897e31400181a747 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 12 Apr 2014 20:58:56 +0100 Subject: [PATCH 24/75] The assertion that you get when destroying an arena without having destroyed all pools has moved from arenavm.c to sa.c. Remove AMS_IS_INVALID_COLOUR assertion from manual: explanation of cause is incorrect. Copied from Perforce Change: 185481 ServerID: perforce.ravenbrook.com --- mps/manual/source/topic/error.rst | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/mps/manual/source/topic/error.rst b/mps/manual/source/topic/error.rst index 97ec2f73216..6b2e9452fc2 100644 --- a/mps/manual/source/topic/error.rst +++ b/mps/manual/source/topic/error.rst @@ -232,7 +232,7 @@ assertion that is listed here but for which you discovered a different cause), please :ref:`let us know ` so that we can improve this documentation. -``arenavm.c: BTIsResRange(vmChunk->pageTableMapped, 0, chunk->pageTablePages)`` +``sa.c: BTIsResRange(sa->mapped, 0, sa->length)`` The client program called :c:func:`mps_arena_destroy` without having destroyed all pools in that arena first. (The assertion is @@ -283,14 +283,6 @@ this documentation. point` instead. -``poolams.c: !AMS_IS_INVALID_COLOUR(seg, i)`` - - The client program failed to :term:`fix` a reference to an object - in an :ref:`pool-ams` pool, violating the :term:`tri-colour - invariant` that the MPS depends on for the correctness of its - :term:`incremental garbage collection`. - - ``poolams.c: AMS_ALLOCED(seg, i)`` The client program tried to :term:`fix` a :term:`reference` to a From 7c107c76c03a285c6aaa7fff76bf789f9208fefe Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 12 Apr 2014 21:33:29 +0100 Subject: [PATCH 25/75] Fix compilation of eventtxt.c on lii6gc. Copied from Perforce Change: 185483 ServerID: perforce.ravenbrook.com --- mps/code/eventtxt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mps/code/eventtxt.c b/mps/code/eventtxt.c index 70962450d9f..4c50ac994f9 100644 --- a/mps/code/eventtxt.c +++ b/mps/code/eventtxt.c @@ -32,6 +32,7 @@ #include "mps.h" #include "mpsavm.h" #include "mpscmvff.h" +#include "check.h" #include "config.h" #include "eventdef.h" #include "eventcom.h" @@ -294,14 +295,14 @@ static size_t labelFind(LabelList list, ulongest_t clock) size_t low = 0, high = list->n; while (low < high) { size_t mid = (low + high) / 2; - assert(0 <= mid && mid < list->n); + assert(NONNEGATIVE(mid) && mid < list->n); if (list->labels[mid].clock > clock) { high = mid; } else { low = mid + 1; } } - assert(0 <= low && low <= list->n); + assert(NONNEGATIVE(low) && low <= list->n); assert(low == list->n || list->labels[low].clock > clock); return low; } @@ -393,8 +394,8 @@ static void printAddr(ulongest_t clock, ulongest_t addr, const char *ident) LabelList list = tmp; size_t pos = labelFind(list, clock); if (pos > 0) { - putchar('['); ulongest_t id = list->labels[pos - 1].id; + putchar('['); if (TableLookup(&tmp, internTable, id)) printStr((char *)tmp); else From bc72bc7f79e83f92a0d63f3761097e1203d3c76b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 12 Apr 2014 21:44:18 +0100 Subject: [PATCH 26/75] Avoid strict aliasing warnings from gcc 4.8. Copied from Perforce Change: 185484 ServerID: perforce.ravenbrook.com --- mps/code/event.c | 2 +- mps/code/prmci3xc.c | 18 +++++++++--------- mps/code/protxc.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mps/code/event.c b/mps/code/event.c index d2166dbba2d..475fa4f875c 100644 --- a/mps/code/event.c +++ b/mps/code/event.c @@ -422,7 +422,7 @@ void EventDump(mps_lib_FILE *stream) for (kind = 0; kind < EventKindLIMIT; ++kind) { for (event = (Event)EventLast[kind]; - event < (Event)(EventBuffer[kind] + EventBufferSIZE); + (char *)event < EventBuffer[kind] + EventBufferSIZE; event = (Event)((char *)event + event->any.size)) { /* Try to keep going even if there's an error, because this is used as a backtrace and we'll take what we can get. */ diff --git a/mps/code/prmci3xc.c b/mps/code/prmci3xc.c index 786145fc084..1fcf5b149df 100644 --- a/mps/code/prmci3xc.c +++ b/mps/code/prmci3xc.c @@ -44,17 +44,17 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) config.h. */ /* TODO: The current arrangement of the fix operation (taking a Ref *) forces us to pun these registers (actually `int` on LII3GC). We can - suppress the warning my casting through `char *` and this might make + suppress the warning by casting through `void *` and this might make it safe, but does it really? RB 2012-09-10 */ switch (regnum) { - case 0: return (MRef)((char *)&mfc->threadState->__eax); - case 1: return (MRef)((char *)&mfc->threadState->__ecx); - case 2: return (MRef)((char *)&mfc->threadState->__edx); - case 3: return (MRef)((char *)&mfc->threadState->__ebx); - case 4: return (MRef)((char *)&mfc->threadState->__esp); - case 5: return (MRef)((char *)&mfc->threadState->__ebp); - case 6: return (MRef)((char *)&mfc->threadState->__esi); - case 7: return (MRef)((char *)&mfc->threadState->__edi); + case 0: return (void *)&mfc->threadState->__eax; + case 1: return (void *)&mfc->threadState->__ecx; + case 2: return (void *)&mfc->threadState->__edx; + case 3: return (void *)&mfc->threadState->__ebx; + case 4: return (void *)&mfc->threadState->__esp; + case 5: return (void *)&mfc->threadState->__ebp; + case 6: return (void *)&mfc->threadState->__esi; + case 7: return (void *)&mfc->threadState->__edi; default: NOTREACHED; return NULL; /* Avoids compiler warning. */ diff --git a/mps/code/protxc.c b/mps/code/protxc.c index 58dee81a179..1d2ae27917c 100644 --- a/mps/code/protxc.c +++ b/mps/code/protxc.c @@ -243,7 +243,7 @@ static void protCatchOne(void) different size" warnings in GCC, for the XCI3GC build. */ mfcStruct.address = (Addr)(Word)request.code[1]; AVER(sizeof(*mfcStruct.threadState) == sizeof(THREAD_STATE_S)); - mfcStruct.threadState = (THREAD_STATE_S *)request.old_state; + mfcStruct.threadState = (void *)request.old_state; if (ArenaAccess(mfcStruct.address, AccessREAD | AccessWRITE, From 2eac6543199b39b053edd1eb7d67bfc35e747688 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 13 Apr 2014 20:51:10 +0100 Subject: [PATCH 27/75] Check rings before destroying the control pool, so that you get an assertion when a ring points into space that is about to be unmapped, instead of a crash after it has been unmapped. Copied from Perforce Change: 185495 ServerID: perforce.ravenbrook.com --- mps/code/global.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/mps/code/global.c b/mps/code/global.c index 9bfe9c20dc0..9fb6c1cb4eb 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -397,25 +397,7 @@ void GlobalsFinish(Globals arenaGlobals) Arena arena; Rank rank; - /* Check that the tear-down is complete: that the client has - * destroyed all data structures associated with the arena. We do - * this *before* calling AVERT(Globals, arenaGlobals) because the - * AVERT will crash if there are any remaining data structures, and - * it is politer to assert than to crash. (The crash would happen - * because by this point in the code the control pool has been - * destroyed and so the address space containing all these rings has - * potentially been unmapped, and so RingCheck dereferences a - * pointer into that unmapped memory.) See job000652. */ arena = GlobalsArena(arenaGlobals); - AVER(RingIsSingle(&arena->formatRing)); - AVER(RingIsSingle(&arena->chainRing)); - AVER(RingIsSingle(&arena->messageRing)); - AVER(RingIsSingle(&arena->threadRing)); - for(rank = 0; rank < RankLIMIT; ++rank) - AVER(RingIsSingle(&arena->greyRing[rank])); - AVER(RingIsSingle(&arenaGlobals->poolRing)); - AVER(RingIsSingle(&arenaGlobals->rootRing)); - AVERT(Globals, arenaGlobals); STATISTIC_STAT(EVENT2(ArenaWriteFaults, arena, @@ -445,6 +427,7 @@ void GlobalsPrepareToDestroy(Globals arenaGlobals) TraceId ti; Trace trace; Chain defaultChain; + Rank rank; AVERT(Globals, arenaGlobals); @@ -499,6 +482,23 @@ void GlobalsPrepareToDestroy(Globals arenaGlobals) arena->finalPool = NULL; PoolDestroy(pool); } + + /* Check that the tear-down is complete: that the client has + * destroyed all data structures associated with the arena. We do + * this here rather than in GlobalsFinish because by the time that + * is called, the control pool has been destroyed and so the address + * space containing all these rings has potentially been unmapped, + * and so RingCheck dereferences a pointer into that unmapped memory + * and we get a crash instead of an assertion. See job000652. + */ + AVER(RingIsSingle(&arena->formatRing)); + AVER(RingIsSingle(&arena->chainRing)); + AVER(RingIsSingle(&arena->messageRing)); + AVER(RingIsSingle(&arena->threadRing)); + AVER(RingIsSingle(&arenaGlobals->rootRing)); + for(rank = 0; rank < RankLIMIT; ++rank) + AVER(RingIsSingle(&arena->greyRing[rank])); + /* poolRing is not yet single (control pool etc. still exist) */ } From e3604e83abb83378e711520253fb8758dd49ece9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 11:34:20 +0100 Subject: [PATCH 28/75] Simpler casting and more checking. Copied from Perforce Change: 185502 ServerID: perforce.ravenbrook.com --- mps/code/prmci6xc.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/mps/code/prmci6xc.c b/mps/code/prmci6xc.c index 02ccb840b6c..131447cd0cc 100644 --- a/mps/code/prmci6xc.c +++ b/mps/code/prmci6xc.c @@ -31,33 +31,38 @@ SRCID(prmci6li, "$Id$"); MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) { + THREAD_STATE_S *threadState; + + AVER(mfc != NULL); AVER(NONNEGATIVE(regnum)); AVER(regnum <= 15); + AVER(mfc->threadState != NULL); + threadState = mfc->threadState; /* .assume.regref */ /* The register numbers (REG_RAX etc.) are defined in but only if _XOPEN_SOURCE is defined: see .feature.xc in config.h. */ /* MRef (a Word *) is not compatible with pointers to the register - types (actually a __uint64_t). To avoid aliasing optimization - problems, The registers are cast through (char *) */ + types (actually a __uint64_t). To avoid aliasing optimization + problems, the registers are cast through (void *). */ switch (regnum) { - case 0: return (MRef)((char *)&mfc->threadState->__rax); - case 1: return (MRef)((char *)&mfc->threadState->__rcx); - case 2: return (MRef)((char *)&mfc->threadState->__rdx); - case 3: return (MRef)((char *)&mfc->threadState->__rbx); - case 4: return (MRef)((char *)&mfc->threadState->__rsp); - case 5: return (MRef)((char *)&mfc->threadState->__rbp); - case 6: return (MRef)((char *)&mfc->threadState->__rsi); - case 7: return (MRef)((char *)&mfc->threadState->__rdi); - case 8: return (MRef)((char *)&mfc->threadState->__r8); - case 9: return (MRef)((char *)&mfc->threadState->__r9); - case 10: return (MRef)((char *)&mfc->threadState->__r10); - case 11: return (MRef)((char *)&mfc->threadState->__r11); - case 12: return (MRef)((char *)&mfc->threadState->__r12); - case 13: return (MRef)((char *)&mfc->threadState->__r13); - case 14: return (MRef)((char *)&mfc->threadState->__r14); - case 15: return (MRef)((char *)&mfc->threadState->__r15); + case 0: return (void *)&threadState->__rax; + case 1: return (void *)&threadState->__rcx; + case 2: return (void *)&threadState->__rdx; + case 3: return (void *)&threadState->__rbx; + case 4: return (void *)&threadState->__rsp; + case 5: return (void *)&threadState->__rbp; + case 6: return (void *)&threadState->__rsi; + case 7: return (void *)&threadState->__rdi; + case 8: return (void *)&threadState->__r8; + case 9: return (void *)&threadState->__r9; + case 10: return (void *)&threadState->__r10; + case 11: return (void *)&threadState->__r11; + case 12: return (void *)&threadState->__r12; + case 13: return (void *)&threadState->__r13; + case 14: return (void *)&threadState->__r14; + case 15: return (void *)&threadState->__r15; default: NOTREACHED; return NULL; /* Avoids compiler warning. */ From 857087804d451f5ad186eb5482686b48e9ca0b4b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 12:07:14 +0100 Subject: [PATCH 29/75] Simpler casting, and more checking. Copied from Perforce Change: 185505 ServerID: perforce.ravenbrook.com --- mps/code/prmci6li.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mps/code/prmci6li.c b/mps/code/prmci6li.c index 2f8bf9afc62..c00c1359014 100644 --- a/mps/code/prmci6li.c +++ b/mps/code/prmci6li.c @@ -33,12 +33,19 @@ SRCID(prmci6li, "$Id$"); MRef Prmci6AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) { - Word *gregs; + MRef gregs; + AVER(mfc != NULL); AVER(NONNEGATIVE(regnum)); AVER(regnum <= 15); + AVER(mfc->ucontext != NULL); - gregs = (Word *)&mfc->ucontext->uc_mcontext.gregs; + /* TODO: The current arrangement of the fix operation (taking a Ref *) + forces us to pun these registers (actually `int` on LII6GC). We can + suppress the warning by casting through `void *` and this might make + it safe, but does it really? RB 2012-09-10 */ + AVER(sizeof(void *) == sizeof(*mfc->ucontext->uc_mcontext.gregs)); + gregs = (void *)mfc->ucontext->uc_mcontext.gregs; /* .assume.regref */ /* The register numbers (REG_RAX etc.) are defined in From 4b5eacdbb7ccd6d0535fc293ad51c7ed4f8f3539 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 12:13:22 +0100 Subject: [PATCH 30/75] Avoid warning on lii3gc. Copied from Perforce Change: 185506 ServerID: perforce.ravenbrook.com --- mps/code/finaltest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index 02c1448d137..88895027286 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -167,7 +167,8 @@ static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap, } finals += final_this_time; printf("%"PRIuLONGEST" objects finalized: total %"PRIuLONGEST - " of %"PRIuLONGEST"\n", final_this_time, finals, object_count); + " of %"PRIuLONGEST"\n", (ulongest_t)final_this_time, + (ulongest_t)finals, (ulongest_t)object_count); } cdie(finals == object_count, "Not all objects were finalized."); } From d728944c5013212d62fbf3e2936f5759dfc76b58 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 12:13:31 +0100 Subject: [PATCH 31/75] Simpler cast, more checking. Copied from Perforce Change: 185507 ServerID: perforce.ravenbrook.com --- mps/code/prmci3li.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/mps/code/prmci3li.c b/mps/code/prmci3li.c index 6a36ae7db2b..5b5d150b8cc 100644 --- a/mps/code/prmci3li.c +++ b/mps/code/prmci3li.c @@ -36,27 +36,34 @@ SRCID(prmci3li, "$Id$"); MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) { + MRef gregs; + + AVER(mfc != NULL); AVER(NONNEGATIVE(regnum)); AVER(regnum <= 7); + AVER(mfc->ucontext != NULL); + + /* TODO: The current arrangement of the fix operation (taking a Ref *) + forces us to pun these registers (actually `int` on LII3GC). We can + suppress the warning by casting through `void *` and this might make + it safe, but does it really? RB 2012-09-10 */ + AVER(sizeof(void *) == sizeof(*mfc->ucontext->uc_mcontext.gregs)); + gregs = (void *)mfc->ucontext->uc_mcontext.gregs; /* .source.i486 */ /* .assume.regref */ /* The register numbers (REG_EAX etc.) are defined in but only if _GNU_SOURCE is defined: see .feature.li in config.h. */ - /* TODO: The current arrangement of the fix operation (taking a Ref *) - forces us to pun these registers (actually `int` on LII3GC). We can - suppress the warning my casting through `char *` and this might make - it safe, but does it really? RB 2012-09-10 */ switch (regnum) { - case 0: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EAX]); - case 1: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ECX]); - case 2: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EDX]); - case 3: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_EBX]); - case 4: return (MRef)((char *)&mfc->ucontext->uc_mcontext.gregs[REG_ESP]); - 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]); + case 0: return &gregs[REG_EAX]; + case 1: return &gregs[REG_ECX]; + case 2: return &gregs[REG_EDX]; + case 3: return &gregs[REG_EBX]; + case 4: return &gregs[REG_ESP]; + case 5: return &gregs[REG_EBP]; + case 6: return &gregs[REG_ESI]; + case 7: return &gregs[REG_EDI]; default: NOTREACHED; return NULL; /* Avoids compiler warning. */ From 8865ac761cdc91b9e211107294d8bd278e42e762 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 12:32:18 +0100 Subject: [PATCH 32/75] Simpler cast, more checking. Copied from Perforce Change: 185510 ServerID: perforce.ravenbrook.com --- mps/code/prmci3xc.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/mps/code/prmci3xc.c b/mps/code/prmci3xc.c index 1fcf5b149df..eafeff61540 100644 --- a/mps/code/prmci3xc.c +++ b/mps/code/prmci3xc.c @@ -34,8 +34,13 @@ SRCID(prmci3li, "$Id$"); MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) { + THREAD_STATE_S *threadState; + + AVER(mfc != NULL); AVER(NONNEGATIVE(regnum)); AVER(regnum <= 7); + AVER(mfc->threadState != NULL); + threadState = mfc->threadState; /* .source.i486 */ /* .assume.regref */ @@ -47,14 +52,14 @@ MRef Prmci3AddressHoldingReg(MutatorFaultContext mfc, unsigned int regnum) suppress the warning by casting through `void *` and this might make it safe, but does it really? RB 2012-09-10 */ switch (regnum) { - case 0: return (void *)&mfc->threadState->__eax; - case 1: return (void *)&mfc->threadState->__ecx; - case 2: return (void *)&mfc->threadState->__edx; - case 3: return (void *)&mfc->threadState->__ebx; - case 4: return (void *)&mfc->threadState->__esp; - case 5: return (void *)&mfc->threadState->__ebp; - case 6: return (void *)&mfc->threadState->__esi; - case 7: return (void *)&mfc->threadState->__edi; + case 0: return (void *)&threadState->__eax; + case 1: return (void *)&threadState->__ecx; + case 2: return (void *)&threadState->__edx; + case 3: return (void *)&threadState->__ebx; + case 4: return (void *)&threadState->__esp; + case 5: return (void *)&threadState->__ebp; + case 6: return (void *)&threadState->__esi; + case 7: return (void *)&threadState->__edi; default: NOTREACHED; return NULL; /* Avoids compiler warning. */ From f92f1d0ac9aad36513f6a86182939d49d362e88d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 16:39:55 +0100 Subject: [PATCH 33/75] New program p4-bisect finds, by binary search, the change that introduced a bug. Copied from Perforce Change: 185519 ServerID: perforce.ravenbrook.com --- mps/tool/p4-bisect | 155 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 mps/tool/p4-bisect diff --git a/mps/tool/p4-bisect b/mps/tool/p4-bisect new file mode 100644 index 00000000000..768b2ba6f0b --- /dev/null +++ b/mps/tool/p4-bisect @@ -0,0 +1,155 @@ +#!/usr/bin/env python +# +# +# Ravenbrook +# +# +# P4-BISECT -- FIND CHANGE THAT INTRODUCED A BUG +# +# Gareth Rees, Ravenbrook Limited, 2014-04-14 +# +# +# 1. INTRODUCTION +# +# This script automates (or partly automates) the process of finding, +# by binary search, the change that introduced a bug. +# +# The interface is modelled closely on git-bisect(1). + +import argparse +from functools import partial +import json +from os import unlink +import p4 +import subprocess +import sys + +BISECT_FILE = '.p4-bisect' + +class State(object): + def __init__(self, **d): + self.filespec = d['filespec'] + self.changes = d['changes'] + if 'current' in d: + self.current = d['current'] + + @classmethod + def load(cls): + with open(BISECT_FILE, 'r') as f: + return cls(**json.load(f)) + + def save(self): + with open(BISECT_FILE, 'w') as f: + json.dump(vars(self), f) + + def update(self): + n = len(self.changes) + if n == 0: + print("no changes remaining.".format(**vars(self))) + elif n == 1: + print("{} change remaining: {}.".format(n, self.changes[0])) + elif n == 2: + print("{} changes remaining: [{}, {}]." + .format(n, self.changes[0], self.changes[-1])) + else: + print("{} changes remaining: [{}, ..., {}]." + .format(n, self.changes[0], self.changes[-1])) + if n > 0: + self.current = self.changes[n // 2] + print("Syncing to changelevel {current}.".format(**vars(self))) + p4.do('update', '{filespec}@{current}'.format(**vars(self))) + self.save() + +def help(parser, args): + parser.print_help() + +def start(args): + changes = sorted(int(c['change']) for c in p4.run('changes', args.filespec)) + if not changes: + parser.error("No changes for {filespec}".format(**vars(args))) + if args.first is None: + args.first = changes[0] + if args.last is None: + args.last = changes[-1] + state = State(filespec=args.filespec, + changes=[c for c in changes if args.first <= c <= args.last]) + state.update() + +def good(args): + state = State.load() + print("Change {current} good.".format(**vars(state))) + state.changes = [c for c in state.changes if c > state.current] + state.update() + +def bad(args): + state = State.load() + print("Change {current} bad.".format(**vars(state))) + state.changes = [c for c in state.changes if c < state.current] + state.update() + +def skip(args): + state = State.load() + print("Skipping change {current}.".format(**vars(state))) + state.changes.remove(state.current) + state.update() + +def reset(args): + state = State.load() + p4.do('update', state.filespec) + unlink(BISECT_FILE) + +def run(args): + while True: + state = State.load() + if not state.changes: + break + result = subprocess.call([args.cmd] + args.args) + if result == 0: + good(None) + elif result == 125: + skip(None) + elif 0 < result < 128: + bad(None) + else: + exit(result) + +def main(argv): + parser = argparse.ArgumentParser(prog='p4-bisect') + subparsers = parser.add_subparsers() + a = subparsers.add_parser + + help_parser = a('help', help='show this help message') + help_parser.set_defaults(func=partial(help, help_parser)) + + start_parser = a('start', help='start a p4-bisect session') + aa = start_parser.add_argument + start_parser.add_argument('-f', '--filespec', default='...', + help='filespec to search') + start_parser.add_argument('first', nargs='?', type=int, + help='earliest changelevel to examine') + start_parser.add_argument('last', nargs='?', type=int, + help='latest changelevel to examine') + start_parser.set_defaults(func=start) + + good_parser = a('good', help='declare current revision good') + good_parser.set_defaults(func=good) + + bad_parser = a('bad', help='declare current revision bad') + bad_parser.set_defaults(func=bad) + + reset_parser = a('reset', help='finish p4-bisect session') + reset_parser.set_defaults(func=reset) + + run_parser = a('run', help='run p4-bisect session automatically') + run_parser.add_argument('cmd', + help='command that determines if current ' + 'changelevel is good or bad') + run_parser.add_argument('args', nargs=argparse.REMAINDER, + help='arguments to pass to cmd') + run_parser.set_defaults(func=run) + + args = parser.parse_args(argv[1:]) + args.func(args) + +if __name__ == '__main__': + main(sys.argv) From 5256f7da8a160cb93ac50ceac5106d4b87918bff Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 17:50:27 +0100 Subject: [PATCH 34/75] Update open dylan configuration procedure. Copied from Perforce Change: 185521 ServerID: perforce.ravenbrook.com --- mps/tool/testopendylan | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mps/tool/testopendylan b/mps/tool/testopendylan index 9c18938ef1e..a8aee4a0025 100755 --- a/mps/tool/testopendylan +++ b/mps/tool/testopendylan @@ -104,7 +104,7 @@ if [ -f "$REPO/Makefile" ]; then else ( cd -- "$REPO" && ./autogen.sh && - ./configure --with-mps="$MPS" --prefix="$PREFIX" + ./configure --with-gc=mps --with-gc-path="$MPS" --prefix="$PREFIX" ) fi ( cd -- "$REPO" && @@ -128,6 +128,9 @@ else ( # # 2014-03-20 GDR Created based on [WELCOME]. # +# 2014-04-14 GDR Updated configure args based on revised build +# instructions [WELCOME]. +# # # C. COPYRIGHT AND LICENCE # From bf117e0251be76429a081be030e1045d5583cfbe Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 17:53:49 +0100 Subject: [PATCH 35/75] Fix branch tool (missing quote). Copied from Perforce Change: 185522 ServerID: perforce.ravenbrook.com --- mps/tool/branch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/tool/branch b/mps/tool/branch index faf69ffb0bc..686cdefa244 100755 --- a/mps/tool/branch +++ b/mps/tool/branch @@ -162,7 +162,7 @@ def main(argv): args.description = fmt("Branching {parent} to {child}.") print(fmt("description={description}")) args.desc_html = re.sub(r'\b(job\d{6})\b', - fmt(r'\1'), args.description) # Create the branch specification From e5c9808c72f10dbef9ec3d59fcfaa3b06ad6877d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 18:37:31 +0100 Subject: [PATCH 36/75] Move the marker down the stack so that gcc's aggressive inline won't scupper it. Copied from Perforce Change: 185524 ServerID: perforce.ravenbrook.com --- mps/code/airtest.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mps/code/airtest.c b/mps/code/airtest.c index 946e585bc2f..56e1bd8c129 100644 --- a/mps/code/airtest.c +++ b/mps/code/airtest.c @@ -90,14 +90,13 @@ static mps_gen_param_s obj_gen_params[] = { { 170, 0.45 } }; -static void test_main(int interior, int stack) +static void test_main(void *marker, int interior, int stack) { mps_res_t res; mps_chain_t obj_chain; mps_fmt_t obj_fmt; mps_thr_t thread; mps_root_t reg_root = NULL; - void *marker = ▮ res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), mps_args_none); if (res != MPS_RES_OK) error("Couldn't create arena"); @@ -145,12 +144,14 @@ static void test_main(int interior, int stack) int main(int argc, char *argv[]) { + void *marker = ▮ + testlib_init(argc, argv); - test_main(TRUE, TRUE); - test_main(TRUE, FALSE); - /* not test_main(FALSE, TRUE) -- see .fail.lii6ll. */ - test_main(FALSE, FALSE); + test_main(marker, TRUE, TRUE); + test_main(marker, TRUE, FALSE); + /* not test_main(marker, FALSE, TRUE) -- see .fail.lii6ll. */ + test_main(marker, FALSE, FALSE); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; From b66714e2daef7925b98a9707f32cec0d64a8b140 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 18:55:00 +0100 Subject: [PATCH 37/75] Update file type to kxtext. Copied from Perforce Change: 185525 ServerID: perforce.ravenbrook.com --- mps/tool/p4-bisect | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 mps/tool/p4-bisect diff --git a/mps/tool/p4-bisect b/mps/tool/p4-bisect old mode 100644 new mode 100755 From 3731f5741bf94c16ed4395767d6851bbd213f8f1 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 22:31:24 +0100 Subject: [PATCH 38/75] Check the poolring so that there is an assertion failure (not a crash) if the client fails to destroy a pool. Copied from Perforce Change: 185527 ServerID: perforce.ravenbrook.com --- mps/code/global.c | 10 +++++++++- mps/code/ring.c | 14 ++++++++++++-- mps/code/ring.h | 5 +++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/mps/code/global.c b/mps/code/global.c index 9fb6c1cb4eb..5f635206bd9 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -498,7 +498,15 @@ void GlobalsPrepareToDestroy(Globals arenaGlobals) AVER(RingIsSingle(&arenaGlobals->rootRing)); for(rank = 0; rank < RankLIMIT; ++rank) AVER(RingIsSingle(&arena->greyRing[rank])); - /* poolRing is not yet single (control pool etc. still exist) */ + + /* At this point the following pools still exist: + * 0. arena->freeCBSBlockPoolStruct + * 1. arena->reservoirStruct + * 2. arena->controlPoolStruct + * 3. arena->controlPoolStruct.blockPoolStruct + * 4. arena->controlPoolStruct.spanPoolStruct + */ + AVER(RingLength(&arenaGlobals->poolRing) == 5); } diff --git a/mps/code/ring.c b/mps/code/ring.c index ff60149ce40..54902ec3818 100644 --- a/mps/code/ring.c +++ b/mps/code/ring.c @@ -1,7 +1,7 @@ /* ring.c: RING IMPLEMENTATION * * $Id$ - * Copyright (c) 2001,2003 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 Rings. * @@ -52,6 +52,16 @@ Bool RingIsSingle(Ring ring) return (ring->next == ring); } +Size RingLength(Ring ring) +{ + Size size = 0; + Ring node, next; + AVERT(Ring, ring); + RING_FOR(node, ring, next) + ++ size; + return size; +} + /* RingInit -- initialize a ring node */ @@ -131,7 +141,7 @@ Ring (RingPrev)(Ring ring) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2003 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/ring.h b/mps/code/ring.h index d5b64076f6c..cbde6afe814 100644 --- a/mps/code/ring.h +++ b/mps/code/ring.h @@ -1,7 +1,7 @@ /* ring.h: RING 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) 2001 Global Graphics Software. */ @@ -30,6 +30,7 @@ typedef struct RingStruct { /* double-ended queue structure */ extern Bool RingCheck(Ring ring); extern Bool RingCheckSingle(Ring ring); extern Bool RingIsSingle(Ring ring); +extern Size RingLength(Ring ring); /* .ring.init: */ extern void (RingInit)(Ring ring); @@ -115,7 +116,7 @@ extern Ring (RingPrev)(Ring ring); /* 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 fc86db4ec6e5aaaaf597e3703eb50b3c0f24c98d Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Mon, 14 Apr 2014 23:38:54 +0100 Subject: [PATCH 39/75] Fix arenarootswalk: 1. Blacken the segments again after scanning the roots, so that the roots can be walked again. 2. Don't cast RootGrey to a RootIterateFn -- the types are not compatible. MMQA test function/122.c now passes. Copied from Perforce Change: 185530 ServerID: perforce.ravenbrook.com --- mps/code/walk.c | 26 +++++++++++++++++++++++++- mps/test/function/122.c | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mps/code/walk.c b/mps/code/walk.c index 3f7f67f99e1..4dd0d6b9e98 100644 --- a/mps/code/walk.c +++ b/mps/code/walk.c @@ -273,6 +273,20 @@ static Res rootWalk(Root root, void *p) } +/* rootWalkGrey -- make the root grey for the trace passed as p */ + +static Res rootWalkGrey(Root root, void *p) +{ + Trace trace = p; + + AVERT(Root, root); + AVERT(Trace, trace); + + RootGrey(root, trace); + return ResOK; +} + + /* ArenaRootsWalk -- walks all the root in the arena */ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, @@ -315,7 +329,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, } /* Make the roots grey so that they are scanned */ - res = RootsIterate(arenaGlobals, (RootIterateFn)RootGrey, (void *)trace); + res = RootsIterate(arenaGlobals, rootWalkGrey, trace); /* Make this trace look like any other trace. */ arena->flippedTraces = TraceSetAdd(arena->flippedTraces, trace); @@ -330,6 +344,16 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, break; } + /* Turn segments black again. */ + if (SegFirst(&seg, arena)) { + do { + if (PoolHasAttr(SegPool(seg), AttrGC)) { + SegSetGrey(seg, TraceSetDel(SegGrey(seg), trace)); + SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace)); + } + } while (SegNext(&seg, arena, seg)); + } + rootsStepClosureFinish(rsc); /* Make this trace look like any other finished trace. */ trace->state = TraceFINISHED; diff --git a/mps/test/function/122.c b/mps/test/function/122.c index 6f1465289cb..4ba0c0c6090 100644 --- a/mps/test/function/122.c +++ b/mps/test/function/122.c @@ -133,7 +133,7 @@ static void test(void) die(allocrdumb(&a[0], aplo, 64, mps_rank_exact()), "alloc"); die(allocrdumb(&a[1], apamc, 64, mps_rank_exact()), "alloc"); die(allocrdumb(&a[3], apawl, 64, mps_rank_exact()), "alloc"); - a[2] = (mycell *)((int)a[3] | 4); + a[2] = (mycell *)((mps_word_t)a[3] | 4); die(allocrdumb(&b[0], aplo, 64, mps_rank_exact()), "alloc"); die(allocrdumb(&b[1], apamc, 64, mps_rank_exact()), "alloc"); From 3251845eadbb8c113c70c8cbc2ac55d493aba48a Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 00:18:29 +0100 Subject: [PATCH 40/75] Update passing list and release notes to reflect job003496 fix. Copied from Perforce Change: 185533 ServerID: perforce.ravenbrook.com --- mps/manual/source/release.rst | 5 +++++ mps/test/testsets/passing | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mps/manual/source/release.rst b/mps/manual/source/release.rst index 4a57665a23b..18cc8ed72e9 100644 --- a/mps/manual/source/release.rst +++ b/mps/manual/source/release.rst @@ -47,6 +47,11 @@ Other changes .. _job001549: https://www.ravenbrook.com/project/mps/issue/job001549/ +#. :c:func:`mps_arena_roots_walk` no longer triggers an assertion + failure when run twice in succession. See job003496_. + + .. _job003496: https://www.ravenbrook.com/project/mps/issue/job003496/ + #. The alignment of :ref:`pool-awl` pools is now configurable via the object format, as documented, and is no longer always :c:macro:`MPS_PF_ALIGN`. See job003745_. diff --git a/mps/test/testsets/passing b/mps/test/testsets/passing index 64c72fe2982..fc00f37feb0 100644 --- a/mps/test/testsets/passing +++ b/mps/test/testsets/passing @@ -110,7 +110,7 @@ function/118.c function/119.c function/120.c % function/121.c -- job003495 -% function/122.c -- job003496 +function/122.c function/123.c function/124.c function/125.c From efac0cc601b890fc1736a6908480bdcc1a1d3e31 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 00:18:47 +0100 Subject: [PATCH 41/75] Avoid bad cast on 64-bit. Copied from Perforce Change: 185534 ServerID: perforce.ravenbrook.com --- mps/test/function/40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/test/function/40.c b/mps/test/function/40.c index c57f8c62ba5..5257e1fcfc1 100644 --- a/mps/test/function/40.c +++ b/mps/test/function/40.c @@ -66,7 +66,7 @@ static void test(void) comment("%i of 10.", i); UC; z[i] = allocone(ap, 1, 1); - if (i % 8 == 0) { z[i] = (mycell *) ((int)z[i] + 4); } /* error to scan this! */ + if (i % 8 == 0) { z[i] = (mycell *) ((mps_word_t)z[i] + 4); } /* error to scan this! */ } for (i=0; i<1000; i++) { From 6e416e92939817effb99ace4a297027cae966fe7 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 09:21:01 +0100 Subject: [PATCH 42/75] P4-bisect improvements: Add skip command. Allow multiple -f options. Better error messages. Copied from Perforce Change: 185536 ServerID: perforce.ravenbrook.com --- mps/tool/p4-bisect | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/mps/tool/p4-bisect b/mps/tool/p4-bisect index 768b2ba6f0b..85c1c8e151e 100755 --- a/mps/tool/p4-bisect +++ b/mps/tool/p4-bisect @@ -26,6 +26,11 @@ import sys BISECT_FILE = '.p4-bisect' +def error(msg): + sys.stderr.write(msg) + sys.stderr.write('\n') + exit(1) + class State(object): def __init__(self, **d): self.filespec = d['filespec'] @@ -35,8 +40,11 @@ class State(object): @classmethod def load(cls): - with open(BISECT_FILE, 'r') as f: - return cls(**json.load(f)) + try: + with open(BISECT_FILE, 'r') as f: + return cls(**json.load(f)) + except FileNotFoundError: + error("p4-bisect not in progress here.") def save(self): with open(BISECT_FILE, 'w') as f: @@ -57,16 +65,18 @@ class State(object): if n > 0: self.current = self.changes[n // 2] print("Syncing to changelevel {current}.".format(**vars(self))) - p4.do('update', '{filespec}@{current}'.format(**vars(self))) + p4.do('sync', *['{}@{}'.format(f, self.current) + for f in self.filespec]) self.save() def help(parser, args): parser.print_help() def start(args): - changes = sorted(int(c['change']) for c in p4.run('changes', args.filespec)) + args.filespec = args.filespec or ['...'] + changes = sorted(int(c['change']) for c in p4.run('changes', *args.filespec)) if not changes: - parser.error("No changes for {filespec}".format(**vars(args))) + error("No changes for {}".format(' '.join(args.filespec))) if args.first is None: args.first = changes[0] if args.last is None: @@ -95,7 +105,7 @@ def skip(args): def reset(args): state = State.load() - p4.do('update', state.filespec) + p4.do('sync', *state.filespec) unlink(BISECT_FILE) def run(args): @@ -119,11 +129,11 @@ def main(argv): a = subparsers.add_parser help_parser = a('help', help='show this help message') - help_parser.set_defaults(func=partial(help, help_parser)) + help_parser.set_defaults(func=partial(help, parser)) start_parser = a('start', help='start a p4-bisect session') aa = start_parser.add_argument - start_parser.add_argument('-f', '--filespec', default='...', + start_parser.add_argument('-f', '--filespec', action='append', help='filespec to search') start_parser.add_argument('first', nargs='?', type=int, help='earliest changelevel to examine') @@ -137,6 +147,9 @@ def main(argv): bad_parser = a('bad', help='declare current revision bad') bad_parser.set_defaults(func=bad) + skip_parser = a('skip', help='skip current revision') + skip_parser.set_defaults(func=skip) + reset_parser = a('reset', help='finish p4-bisect session') reset_parser.set_defaults(func=reset) From 7ffe33068e1b68b72da11399911aeb21891070d9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 09:30:09 +0100 Subject: [PATCH 43/75] Better handling of "file(s) up-to-date" error. Copied from Perforce Change: 185537 ServerID: perforce.ravenbrook.com --- mps/tool/p4-bisect | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mps/tool/p4-bisect b/mps/tool/p4-bisect index 85c1c8e151e..97ff39dad74 100755 --- a/mps/tool/p4-bisect +++ b/mps/tool/p4-bisect @@ -31,6 +31,13 @@ def error(msg): sys.stderr.write('\n') exit(1) +def sync(*filespecs): + try: + p4.do('sync', *filespecs) + except p4.Error as e: + if 'file(s) up-to-date' not in e.args[0]: + raise + class State(object): def __init__(self, **d): self.filespec = d['filespec'] @@ -65,8 +72,7 @@ class State(object): if n > 0: self.current = self.changes[n // 2] print("Syncing to changelevel {current}.".format(**vars(self))) - p4.do('sync', *['{}@{}'.format(f, self.current) - for f in self.filespec]) + sync(*['{}@{}'.format(f, self.current) for f in self.filespec]) self.save() def help(parser, args): @@ -105,7 +111,7 @@ def skip(args): def reset(args): state = State.load() - p4.do('sync', *state.filespec) + sync(*state.filespec) unlink(BISECT_FILE) def run(args): From d1af6e61bcc21706130ea4967ab4ac02179cff1b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 10:39:52 +0100 Subject: [PATCH 44/75] Branching master to branch/2014-04-15/shared. Copied from Perforce Change: 185539 ServerID: perforce.ravenbrook.com From fa3e80eb7cc603489d71ca1fae2b95c16e29c7bd Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 11:02:05 +0100 Subject: [PATCH 45/75] Build and install a shared library on unix platforms. Copied from Perforce Change: 185543 ServerID: perforce.ravenbrook.com --- mps/Makefile.in | 6 +- mps/code/comm.gmk | 20 ++-- mps/code/mps.xcodeproj/project.pbxproj | 153 +++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 10 deletions(-) diff --git a/mps/Makefile.in b/mps/Makefile.in index 2d558588673..ccc56ff2bd4 100644 --- a/mps/Makefile.in +++ b/mps/Makefile.in @@ -1,7 +1,7 @@ # Makefile.in -- source for autoconf Makefile # # $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. # # YOU DON'T NEED AUTOCONF TO BUILD THE MPS # This is just here for people who want or expect a configure script. @@ -30,7 +30,9 @@ clean-make-build: install-make-build: make-install-dirs build-via-make $(INSTALL_DATA) code/mps*.h $(prefix)/include/ $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/cool/mps.a $(prefix)/lib/libmps-debug.a + $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/cool/libmps.so $(prefix)/lib/libmps-debug.so $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/hot/mps.a $(prefix)/lib/libmps.a + $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/hot/libmps.so $(prefix)/lib/libmps.so $(INSTALL_PROGRAM) $(addprefix code/$(MPS_TARGET_NAME)/hot/Release/,$(EXTRA_TARGETS)) $(prefix)/bin build-via-xcode: @@ -44,7 +46,9 @@ clean-xcode-build: install-xcode-build: make-install-dirs build-via-xcode $(INSTALL_DATA) code/mps*.h $(prefix)/include/ $(INSTALL_DATA) code/xc/Debug/libmps.a $(prefix)/lib/libmps-debug.a + $(INSTALL_DATA) code/xc/Debug/libmps.dylib $(prefix)/lib/libmps-debug.dylib $(INSTALL_DATA) code/xc/Release/libmps.a $(prefix)/lib/libmps.a + $(INSTALL_DATA) code/xc/Release/libmps.dylib $(prefix)/lib/libmps.dylib $(INSTALL_PROGRAM) $(addprefix code/xc/Release/,$(EXTRA_TARGETS)) $(prefix)/bin Makefile: Makefile.in config.status diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk index 70fed15d507..ce46bba68f4 100644 --- a/mps/code/comm.gmk +++ b/mps/code/comm.gmk @@ -170,7 +170,7 @@ MPMCOMMON = abq.c arena.c arenacl.c arenavm.c arg.c boot.c bt.c \ global.c ld.c locus.c message.c meter.c mpm.c mpsi.c nailboard.c \ pool.c poolabs.c poolmfs.c poolmrg.c poolmv.c protocol.c range.c \ ref.c reserv.c ring.c root.c sa.c sac.c seg.c shield.c splay.c ss.c \ - table.c trace.c traceanc.c tract.c tree.c walk.c + table.c trace.c traceanc.c tract.c tree.c version.c walk.c MPM = $(MPMCOMMON) $(MPMPF) @@ -223,7 +223,7 @@ endif # %%TARGET: When adding a new target, add it to one of the variables # in this section. Library components go in LIB_TARGETS. -LIB_TARGETS=mps.a mpsplan.a +LIB_TARGETS=mps.a libmps.so # Test executables go in TEST_TARGETS. @@ -352,10 +352,10 @@ endif # %%VARIETY: When adding a new variety, add a rule for how to build the # MPS library for the variety. -$(PFM)/rash/mps.a: $(PFM)/rash/mps.o -$(PFM)/hot/mps.a: $(PFM)/hot/mps.o +$(PFM)/rash/libmps.so $(PFM)/rash/mps.a: $(PFM)/rash/mps.o +$(PFM)/hot/libmps.so $(PFM)/hot/mps.a: $(PFM)/hot/mps.o -$(PFM)/cool/mps.a: \ +$(PFM)/cool/libmps.so $(PFM)/cool/mps.a: \ $(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \ $(MV2OBJ) $(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ) @@ -508,8 +508,6 @@ $(PFM)/$(VARIETY)/replay: $(PFM)/$(VARIETY)/replay.o \ $(PFM)/$(VARIETY)/table.o \ $(PFM)/$(VARIETY)/mps.a -$(PFM)/$(VARIETY)/mpsplan.a: $(PLINTHOBJ) - endif @@ -604,10 +602,14 @@ endif $(PFM)/$(VARIETY)/%.a: $(ECHO) "$(PFM): $@" rm -f $@ - $(CC) $(CFLAGS) -c -o $(PFM)/$(VARIETY)/version.o version.c - $(AR) $(ARFLAGS) $@ $^ $(PFM)/$(VARIETY)/version.o + $(AR) $(ARFLAGS) $@ $^ $(RANLIB) $@ +$(PFM)/$(VARIETY)/%.so: + $(ECHO) "$(PFM): $@" + rm -f $@ + $(CC) $(CFLAGS) $(LINKFLAGS) -shared -o $@ $^ + # Executable $(PFM)/$(VARIETY)/%: diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj index 88f110bab01..b3547175c39 100644 --- a/mps/code/mps.xcodeproj/project.pbxproj +++ b/mps/code/mps.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ ); dependencies = ( 3104AFF6156D37BC000A585A /* PBXTargetDependency */, + 223A19AB18FD2CF300AF81C1 /* PBXTargetDependency */, 3114A644156E94FB001E0AA3 /* PBXTargetDependency */, 22FACEF1188809B5000FDBC1 /* PBXTargetDependency */, 3104AFF8156D37BE000A585A /* PBXTargetDependency */, @@ -85,6 +86,7 @@ 2231BB6118CA97DC002D6322 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; 2231BB6A18CA984F002D6322 /* locusss.c in Sources */ = {isa = PBXBuildFile; fileRef = 2231BB6918CA983C002D6322 /* locusss.c */; }; 2231BB6B18CA9861002D6322 /* locbwcss.c in Sources */ = {isa = PBXBuildFile; fileRef = 2231BB6818CA9834002D6322 /* locbwcss.c */; }; + 223A19AC18FD2D2900AF81C1 /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; }; 224CC791175E1821002FF81B /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; 224CC793175E1821002FF81B /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; 224CC79F175E321C002FF81B /* mv2test.c in Sources */ = {isa = PBXBuildFile; fileRef = 3114A686156E9674001E0AA3 /* mv2test.c */; }; @@ -315,6 +317,13 @@ remoteGlobalIDString = 2231BB5A18CA97DC002D6322; remoteInfo = locusss; }; + 223A19AA18FD2CF300AF81C1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 223A19A418FD2CE200AF81C1; + remoteInfo = "mps-shared"; + }; 224CC78E175E1821002FF81B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */; @@ -1327,6 +1336,7 @@ 2231BB6718CA97DC002D6322 /* locusss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = locusss; sourceTree = BUILT_PRODUCTS_DIR; }; 2231BB6818CA9834002D6322 /* locbwcss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locbwcss.c; sourceTree = ""; }; 2231BB6918CA983C002D6322 /* locusss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locusss.c; sourceTree = ""; }; + 223A19A518FD2CE200AF81C1 /* libmps.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libmps.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 224CC799175E1821002FF81B /* fotest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fotest; sourceTree = BUILT_PRODUCTS_DIR; }; 224CC79E175E3202002FF81B /* fotest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fotest.c; sourceTree = ""; }; 22561A9618F4263300372C66 /* testthr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testthr.h; sourceTree = ""; }; @@ -1652,6 +1662,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 223A19A218FD2CE200AF81C1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 224CC792175E1821002FF81B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2266,6 +2283,7 @@ 22FACEED18880983000FDBC1 /* airtest */, 22C2ACAF18BE400A006B3677 /* nailboardtest */, 22F846BD18F437B900982BA7 /* lockut */, + 223A19A518FD2CE200AF81C1 /* libmps.dylib */, ); name = Products; sourceTree = ""; @@ -2441,6 +2459,13 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 223A19A318FD2CE200AF81C1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 31EEABF9156AAF9D00714D05 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -2487,6 +2512,23 @@ productReference = 2231BB6718CA97DC002D6322 /* locusss */; productType = "com.apple.product-type.tool"; }; + 223A19A418FD2CE200AF81C1 /* mps-shared */ = { + isa = PBXNativeTarget; + buildConfigurationList = 223A19A918FD2CE300AF81C1 /* Build configuration list for PBXNativeTarget "mps-shared" */; + buildPhases = ( + 223A19A118FD2CE200AF81C1 /* Sources */, + 223A19A218FD2CE200AF81C1 /* Frameworks */, + 223A19A318FD2CE200AF81C1 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "mps-shared"; + productName = "mps-shared"; + productReference = 223A19A518FD2CE200AF81C1 /* libmps.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; 224CC78C175E1821002FF81B /* fotest */ = { isa = PBXNativeTarget; buildConfigurationList = 224CC795175E1821002FF81B /* Build configuration list for PBXNativeTarget "fotest" */; @@ -3313,6 +3355,7 @@ 3104AFF1156D37A0000A585A /* all */, 22CDE8EF16E9E97D00366D0A /* testrun */, 31EEABFA156AAF9D00714D05 /* mps */, + 223A19A418FD2CE200AF81C1 /* mps-shared */, 3114A632156E94DB001E0AA3 /* abqtest */, 22FACEE018880983000FDBC1 /* airtest */, 3124CAEA156BE7F300753214 /* amcss */, @@ -3399,6 +3442,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 223A19A118FD2CE200AF81C1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 223A19AC18FD2D2900AF81C1 /* mps.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 224CC78F175E1821002FF81B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3896,6 +3947,11 @@ target = 2231BB5A18CA97DC002D6322 /* locusss */; targetProxy = 2231BB6E18CA986D002D6322 /* PBXContainerItemProxy */; }; + 223A19AB18FD2CF300AF81C1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 223A19A418FD2CE200AF81C1 /* mps-shared */; + targetProxy = 223A19AA18FD2CF300AF81C1 /* PBXContainerItemProxy */; + }; 224CC78D175E1821002FF81B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 31EEABFA156AAF9D00714D05 /* mps */; @@ -4361,6 +4417,94 @@ }; name = RASH; }; + 223A19A618FD2CE200AF81C1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + EXECUTABLE_PREFIX = lib; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_NAME = mps; + }; + name = Debug; + }; + 223A19A718FD2CE200AF81C1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + EXECUTABLE_PREFIX = lib; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_NAME = mps; + }; + name = Release; + }; + 223A19A818FD2CE200AF81C1 /* RASH */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + EXECUTABLE_PREFIX = lib; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_NAME = mps; + }; + name = RASH; + }; 224CC796175E1821002FF81B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5577,6 +5721,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 223A19A918FD2CE300AF81C1 /* Build configuration list for PBXNativeTarget "mps-shared" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 223A19A618FD2CE200AF81C1 /* Debug */, + 223A19A718FD2CE200AF81C1 /* Release */, + 223A19A818FD2CE200AF81C1 /* RASH */, + ); + defaultConfigurationIsVisible = 0; + }; 224CC795175E1821002FF81B /* Build configuration list for PBXNativeTarget "fotest" */ = { isa = XCConfigurationList; buildConfigurations = ( From 8d17a01e96e1797726ae2a2eb3347abb9cdc2659 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 11:13:54 +0100 Subject: [PATCH 46/75] Be clearer in the output of configure that configure/make is one way to build the mps, but alternative approaches may be better. Copied from Perforce Change: 185544 ServerID: perforce.ravenbrook.com --- mps/configure | 21 +++++++++++---------- mps/configure.ac | 3 ++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/mps/configure b/mps/configure index e491a01208f..9b4df170d39 100755 --- a/mps/configure +++ b/mps/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Memory Pool System Kit release/1.113.0. +# Generated by GNU Autoconf 2.69 for Memory Pool System Kit release/1.114.0. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Memory Pool System Kit' PACKAGE_TARNAME='mps-kit' -PACKAGE_VERSION='release/1.113.0' -PACKAGE_STRING='Memory Pool System Kit release/1.113.0' +PACKAGE_VERSION='release/1.114.0' +PACKAGE_STRING='Memory Pool System Kit release/1.114.0' PACKAGE_BUGREPORT='mps-questions@ravenbrook.com' PACKAGE_URL='http://www.ravenbrook.com/project/mps/' @@ -1243,7 +1243,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Memory Pool System Kit release/1.113.0 to adapt to many kinds of systems. +\`configure' configures Memory Pool System Kit release/1.114.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1308,7 +1308,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Memory Pool System Kit release/1.113.0:";; + short | recursive ) echo "Configuration of Memory Pool System Kit release/1.114.0:";; esac cat <<\_ACEOF @@ -1389,7 +1389,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Memory Pool System Kit configure release/1.113.0 +Memory Pool System Kit configure release/1.114.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1691,7 +1691,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Memory Pool System Kit $as_me release/1.113.0, which was +It was created by Memory Pool System Kit $as_me release/1.114.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4126,7 +4126,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Memory Pool System Kit $as_me release/1.113.0, which was +This file was extended by Memory Pool System Kit $as_me release/1.114.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4180,7 +4180,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Memory Pool System Kit config.status release/1.113.0 +Memory Pool System Kit config.status release/1.114.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -4748,4 +4748,5 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi -echo 1>&2 "CONFIGURE/MAKE IS NOT THE BEST WAY TO BUILD THE MPS -- see " +echo 1>&2 "CONFIGURE/MAKE MAY NOT BE THE BEST WAY TO BUILD THE MPS +-- see for alternative approaches" diff --git a/mps/configure.ac b/mps/configure.ac index 6ee47ca05a6..4ebb0aee578 100644 --- a/mps/configure.ac +++ b/mps/configure.ac @@ -124,4 +124,5 @@ AC_CONFIG_FILES(Makefile example/scheme/Makefile) AC_OUTPUT -echo 1>&2 "CONFIGURE/MAKE IS NOT THE BEST WAY TO BUILD THE MPS -- see " +echo 1>&2 "CONFIGURE/MAKE MAY NOT BE THE BEST WAY TO BUILD THE MPS +-- see for alternative approaches" From 59e9d6288868fc269c5b5c3996ed7ba5919149d7 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 11:15:21 +0100 Subject: [PATCH 47/75] Fix installation on linux and freebsd. Copied from Perforce Change: 185545 ServerID: perforce.ravenbrook.com --- mps/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/Makefile.in b/mps/Makefile.in index ccc56ff2bd4..7eb319c27d8 100644 --- a/mps/Makefile.in +++ b/mps/Makefile.in @@ -33,7 +33,7 @@ install-make-build: make-install-dirs build-via-make $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/cool/libmps.so $(prefix)/lib/libmps-debug.so $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/hot/mps.a $(prefix)/lib/libmps.a $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/hot/libmps.so $(prefix)/lib/libmps.so - $(INSTALL_PROGRAM) $(addprefix code/$(MPS_TARGET_NAME)/hot/Release/,$(EXTRA_TARGETS)) $(prefix)/bin + $(INSTALL_PROGRAM) $(addprefix code/$(MPS_TARGET_NAME)/hot/,$(EXTRA_TARGETS)) $(prefix)/bin build-via-xcode: $(XCODEBUILD) -config Release From a755d1658521f8e7e71c25f15af5d195aa3af397 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 12:39:51 +0100 Subject: [PATCH 48/75] Revert hasty merge of branch/2014-04-15/shared -- broke xcode build. Copied from Perforce Change: 185553 ServerID: perforce.ravenbrook.com --- mps/Makefile.in | 8 +- mps/code/comm.gmk | 20 ++-- mps/code/mps.xcodeproj/project.pbxproj | 153 ------------------------- mps/configure | 21 ++-- mps/configure.ac | 3 +- 5 files changed, 22 insertions(+), 183 deletions(-) diff --git a/mps/Makefile.in b/mps/Makefile.in index 7eb319c27d8..2d558588673 100644 --- a/mps/Makefile.in +++ b/mps/Makefile.in @@ -1,7 +1,7 @@ # Makefile.in -- source for autoconf Makefile # # $Id$ -# Copyright (C) 2012-2014 Ravenbrook Limited. See end of file for license. +# Copyright (C) 2012-2013 Ravenbrook Limited. See end of file for license. # # YOU DON'T NEED AUTOCONF TO BUILD THE MPS # This is just here for people who want or expect a configure script. @@ -30,10 +30,8 @@ clean-make-build: install-make-build: make-install-dirs build-via-make $(INSTALL_DATA) code/mps*.h $(prefix)/include/ $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/cool/mps.a $(prefix)/lib/libmps-debug.a - $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/cool/libmps.so $(prefix)/lib/libmps-debug.so $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/hot/mps.a $(prefix)/lib/libmps.a - $(INSTALL_DATA) code/$(MPS_TARGET_NAME)/hot/libmps.so $(prefix)/lib/libmps.so - $(INSTALL_PROGRAM) $(addprefix code/$(MPS_TARGET_NAME)/hot/,$(EXTRA_TARGETS)) $(prefix)/bin + $(INSTALL_PROGRAM) $(addprefix code/$(MPS_TARGET_NAME)/hot/Release/,$(EXTRA_TARGETS)) $(prefix)/bin build-via-xcode: $(XCODEBUILD) -config Release @@ -46,9 +44,7 @@ clean-xcode-build: install-xcode-build: make-install-dirs build-via-xcode $(INSTALL_DATA) code/mps*.h $(prefix)/include/ $(INSTALL_DATA) code/xc/Debug/libmps.a $(prefix)/lib/libmps-debug.a - $(INSTALL_DATA) code/xc/Debug/libmps.dylib $(prefix)/lib/libmps-debug.dylib $(INSTALL_DATA) code/xc/Release/libmps.a $(prefix)/lib/libmps.a - $(INSTALL_DATA) code/xc/Release/libmps.dylib $(prefix)/lib/libmps.dylib $(INSTALL_PROGRAM) $(addprefix code/xc/Release/,$(EXTRA_TARGETS)) $(prefix)/bin Makefile: Makefile.in config.status diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk index ce46bba68f4..70fed15d507 100644 --- a/mps/code/comm.gmk +++ b/mps/code/comm.gmk @@ -170,7 +170,7 @@ MPMCOMMON = abq.c arena.c arenacl.c arenavm.c arg.c boot.c bt.c \ global.c ld.c locus.c message.c meter.c mpm.c mpsi.c nailboard.c \ pool.c poolabs.c poolmfs.c poolmrg.c poolmv.c protocol.c range.c \ ref.c reserv.c ring.c root.c sa.c sac.c seg.c shield.c splay.c ss.c \ - table.c trace.c traceanc.c tract.c tree.c version.c walk.c + table.c trace.c traceanc.c tract.c tree.c walk.c MPM = $(MPMCOMMON) $(MPMPF) @@ -223,7 +223,7 @@ endif # %%TARGET: When adding a new target, add it to one of the variables # in this section. Library components go in LIB_TARGETS. -LIB_TARGETS=mps.a libmps.so +LIB_TARGETS=mps.a mpsplan.a # Test executables go in TEST_TARGETS. @@ -352,10 +352,10 @@ endif # %%VARIETY: When adding a new variety, add a rule for how to build the # MPS library for the variety. -$(PFM)/rash/libmps.so $(PFM)/rash/mps.a: $(PFM)/rash/mps.o -$(PFM)/hot/libmps.so $(PFM)/hot/mps.a: $(PFM)/hot/mps.o +$(PFM)/rash/mps.a: $(PFM)/rash/mps.o +$(PFM)/hot/mps.a: $(PFM)/hot/mps.o -$(PFM)/cool/libmps.so $(PFM)/cool/mps.a: \ +$(PFM)/cool/mps.a: \ $(MPMOBJ) $(AMCOBJ) $(AMSOBJ) $(AWLOBJ) $(LOOBJ) $(SNCOBJ) \ $(MV2OBJ) $(MVFFOBJ) $(PLINTHOBJ) $(POOLNOBJ) @@ -508,6 +508,8 @@ $(PFM)/$(VARIETY)/replay: $(PFM)/$(VARIETY)/replay.o \ $(PFM)/$(VARIETY)/table.o \ $(PFM)/$(VARIETY)/mps.a +$(PFM)/$(VARIETY)/mpsplan.a: $(PLINTHOBJ) + endif @@ -602,14 +604,10 @@ endif $(PFM)/$(VARIETY)/%.a: $(ECHO) "$(PFM): $@" rm -f $@ - $(AR) $(ARFLAGS) $@ $^ + $(CC) $(CFLAGS) -c -o $(PFM)/$(VARIETY)/version.o version.c + $(AR) $(ARFLAGS) $@ $^ $(PFM)/$(VARIETY)/version.o $(RANLIB) $@ -$(PFM)/$(VARIETY)/%.so: - $(ECHO) "$(PFM): $@" - rm -f $@ - $(CC) $(CFLAGS) $(LINKFLAGS) -shared -o $@ $^ - # Executable $(PFM)/$(VARIETY)/%: diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj index b3547175c39..88f110bab01 100644 --- a/mps/code/mps.xcodeproj/project.pbxproj +++ b/mps/code/mps.xcodeproj/project.pbxproj @@ -26,7 +26,6 @@ ); dependencies = ( 3104AFF6156D37BC000A585A /* PBXTargetDependency */, - 223A19AB18FD2CF300AF81C1 /* PBXTargetDependency */, 3114A644156E94FB001E0AA3 /* PBXTargetDependency */, 22FACEF1188809B5000FDBC1 /* PBXTargetDependency */, 3104AFF8156D37BE000A585A /* PBXTargetDependency */, @@ -86,7 +85,6 @@ 2231BB6118CA97DC002D6322 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; 2231BB6A18CA984F002D6322 /* locusss.c in Sources */ = {isa = PBXBuildFile; fileRef = 2231BB6918CA983C002D6322 /* locusss.c */; }; 2231BB6B18CA9861002D6322 /* locbwcss.c in Sources */ = {isa = PBXBuildFile; fileRef = 2231BB6818CA9834002D6322 /* locbwcss.c */; }; - 223A19AC18FD2D2900AF81C1 /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; }; 224CC791175E1821002FF81B /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; 224CC793175E1821002FF81B /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; 224CC79F175E321C002FF81B /* mv2test.c in Sources */ = {isa = PBXBuildFile; fileRef = 3114A686156E9674001E0AA3 /* mv2test.c */; }; @@ -317,13 +315,6 @@ remoteGlobalIDString = 2231BB5A18CA97DC002D6322; remoteInfo = locusss; }; - 223A19AA18FD2CF300AF81C1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 223A19A418FD2CE200AF81C1; - remoteInfo = "mps-shared"; - }; 224CC78E175E1821002FF81B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */; @@ -1336,7 +1327,6 @@ 2231BB6718CA97DC002D6322 /* locusss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = locusss; sourceTree = BUILT_PRODUCTS_DIR; }; 2231BB6818CA9834002D6322 /* locbwcss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locbwcss.c; sourceTree = ""; }; 2231BB6918CA983C002D6322 /* locusss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = locusss.c; sourceTree = ""; }; - 223A19A518FD2CE200AF81C1 /* libmps.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libmps.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 224CC799175E1821002FF81B /* fotest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fotest; sourceTree = BUILT_PRODUCTS_DIR; }; 224CC79E175E3202002FF81B /* fotest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fotest.c; sourceTree = ""; }; 22561A9618F4263300372C66 /* testthr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testthr.h; sourceTree = ""; }; @@ -1662,13 +1652,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 223A19A218FD2CE200AF81C1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 224CC792175E1821002FF81B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2283,7 +2266,6 @@ 22FACEED18880983000FDBC1 /* airtest */, 22C2ACAF18BE400A006B3677 /* nailboardtest */, 22F846BD18F437B900982BA7 /* lockut */, - 223A19A518FD2CE200AF81C1 /* libmps.dylib */, ); name = Products; sourceTree = ""; @@ -2459,13 +2441,6 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 223A19A318FD2CE200AF81C1 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 31EEABF9156AAF9D00714D05 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -2512,23 +2487,6 @@ productReference = 2231BB6718CA97DC002D6322 /* locusss */; productType = "com.apple.product-type.tool"; }; - 223A19A418FD2CE200AF81C1 /* mps-shared */ = { - isa = PBXNativeTarget; - buildConfigurationList = 223A19A918FD2CE300AF81C1 /* Build configuration list for PBXNativeTarget "mps-shared" */; - buildPhases = ( - 223A19A118FD2CE200AF81C1 /* Sources */, - 223A19A218FD2CE200AF81C1 /* Frameworks */, - 223A19A318FD2CE200AF81C1 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "mps-shared"; - productName = "mps-shared"; - productReference = 223A19A518FD2CE200AF81C1 /* libmps.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; 224CC78C175E1821002FF81B /* fotest */ = { isa = PBXNativeTarget; buildConfigurationList = 224CC795175E1821002FF81B /* Build configuration list for PBXNativeTarget "fotest" */; @@ -3355,7 +3313,6 @@ 3104AFF1156D37A0000A585A /* all */, 22CDE8EF16E9E97D00366D0A /* testrun */, 31EEABFA156AAF9D00714D05 /* mps */, - 223A19A418FD2CE200AF81C1 /* mps-shared */, 3114A632156E94DB001E0AA3 /* abqtest */, 22FACEE018880983000FDBC1 /* airtest */, 3124CAEA156BE7F300753214 /* amcss */, @@ -3442,14 +3399,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 223A19A118FD2CE200AF81C1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 223A19AC18FD2D2900AF81C1 /* mps.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 224CC78F175E1821002FF81B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3947,11 +3896,6 @@ target = 2231BB5A18CA97DC002D6322 /* locusss */; targetProxy = 2231BB6E18CA986D002D6322 /* PBXContainerItemProxy */; }; - 223A19AB18FD2CF300AF81C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 223A19A418FD2CE200AF81C1 /* mps-shared */; - targetProxy = 223A19AA18FD2CF300AF81C1 /* PBXContainerItemProxy */; - }; 224CC78D175E1821002FF81B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 31EEABFA156AAF9D00714D05 /* mps */; @@ -4417,94 +4361,6 @@ }; name = RASH; }; - 223A19A618FD2CE200AF81C1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - EXECUTABLE_PREFIX = lib; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MACOSX_DEPLOYMENT_TARGET = 10.9; - PRODUCT_NAME = mps; - }; - name = Debug; - }; - 223A19A718FD2CE200AF81C1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - EXECUTABLE_PREFIX = lib; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MACOSX_DEPLOYMENT_TARGET = 10.9; - PRODUCT_NAME = mps; - }; - name = Release; - }; - 223A19A818FD2CE200AF81C1 /* RASH */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - EXECUTABLE_PREFIX = lib; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MACOSX_DEPLOYMENT_TARGET = 10.9; - PRODUCT_NAME = mps; - }; - name = RASH; - }; 224CC796175E1821002FF81B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5721,15 +5577,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 223A19A918FD2CE300AF81C1 /* Build configuration list for PBXNativeTarget "mps-shared" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 223A19A618FD2CE200AF81C1 /* Debug */, - 223A19A718FD2CE200AF81C1 /* Release */, - 223A19A818FD2CE200AF81C1 /* RASH */, - ); - defaultConfigurationIsVisible = 0; - }; 224CC795175E1821002FF81B /* Build configuration list for PBXNativeTarget "fotest" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/mps/configure b/mps/configure index 9b4df170d39..e491a01208f 100755 --- a/mps/configure +++ b/mps/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Memory Pool System Kit release/1.114.0. +# Generated by GNU Autoconf 2.69 for Memory Pool System Kit release/1.113.0. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Memory Pool System Kit' PACKAGE_TARNAME='mps-kit' -PACKAGE_VERSION='release/1.114.0' -PACKAGE_STRING='Memory Pool System Kit release/1.114.0' +PACKAGE_VERSION='release/1.113.0' +PACKAGE_STRING='Memory Pool System Kit release/1.113.0' PACKAGE_BUGREPORT='mps-questions@ravenbrook.com' PACKAGE_URL='http://www.ravenbrook.com/project/mps/' @@ -1243,7 +1243,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Memory Pool System Kit release/1.114.0 to adapt to many kinds of systems. +\`configure' configures Memory Pool System Kit release/1.113.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1308,7 +1308,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Memory Pool System Kit release/1.114.0:";; + short | recursive ) echo "Configuration of Memory Pool System Kit release/1.113.0:";; esac cat <<\_ACEOF @@ -1389,7 +1389,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Memory Pool System Kit configure release/1.114.0 +Memory Pool System Kit configure release/1.113.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1691,7 +1691,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Memory Pool System Kit $as_me release/1.114.0, which was +It was created by Memory Pool System Kit $as_me release/1.113.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4126,7 +4126,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Memory Pool System Kit $as_me release/1.114.0, which was +This file was extended by Memory Pool System Kit $as_me release/1.113.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4180,7 +4180,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Memory Pool System Kit config.status release/1.114.0 +Memory Pool System Kit config.status release/1.113.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -4748,5 +4748,4 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi -echo 1>&2 "CONFIGURE/MAKE MAY NOT BE THE BEST WAY TO BUILD THE MPS --- see for alternative approaches" +echo 1>&2 "CONFIGURE/MAKE IS NOT THE BEST WAY TO BUILD THE MPS -- see " diff --git a/mps/configure.ac b/mps/configure.ac index 4ebb0aee578..6ee47ca05a6 100644 --- a/mps/configure.ac +++ b/mps/configure.ac @@ -124,5 +124,4 @@ AC_CONFIG_FILES(Makefile example/scheme/Makefile) AC_OUTPUT -echo 1>&2 "CONFIGURE/MAKE MAY NOT BE THE BEST WAY TO BUILD THE MPS --- see for alternative approaches" +echo 1>&2 "CONFIGURE/MAKE IS NOT THE BEST WAY TO BUILD THE MPS -- see " From ecdd5a04cf4cc50fe942b612a70e4d466fe4a903 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 12:40:15 +0100 Subject: [PATCH 49/75] Ignore test objects and design images. Copied from Perforce Change: 185555 ServerID: perforce.ravenbrook.com --- mps/.p4ignore | 1 + mps/manual/source/design/.p4ignore | 1 + 2 files changed, 2 insertions(+) diff --git a/mps/.p4ignore b/mps/.p4ignore index b640360caf6..25cd419ae6d 100644 --- a/mps/.p4ignore +++ b/mps/.p4ignore @@ -16,6 +16,7 @@ TAGS *.dSYM code/*/*/*.d *.pyc +test/obj test/test/log test/test/obj ....gcda diff --git a/mps/manual/source/design/.p4ignore b/mps/manual/source/design/.p4ignore index 0e9be69cee0..2457ad19192 100644 --- a/mps/manual/source/design/.p4ignore +++ b/mps/manual/source/design/.p4ignore @@ -1,5 +1,6 @@ # The files in this directory are generated by the "mps" extension to Sphinx, # except the index and the "old designs" index. *.rst +*.svg !index.rst !old.rst From c376a2b808480d92853bdad98659500cc69129d9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 12:41:10 +0100 Subject: [PATCH 50/75] Mvt does not actually need to use gcsegs: in fact, gcsegs create difficulties because buffers need to be detached. so switch to using ordinary segs just like mvff. Copied from Perforce Change: 185556 ServerID: perforce.ravenbrook.com --- mps/code/poolmv2.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index 51b346e9f43..f6d85b1b134 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -78,7 +78,6 @@ typedef struct MVTStruct Bool abqOverflow; /* ABQ dropped some candidates */ /* .* */ Bool splinter; /* Saved splinter */ - Seg splinterSeg; /* Saved splinter seg */ Addr splinterBase; /* Saved splinter base */ Addr splinterLimit; /* Saved splinter size */ @@ -133,7 +132,7 @@ typedef struct MVTStruct DEFINE_POOL_CLASS(MVTPoolClass, this) { - INHERIT_CLASS(this, AbstractSegBufPoolClass); + INHERIT_CLASS(this, AbstractBufferPoolClass); this->name = "MVT"; this->size = sizeof(MVTStruct); this->offset = offsetof(MVTStruct, poolStruct); @@ -292,7 +291,6 @@ static Res MVTInit(Pool pool, ArgList args) mvt->maxSize = maxSize; mvt->fragLimit = fragLimit; mvt->splinter = FALSE; - mvt->splinterSeg = NULL; mvt->splinterBase = (Addr)0; mvt->splinterLimit = (Addr)0; @@ -378,9 +376,7 @@ static Bool MVTCheck(MVT mvt) if (mvt->splinter) { CHECKL(AddrOffset(mvt->splinterBase, mvt->splinterLimit) >= mvt->minSize); - CHECKD(Seg, mvt->splinterSeg); - CHECKL(mvt->splinterBase >= SegBase(mvt->splinterSeg)); - CHECKL(mvt->splinterLimit <= SegLimit(mvt->splinterSeg)); + CHECKL(mvt->splinterBase < mvt->splinterLimit); } CHECKL(mvt->size == mvt->allocated + mvt->available + mvt->unavailable); @@ -951,7 +947,6 @@ static void MVTBufferEmpty(Pool pool, Buffer buffer, } mvt->splinter = TRUE; - mvt->splinterSeg = BufferSeg(buffer); mvt->splinterBase = base; mvt->splinterLimit = limit; } @@ -998,8 +993,6 @@ static void MVTFree(Pool pool, Addr base, Size size) AVER(mvt->size == mvt->allocated + mvt->available + mvt->unavailable); METER_ACC(mvt->exceptionReturns, SegSize(seg)); - if (SegBuffer(seg) != NULL) - BufferDetach(SegBuffer(seg), MVT2Pool(mvt)); MVTSegFree(mvt, seg); return; } @@ -1031,7 +1024,6 @@ static Res MVTDescribe(Pool pool, mps_lib_FILE *stream) " availLimit: $U \n", (WriteFU)mvt->availLimit, " abqOverflow: $S \n", mvt->abqOverflow?"TRUE":"FALSE", " splinter: $S \n", mvt->splinter?"TRUE":"FALSE", - " splinterSeg: $P \n", (WriteFP)mvt->splinterSeg, " splinterBase: $A \n", (WriteFA)mvt->splinterBase, " splinterLimit: $A \n", (WriteFU)mvt->splinterLimit, " size: $U \n", (WriteFU)mvt->size, @@ -1158,7 +1150,7 @@ static Res MVTSegAlloc(Seg *segReturn, MVT mvt, Size size, { /* Can't use plain old SegClass here because we need to call * SegBuffer() in MVTFree(). */ - Res res = SegAlloc(segReturn, GCSegClassGet(), + Res res = SegAlloc(segReturn, SegClassGet(), SegPrefDefault(), size, MVT2Pool(mvt), withReservoirPermit, argsNone); @@ -1182,7 +1174,6 @@ static Res MVTSegAlloc(Seg *segReturn, MVT mvt, Size size, */ static void MVTSegFree(MVT mvt, Seg seg) { - Buffer buffer; Size size; size = SegSize(seg); @@ -1192,16 +1183,6 @@ static void MVTSegFree(MVT mvt, Seg seg) mvt->size -= size; mvt->availLimit = mvt->size * mvt->fragLimit / 100; AVER(mvt->size == mvt->allocated + mvt->available + mvt->unavailable); - - /* If the client program allocates the exactly the entire buffer then - frees the allocated memory then we'll try to free the segment with - the buffer still attached. It's safe, but we must detach the buffer - first. See job003520 and job003672. */ - buffer = SegBuffer(seg); - if (buffer != NULL) { - AVER(BufferAP(buffer)->init == SegLimit(seg)); - BufferDetach(buffer, MVT2Pool(mvt)); - } SegFree(seg); METER_ACC(mvt->segFrees, size); From e97db74a0c8ad9eff63155a7f9050933c9542742 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 16 Apr 2014 13:23:56 +0100 Subject: [PATCH 51/75] Avoid avers with side effects, as requested by rb in Copied from Perforce Change: 185595 ServerID: perforce.ravenbrook.com --- mps/code/poolams.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mps/code/poolams.c b/mps/code/poolams.c index d769630f009..8c1db1e990e 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -172,9 +172,14 @@ static Res amsCreateTables(AMS ams, BT *allocReturn, goto failWhite; } - /* Invalidate the colour tables in checking varieties. */ - AVER((BTResRange(nongreyTable, 0, length), TRUE)); - AVER((BTSetRange(nonwhiteTable, 0, length), TRUE)); +#if defined(AVER_AND_CHECK) + /* Invalidate the colour tables in checking varieties. The algorithm + * is designed not to depend on the initial values of these tables, + * so by invalidating them we get some checking of this. + */ + BTResRange(nongreyTable, 0, length); + BTSetRange(nonwhiteTable, 0, length); +#endif *allocReturn = allocTable; *nongreyReturn = nongreyTable; From e8a0bce7239156172641c122beabf5b28839d90c Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 16 Apr 2014 13:42:46 +0100 Subject: [PATCH 52/75] Good,bad are better names than first,last for the arguments to p4-bisect start. Copied from Perforce Change: 185601 ServerID: perforce.ravenbrook.com --- mps/tool/p4-bisect | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mps/tool/p4-bisect b/mps/tool/p4-bisect index 97ff39dad74..5fa77639e30 100755 --- a/mps/tool/p4-bisect +++ b/mps/tool/p4-bisect @@ -83,12 +83,12 @@ def start(args): changes = sorted(int(c['change']) for c in p4.run('changes', *args.filespec)) if not changes: error("No changes for {}".format(' '.join(args.filespec))) - if args.first is None: - args.first = changes[0] - if args.last is None: - args.last = changes[-1] + if args.good is None: + args.good = changes[0] + if args.bad is None: + args.bad = changes[-1] state = State(filespec=args.filespec, - changes=[c for c in changes if args.first <= c <= args.last]) + changes=[c for c in changes if args.good <= c <= args.bad]) state.update() def good(args): @@ -140,11 +140,11 @@ def main(argv): start_parser = a('start', help='start a p4-bisect session') aa = start_parser.add_argument start_parser.add_argument('-f', '--filespec', action='append', - help='filespec to search') - start_parser.add_argument('first', nargs='?', type=int, - help='earliest changelevel to examine') - start_parser.add_argument('last', nargs='?', type=int, - help='latest changelevel to examine') + help='filespec(s) to search') + start_parser.add_argument('good', nargs='?', type=int, + help='known good changelevel') + start_parser.add_argument('bad', nargs='?', type=int, + help='known bad changelevel') start_parser.set_defaults(func=start) good_parser = a('good', help='declare current revision good') From 5eebc02a462ac522af51005f74949c3aab6b2637 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 16 Apr 2014 13:59:33 +0100 Subject: [PATCH 53/75] Explain reasoning in amsbufferempty, as requested by rb . Copied from Perforce Change: 185603 ServerID: perforce.ravenbrook.com --- mps/code/poolams.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 8c1db1e990e..65b2dcf754f 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -1037,7 +1037,19 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit) AVER(limitIndex <= amsseg->firstFree); if (limitIndex == amsseg->firstFree) /* is it at the end? */ { amsseg->firstFree = initIndex; - } else if (!ams->shareAllocTable || !amsseg->colourTablesInUse) { + } else if (ams->shareAllocTable && amsseg->colourTablesInUse) { + /* The nonwhiteTable is shared with allocTable and in use, so we + * mustn't start using allocTable. In this case we know: 1. the + * segment has been condemned (because colour tables are turned + * on in AMSCondemn); 2. the segment has not yet been reclaimed + * (because colour tables are turned off in AMSReclaim); 3. the + * unused portion of the buffer is black (see AMSCondemn). So we + * need to whiten the unused portion of the buffer. The + * allocTable will be turned back on (if necessary) in + * AMSReclaim, when we know that the nonwhite grains are exactly + * the allocated grains. + */ + } else { /* start using allocTable */ amsseg->allocTableInUse = TRUE; BTSetRange(amsseg->allocTable, 0, amsseg->firstFree); From 0fae2b083bb07fc770ee141afb79805d08d35e80 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 16 Apr 2014 17:04:08 +0100 Subject: [PATCH 54/75] Use "active" rather than "in development" to avoid ugly wrapping in the table. Copied from Perforce Change: 185610 ServerID: perforce.ravenbrook.com --- mps/tool/branch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/tool/branch b/mps/tool/branch index 686cdefa244..790dceb0eba 100755 --- a/mps/tool/branch +++ b/mps/tool/branch @@ -49,7 +49,7 @@ TASK_BRANCH_ENTRY = ''' {date}/{task} Changes {desc_html} - In development (diffs). + Active (diffs). ''' From b3c0f1467eb3796ccfc17dd6be4b6fe46fad413b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 17 Apr 2014 23:40:07 +0100 Subject: [PATCH 55/75] Function now called rangecopy. Copied from Perforce Change: 185646 ServerID: perforce.ravenbrook.com --- mps/design/range.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/design/range.txt b/mps/design/range.txt index bf0f924430e..1b42d69ac22 100644 --- a/mps/design/range.txt +++ b/mps/design/range.txt @@ -51,7 +51,7 @@ between ``base`` (inclusive) and ``limit`` (exclusive). It must be the case that ``base <= limit``. If ``base == limit`` then the range is empty. -``void RangeInitCopy(Range dest, Range src)`` +``void RangeCopy(Range dest, Range src)`` Initialize ``dest`` to be a copy of ``src``. From 753634c8b040d9a1eebeea5953b45fed0bf1095c Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 17 Apr 2014 23:41:09 +0100 Subject: [PATCH 56/75] Explain how to declare and update boolean bitfields. SegPrefs are not necessarily to do with segments. Copied from Perforce Change: 185647 ServerID: perforce.ravenbrook.com --- mps/design/type.txt | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/mps/design/type.txt b/mps/design/type.txt index 6ce0da3c035..900980970dc 100644 --- a/mps/design/type.txt +++ b/mps/design/type.txt @@ -151,6 +151,14 @@ compared ``w3i3mv\hi\amcss.exe`` running with and without the macro for ``BoolCheck`` on the PC Aaron. "With" ran in 97.7% of the time (averaged over 3 runs). +_`.bool.bitfield`: When a Boolean needs to be stored in a bitfield, +the type of the bitfield must be ``unsigned:1``, not ``Bool:1``. +(That's because the two values of the type ``Bool:1`` are ``0`` and +``-1``, which means that assigning ``TRUE`` would require a sign +conversion.) To avoid warnings about loss of data from GCC with the +``-Wconversion`` option, ``misc.h`` provides the ``BOOL`` macro for +coercing a value to an unsigned single-bit field. + ``typedef unsigned BufferMode`` @@ -235,7 +243,8 @@ 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. +occurred, in which objects may have moved. 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``. @@ -351,7 +360,7 @@ 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:: Could ``Rank`` be an ``unsigned short`` or ``unsigned char``? .. note:: @@ -459,30 +468,35 @@ create a valid registered constant root that contains any references. 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. +_`.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``. +_`.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 +_`.segprefkind`: The type ``SegPrefKind`` expresses a preference for +addresses within an address space. 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. +``SegPrefHigh`` Prefer high addresses. +``SegPrefLow`` Prefer low addresses. +``SegPrefZoneSet`` Prefer addresses in specified zones. ================== ==================================================== +.. note:: + + The name is misleading as this is used to refer to address + preferences in general, not just addresses of segments. + ``typedef unsigned Serial`` @@ -490,9 +504,8 @@ _`.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] +global root. For example, "the third arena's fifth pool's second +buffer". Why? Consistency checking, debugging, and logging. Not well thought out. @@ -509,6 +522,8 @@ 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. +.. note:: Could ``Shift`` be an ``unsigned short`` or ``unsigned char``? + ``typedef unsigned long Sig`` @@ -640,7 +655,7 @@ _`.word.ops`: ``WordIsAligned()``, ``WordAlignUp()``, ``typedef Word ZoneSet`` _`.zoneset`: ``ZoneSet`` is a conservative approximation to a set of -zone. See design.mps.refset_. +zones. See design.mps.refset_. Abstract types From 8187140fbe94c89aeb8eeb95690404830a6047a9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 17 Apr 2014 23:41:18 +0100 Subject: [PATCH 57/75] Learn some more types. Copied from Perforce Change: 185648 ServerID: perforce.ravenbrook.com --- mps/manual/source/extensions/mps/designs.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mps/manual/source/extensions/mps/designs.py b/mps/manual/source/extensions/mps/designs.py index 57959f1ea0c..230594e9392 100644 --- a/mps/manual/source/extensions/mps/designs.py +++ b/mps/manual/source/extensions/mps/designs.py @@ -22,10 +22,11 @@ TYPES = ''' Arena Attr Bool BootBlock BT Buffer BufferMode Byte Chain Chunk Clock Compare Count Epoch FindDelete Format FrameState Fun Globals Index Land LD Lock Message MessageType MutatorFaultContext Page - Pointer Pool PThreadext Range Rank RankSet Ref Res Reservoir Ring - Root RootMode RootVar ScanState Seg SegBuf SegPref SegPrefKind - Serial Shift Sig Size Space SplayNode SplayTree StackContext - Thread Trace TraceId TraceSet ULongest VM Word ZoneSet + Pointer Pool PThreadext Range Rank RankSet Ref RefSet Res + Reservoir Ring Root RootMode RootVar ScanState Seg SegBuf SegPref + SegPrefKind Serial Shift Sig Size Space SplayNode SplayTree + StackContext Thread Trace TraceId TraceSet TraceStartWhy + TraceState ULongest VM Word ZoneSet ''' From efee845d4ca6920ed3f27c83cdd72b12ddb23e3b Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 18 Apr 2014 00:41:33 +0100 Subject: [PATCH 58/75] Fix typo. Copied from Perforce Change: 185649 ServerID: perforce.ravenbrook.com --- mps/manual/source/pool/awl.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/manual/source/pool/awl.rst b/mps/manual/source/pool/awl.rst index 79df0258804..094335ba3b8 100644 --- a/mps/manual/source/pool/awl.rst +++ b/mps/manual/source/pool/awl.rst @@ -283,9 +283,9 @@ the format of objects allocated in it: "Aligned pointer" means a word whose numeric value (that is, its value when treated as an unsigned integer) is a multiple of the size - of a pointer. For you're using a 32-bit architecture, that means - that an aligned pointer is a multiple of 4 and its bottom two bits - are both zero. + of a pointer. If you're using a 64-bit architecture, that means that + an aligned pointer is a multiple of 8 and its bottom three bits are + zero. The bottom line is that references from an object in an AWL pool must be untagged and aligned, and integers must be tagged with a From 9c4a5de236f874aa1cfecc2291b5af2385e7d0db Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 18 Apr 2014 08:55:26 +0100 Subject: [PATCH 59/75] Building open dylan side by side with boehm or mps. Copied from Perforce Change: 185650 ServerID: perforce.ravenbrook.com --- mps/tool/testopendylan | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/mps/tool/testopendylan b/mps/tool/testopendylan index a8aee4a0025..0c185ff2fd0 100755 --- a/mps/tool/testopendylan +++ b/mps/tool/testopendylan @@ -20,8 +20,21 @@ # 2. CONFIGURATION -# MPS sources we are testing against -MPS=$(cd -- "$(dirname "$0")/.." && pwd) +# Check command-line argument +GC=$1 +case "$GC" in + mps) + # MPS sources we are testing against + CONFIGURE=--with-gc-path=$(cd -- "$(dirname "$0")/.." && pwd) + ;; + boehm) + CONFIGURE= + ;; + *) + echo "Backend '$GC' not supported: choose mps or boehm." + exit 1 +esac + # OpenDylan version for bootstrapping VERSION=2013.2 @@ -30,7 +43,7 @@ VERSION=2013.2 REMOTE=https://github.com/dylan-lang/opendylan.git # Directory to put everything in -TESTDIR="$PWD/.test" +TESTDIR="$PWD/.test/$GC" mkdir -p -- "$TESTDIR" cd -- "$TESTDIR" @@ -104,7 +117,7 @@ if [ -f "$REPO/Makefile" ]; then else ( cd -- "$REPO" && ./autogen.sh && - ./configure --with-gc=mps --with-gc-path="$MPS" --prefix="$PREFIX" + ./configure --with-gc="$GC" --prefix="$PREFIX" $CONFIGURE ) fi ( cd -- "$REPO" && From 1d6c7ca8f1e68ce6d969371dbd7466b6f4b1d303 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 18 Apr 2014 10:24:36 +0100 Subject: [PATCH 60/75] Fix typo. Copied from Perforce Change: 185659 ServerID: perforce.ravenbrook.com --- mps/procedure/release-build.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mps/procedure/release-build.rst b/mps/procedure/release-build.rst index bdce60df4ca..ee65b5f645d 100644 --- a/mps/procedure/release-build.rst +++ b/mps/procedure/release-build.rst @@ -47,7 +47,7 @@ All relative paths are relative to 1.111.0), where *VERSION* is the number of the version you’re releasing, and *N* is the first unused release number (starting at zero). Look in the index of releases (``release/index.html``) for - existing release numbers for your version:: + existing release numbers for your version. :: VERSION=A.BBB RELEASE=$VERSION.N @@ -111,7 +111,7 @@ Run the script ``tool/release``, passing the options: * ``-P mps`` — project name * ``-b BRANCH`` — branch to make the release from: for example ``version/1.113`` * ``-C CHANGELEVEL`` — changelevel at which to make the release -* ``-d "DESCRIPTION"`` — changelevel at which to make the release +* ``-d "DESCRIPTION"`` — description of the release * ``-y`` — yes, really make the release If omitted, the project and branch are deduced from the current @@ -231,8 +231,6 @@ A. References Ravenbrook Limited; 2008-10-16; http://info.ravenbrook.com/mail/2008/10/16/13-08-20/0.txt -.. [Sphinx] "Sphinx: Python document generator"; http://sphinx-doc.org/ - B. Document History ------------------- From 831e3c1a3e189f9aabe4b46d10e289dbd797eb7a Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sun, 20 Apr 2014 22:53:49 +0100 Subject: [PATCH 61/75] Improve help text. Copied from Perforce Change: 185701 ServerID: perforce.ravenbrook.com --- mps/tool/p4-bisect | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mps/tool/p4-bisect b/mps/tool/p4-bisect index 5fa77639e30..2886d823c59 100755 --- a/mps/tool/p4-bisect +++ b/mps/tool/p4-bisect @@ -130,7 +130,9 @@ def run(args): exit(result) def main(argv): - parser = argparse.ArgumentParser(prog='p4-bisect') + parser = argparse.ArgumentParser( + prog='p4-bisect', epilog='For help on CMD, use p4-bisect CMD -h') + parser.set_defaults(func=partial(help, parser)) subparsers = parser.add_subparsers() a = subparsers.add_parser From 5cd16daeb4525f2bf8f900a5be99b67d8c214137 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 22 Apr 2014 14:45:51 +0100 Subject: [PATCH 62/75] Branching master to branch/2014-04-22/condemn. Copied from Perforce Change: 185735 ServerID: perforce.ravenbrook.com From 6ffd4c7df53740579360ee2dfa06e83c63e0cabf Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 22 Apr 2014 17:53:47 +0100 Subject: [PATCH 63/75] Fix bugs in condemn logic: 1. TraceStartCollectAll now condemns all segments in pools with AttrGC (not just pools attached to generation zero of some chain, as before). 2. ChainDeferral now looks at all generations in the chain, so that the chain is condemned if any generation's new size is greater than its capacity (not just generation zero, as before). 3. ChainCondemnAuto now condemns all generations up to and including the highest generation whose new size is greater than its capacity (rather than, as before, up to and excluding the lowest generation whose new size is lower than its capacity). Update finaltest.c so that it has a mode in which it allocates in generation 1 of a chain and with the arena released so that the above fixes are tested. Remove the MPS_KEY_GEN workarounds from awlut and awluthe as these are no longer needed. Copied from Perforce Change: 185741 ServerID: perforce.ravenbrook.com --- mps/code/awlut.c | 3 -- mps/code/awluthe.c | 3 -- mps/code/chain.h | 1 - mps/code/finaltest.c | 104 +++++++++++++++++++++++++++++++++---------- mps/code/locus.c | 100 +++++++++++++++++------------------------ mps/code/trace.c | 28 ++++++++---- 6 files changed, 140 insertions(+), 99 deletions(-) diff --git a/mps/code/awlut.c b/mps/code/awlut.c index c62153ed44c..464a2dba91f 100644 --- a/mps/code/awlut.c +++ b/mps/code/awlut.c @@ -275,9 +275,6 @@ static void *setup(void *v, size_t s) die(mps_fmt_create_A(&dylanweakfmt, arena, dylan_fmt_A_weak()), "Format Create (weak)\n"); 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. */ - MPS_ARGS_ADD(args, MPS_KEY_GEN, 0); MPS_ARGS_ADD(args, MPS_KEY_FORMAT, dylanfmt); die(mps_pool_create_k(&leafpool, arena, mps_class_lo(), args), "Leaf Pool Create\n"); diff --git a/mps/code/awluthe.c b/mps/code/awluthe.c index d3b2d572319..6ea468977f1 100644 --- a/mps/code/awluthe.c +++ b/mps/code/awluthe.c @@ -277,9 +277,6 @@ static void *setup(void *v, size_t s) 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. */ - MPS_ARGS_ADD(args, MPS_KEY_GEN, 0); MPS_ARGS_ADD(args, MPS_KEY_FORMAT, dylanfmt); die(mps_pool_create_k(&leafpool, arena, mps_class_lo(), args), "Leaf Pool Create\n"); diff --git a/mps/code/chain.h b/mps/code/chain.h index e47f8000c0b..ec5bc228ebf 100644 --- a/mps/code/chain.h +++ b/mps/code/chain.h @@ -81,7 +81,6 @@ extern Bool ChainCheck(Chain chain); extern double ChainDeferral(Chain chain); extern Res ChainCondemnAuto(double *mortalityReturn, Chain chain, Trace trace); -extern Res ChainCondemnAll(Chain chain, Trace trace); extern void ChainStartGC(Chain chain, Trace trace); extern void ChainEndGC(Chain chain, Trace trace); extern size_t ChainGens(Chain chain); diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index 88895027286..a9580bfcbdf 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -6,6 +6,20 @@ * * DESIGN * + * .mode: This test has two modes. + * + * .mode.park: In this mode, we use the arena's default generation + * chain, leave the arena parked and call mps_arena_collect. This + * tests that the default generation chain works and that all segments + * get condemned via TraceStartCollectAll. (See job003771 item 4.) + * + * .mode.poll: In this mode, we use our own generation chain (with + * small generations), allocate into generation 1, unclamp the arena, + * and provoke collection by allocating. This tests that custom + * generation chains work, and that segments get condemned via + * TracePoll even if there is no allocation into generation 0 of the + * chain. (See job003771 item 5.) + * * DEPENDENCIES * * This test uses the dylan object format, but the reliance on this @@ -16,6 +30,7 @@ * This code was created by first copying */ +#include "mpm.h" #include "testlib.h" #include "mpslib.h" #include "mps.h" @@ -30,10 +45,15 @@ #include /* fflush, printf, stdout */ +enum { + ModePARK, /* .mode.park */ + ModePOLL /* .mode.poll */ +}; + #define testArenaSIZE ((size_t)16<<20) #define rootCOUNT 20 -#define maxtreeDEPTH 10 +#define maxtreeDEPTH 9 #define collectionCOUNT 10 @@ -126,17 +146,21 @@ static mps_addr_t test_awl_find_dependent(mps_addr_t addr) static void *root[rootCOUNT]; -static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap, +static void test_trees(int mode, 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; + int object_alloc; object_count = 0; printf("Making some %s finalized trees of objects.\n", name); + mps_arena_park(arena); + /* make some trees */ for(i = 0; i < rootCOUNT; ++i) { root[i] = (void *)(*make)(maxtreeDEPTH, ap); @@ -151,10 +175,23 @@ static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap, 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"); + switch (mode) { + default: + case ModePARK: + printf("Collecting..."); + (void)fflush(stdout); + die(mps_arena_collect(arena), "collect"); + printf(" Done.\n"); + break; + case ModePOLL: + mps_arena_release(arena); + printf("Allocating..."); + (void)fflush(stdout); + object_alloc = 0; + while (object_alloc < 1000 && !mps_message_poll(arena)) + (void)DYLAN_INT(object_alloc++); + break; + } ++ collections; while (mps_message_poll(arena)) { mps_message_t message; @@ -170,10 +207,14 @@ static void test_trees(const char *name, mps_arena_t arena, mps_ap_t ap, " of %"PRIuLONGEST"\n", (ulongest_t)final_this_time, (ulongest_t)finals, (ulongest_t)object_count); } - cdie(finals == object_count, "Not all objects were finalized."); + if (finals != object_count) + error("Not all objects were finalized for %s in mode %s.", + BufferOfAP(ap)->pool->class->name, + mode == ModePOLL ? "POLL" : "PARK"); } -static void *test(mps_arena_t arena, mps_class_t pool_class) +static void test_pool(int mode, mps_arena_t arena, mps_chain_t chain, + mps_class_t pool_class) { mps_ap_t ap; mps_fmt_t fmt; @@ -182,10 +223,13 @@ static void *test(mps_arena_t arena, mps_class_t pool_class) die(mps_fmt_create_A(&fmt, arena, dylan_fmt_A()), "fmt_create\n"); MPS_ARGS_BEGIN(args) { - /* Allocate into generation 0 so that they get finalized quickly. */ - MPS_ARGS_ADD(args, MPS_KEY_GEN, 0); MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt); - MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent); + if (mode == ModePOLL) { + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); + MPS_ARGS_ADD(args, MPS_KEY_GEN, 1); + } + if (pool_class == mps_class_awl()) + 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); @@ -194,19 +238,25 @@ static void *test(mps_arena_t arena, mps_class_t pool_class) "root_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); - - test_trees("numbered", arena, ap, make_numbered_tree, register_numbered_tree); - test_trees("indirect", arena, ap, make_indirect_tree, register_indirect_tree); + test_trees(mode, "numbered", arena, ap, make_numbered_tree, + register_numbered_tree); + test_trees(mode, "indirect", arena, ap, make_indirect_tree, + register_indirect_tree); mps_ap_destroy(ap); mps_root_destroy(mps_root); mps_pool_destroy(pool); mps_fmt_destroy(fmt); +} - return NULL; + +static void test_mode(int mode, mps_arena_t arena, mps_chain_t chain) +{ + test_pool(mode, arena, chain, mps_class_amc()); + test_pool(mode, arena, chain, mps_class_amcz()); + test_pool(mode, arena, chain, mps_class_ams()); + /* test_pool(mode, arena, chain, mps_class_lo()); TODO: job003772 */ + /* test_pool(mode, arena, chain, mps_class_awl()); TODO: job003772 */ } @@ -214,19 +264,27 @@ int main(int argc, char *argv[]) { mps_arena_t arena; mps_thr_t thread; + mps_chain_t chain; + mps_gen_param_s params[2]; + size_t gens = 2; + size_t i; testlib_init(argc, argv); die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "arena_create\n"); + mps_message_type_enable(arena, mps_message_type_finalization()); die(mps_thread_reg(&thread, arena), "thread_reg\n"); + for (i = 0; i < gens; ++i) { + params[i].mps_capacity = 1; + params[i].mps_mortality = 0.5; + } + die(mps_chain_create(&chain, arena, gens, params), "chain_create\n"); - test(arena, mps_class_amc()); - test(arena, mps_class_amcz()); - test(arena, mps_class_ams()); - test(arena, mps_class_awl()); - /* TODO: test(arena, mps_class_lo()); */ + test_mode(ModePOLL, arena, chain); + test_mode(ModePARK, arena, NULL); + mps_chain_destroy(chain); mps_thread_dereg(thread); mps_arena_destroy(arena); diff --git a/mps/code/locus.c b/mps/code/locus.c index a704c8b820b..e69b276ab93 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -287,13 +287,20 @@ Res ChainAlloc(Seg *segReturn, Chain chain, Serial genNr, SegClass class, double ChainDeferral(Chain chain) { + double time = DBL_MAX; + size_t i; + AVERT(Chain, chain); - if (chain->activeTraces != TraceSetEMPTY) - return DBL_MAX; - else - return chain->gens[0].capacity * 1024.0 - - (double)GenDescNewSize(&chain->gens[0]); + if (chain->activeTraces == TraceSetEMPTY) + for (i = 0; i < chain->genCount; ++i) { + double genTime = chain->gens[i].capacity * 1024.0 + - (double)GenDescNewSize(&chain->gens[i]); + if (genTime < time) + time = genTime; + } + + return time; } @@ -306,7 +313,7 @@ double ChainDeferral(Chain chain) Res ChainCondemnAuto(double *mortalityReturn, Chain chain, Trace trace) { Res res; - Serial topCondemnedGenSerial, currGenSerial; + size_t topCondemnedGen, i; GenDesc gen; ZoneSet condemnedSet = ZoneSetEMPTY; Size condemnedSize = 0, survivorSize = 0, genNewSize, genTotalSize; @@ -314,33 +321,39 @@ Res ChainCondemnAuto(double *mortalityReturn, Chain chain, Trace trace) AVERT(Chain, chain); AVERT(Trace, trace); - /* Find lowest gen within its capacity, set topCondemnedGenSerial to the */ - /* preceeding one. */ - currGenSerial = 0; - gen = &chain->gens[0]; - AVERT(GenDesc, gen); - genNewSize = GenDescNewSize(gen); - do { /* At this point, we've decided to collect currGenSerial. */ - topCondemnedGenSerial = currGenSerial; + /* Find the highest generation that's over capacity. We will condemn + * this and all lower generations in the chain. */ + topCondemnedGen = chain->genCount; + for (;;) { + /* It's an error to call this function unless some generation is + * over capacity as reported by ChainDeferral. */ + AVER(topCondemnedGen > 0); + if (topCondemnedGen == 0) + return ResFAIL; + -- topCondemnedGen; + gen = &chain->gens[topCondemnedGen]; + AVERT(GenDesc, gen); + genNewSize = GenDescNewSize(gen); + if (genNewSize >= gen->capacity * (Size)1024) + break; + } + + /* At this point, we've decided to condemn topCondemnedGen and all + * lower generations. */ + for (i = 0; i <= topCondemnedGen; ++i) { + gen = &chain->gens[i]; + AVERT(GenDesc, gen); condemnedSet = ZoneSetUnion(condemnedSet, gen->zones); genTotalSize = GenDescTotalSize(gen); + genNewSize = GenDescNewSize(gen); condemnedSize += genTotalSize; survivorSize += (Size)(genNewSize * (1.0 - gen->mortality)) /* predict survivors will survive again */ + (genTotalSize - genNewSize); - - /* is there another one to consider? */ - currGenSerial += 1; - if (currGenSerial >= chain->genCount) - break; /* reached the top */ - gen = &chain->gens[currGenSerial]; - AVERT(GenDesc, gen); - genNewSize = GenDescNewSize(gen); - } while (genNewSize >= gen->capacity * (Size)1024); + } AVER(condemnedSet != ZoneSetEMPTY || condemnedSize == 0); - EVENT3(ChainCondemnAuto, chain, topCondemnedGenSerial, chain->genCount); - UNUSED(topCondemnedGenSerial); /* only used for EVENT */ + EVENT3(ChainCondemnAuto, chain, topCondemnedGen, chain->genCount); /* Condemn everything in these zones. */ if (condemnedSet != ZoneSetEMPTY) { @@ -354,41 +367,6 @@ Res ChainCondemnAuto(double *mortalityReturn, Chain chain, Trace trace) } -/* ChainCondemnAll -- condemn everything in the chain */ - -Res ChainCondemnAll(Chain chain, Trace trace) -{ - Ring node, nextNode; - Bool haveWhiteSegs = FALSE; - Res res; - - /* Condemn every segment in every pool using this chain. */ - /* Finds the pools by iterating over the PoolGens in gen 0. */ - RING_FOR(node, &chain->gens[0].locusRing, nextNode) { - PoolGen nursery = RING_ELT(PoolGen, genRing, node); - Pool pool = nursery->pool; - Ring segNode, nextSegNode; - - AVERT(Pool, pool); - AVER(PoolHasAttr(pool, AttrGC)); - RING_FOR(segNode, PoolSegRing(pool), nextSegNode) { - Seg seg = SegOfPoolRing(segNode); - - res = TraceAddWhite(trace, seg); - if (res != ResOK) - goto failBegin; - haveWhiteSegs = TRUE; - } - } - - return ResOK; - -failBegin: - AVER(!haveWhiteSegs); /* Would leave white sets inconsistent. */ - return res; -} - - /* ChainStartGC -- called to notify start of GC for this chain */ void ChainStartGC(Chain chain, Trace trace) @@ -416,9 +394,11 @@ void ChainEndGC(Chain chain, Trace trace) Res PoolGenInit(PoolGen gen, Chain chain, Serial nr, Pool pool) { /* Can't check gen, because it's not been initialized. */ + AVER(gen != NULL); AVERT(Chain, chain); AVER(nr <= chain->genCount); AVERT(Pool, pool); + AVER(PoolHasAttr(pool, AttrGC)); gen->nr = nr; gen->pool = pool; diff --git a/mps/code/trace.c b/mps/code/trace.c index 61e9d396155..5a656e9489d 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1503,21 +1503,31 @@ static Res traceCondemnAll(Trace trace) { Res res; Arena arena; - Ring chainNode, nextChainNode; + Ring poolNode, nextPoolNode, chainNode, nextChainNode; Bool haveWhiteSegs = FALSE; arena = trace->arena; AVERT(Arena, arena); - /* Condemn all the chains. */ - RING_FOR(chainNode, &arena->chainRing, nextChainNode) { - Chain chain = RING_ELT(Chain, chainRing, chainNode); - AVERT(Chain, chain); - res = ChainCondemnAll(chain, trace); - if(res != ResOK) - goto failBegin; - haveWhiteSegs = TRUE; + /* Condemn all segments in pools with the GC attribute. */ + RING_FOR(poolNode, &ArenaGlobals(arena)->poolRing, nextPoolNode) { + Pool pool = RING_ELT(Pool, arenaRing, poolNode); + AVERT(Pool, pool); + + if (PoolHasAttr(pool, AttrGC)) { + Ring segNode, nextSegNode; + RING_FOR(segNode, PoolSegRing(pool), nextSegNode) { + Seg seg = SegOfPoolRing(segNode); + AVERT(Seg, seg); + + res = TraceAddWhite(trace, seg); + if (res != ResOK) + goto failBegin; + haveWhiteSegs = TRUE; + } + } } + /* Notify all the chains. */ RING_FOR(chainNode, &arena->chainRing, nextChainNode) { Chain chain = RING_ELT(Chain, chainRing, chainNode); From 8815555fd9df1ea39e8ed69605df6b11f4c74ba3 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 22 Apr 2014 21:40:59 +0100 Subject: [PATCH 64/75] Separate jobs for lo and awl finalization. Copied from Perforce Change: 185743 ServerID: perforce.ravenbrook.com --- mps/code/finaltest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index a9580bfcbdf..f449d7e1acf 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -255,7 +255,7 @@ static void test_mode(int mode, mps_arena_t arena, mps_chain_t chain) test_pool(mode, arena, chain, mps_class_amc()); test_pool(mode, arena, chain, mps_class_amcz()); test_pool(mode, arena, chain, mps_class_ams()); - /* test_pool(mode, arena, chain, mps_class_lo()); TODO: job003772 */ + /* test_pool(mode, arena, chain, mps_class_lo()); TODO: job003773 */ /* test_pool(mode, arena, chain, mps_class_awl()); TODO: job003772 */ } From 204abf130ec599c069af5613584f91b0e1d873ed Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 22 Apr 2014 21:57:16 +0100 Subject: [PATCH 65/75] Fix indentation. Copied from Perforce Change: 185746 ServerID: perforce.ravenbrook.com --- mps/code/locus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mps/code/locus.c b/mps/code/locus.c index e69b276ab93..6e6e22128b7 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -292,12 +292,13 @@ double ChainDeferral(Chain chain) AVERT(Chain, chain); - if (chain->activeTraces == TraceSetEMPTY) + if (chain->activeTraces == TraceSetEMPTY) { for (i = 0; i < chain->genCount; ++i) { double genTime = chain->gens[i].capacity * 1024.0 - (double)GenDescNewSize(&chain->gens[i]); if (genTime < time) time = genTime; + } } return time; From 4ed2986197d06c80e9c32647d7d79bedaf0af3df Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 22 Apr 2014 23:18:42 +0100 Subject: [PATCH 66/75] Test the arena default chain. set the commit limit to make sure that the collector can make progress. Copied from Perforce Change: 185749 ServerID: perforce.ravenbrook.com --- mps/code/amsss.c | 90 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/mps/code/amsss.c b/mps/code/amsss.c index 1d04f199349..e4e66ae0529 100644 --- a/mps/code/amsss.c +++ b/mps/code/amsss.c @@ -27,7 +27,7 @@ #define totalSizeSTEP 200 * (size_t)1024 /* objNULL needs to be odd so that it's ignored in exactRoots. */ #define objNULL ((mps_addr_t)MPS_WORD_CONST(0xDECEA5ED)) -#define testArenaSIZE ((size_t)16<<20) +#define testArenaSIZE ((size_t)1<<20) #define initTestFREQ 3000 #define splatTestFREQ 6000 static mps_gen_param_s testChain[1] = { { 160, 0.90 } }; @@ -107,7 +107,8 @@ static mps_addr_t make(void) static mps_pool_debug_option_s freecheckOptions = { NULL, 0, (const void *)"Dead", 4 }; -static void *test(void *arg, size_t haveAmbigous) +static void test_pool(mps_class_t pool_class, mps_arg_s args[], + size_t haveAmbiguous) { mps_pool_t pool; mps_root_t exactRoot, ambigRoot = NULL; @@ -116,14 +117,13 @@ static void *test(void *arg, size_t haveAmbigous) mps_ap_t busy_ap; mps_addr_t busy_init; - pool = (mps_pool_t)arg; - + die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); die(mps_ap_create(&busy_ap, pool, mps_rank_exact()), "BufferCreate 2"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; - if (haveAmbigous) + if (haveAmbiguous) for(i = 0; i < ambigRootsCOUNT; ++i) ambigRoots[i] = rnd_addr(); @@ -132,7 +132,7 @@ static void *test(void *arg, size_t haveAmbigous) &exactRoots[0], exactRootsCOUNT, (mps_word_t)1), "root_create_table(exact)"); - if (haveAmbigous) + if (haveAmbiguous) die(mps_root_create_table(&ambigRoot, arena, mps_rank_ambig(), (mps_rm_t)0, &ambigRoots[0], ambigRootsCOUNT), @@ -154,7 +154,7 @@ static void *test(void *arg, size_t haveAmbigous) } r = (size_t)rnd(); - if (!haveAmbigous || (r & 1)) { + if (!haveAmbiguous || (r & 1)) { i = (r >> 1) % exactRootsCOUNT; if (exactRoots[i] != objNULL) cdie(dylan_check(exactRoots[i]), "dying root check"); @@ -187,10 +187,10 @@ static void *test(void *arg, size_t haveAmbigous) mps_ap_destroy(busy_ap); mps_ap_destroy(ap); mps_root_destroy(exactRoot); - if (haveAmbigous) + if (haveAmbiguous) mps_root_destroy(ambigRoot); - return NULL; + mps_pool_destroy(pool); } @@ -199,68 +199,66 @@ int main(int argc, char *argv[]) mps_thr_t thread; mps_fmt_t format; mps_chain_t chain; - mps_pool_t pool; - void *r; testlib_init(argc, argv); die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "arena_create"); + die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "commit_limit_set"); + mps_message_type_enable(arena, mps_message_type_gc_start()); mps_message_type_enable(arena, mps_message_type_gc()); die(mps_thread_reg(&thread, arena), "thread_reg"); die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create"); die(mps_chain_create(&chain, arena, 1, testChain), "chain_create"); - /* TODO: Add tests using the arena default chain. */ + printf("\n\n*** AMS with !CHAIN and SUPPORT_AMBIGUOUS\n"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); + test_pool(mps_class_ams(), args, TRUE); + } MPS_ARGS_END(args); - printf("\n\n****************************** Testing AMS Debug\n"); + printf("\n\n*** AMS with !CHAIN and !SUPPORT_AMBIGUOUS\n"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); + test_pool(mps_class_ams(), args, FALSE); + } MPS_ARGS_END(args); + + printf("\n\n*** AMS with CHAIN and SUPPORT_AMBIGUOUS\n"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); + test_pool(mps_class_ams(), args, TRUE); + } MPS_ARGS_END(args); + + printf("\n\n*** AMS with CHAIN and !SUPPORT_AMBIGUOUS\n"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); + test_pool(mps_class_ams(), args, FALSE); + } MPS_ARGS_END(args); + + printf("\n\n*** AMS Debug with CHAIN and !SUPPORT_AMBIGUOUS\n"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - die(mps_pool_create_k(&pool, arena, mps_class_ams_debug(), args), - "pool_create(ams_debug,share)"); + test_pool(mps_class_ams_debug(), args, FALSE); } MPS_ARGS_END(args); - mps_tramp(&r, test, pool, 0); - mps_pool_destroy(pool); - printf("\n\n****************************** Testing AMS Debug\n"); + printf("\n\n*** AMS Debug with CHAIN and SUPPORT_AMBIGUOUS\n"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - die(mps_pool_create_k(&pool, arena, mps_class_ams_debug(), args), - "pool_create(ams_debug,ambig)"); + test_pool(mps_class_ams_debug(), args, TRUE); } MPS_ARGS_END(args); - mps_tramp(&r, test, pool, 1); - mps_pool_destroy(pool); - - printf("\n\n****************************** Testing AMS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); - MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - die(mps_pool_create_k(&pool, arena, mps_class_ams(), args), - "pool_create(ams,ambig)"); - } MPS_ARGS_END(args); - mps_tramp(&r, test, pool, 1); - mps_pool_destroy(pool); - - printf("\n\n****************************** Testing AMS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); - MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - die(mps_pool_create_k(&pool, arena, mps_class_ams(), args), - "pool_create(ams,share)"); - } MPS_ARGS_END(args); - mps_tramp(&r, test, pool, 0); - mps_pool_destroy(pool); mps_chain_destroy(chain); mps_fmt_destroy(format); From ca7dab39da319f4b0500663717da08fc3cc23374 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 23 Apr 2014 19:42:27 +0100 Subject: [PATCH 67/75] Test all 8 combinations of debug, chain, ambig. Copied from Perforce Change: 185763 ServerID: perforce.ravenbrook.com --- mps/code/amsss.c | 65 ++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/mps/code/amsss.c b/mps/code/amsss.c index e4e66ae0529..8538fd354e2 100644 --- a/mps/code/amsss.c +++ b/mps/code/amsss.c @@ -196,6 +196,7 @@ static void test_pool(mps_class_t pool_class, mps_arg_s args[], int main(int argc, char *argv[]) { + int i; mps_thr_t thread; mps_fmt_t format; mps_chain_t chain; @@ -212,53 +213,23 @@ int main(int argc, char *argv[]) die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create"); die(mps_chain_create(&chain, arena, 1, testChain), "chain_create"); - printf("\n\n*** AMS with !CHAIN and SUPPORT_AMBIGUOUS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); - test_pool(mps_class_ams(), args, TRUE); - } MPS_ARGS_END(args); - - printf("\n\n*** AMS with !CHAIN and !SUPPORT_AMBIGUOUS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); - test_pool(mps_class_ams(), args, FALSE); - } MPS_ARGS_END(args); - - printf("\n\n*** AMS with CHAIN and SUPPORT_AMBIGUOUS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); - test_pool(mps_class_ams(), args, TRUE); - } MPS_ARGS_END(args); - - printf("\n\n*** AMS with CHAIN and !SUPPORT_AMBIGUOUS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); - test_pool(mps_class_ams(), args, FALSE); - } MPS_ARGS_END(args); - - printf("\n\n*** AMS Debug with CHAIN and !SUPPORT_AMBIGUOUS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, FALSE); - MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - test_pool(mps_class_ams_debug(), args, FALSE); - } MPS_ARGS_END(args); - - printf("\n\n*** AMS Debug with CHAIN and SUPPORT_AMBIGUOUS\n"); - MPS_ARGS_BEGIN(args) { - MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); - MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, TRUE); - MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - test_pool(mps_class_ams_debug(), args, TRUE); - } MPS_ARGS_END(args); + for (i = 0; i < 8; i++) { + int debug = i % 2; + int ownChain = (i / 2) % 2; + int ambig = (i / 4) % 2; + printf("\n\n*** AMS%s with %sCHAIN and %sSUPPORT_AMBIGUOUS\n", + debug ? " Debug" : "", + ownChain ? "" : "!", + ambig ? "" : "!"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + if (chain) + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); + MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, ambig); + MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); + test_pool(debug ? mps_class_ams_debug() : mps_class_ams(), args, TRUE); + } MPS_ARGS_END(args); + } mps_chain_destroy(chain); mps_fmt_destroy(format); From b674ece7495d9427be486688ba4da0aead7eee8f Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 23 Apr 2014 20:22:19 +0100 Subject: [PATCH 68/75] Tracecondemnzones could leave the white set inconsistent if traceaddwhite failed. add an assertion to cover this case (corresponding to the similar assertion in tracecondemnall). Copied from Perforce Change: 185765 ServerID: perforce.ravenbrook.com --- mps/code/trace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mps/code/trace.c b/mps/code/trace.c index 5a656e9489d..76769583748 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -390,6 +390,7 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet) Seg seg; Arena arena; Res res; + Bool haveWhiteSegs = FALSE; AVERT(Trace, trace); AVER(condemnedSet != ZoneSetEMPTY); @@ -414,8 +415,11 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet) && ZoneSetSuper(condemnedSet, ZoneSetOfSeg(arena, seg))) { res = TraceAddWhite(trace, seg); - if(res != ResOK) + if(res != ResOK) { + AVER(!haveWhiteSegs); /* Would leave white sets inconsistent. */ return res; + } + haveWhiteSegs = TRUE; } } while (SegNext(&seg, arena, seg)); } From b888d047ba835412fc23bf7b0bd705757ecdde63 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Fri, 25 Apr 2014 17:41:56 +0100 Subject: [PATCH 69/75] Explain traceaddwhite failure logic as requested by nb in . Copied from Perforce Change: 185800 ServerID: perforce.ravenbrook.com --- mps/code/trace.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/mps/code/trace.c b/mps/code/trace.c index 76769583748..f94d245fbf7 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -415,10 +415,8 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet) && ZoneSetSuper(condemnedSet, ZoneSetOfSeg(arena, seg))) { res = TraceAddWhite(trace, seg); - if(res != ResOK) { - AVER(!haveWhiteSegs); /* Would leave white sets inconsistent. */ - return res; - } + if(res != ResOK) + goto failBegin; haveWhiteSegs = TRUE; } } while (SegNext(&seg, arena, seg)); @@ -430,6 +428,10 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet) AVER(ZoneSetSuper(condemnedSet, trace->white)); return ResOK; + +failBegin: + AVER(!haveWhiteSegs); /* See .whiten.fail. */ + return res; } @@ -1541,7 +1543,14 @@ static Res traceCondemnAll(Trace trace) return ResOK; failBegin: - AVER(!haveWhiteSegs); /* Would leave white sets inconsistent. */ + /* .whiten.fail: If we successfully whitened one or more segments, + * but failed to whiten them all, then the white sets would now be + * inconsistent. This can't happen in practice (at time of writing) + * because all PoolWhiten methods always succeed. If we ever have a + * pool class that fails to whiten a segment, then this assertion + * will be triggered. In that case, we'll have to recover here by + * blackening the segments again. */ + AVER(!haveWhiteSegs); return res; } From 0582cdfc38f2b9f4e7a342e50e9b89f25173b211 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 26 Apr 2014 11:12:45 +0100 Subject: [PATCH 70/75] Fix amsss. Copied from Perforce Change: 185813 ServerID: perforce.ravenbrook.com --- mps/code/amsss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mps/code/amsss.c b/mps/code/amsss.c index 8538fd354e2..9128561ecf2 100644 --- a/mps/code/amsss.c +++ b/mps/code/amsss.c @@ -108,7 +108,7 @@ static mps_pool_debug_option_s freecheckOptions = { NULL, 0, (const void *)"Dead", 4 }; static void test_pool(mps_class_t pool_class, mps_arg_s args[], - size_t haveAmbiguous) + mps_bool_t haveAmbiguous) { mps_pool_t pool; mps_root_t exactRoot, ambigRoot = NULL; @@ -223,11 +223,11 @@ int main(int argc, char *argv[]) ambig ? "" : "!"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); - if (chain) + if (ownChain) MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, ambig); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &freecheckOptions); - test_pool(debug ? mps_class_ams_debug() : mps_class_ams(), args, TRUE); + test_pool(debug ? mps_class_ams_debug() : mps_class_ams(), args, ambig); } MPS_ARGS_END(args); } From 70c0cb9a94240a12b3714daa15f579a90f9fb752 Mon Sep 17 00:00:00 2001 From: David Lovemore Date: Mon, 28 Apr 2014 13:14:04 +0100 Subject: [PATCH 71/75] Rename bool(v) to boolof(v) to fix clash with the windows header file windows.h Copied from Perforce Change: 185841 ServerID: perforce.ravenbrook.com --- mps/code/buffer.c | 6 +++--- mps/code/global.c | 2 +- mps/code/misc.h | 2 +- mps/code/poolmfs.c | 2 +- mps/code/poolmvff.c | 2 +- mps/code/seg.c | 2 +- mps/code/trace.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mps/code/buffer.c b/mps/code/buffer.c index 27314924600..bbae1f3eacd 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -1075,7 +1075,7 @@ static Res bufferTrivInit(Buffer buffer, Pool pool, ArgList args) AVERT(Buffer, buffer); AVERT(Pool, pool); UNUSED(args); - EVENT3(BufferInit, buffer, pool, BOOL(buffer->isMutator)); + EVENT3(BufferInit, buffer, pool, BOOLOF(buffer->isMutator)); return ResOK; } @@ -1288,7 +1288,7 @@ static Res segBufInit(Buffer buffer, Pool pool, ArgList args) segbuf->rankSet = RankSetEMPTY; AVERT(SegBuf, segbuf); - EVENT3(BufferInitSeg, buffer, pool, BOOL(buffer->isMutator)); + EVENT3(BufferInitSeg, buffer, pool, BOOLOF(buffer->isMutator)); return ResOK; } @@ -1515,7 +1515,7 @@ static Res rankBufInit(Buffer buffer, Pool pool, ArgList args) BufferSetRankSet(buffer, RankSetSingle(rank)); /* There's nothing to check that the superclass doesn't, so no AVERT. */ - EVENT4(BufferInitRank, buffer, pool, BOOL(buffer->isMutator), rank); + EVENT4(BufferInitRank, buffer, pool, BOOLOF(buffer->isMutator), rank); return ResOK; } diff --git a/mps/code/global.c b/mps/code/global.c index 5f635206bd9..ce4ebbe6faa 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -1140,7 +1140,7 @@ void ArenaSetEmergency(Arena arena, Bool emergency) AVERT(Arena, arena); AVERT(Bool, emergency); - EVENT2(ArenaSetEmergency, arena, BOOL(emergency)); + EVENT2(ArenaSetEmergency, arena, BOOLOF(emergency)); arena->emergency = emergency; } diff --git a/mps/code/misc.h b/mps/code/misc.h index 809fd7e954a..fed416157dd 100644 --- a/mps/code/misc.h +++ b/mps/code/misc.h @@ -178,7 +178,7 @@ typedef const struct SrcIdStruct { */ #define BITFIELD(type, value, width) ((type)value & (((type)1 << (width)) - 1)) -#define BOOL(v) BITFIELD(unsigned, (v), 1) +#define BOOLOF(v) BITFIELD(unsigned, (v), 1) /* Bit Sets -- sets of integers in [0,N-1]. diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 214b2b232d3..139b3f5c872 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -136,7 +136,7 @@ static Res MFSInit(Pool pool, ArgList args) mfs->sig = MFSSig; AVERT(MFS, mfs); - EVENT5(PoolInitMFS, pool, arena, extendBy, BOOL(extendSelf), unitSize); + EVENT5(PoolInitMFS, pool, arena, extendBy, BOOLOF(extendSelf), unitSize); return ResOK; } diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index fc4307d50a2..4971550c76a 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -610,7 +610,7 @@ static Res MVFFInit(Pool pool, ArgList args) mvff->sig = MVFFSig; AVERT(MVFF, mvff); EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align, - BOOL(slotHigh), BOOL(arenaHigh), BOOL(firstFit)); + BOOLOF(slotHigh), BOOLOF(arenaHigh), BOOLOF(firstFit)); return ResOK; failInit: diff --git a/mps/code/seg.c b/mps/code/seg.c index 31dd0759ff9..7f0cd4bc907 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -593,7 +593,7 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi, if (ResOK != res) goto failMerge; - EVENT3(SegMerge, segLo, segHi, BOOL(withReservoirPermit)); + EVENT3(SegMerge, segLo, segHi, BOOLOF(withReservoirPermit)); /* Deallocate segHi object */ ControlFree(arena, segHi, class->size); AVERT(Seg, segLo); diff --git a/mps/code/trace.c b/mps/code/trace.c index f94d245fbf7..bd2b871fb11 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -1593,7 +1593,7 @@ static void TraceStartPoolGen(Chain chain, GenDesc desc, Bool top, Index i) Ring n, nn; RING_FOR(n, &desc->locusRing, nn) { PoolGen gen = RING_ELT(PoolGen, genRing, n); - EVENT11(TraceStartPoolGen, chain, BOOL(top), i, desc, + EVENT11(TraceStartPoolGen, chain, BOOLOF(top), i, desc, desc->capacity, desc->mortality, desc->zones, gen->pool, gen->nr, gen->totalSize, gen->newSizeAtCreate); From cc0a22847ddcdcc9e86e1224d5b213d9e5fa7dff Mon Sep 17 00:00:00 2001 From: David Lovemore Date: Mon, 28 Apr 2014 15:30:37 +0100 Subject: [PATCH 72/75] Allow branching from custom/*/main. Copied from Perforce Change: 185845 ServerID: perforce.ravenbrook.com --- mps/tool/branch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/tool/branch b/mps/tool/branch index 790dceb0eba..db54da83ce1 100755 --- a/mps/tool/branch +++ b/mps/tool/branch @@ -154,7 +154,7 @@ def main(argv): m = re.match(CHILD_RE, args.child) if not m: raise Error(fmt("Invalid child: {child}")) - if args.customer != m.group(3): + if not args.task and args.customer != m.group(3): raise Error(fmt("Customer mismatch between {parent} and {child}.")) args.date, args.task, _, args.version = m.groups() From e0290cfd38b0685d531acfe61740d1a76eb14183 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 30 Apr 2014 09:48:08 +0100 Subject: [PATCH 73/75] Rename bool to boolof to match change 185841. Copied from Perforce Change: 185868 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 900980970dc..baee04ef3d2 100644 --- a/mps/design/type.txt +++ b/mps/design/type.txt @@ -156,7 +156,7 @@ the type of the bitfield must be ``unsigned:1``, not ``Bool:1``. (That's because the two values of the type ``Bool:1`` are ``0`` and ``-1``, which means that assigning ``TRUE`` would require a sign conversion.) To avoid warnings about loss of data from GCC with the -``-Wconversion`` option, ``misc.h`` provides the ``BOOL`` macro for +``-Wconversion`` option, ``misc.h`` provides the ``BOOLOF`` macro for coercing a value to an unsigned single-bit field. From b6e8dddfccdde40c34206441559ce179fbdba8c6 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 30 Apr 2014 15:07:00 +0100 Subject: [PATCH 74/75] Correct links to task branches. Copied from Perforce Change: 185895 ServerID: perforce.ravenbrook.com --- mps/tool/branch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mps/tool/branch b/mps/tool/branch index db54da83ce1..5a3b4d8652d 100755 --- a/mps/tool/branch +++ b/mps/tool/branch @@ -46,7 +46,7 @@ CHILD_RE = r'(?:{}|{})$'.format(TASK_BRANCH_RE, VERSION_BRANCH_RE) TASK_BRANCH_ENTRY = ''' - {date}/{task} + {date}/{task} Changes {desc_html} Active (diffs). From 3bdf7fc87843d8f0b41b7fda0cf0982c83d9e543 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 30 Apr 2014 16:29:42 +0100 Subject: [PATCH 75/75] All prottramp implementations are now the same, so there is no need for separate implementations. Copied from Perforce Change: 185901 ServerID: perforce.ravenbrook.com --- mps/code/mpm.h | 2 -- mps/code/mpsi.c | 2 +- mps/code/protan.c | 17 ++--------------- mps/code/protix.c | 23 ++--------------------- mps/code/protw3.c | 22 ++-------------------- mps/design/prot.txt | 4 ---- mps/design/protli.txt | 5 ----- mps/design/protsu.txt | 5 ----- 8 files changed, 7 insertions(+), 73 deletions(-) diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 0cbad2b0f1c..499ca555113 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -922,8 +922,6 @@ extern void (ShieldFlush)(Arena arena); extern void ProtSetup(void); extern void ProtSet(Addr base, Addr limit, AccessSet mode); -extern void ProtTramp(void **resultReturn, void *(*f)(void *, size_t), - void *p, size_t s); extern void ProtSync(Arena arena); extern Bool ProtCanStepInstruction(MutatorFaultContext context); extern Res ProtStepInstruction(MutatorFaultContext context); diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c index 3df0913df83..45ffff50166 100644 --- a/mps/code/mpsi.c +++ b/mps/code/mpsi.c @@ -1380,7 +1380,7 @@ void (mps_tramp)(void **r_o, AVER(FUNCHECK(f)); /* Can't check p and s as they are interpreted by the client */ - ProtTramp(r_o, f, p, s); + *r_o = (*f)(p, s); } diff --git a/mps/code/protan.c b/mps/code/protan.c index 51b2edd6df8..3709e88be59 100644 --- a/mps/code/protan.c +++ b/mps/code/protan.c @@ -1,7 +1,7 @@ /* protan.c: ANSI MEMORY PROTECTION * * $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 @@ -65,22 +65,9 @@ void ProtSync(Arena arena) } -/* ProtTramp -- protection trampoline */ - -void ProtTramp(void **rReturn, void *(*f)(void *, size_t), - void *p, size_t s) -{ - AVER(rReturn != NULL); - AVER(FUNCHECK(f)); - /* Can't check p and s as they are interpreted by the client */ - - *(rReturn) = (*(f))(p, s); -} - - /* 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/protix.c b/mps/code/protix.c index 31c272bc5b9..854bfc98174 100644 --- a/mps/code/protix.c +++ b/mps/code/protix.c @@ -1,7 +1,7 @@ /* protix.c: PROTECTION FOR UNIX * * $Id$ - * Copyright (c) 2001,2007 Ravenbrook Limited. See end of file for license. + * Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license. * * Somewhat generic across different Unix systems. Shared between * Darwin (OS X), FreeBSD, and Linux. @@ -114,28 +114,9 @@ void ProtSync(Arena arena) } -/* ProtTramp -- protection trampoline - * - * The protection trampoline is trivial under Unix, as there is - * nothing that needs to be done in the dynamic context of the mutator in - * order to catch faults. (Contrast this with Win32 Structured Exception - * Handling.) - */ - -void ProtTramp(void **resultReturn, void *(*f)(void *, size_t), - void *p, size_t s) -{ - AVER(resultReturn != NULL); - AVER(FUNCHECK(f)); - /* Can't check p and s as they are interpreted by the client */ - - *resultReturn = (*f)(p, s); -} - - /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2007 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/protw3.c b/mps/code/protw3.c index 43e0522c074..84ef680ffb9 100644 --- a/mps/code/protw3.c +++ b/mps/code/protw3.c @@ -1,7 +1,7 @@ /* protw3.c: PROTECTION FOR WIN32 * * $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" @@ -131,27 +131,9 @@ void ProtSync(Arena arena) } -/* ProtTramp -- wrap a mutator thread in a Structured Exception Handler filter - * - * This was the method by which we installed an exception handler on Windows - * prior to MPS 1.111. Now we are using Vectored Exception Handlers, so this - * is deprecated and just calls through to the mutator function. - */ - -void ProtTramp(void **resultReturn, void *(*f)(void *, size_t), - void *p, size_t s) -{ - AVER(resultReturn != NULL); - AVER(FUNCHECK(f)); - /* Can't check p and s as they are interpreted by the client */ - - *resultReturn = f(p, s); -} - - /* 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/prot.txt b/mps/design/prot.txt index a56e53db096..0d30017fede 100644 --- a/mps/design/prot.txt +++ b/mps/design/prot.txt @@ -47,10 +47,6 @@ forbidden. A request to forbid read accesses (that is, ``AccessREAD`` is set) may also forbid write accesses, but read accesses will not be forbidden unless ``AccessREAD`` is set. -``void ProtTramp(void **resultReturn, void *(*f)(void *, size_t), void *p, size_t s)`` - -_`.if.tramp`: [undocumented] - ``void ProtSync(Space space)`` _`.if.sync`: ``ProtSync()`` is called to ensure that the actual diff --git a/mps/design/protli.txt b/mps/design/protli.txt index a5cc1d57a15..9b0958ac191 100644 --- a/mps/design/protli.txt +++ b/mps/design/protli.txt @@ -88,11 +88,6 @@ underlying object). _`.fun.sync`: ``ProtSync()`` does nothing in this implementation as ``ProtSet()`` sets the protection without any delay. -_`.fun.tramp`: The protection trampoline, ``ProtTramp()``, is trivial -under Linux, as there is nothing that needs to be done in the dynamic -context of the mutator in order to catch faults. (Contrast this with -Win32 Structured Exception Handling.) - Threads ------- diff --git a/mps/design/protsu.txt b/mps/design/protsu.txt index 616d9134c88..1bd57e1004a 100644 --- a/mps/design/protsu.txt +++ b/mps/design/protsu.txt @@ -110,11 +110,6 @@ access that is compatible with the access of the underlying object). _`.fun.sync`: ``ProtSync()``. This does nothing in this implementation as ProtSet sets the protection without any delay. -_`.fun.tramp`: ``ProtTramp()``. The protection trampoline is trivial -under SunOS, as there is nothing that needs to be done in the dynamic -context of the mutator in order to catch faults. (Contrast this with -Win32 Structured Exception Handling.) - Document History ----------------