diff --git a/mps/code/arenacl.c b/mps/code/arenacl.c index 5b233e7d936..6fbf91e8a73 100644 --- a/mps/code/arenacl.c +++ b/mps/code/arenacl.c @@ -100,7 +100,7 @@ static Res clientChunkCreate(Chunk *chunkReturn, Addr base, Addr limit, AVER(chunkReturn != NULL); AVER(base != (Addr)0); - /* @@@@ Should refuse on small chunks, instead of AVERring. */ + /* TODO: Should refuse on small chunks, instead of AVERring. */ AVER(limit != (Addr)0); AVER(limit > base); @@ -113,7 +113,7 @@ static Res clientChunkCreate(Chunk *chunkReturn, Addr base, Addr limit, goto failBootInit; /* Allocate the chunk. */ - /* See .@@@@ */ + /* TODO: Add reference to design. */ res = BootAlloc(&p, boot, sizeof(ClientChunkStruct), MPS_PF_ALIGN); if (res != ResOK) goto failChunkAlloc; @@ -154,7 +154,9 @@ static Res ClientChunkInit(Chunk chunk, BootBlock boot) AVERT(BootBlock, boot); UNUSED(boot); - clChunk->freePages = chunk->pages; /* too large @@@@ */ + /* TODO: An old comment claimed this is too large. + Does it fail to exclude the page table or something? */ + clChunk->freePages = chunk->pages; /* Put the page table as late as possible, as in VM systems we don't want */ /* to map it. */ diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 048c38db025..fa66c89f042 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -31,8 +31,10 @@ SRCID(arenavm, "$Id$"); -/* @@@@ Arbitrary calculation for the maximum number of distinct */ -/* object sets for generations. Should be in config.h. */ +/* Arbitrary calculation for the maximum number of distinct */ +/* object sets for generations. */ +/* TODO: Should be in config.h. */ +/* TODO: The arena shouldn't be managing generations */ /* .gencount.const: Must be a constant suitable for use as an */ /* array size. */ #define VMArenaGenCount ((Count)(MPS_WORD_WIDTH/2)) @@ -401,7 +403,7 @@ static Res VMChunkInit(Chunk chunk, BootBlock boot) goto failAllocPageTable; chunk->pageTable = p; - /* Actually commit all the tables. .@@@@ */ + /* Map memory for the bit tables. */ if (vmChunk->overheadMappedLimit < overheadLimit) { overheadLimit = AddrAlignUp(overheadLimit, ChunkPageSize(chunk)); res = vmArenaMap(VMChunkVMArena(vmChunk), vmChunk->vm, @@ -899,7 +901,7 @@ static Bool pagesFindFreeWithSegPref(Index *baseReturn, VMChunk *chunkReturn, preferred = pref->zones; } - /* @@@@ Some of these tests might be duplicates. If we're about */ + /* Some of these tests might be duplicates. If we're about */ /* to run out of virtual address space, then slow allocation is */ /* probably the least of our worries. */ diff --git a/mps/code/buffer.c b/mps/code/buffer.c index e7946dda64f..c63310980ee 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -778,7 +778,8 @@ Bool BufferCommit(Buffer buffer, Addr p, Size size) /* .commit.after: If a flip occurs at this point, the pool will */ /* see "initAtFlip" above the object, which is valid, so it will */ /* be collected. The commit must succeed when trip is called. */ - /* The pointer "p" will have been fixed up. (@@@@ Will it?) */ + /* The pointer "p" will have been fixed up. */ + /* TODO: Check the above assertion and explain why it is so. */ /* .commit.trip: Trip the buffer if a flip has occurred. */ if (buffer->ap_s.limit == 0) return BufferTrip(buffer, p, size); @@ -887,7 +888,7 @@ void BufferFlip(Buffer buffer) && !BufferIsReset(buffer)) { AVER(buffer->initAtFlip == (Addr)0); buffer->initAtFlip = buffer->ap_s.init; - /* Memory Barrier here? @@@@ */ + /* TODO: Is a memory barrier required here? */ buffer->ap_s.limit = (Addr)0; buffer->mode |= BufferModeFLIPPED; } diff --git a/mps/code/fmtdytst.c b/mps/code/fmtdytst.c index 83ab1f4b81a..790840f5491 100644 --- a/mps/code/fmtdytst.c +++ b/mps/code/fmtdytst.c @@ -43,7 +43,7 @@ static mps_word_t dylan_make_WV(mps_word_t version, mps_word_t vb, vf); } -static mps_res_t dylan_make_wrapper_wrapper(void) +mps_res_t dylan_make_wrappers(void) { if(ww == NULL) { ww = malloc(sizeof(mps_word_t) * (BASIC_WRAPPER_SIZE + 1)); @@ -74,7 +74,6 @@ static mps_res_t dylan_make_wrapper_wrapper(void) return MPS_RES_OK; } - /* dylan_init -- turn raw memory into initialised dylan-vector (or pad) * * If the raw memory is large enough, initialises it to a dylan-vector, @@ -92,7 +91,7 @@ mps_res_t dylan_init(mps_addr_t addr, size_t size, /* Make sure the size is aligned. */ assert((size & (ALIGN-1)) == 0); - res = dylan_make_wrapper_wrapper(); + res = dylan_make_wrappers(); if (res != MPS_RES_OK) return res; @@ -127,7 +126,7 @@ mps_res_t make_dylan_vector(mps_word_t *v, mps_ap_t ap, size_t slots) size_t size; size_t i; - res = dylan_make_wrapper_wrapper(); + res = dylan_make_wrappers(); if (res != MPS_RES_OK) return res; diff --git a/mps/code/fmtdytst.h b/mps/code/fmtdytst.h index 14f8993383d..5b8e5405143 100644 --- a/mps/code/fmtdytst.h +++ b/mps/code/fmtdytst.h @@ -19,6 +19,7 @@ extern mps_addr_t dylan_read(mps_addr_t addr); extern mps_bool_t dylan_check(mps_addr_t addr); extern void dylan_pad(mps_addr_t addr, size_t size); extern int dylan_wrapper_check(mps_word_t *w); +extern mps_res_t dylan_make_wrappers(void); extern mps_res_t make_dylan_vector(mps_word_t *v, mps_ap_t ap, size_t slots); diff --git a/mps/code/gcbench.c b/mps/code/gcbench.c new file mode 100644 index 00000000000..77886851d41 --- /dev/null +++ b/mps/code/gcbench.c @@ -0,0 +1,467 @@ +/* gcbench.c -- "GC" Benchmark on ANSI C library + * + * $Id$ + * Copyright 2014 Ravenbrook Limited. See end of file for license. + * + * This is an allocation stress benchmark test for gc pools + */ + +#include "mps.c" + +#include +#include +#include +#include +#include +#include +#include "getopt.h" +#include "testlib.h" + +#include "fmtdy.h" +#include "fmtdytst.h" + +#define RESMUST(expr) \ + do { \ + mps_res_t res = (expr); \ + if (res != MPS_RES_OK) { \ + fprintf(stderr, #expr " returned %d\n", res); \ + exit(EXIT_FAILURE); \ + } \ + } while(0) + +static mps_arena_t arena; +static mps_pool_t pool; +static mps_fmt_t format; +static mps_chain_t chain; +static mps_gen_param_s genDefault[] = { + { 5 * 1024 * 1024, 0.85 }, + { 50 * 1024 * 1024, 0.45 } }; + +/* objNULL needs to be odd so that it's ignored in exactRoots. */ +#define objNULL ((obj_t)MPS_WORD_CONST(0xDECEA5ED)) +#define genLIMIT 100 + +static rnd_state_t seed = 0; /* random number seed */ +static unsigned nthreads = 1; /* threads */ +static unsigned niter = 5; /* iterations */ +static unsigned npass = 10; /* passes over tree */ +static size_t width = 2; /* width of tree nodes */ +static unsigned depth = 20; /* depth of tree */ +static double preuse = 0.2; /* probability of reuse */ +static double pupdate = 0.1; /* probability of update */ +static unsigned ngen = 0; /* number of generations specified */ +static mps_gen_param_s gen[genLIMIT]; /* generation parameters */ +static size_t arenasize = 256ul * 1024 * 1024; /* arena size */ + +typedef struct gcthread_s *gcthread_t; + +typedef void *(*gcthread_fn_t)(gcthread_t thread); + +struct gcthread_s { + pthread_t pthread; + mps_thr_t mps_thread; + mps_root_t reg_root; + mps_ap_t ap; + gcthread_fn_t fn; +}; + +typedef mps_word_t obj_t; + +static obj_t mkvector(mps_ap_t ap, size_t n) { + mps_word_t v; + RESMUST(make_dylan_vector(&v, ap, n)); + return v; +} + +static obj_t aref(obj_t v, size_t i) { + return DYLAN_VECTOR_SLOT(v, i); +} + +static void aset(obj_t v, size_t i, obj_t val) { + DYLAN_VECTOR_SLOT(v, i) = val; +} + +/* mktree - make a tree of nodes with depth d. */ +static obj_t mktree(mps_ap_t ap, unsigned d) { + obj_t tree; + size_t i; + if (d <= 0) return objNULL; + tree = mkvector(ap, width); + for (i = 0; i < width; ++i) { + aset(tree, i, mktree(ap, d - 1)); + } + return tree; +} + +static obj_t random_subtree(obj_t tree, unsigned levels) { + while(tree != objNULL && levels > 0) { + tree = aref(tree, rnd() % width); + --levels; + } + return tree; +} + +/* new_tree - Make a new tree from an old tree. + * The new tree is the same depth as the old tree and + * reuses old nodes with probability preuse. + * NOTE: If a new node is reused multiple times, the total size + * will be smaller. + * NOTE: Changing preuse will dramatically change how much work + * is done. In particular, if preuse==1, the old tree is returned + * unchanged. */ +static obj_t new_tree(mps_ap_t ap, obj_t oldtree, unsigned d) { + obj_t subtree; + size_t i; + if (rnd_double() < preuse) { + subtree = random_subtree(oldtree, depth - d); + } else { + if (d == 0) + return objNULL; + subtree = mkvector(ap, width); + for (i = 0; i < width; ++i) { + aset(subtree, i, new_tree(ap, oldtree, d - 1)); + } + } + return subtree; +} + +/* Update tree to be identical tree but with nodes reallocated + * with probability pupdate. This avoids writing to vector slots + * if unecessary. */ +static obj_t update_tree(mps_ap_t ap, obj_t oldtree, unsigned d) { + obj_t tree; + size_t i; + if (oldtree == objNULL || d == 0) + return oldtree; + if (rnd_double() < pupdate) { + tree = mkvector(ap, width); + for (i = 0; i < width; ++i) { + aset(tree, i, update_tree(ap, aref(oldtree, i), d - 1)); + } + } else { + tree = oldtree; + for (i = 0; i < width; ++i) { + obj_t oldsubtree = aref(oldtree, i); + obj_t subtree = update_tree(ap, oldsubtree, d - 1); + if (subtree != oldsubtree) { + aset(tree, i, subtree); + } + } + } + return tree; +} + +static void *gc_tree(gcthread_t thread) { + unsigned i, j; + mps_ap_t ap = thread->ap; + for (i = 0; i < niter; ++i) { + obj_t tree = mktree(ap, depth); + for (j = 0 ; j < npass; ++j) { + if (preuse < 1.0) + tree = new_tree(ap, tree, depth); + if (pupdate > 0.0) + tree = update_tree(ap, tree, depth); + } + } + return NULL; +} + +/* start -- start routine for each thread */ +static void *start(void *p) { + gcthread_t thread = p; + void *marker; + RESMUST(mps_thread_reg(&thread->mps_thread, arena)); + RESMUST(mps_root_create_reg(&thread->reg_root, arena, + mps_rank_ambig(), (mps_rm_t)0, + thread->mps_thread, &mps_stack_scan_ambig, + &marker, (size_t)0)); + RESMUST(mps_ap_create_k(&thread->ap, pool, mps_args_none)); + thread->fn(thread); + mps_ap_destroy(thread->ap); + mps_root_destroy(thread->reg_root); + mps_thread_dereg(thread->mps_thread); + return NULL; +} + +static void weave(gcthread_fn_t fn) +{ + gcthread_t threads = alloca(sizeof(threads[0]) * nthreads); + unsigned t; + + for (t = 0; t < nthreads; ++t) { + gcthread_t thread = &threads[t]; + int err; + thread->fn = fn; + err = pthread_create(&thread->pthread, NULL, start, thread); + if (err != 0) { + fprintf(stderr, "Unable to create thread: %d\n", err); + exit(EXIT_FAILURE); + } + } + + for (t = 0; t < nthreads; ++t) { + gcthread_t thread = &threads[t]; + int err = pthread_join(thread->pthread, NULL); + if (err != 0) { + fprintf(stderr, "Unable to join thread: %d\n", err); + exit(EXIT_FAILURE); + } + } +} + +static void weave1(gcthread_fn_t fn) +{ + gcthread_t thread = alloca(sizeof(thread[0])); + + thread->fn = fn; + start(thread); +} + + +static void watch(gcthread_fn_t fn, const char *name) +{ + clock_t start, finish; + + start = clock(); + if (nthreads == 1) + weave1(fn); + else + weave(fn); + finish = clock(); + + printf("%s: %g\n", name, (double)(finish - start) / CLOCKS_PER_SEC); +} + + +/* Setup MPS arena and call benchmark. */ + +static void arena_setup(gcthread_fn_t fn, + mps_class_t pool_class, + const char *name) +{ + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, arenasize); + MPS_ARGS_DONE(args); + RESMUST(mps_arena_create_k(&arena, mps_arena_class_vm(), args)); + } MPS_ARGS_END(args); + RESMUST(dylan_fmt(&format, arena)); + /* Make wrappers now to avoid race condition. */ + /* dylan_make_wrappers() uses malloc. */ + RESMUST(dylan_make_wrappers()); + RESMUST(mps_chain_create(&chain, arena, ngen, gen)); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); + MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); + MPS_ARGS_DONE(args); + RESMUST(mps_pool_create_k(&pool, arena, pool_class, args)); + } MPS_ARGS_END(args); + watch(fn, name); + mps_pool_destroy(pool); + mps_fmt_destroy(format); + mps_chain_destroy(chain); + mps_arena_destroy(arena); +} + + +/* Command-line options definitions. See getopt_long(3). */ + +static struct option longopts[] = { + {"help", no_argument, NULL, 'h'}, + {"nthreads", required_argument, NULL, 't'}, + {"niter", required_argument, NULL, 'i'}, + {"npass", required_argument, NULL, 'p'}, + {"gen", required_argument, NULL, 'g'}, + {"arena-size",required_argument, NULL, 'm'}, + {"width", required_argument, NULL, 'w'}, + {"depth", required_argument, NULL, 'd'}, + {"preuse", required_argument, NULL, 'r'}, + {"pupdate", required_argument, NULL, 'u'}, + {NULL, 0, NULL, 0} +}; + + +static struct { + const char *name; + gcthread_fn_t fn; + mps_class_t (*pool_class)(void); +} pools[] = { + {"amc", gc_tree, mps_class_amc}, + {"ams", gc_tree, mps_class_ams}, +}; + + +/* Command-line driver */ + +int main(int argc, char *argv[]) { + int ch; + unsigned i; + + seed = rnd_seed(); + + while ((ch = getopt_long(argc, argv, "ht:i:p:g:m:w:d:r:u:x:", longopts, NULL)) != -1) + switch (ch) { + case 't': + nthreads = (unsigned)strtoul(optarg, NULL, 10); + break; + case 'i': + niter = (unsigned)strtoul(optarg, NULL, 10); + break; + case 'p': + npass = (unsigned)strtoul(optarg, NULL, 10); + break; + case 'g': + if (ngen >= genLIMIT) { + fprintf(stderr, "exceeded genLIMIT\n"); + return EXIT_FAILURE; + } + { + char *p; + size_t cap = 0; + double mort = 0.0; + cap = (size_t)strtoul(optarg, &p, 10); + switch(toupper(*p)) { + case 'G': cap *= 1024; + case 'M': cap *= 1024; + case 'K': p++; break; + default: cap = 0; break; + } + if (sscanf(p, ",%lg", &mort) != 1 || cap == 0) { + fprintf(stderr, "Bad gen format '%s'\n" + "Each gen option has format --gen=capacity[KMG],mortality\n" + "where capacity is a size specified in kilobytes, megabytes or gigabytes\n" + "and mortality is a number between 0 and 1\n" + "e.g.: --gen=500K,0.85 --gen=20M,0.45\n", optarg); + return EXIT_FAILURE; + } + gen[ngen].mps_capacity = cap; + gen[ngen].mps_mortality = mort; + ngen++; + } + break; + case 'm': { + char *p; + arenasize = (unsigned)strtoul(optarg, &p, 10); + switch(toupper(*p)) { + case 'G': arenasize *= 1024; + case 'M': arenasize *= 1024; + case 'K': arenasize *= 1024; break; + } + } + break; + case 'w': + width = (size_t)strtoul(optarg, NULL, 10); + break; + case 'd': + depth = (unsigned)strtoul(optarg, NULL, 10); + break; + case 'r': + preuse = strtod(optarg, NULL); + break; + case 'u': + pupdate = strtod(optarg, NULL); + break; + default: + fprintf(stderr, + "Usage: %s [option...] [test...]\n" + "Options:\n" + " -t n, --nthreads=n\n" + " Launch n threads each running the test (default %u).\n" + " -i n, --niter=n\n" + " Iterate each test n times (default %u).\n" + " -p n, --npass=n\n" + " Pass over the tree n times (default %u).\n" + " -g c,m, --gen=c[KMG],m\n" + " Generation with capacity c (in Kb) and mortality m\n" + " Use multiple times for multiple generations.\n" + " -m n, --arena-size=n[KMG]?\n" + " Initial size of arena (default %lu).\n" + " -w n, --width=n\n" + " Width of tree nodes made (default %lu)\n", + argv[0], + nthreads, + niter, + npass, + (unsigned long)arenasize, + (unsigned long)width); + fprintf(stderr, + " -d n, --depth=n\n" + " Depth of tree made (default %u)\n" + " -r p, --preuse=p\n" + " Probability of reusing a node (default %g)\n" + " -u p, --pupdate=p\n" + " Probability of updating a node (default %g)\n" + "Tests:\n" + " amc pool class AMC\n" + " ams pool class AMS\n", + depth, + preuse, + pupdate); + return EXIT_FAILURE; + } + argc -= optind; + argv += optind; + + if (ngen == 0) { + memcpy(gen, genDefault, sizeof(genDefault)); + ngen = sizeof(genDefault) / sizeof(genDefault[0]); + } + + printf("seed: %lu\n", seed); + + while (argc > 0) { + for (i = 0; i < sizeof(pools) / sizeof(pools[0]); ++i) + if (strcmp(argv[0], pools[i].name) == 0) + goto found; + fprintf(stderr, "unknown pool test \"%s\"\n", argv[0]); + return EXIT_FAILURE; + found: + rnd_state_set(seed); + arena_setup(pools[i].fn, pools[i].pool_class(), pools[i].name); + --argc; + ++argv; + } + + return EXIT_SUCCESS; +} + + +/* C. COPYRIGHT AND LICENSE + * + * Copyright (c) 2001-2014 Ravenbrook Limited . + * All rights reserved. This is an open source license. Contact + * Ravenbrook for commercial licensing options. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Redistributions in any form must be accompanied by information on how + * to obtain complete source code for this software and any accompanying + * software that uses this software. The source code must either be + * included in the distribution or be available for no more than the cost + * of distribution plus a nominal fee, and must be freely redistributable + * under reasonable conditions. For an executable file, complete source + * code means the source code for all modules it contains. It does not + * include source code for modules or files that typically accompany the + * major components of the operating system on which the executable file + * runs. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/mps/code/mps.xcodeproj/project.pbxproj b/mps/code/mps.xcodeproj/project.pbxproj index 2b0c12bae70..36fec975cb9 100644 --- a/mps/code/mps.xcodeproj/project.pbxproj +++ b/mps/code/mps.xcodeproj/project.pbxproj @@ -204,7 +204,6 @@ 3124CAFB156BE82000753214 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; 3124CAFC156BE82900753214 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; 3150AE53156ABA2500A6E22A /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; }; - 318DA8CF1892B1210089718C /* djbench.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8CE1892B1210089718C /* djbench.c */; }; 318DA8D21892B13B0089718C /* getoptl.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8D11892B13B0089718C /* getoptl.c */; }; 318DA8D31892B27E0089718C /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; 31A47BA4156C1E130039B1C2 /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; }; @@ -246,6 +245,13 @@ 31EEAC9F156AB73400714D05 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; 31FCAE161769244F008C034C /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; }; 31FCAE19176924D4008C034C /* scheme.c in Sources */ = {isa = PBXBuildFile; fileRef = 31FCAE18176924D4008C034C /* scheme.c */; }; + 6313D46918A400B200EB03EF /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; }; + 6313D46A18A400B200EB03EF /* getoptl.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8D11892B13B0089718C /* getoptl.c */; }; + 6313D47318A4028E00EB03EF /* djbench.c in Sources */ = {isa = PBXBuildFile; fileRef = 318DA8CE1892B1210089718C /* djbench.c */; }; + 6313D47418A4029200EB03EF /* gcbench.c in Sources */ = {isa = PBXBuildFile; fileRef = 6313D46618A3FDC900EB03EF /* gcbench.c */; }; + 6313D47518A40C6300EB03EF /* fmtdytst.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC7156BE48D00753214 /* fmtdytst.c */; }; + 6313D47618A40C7B00EB03EF /* fmtdy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC6156BE48D00753214 /* fmtdy.c */; }; + 6313D47718A40D0400EB03EF /* fmtno.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CACC156BE4C200753214 /* fmtno.c */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1121,6 +1127,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 6313D46D18A400B200EB03EF /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -1334,6 +1349,8 @@ 31F6CCAD1739B0CF00C48748 /* mpscsnc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpscsnc.h; sourceTree = ""; }; 31FCAE0A17692403008C034C /* scheme */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = scheme; sourceTree = BUILT_PRODUCTS_DIR; }; 31FCAE18176924D4008C034C /* scheme.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scheme.c; path = ../example/scheme/scheme.c; sourceTree = ""; }; + 6313D46618A3FDC900EB03EF /* gcbench.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gcbench.c; sourceTree = ""; }; + 6313D47218A400B200EB03EF /* gcbench */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gcbench; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1654,6 +1671,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 6313D46C18A400B200EB03EF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1744,6 +1768,7 @@ 318DA8D01892B13B0089718C /* getopt.h */, 318DA8D11892B13B0089718C /* getoptl.c */, 318DA8CE1892B1210089718C /* djbench.c */, + 6313D46618A3FDC900EB03EF /* gcbench.c */, ); name = Benchmarks; sourceTree = ""; @@ -1816,6 +1841,7 @@ 224CC799175E1821002FF81B /* fotest */, 31FCAE0A17692403008C034C /* scheme */, 318DA8CD1892B0F30089718C /* djbench */, + 6313D47218A400B200EB03EF /* gcbench */, ); name = Products; sourceTree = ""; @@ -2705,6 +2731,23 @@ productReference = 31FCAE0A17692403008C034C /* scheme */; productType = "com.apple.product-type.tool"; }; + 6313D46718A400B200EB03EF /* gcbench */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6313D46E18A400B200EB03EF /* Build configuration list for PBXNativeTarget "gcbench" */; + buildPhases = ( + 6313D46818A400B200EB03EF /* Sources */, + 6313D46C18A400B200EB03EF /* Frameworks */, + 6313D46D18A400B200EB03EF /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = gcbench; + productName = scheme; + productReference = 6313D47218A400B200EB03EF /* gcbench */; + productType = "com.apple.product-type.tool"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -2767,6 +2810,7 @@ 22CDE8EF16E9E97D00366D0A /* testrun */, 31FCAE0917692403008C034C /* scheme */, 318DA8C31892B0F30089718C /* djbench */, + 6313D46718A400B200EB03EF /* gcbench */, ); }; /* End PBXProject section */ @@ -3109,8 +3153,8 @@ buildActionMask = 2147483647; files = ( 318DA8D31892B27E0089718C /* testlib.c in Sources */, + 6313D47318A4028E00EB03EF /* djbench.c in Sources */, 318DA8D21892B13B0089718C /* getoptl.c in Sources */, - 318DA8CF1892B1210089718C /* djbench.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3208,6 +3252,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 6313D46818A400B200EB03EF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6313D47718A40D0400EB03EF /* fmtno.c in Sources */, + 6313D46918A400B200EB03EF /* testlib.c in Sources */, + 6313D47418A4029200EB03EF /* gcbench.c in Sources */, + 6313D47518A40C6300EB03EF /* fmtdytst.c in Sources */, + 6313D47618A40C7B00EB03EF /* fmtdy.c in Sources */, + 6313D46A18A400B200EB03EF /* getoptl.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -4874,6 +4931,30 @@ }; name = Release; }; + 6313D46F18A400B200EB03EF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + PRODUCT_NAME = gcbench; + }; + name = Debug; + }; + 6313D47018A400B200EB03EF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + PRODUCT_NAME = gcbench; + }; + name = Release; + }; + 6313D47118A400B200EB03EF /* RASH */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + PRODUCT_NAME = gcbench; + }; + name = RASH; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -5307,6 +5388,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 6313D46E18A400B200EB03EF /* Build configuration list for PBXNativeTarget "gcbench" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6313D46F18A400B200EB03EF /* Debug */, + 6313D47018A400B200EB03EF /* Release */, + 6313D47118A400B200EB03EF /* RASH */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 31EEABDA156AAE9E00714D05 /* Project object */; diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index 53237d5861f..315215473be 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -832,8 +832,8 @@ static Res MVTInsert(MVT mvt, Addr base, Addr limit) if (RangeSize(&newRange) >= mvt->reuseSize) { /* The new range is big enough that it might have been coalesced - * with ranges on the ABQ, so ensure that they are removed before - * reserving the new range. + * with ranges on the ABQ, so ensure that the corresponding ranges + * are coalesced on the ABQ. */ ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, 0); MVTReserve(mvt, &newRange); diff --git a/mps/code/trace.c b/mps/code/trace.c index 0e7b964b001..6bc054399eb 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c @@ -399,9 +399,7 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet) arena = trace->arena; if(SegFirst(&seg, arena)) { - Addr base; do { - base = SegBase(seg); /* Segment should be black now. */ AVER(!TraceSetIsMember(SegGrey(seg), trace)); AVER(!TraceSetIsMember(SegWhite(seg), trace)); diff --git a/mps/code/version.c b/mps/code/version.c index 90c32173c38..f2de0e83a8d 100644 --- a/mps/code/version.c +++ b/mps/code/version.c @@ -1,7 +1,7 @@ /* version.c: VERSION INSPECTION * * $Id$ - * Copyright (c) 2001-2013 Ravenbrook Limited. + * Copyright (c) 2001-2014 Ravenbrook Limited. * See end of file for license. * * PURPOSE @@ -29,7 +29,7 @@ SRCID(version, "$Id$"); * (Note: before 2006-02-01 the style was "release.epcore.chub") */ -#define MPS_RELEASE "release/1.112.0" +#define MPS_RELEASE "release/1.113.0" /* MPSCopyrightNotice -- copyright notice for the binary @@ -39,7 +39,7 @@ SRCID(version, "$Id$"); */ char MPSCopyrightNotice[] = - "Portions copyright (c) 2010-2013 Ravenbrook Limited and Global Graphics Software."; + "Portions copyright (c) 2010-2014 Ravenbrook Limited and Global Graphics Software."; /* MPSVersion -- return version string @@ -63,7 +63,7 @@ char *MPSVersion(void) /* C. COPYRIGHT AND LICENSE * - * Copyright (C) 2001-2013 Ravenbrook Limited + * Copyright (C) 2001-2014 Ravenbrook Limited * . * All rights reserved. This is an open source license. Contact * Ravenbrook for commercial licensing options. diff --git a/mps/code/walk.c b/mps/code/walk.c index bab74bc57e7..b17540e4954 100644 --- a/mps/code/walk.c +++ b/mps/code/walk.c @@ -74,10 +74,8 @@ static void ArenaFormattedObjectsWalk(Arena arena, FormattedObjectsStepMethod f, AVERT(FormattedObjectsStepClosure, c); if (SegFirst(&seg, arena)) { - Addr base; do { Pool pool; - base = SegBase(seg); pool = SegPool(seg); if (pool->class->attr & AttrFMT) { ShieldExpose(arena, seg); @@ -308,9 +306,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f, /* ArenaRootsWalk only passes references to GCable pools to the client. */ /* NOTE: I'm not sure why this is. RB 2012-07-24 */ if (SegFirst(&seg, arena)) { - Addr base; do { - base = SegBase(seg); if ((SegPool(seg)->class->attr & AttrGC) != 0) { TraceAddWhite(trace, seg); }