diff --git a/mps/src/amcss.c b/mps/src/amcss.c index c81c080ee08..a93937db7f1 100644 --- a/mps/src/amcss.c +++ b/mps/src/amcss.c @@ -1,7 +1,7 @@ /* impl.c.amcss: POOL CLASS AMC STRESS TEST * - * $HopeName: MMsrc!amcss.c(trunk.26) $ - * Copyright (C) 1998. Harlequin Group plc. All rights reserved. + * $HopeName: MMsrc!amcss.c(trunk.27) $ + * Copyright (C) 1998 Harlequin Group plc. All rights reserved. */ #include "fmtdy.h" @@ -23,9 +23,11 @@ #define testArenaSIZE ((size_t)64<<20) +#define avLEN 4 #define exactRootsCOUNT 50 #define ambigRootsCOUNT 100 -#define collectionsCOUNT 5 +#define collectionsCOUNT 18 +#define rampSIZE 5 #define initTestFREQ 6000 /* objNULL needs to be odd so that it's ignored in exactRoots. */ #define objNULL ((mps_addr_t)0xDECEA5ED) @@ -38,7 +40,8 @@ static mps_addr_t ambigRoots[ambigRootsCOUNT]; static mps_addr_t make(void) { - size_t length = rnd() % 20, size = (length+2)*sizeof(mps_word_t); + size_t length = rnd() % (2*avLEN); + size_t size = (length+2) * sizeof(mps_word_t); mps_addr_t p; mps_res_t res; @@ -54,6 +57,7 @@ static mps_addr_t make(void) return p; } + static void test_stepper(mps_addr_t object, void *p, size_t s) { (*(unsigned long *)p)++; @@ -67,8 +71,10 @@ static void *test(void *arg, size_t s) mps_arena_t arena; mps_fmt_t format; mps_root_t exactRoot, ambigRoot; - unsigned long i; - mps_word_t collections; + unsigned long objs; size_t i; + mps_word_t collections, rampSwitch; + mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); + int ramping; mps_ap_t busy_ap; mps_addr_t busy_init; @@ -102,7 +108,11 @@ static void *test(void *arg, size_t s) die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); collections = 0; - i = 0; + rampSwitch = rampSIZE; + mps_ap_alloc_pattern_begin(ap, ramp); + mps_ap_alloc_pattern_begin(busy_ap, ramp); + ramping = 1; + objs = 0; while(collections < collectionsCOUNT) { unsigned long c; size_t r; @@ -112,7 +122,7 @@ static void *test(void *arg, size_t s) if(collections != c) { collections = c; printf("\nCollection %lu, %lu objects.\n", - c, i); + c, objs); for(r = 0; r < exactRootsCOUNT; ++r) assert(exactRoots[r] == objNULL || dylan_check(exactRoots[r])); @@ -123,30 +133,44 @@ static void *test(void *arg, size_t s) mps_arena_release(arena); printf("mps_amc_apply stepped on %lu objects.\n", object_count); } + if(collections == rampSwitch) { + rampSwitch += rampSIZE; + if(ramping) { + mps_ap_alloc_pattern_end(ap, ramp); + mps_ap_alloc_pattern_end(busy_ap, ramp); + /* Every other time, switch back immediately. */ + if(collections & 1) ramping = 0; + } + if(!ramping) { + mps_ap_alloc_pattern_begin(ap, ramp); + mps_ap_alloc_pattern_begin(busy_ap, ramp); + ramping = 1; + } + } } - if(rnd() & 1) - exactRoots[rnd() % exactRootsCOUNT] = make(); - else - ambigRoots[rnd() % ambigRootsCOUNT] = make(); + r = rnd(); + if(r & 1) { + i = (r >> 1) % exactRootsCOUNT; + if(exactRoots[i] != objNULL) + assert(dylan_check(exactRoots[i])); + exactRoots[i] = make(); + } else { + i = (r >> 1) % ambigRootsCOUNT; + ambigRoots[(ambigRootsCOUNT-1) - i] = make(); + /* Create random interior pointers */ + ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); + } - /* Create random interior pointers */ - r = rnd() % ambigRootsCOUNT; - ambigRoots[r] = (mps_addr_t)((char *)(ambigRoots[r/2]) + 1); - - r = rnd() % exactRootsCOUNT; - if(exactRoots[r] != objNULL) - assert(dylan_check(exactRoots[r])); - - if(rnd() % initTestFREQ == 0) + if(r % initTestFREQ == 0) *(int*)busy_init = -1; /* check that the buffer is still there */ - if(i % 1000 == 0) { + if(objs % 1000 == 0) { putchar('.'); fflush(stdout); } - ++i; + ++objs; } (void)mps_commit(busy_ap, busy_init, 64); @@ -169,11 +193,13 @@ int main(void) die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "arena_create\n"); + adjust_collection_freq(0.0); die(mps_thread_reg(&thread, arena), "thread_reg"); mps_tramp(&r, test, arena, 0); mps_thread_dereg(thread); mps_arena_destroy(arena); + fflush(stdout); /* synchronize */ fprintf(stderr, "\nConclusion: Failed to find any defects.\n"); return 0; } diff --git a/mps/src/buffer.c b/mps/src/buffer.c index 09ac40a50e5..d5c05b49e01 100644 --- a/mps/src/buffer.c +++ b/mps/src/buffer.c @@ -1,7 +1,7 @@ /* impl.c.buffer: ALLOCATION BUFFER IMPLEMENTATION * - * $HopeName: MMsrc!buffer.c(trunk.39) $ - * Copyright (C) 1997,1998. Harlequin Group plc. All rights reserved. + * $HopeName: MMsrc!buffer.c(trunk.40) $ + * Copyright (C) 1997, 1998 Harlequin Group plc. All rights reserved. * * This is (part of) the implementation of allocation buffers. * @@ -25,7 +25,7 @@ #include "mpm.h" -SRCID(buffer, "$HopeName: MMsrc!buffer.c(trunk.39) $"); +SRCID(buffer, "$HopeName: MMsrc!buffer.c(trunk.40) $"); /* BufferCheck -- check consistency of a buffer */ @@ -195,6 +195,7 @@ static Res BufferInitV(Buffer buffer, Pool pool, Bool isMutator, va_list args) buffer->apStruct.alloc = (Addr)0; buffer->apStruct.limit = (Addr)0; buffer->poolLimit = (Addr)0; + buffer->rampCount = 0; buffer->p = NULL; buffer->i = 0; @@ -767,3 +768,62 @@ Addr (BufferLimit)(Buffer buffer) AVERT(Buffer, buffer); return BufferLimit(buffer); } + + +/* BufferRampBegin -- note an entry into a ramp pattern + * + * .ramp.hack: We count the number of times the ap has begun ramp mode + * (and not ended), so we can do reset by ending all the current ramps. + */ + +void BufferRampBegin(Buffer buffer) +{ + Pool pool; + + AVERT(Buffer, buffer); + + AVER(buffer->rampCount < UINT_MAX); + ++buffer->rampCount; + + pool = BufferPool(buffer); + AVERT(Pool, pool); + (*pool->class->rampBegin)(pool, buffer); +} + + +/* BufferRampEnd -- note an exit from a ramp pattern */ + +Res BufferRampEnd(Buffer buffer) +{ + Pool pool; + + AVERT(Buffer, buffer); + + if(buffer->rampCount == 0) + return ResFAIL; + --buffer->rampCount; + + pool = BufferPool(buffer); + AVERT(Pool, pool); + (*pool->class->rampEnd)(pool, buffer); + return ResOK; +} + + +/* BufferRampReset -- exit from ramp mode */ + +void BufferRampReset(Buffer buffer) +{ + Pool pool; + + AVERT(Buffer, buffer); + + if(buffer->rampCount == 0) + return; + + pool = BufferPool(buffer); + AVERT(Pool, pool); + do + (*pool->class->rampEnd)(pool, buffer); + while(--buffer->rampCount > 0); +} diff --git a/mps/src/mpm.h b/mps/src/mpm.h index f1b37d25d6b..55ada518b5d 100644 --- a/mps/src/mpm.h +++ b/mps/src/mpm.h @@ -1,6 +1,6 @@ /* impl.h.mpm: MEMORY POOL MANAGER DEFINITIONS * - * $HopeName: MMsrc!mpm.h(trunk.90) $ + * $HopeName: MMsrc!mpm.h(trunk.91) $ * Copyright (C) 1998. Harlequin Group plc. All rights reserved. */ @@ -337,6 +337,8 @@ extern Res PoolNoFix(Pool pool, ScanState ss, Seg seg, Ref *refIO); extern void PoolNoReclaim(Pool pool, Trace trace, Seg seg); extern double PoolNoBenefit(Pool pool, Action action); extern Res PoolNoAct(Pool pool, Action action); +extern void PoolNoRampBegin(Pool pool, Buffer buf); +extern void PoolNoRampEnd(Pool pool, Buffer buf); extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod, void *, unsigned long); @@ -414,14 +416,22 @@ extern Res TraceFixEmergency(ScanState ss, Ref *refIO); extern Size TraceGreyEstimate(Arena arena, RefSet refSet); /* Collection control parameters */ -/* Defined here, because they are used by more than one module (pool). */ -/* They have the wrong name because they originally came from AMC, and */ -/* binary compatibility is required. */ +/* Defined here, because they are used by more than one module. */ +/* There are two sets of frequencies, for inside and outside ramp */ +/* mode (except for the ramp generation itself). */ +/* They have the wrong names because they originally came from AMC, */ +/* and binary compatibility is required for external clients. */ extern unsigned long AMCGen0Frequency; extern unsigned long AMCGen1Frequency; extern unsigned long AMCGen2Frequency; extern unsigned long AMCGen2plusFrequencyMultiplier; +extern unsigned long AMCRampGenFrequency; +extern unsigned long AMCGen0RampmodeFrequency; +extern unsigned long AMCGen1RampmodeFrequency; +extern unsigned long AMCGen2RampmodeFrequency; +extern unsigned long AMCGen2plusRampmodeFrequencyMultiplier; +extern Serial AMCRampGenFollows; extern Serial AMCGenFinal; extern double TraceGen0IncrementalityMultiple; @@ -685,6 +695,9 @@ extern Addr (BufferAlloc)(Buffer buffer); #define BufferAlloc(buffer) (BufferAP(buffer)->alloc) extern Addr (BufferLimit)(Buffer buffer); #define BufferLimit(buffer) ((buffer)->poolLimit) +extern void BufferRampBegin(Buffer buffer); +extern Res BufferRampEnd(Buffer buffer); +extern void BufferRampReset(Buffer buffer); /* Format Interface -- see impl.c.format */ diff --git a/mps/src/mpmst.h b/mps/src/mpmst.h index 52123aa2adc..e247c809487 100644 --- a/mps/src/mpmst.h +++ b/mps/src/mpmst.h @@ -1,6 +1,6 @@ /* impl.h.mpmst: MEMORY POOL MANAGER DATA STRUCTURES * - * $HopeName: MMsrc!mpmst.h(trunk.59) $ + * $HopeName: MMsrc!mpmst.h(trunk.60) $ * Copyright (C) 1998 Harlequin Group plc. All rights reserved. * * .readership: MM developers. @@ -93,6 +93,8 @@ typedef struct PoolClassStruct { PoolReclaimMethod reclaim; /* reclaim dead objects after tracing */ PoolBenefitMethod benefit; /* calculate benefit of action */ PoolActMethod act; /* do an action */ + PoolRampBeginMethod rampBegin;/* begin a ramp pattern */ + PoolRampEndMethod rampEnd; /* end a ramp pattern */ PoolWalkMethod walk; /* walk over a segment */ PoolDescribeMethod describe; /* describe the contents of the pool */ Sig endSig; /* .class.end-sig */ @@ -307,6 +309,7 @@ typedef struct BufferStruct { APStruct apStruct; /* the allocation point */ Addr poolLimit; /* the pool's idea of the limit */ Align alignment; /* allocation alignment */ + unsigned rampCount; /* see impl.c.buffer.ramp.hack */ void *p; /* closure variable for pool */ int i; /* closure variable for pool */ } BufferStruct; diff --git a/mps/src/mpmtypes.h b/mps/src/mpmtypes.h index 82cc0d289c8..bf118a1770c 100644 --- a/mps/src/mpmtypes.h +++ b/mps/src/mpmtypes.h @@ -1,7 +1,7 @@ /* impl.h.mpmtypes: MEMORY POOL MANAGER TYPES * - * $HopeName: MMsrc!mpmtypes.h(trunk.50) $ - * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. + * $HopeName: MMsrc!mpmtypes.h(trunk.51) $ + * Copyright (C) 1997, 1998 Harlequin Group plc. All rights reserved. * * .readership: MM developers. * .design: design.mps.type @@ -167,6 +167,8 @@ typedef Res (*PoolFixEmergencyMethod)(Pool pool, ScanState ss, typedef void (*PoolReclaimMethod)(Pool pool, Trace trace, Seg seg); typedef double (*PoolBenefitMethod)(Pool pool, Action action); typedef Res (*PoolActMethod)(Pool pool, Action action); +typedef void (*PoolRampBeginMethod)(Pool pool, Buffer buf); +typedef void (*PoolRampEndMethod)(Pool pool, Buffer buf); typedef void (*PoolWalkMethod)(Pool pool, Seg seg, FormattedObjectsStepMethod f, void *p, unsigned long s); diff --git a/mps/src/mpsi.c b/mps/src/mpsi.c index 62f4c9412c1..fd5ed15d995 100644 --- a/mps/src/mpsi.c +++ b/mps/src/mpsi.c @@ -1,6 +1,6 @@ /* impl.c.mpsi: MEMORY POOL SYSTEM C INTERFACE LAYER * - * $HopeName: MMsrc!mpsi.c(trunk.51) $ + * $HopeName: MMsrc!mpsi.c(trunk.52) $ * Copyright (C) 1997. Harlequin Group plc. All rights reserved. * * .purpose: This code bridges between the MPS interface to C, @@ -52,7 +52,7 @@ #include "mps.h" #include "mpsavm.h" /* only for mps_space_create */ -SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.51) $"); +SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.52) $"); /* mpsi_check -- check consistency of interface mappings @@ -723,7 +723,7 @@ mps_res_t mps_ap_fill(mps_addr_t *p_o, mps_ap_t mps_ap, size_t size) Res res; AVER(mps_ap != NULL); - AVER(CHECKT(Buffer, buf)); + AVERT(Buffer, buf); arena = BufferArena(buf); ArenaEnter(arena); @@ -1267,35 +1267,76 @@ void mps_telemetry_label(mps_addr_t addr, mps_word_t intern_id) /* Allocation Patterns */ -/* Dummy interface at the moment, ie no useful implementation. */ +/* .alloc-pattern.null: There's only one kind of alloc_pattern now, */ +/* so we represent it by NULL. Eventually, we'll have a data type */ +/* for allocation patterns. */ mps_alloc_pattern_t mps_alloc_pattern_ramp(void) { return NULL; } + mps_res_t mps_ap_alloc_pattern_begin(mps_ap_t mps_ap, mps_alloc_pattern_t mps_alloc_pattern) { - UNUSED(mps_ap); - UNUSED(mps_alloc_pattern); - + Buffer buf; + Arena arena; + + AVER(mps_ap != NULL); + buf = BufferOfAP((AP)mps_ap); + AVERT(Buffer, buf); + AVER(mps_alloc_pattern == NULL); + + arena = BufferArena(buf); + ArenaEnter(arena); + + BufferRampBegin(buf); + + ArenaLeave(arena); return MPS_RES_OK; } + mps_res_t mps_ap_alloc_pattern_end(mps_ap_t mps_ap, mps_alloc_pattern_t mps_alloc_pattern) { - UNUSED(mps_ap); - UNUSED(mps_alloc_pattern); - - return MPS_RES_OK; + Buffer buf; + Arena arena; + Res res; + + AVER(mps_ap != NULL); + buf = BufferOfAP((AP)mps_ap); + AVERT(Buffer, buf); + AVER(mps_alloc_pattern == NULL); + + arena = BufferArena(buf); + ArenaEnter(arena); + + res = BufferRampEnd(buf); + ArenaPoll(arena); /* .poll */ + + ArenaLeave(arena); + return res; } + mps_res_t mps_ap_alloc_pattern_reset(mps_ap_t mps_ap) { - UNUSED(mps_ap); + Buffer buf; + Arena arena; + AVER(mps_ap != NULL); + buf = BufferOfAP((AP)mps_ap); + AVERT(Buffer, buf); + + arena = BufferArena(buf); + ArenaEnter(arena); + + BufferRampReset(buf); + ArenaPoll(arena); /* .poll */ + + ArenaLeave(arena); return MPS_RES_OK; } diff --git a/mps/src/mpsicv.c b/mps/src/mpsicv.c index ac6a5a5828e..48ab07a028d 100644 --- a/mps/src/mpsicv.c +++ b/mps/src/mpsicv.c @@ -1,17 +1,10 @@ /* impl.c.mpsicv: MPSI COVERAGE TEST * - * $HopeName: MMsrc!mpsicv.c(trunk.14) $ - * Copyright (C) 1996, 1997 Harlequin Group, all rights reserved + * $HopeName: MMsrc!mpsicv.c(trunk.15) $ + * Copyright (C) 1996, 1997, 1998 Harlequin Group plc. All rights reserved. */ -#include -#include -#include -#include -#include -#include #include "testlib.h" -#include "mps.h" #include "mpscamc.h" #include "mpsavm.h" #include "mpscmv.h" @@ -20,16 +13,27 @@ #ifdef MPS_OS_W3 #include "mpsw3.h" #endif +#include "mps.h" #ifdef MPS_OS_SU #include "ossu.h" #endif +#include +#include +#include +#include +#include +#include #define exactRootsCOUNT 50 #define ambigRootsCOUNT 50 -#define OBJECTS 4000 +#define OBJECTS 4000 +#define patternFREQ 100 + +/* objNULL needs to be odd so that it's ignored in exactRoots. */ #define objNULL ((mps_addr_t)0xDECEA5ED) #define FILLER_OBJECT_SIZE 1024 + static mps_pool_t amcpool; static mps_ap_t ap; static mps_addr_t exactRoots[exactRootsCOUNT]; @@ -110,6 +114,7 @@ static mps_res_t root_single(mps_ss_t ss, void *p, size_t s) return mps_fix(ss, (mps_addr_t *)p); } + /* == arena_commit_test == * * intended to test: @@ -165,13 +170,15 @@ static void *test(void *arg, size_t s) mps_arena_t arena; mps_fmt_t format; mps_root_t exactRoot, ambigRoot, singleRoot, fmtRoot; - mps_word_t i; + unsigned long i; + size_t j; mps_word_t collections; mps_pool_t mv; mps_addr_t alloced_obj; size_t asize = 32; /* size of alloced obj */ mps_addr_t obj; mps_ld_s ld; + mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); arena = (mps_arena_t)arg; testlib_unused(s); @@ -187,18 +194,16 @@ static void *test(void *arg, size_t s) die(mps_ap_create(&ap, amcpool), "ap_create"); - for(i=0; igenSerial */ + Serial serial; /* generation number */ int type; /* AMCPTypeGen for a gen */ AMC amc; /* owning AMC pool */ RingStruct amcRing; /* link in list of gens in pool */ @@ -40,6 +43,16 @@ typedef struct AMCGenStruct { } AMCGenStruct; +#define AMCBufferGen(buffer) ((AMCGen)((buffer)->p)) +#define AMCBufferSetGen(buffer, gen) ((buffer)->p = (void*)(gen)) + + +/* .ramp.generation: The ramp gen has serial AMCTopGen+1. */ +#define AMCRampGen AMCTopGen+1 + +enum { outsideRamp, beginRamp, ramping, finishRamp, collectingRamp }; + + /* AMCNailBoard -- the nail board */ typedef struct AMCNailBoardStruct *AMCNailBoard; @@ -112,8 +125,11 @@ typedef struct AMCStruct { /* design.mps.poolamc.struct */ Format format; /* container format */ RankSet rankSet; /* rankSet for entire pool */ RingStruct genRing; /* ring of generations */ - Serial genSerial; /* serial of next generation */ - AMCGen nursery; /* default mutator generation */ + AMCGen nursery; /* the default mutator generation */ + AMCGen rampGen; /* the ramp generation */ + AMCGen afterRampGen; /* the generation after rampGen */ + unsigned rampCount; /* see .ramp.hack */ + int rampMode; /* see .ramp.hack */ Sig sig; /* impl.h.misc.sig */ } AMCStruct; @@ -153,7 +169,7 @@ static Bool AMCGenCheck(AMCGen gen) CHECKD(Action, &gen->actionStruct); CHECKD(Buffer, gen->forward); CHECKL(RingCheck(&gen->amcRing)); - CHECKL(gen->serial < gen->amc->genSerial); + CHECKL(gen->serial <= AMCTopGen + 1); /* see .ramp.generation */ CHECKL((gen->size == 0) == (gen->segs == 0)); arena = gen->amc->poolStruct.arena; CHECKL(gen->size >= gen->segs * ArenaAlign(arena)); @@ -182,7 +198,7 @@ static Bool AMCNailBoardCheck(AMCNailBoard board) /* AMCGenCreate -- create a generation */ -static Res AMCGenCreate(AMCGen *genReturn, AMC amc) +static Res AMCGenCreate(AMCGen *genReturn, AMC amc, Serial genNum) { Arena arena; Buffer buffer; @@ -217,12 +233,15 @@ static Res AMCGenCreate(AMCGen *genReturn, AMC amc) gen->collected = ArenaMutatorAllocSize(arena); gen->sig = AMCGenSig; - gen->serial = amc->genSerial; - ++amc->genSerial; + gen->serial = genNum; AVERT(AMCGen, gen); RingAppend(&amc->genRing, &gen->amcRing); + if(genNum == AMCRampGenFollows + 1) + amc->afterRampGen = gen; + if(genNum == AMCRampGen) + amc->rampGen = gen; EVENT_PP(AMCGenCreate, amc, gen); @@ -430,16 +449,18 @@ static Res AMCInitComm(Pool pool, RankSet rankSet, va_list arg) amc->rankSet = rankSet; RingInit(&amc->genRing); - amc->genSerial = (Serial)0; /* amc gets checked before the nursery gets created, but the */ /* nursery gets created later in this function. */ amc->nursery = NULL; + /* The other generations get created when only needed. */ + amc->rampGen = NULL; amc->afterRampGen = NULL; + + amc->rampCount = 0; amc->rampMode = outsideRamp; amc->sig = AMCSig; - AVERT(AMC, amc); - res = AMCGenCreate(&gen, amc); + res = AMCGenCreate(&gen, amc, (Serial)0); if(res != ResOK) return res; amc->nursery = gen; @@ -587,6 +608,8 @@ static Res AMCBufferFill(Seg *segReturn, SegSetP(seg, &gen->type); /* design.mps.poolamc.fix.nail.distinguish */ ++gen->segs; gen->size += alignedSize; + /* If the generation was empty, restart the collection clock. */ + if(gen->segs == 1) gen->collected = ArenaMutatorAllocSize(arena); /* Give the buffer the entire segment to allocate in. */ *segReturn = seg; @@ -633,28 +656,44 @@ static void AMCBufferEmpty(Pool pool, Buffer buffer) /* AMCBenefit -- calculate benefit of collecting some generation */ -/* Binary i/f used by ASG (drj 1998-06-11) */ -unsigned long AMCTopGen = 2; - static double AMCBenefit(Pool pool, Action action) { AMCGen gen; /* generation which owns action */ + AMC amc; Arena arena; double f; /* frequency of collection, in Mb of alloc */ + Bool inRampMode; + AVERT(Pool, pool); + amc = PoolPoolAMC(pool); + AVERT(AMC, amc); AVERT(Action, action); gen = ActionAMCGen(action); AVERT(AMCGen, gen); + inRampMode = amc->rampMode != outsideRamp; + switch(gen->serial) { - case 0: f = AMCGen0Frequency; break; - case 1: f = AMCGen1Frequency; break; - case 2: f = AMCGen2Frequency; break; + case 0: f = inRampMode ? AMCGen0RampmodeFrequency : AMCGen0Frequency; + break; + case 1: f = inRampMode ? AMCGen1RampmodeFrequency : AMCGen1Frequency; + break; + case 2: f = inRampMode ? AMCGen2RampmodeFrequency : AMCGen2Frequency; + break; default: if(gen->serial == AMCGenFinal) { f = 1e99; /* Don't ever collect the final generation. */ + } else if(gen->serial == AMCRampGen) { + if(amc->rampMode == finishRamp) + return 1e99; /* do it now */ + else + f = gen->size != 0 ? AMCRampGenFrequency : 1e99; } else { - f = AMCGen2Frequency + AMCGen2plusFrequencyMultiplier * gen->serial; + f = inRampMode + ? (AMCGen2RampmodeFrequency + + AMCGen2plusRampmodeFrequencyMultiplier * gen->serial) + : (AMCGen2Frequency + + AMCGen2plusFrequencyMultiplier * gen->serial); } break; } @@ -665,6 +704,45 @@ static double AMCBenefit(Pool pool, Action action) } +/* AMCRampBegin -- note an entry into a ramp pattern */ + +static void AMCRampBegin(Pool pool, Buffer buf) +{ + AMC amc; + + AVERT(Pool, pool); + amc = PoolPoolAMC(pool); + AVERT(AMC, amc); + AVERT(Buffer, buf); + + AVER(amc->rampCount < UINT_MAX); + ++amc->rampCount; + if(amc->rampCount == 1 && amc->rampMode != finishRamp) + amc->rampMode = beginRamp; +} + + +/* AMCRampEnd -- note an exit from a ramp pattern */ + +static void AMCRampEnd(Pool pool, Buffer buf) +{ + AMC amc; + + AVERT(Pool, pool); + amc = PoolPoolAMC(pool); + AVERT(AMC, amc); + AVERT(Buffer, buf); + + AVER(amc->rampCount > 0); + --amc->rampCount; + if(amc->rampCount == 0) + if(amc->rampGen != NULL) /* if we have old objects, clean up */ + amc->rampMode = finishRamp; + else + amc->rampMode = outsideRamp; +} + + /* AMCWhiten -- condemn the segment for the trace * * If the segment has a mutator buffer on it, we nail the buffer, @@ -673,7 +751,8 @@ static double AMCBenefit(Pool pool, Action action) static Res AMCWhiten(Pool pool, Trace trace, Seg seg) { - AMCGen gen, forwardingGen; + AMCGen gen, newGen; + AMC amc; Buffer buffer; Res res; @@ -732,24 +811,55 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg) SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace->ti)); trace->condemned += SegSize(seg); + /* ensure we are forwarding into the right generation */ + gen = AMCSegGen(seg); AVERT(AMCGen, gen); - /* see .forward.gen */ - forwardingGen = (AMCGen)(gen->forward->p); - if(forwardingGen == NULL) { + amc = PoolPoolAMC(pool); + AVERT(AMC, amc); + /* see design.mps.poolamc.gen.ramp */ + /* This switching needs to be more complex for multiple traces. */ + AVER(TraceSetIsSingle(PoolArena(pool)->busyTraces)); + if(amc->rampMode == beginRamp && gen->serial == AMCRampGenFollows) { + if(amc->rampGen == NULL) { + res = AMCGenCreate(&newGen, amc, AMCRampGen); + if(res != ResOK) + return res; /* @@@@ should we clean up? */ + } + BufferDetach(gen->forward, pool); + AMCBufferSetGen(gen->forward, amc->rampGen); + BufferDetach(amc->rampGen->forward, pool); + AMCBufferSetGen(amc->rampGen->forward, amc->rampGen); + amc->rampMode = ramping; + } else + if(amc->rampMode == finishRamp && gen->serial == AMCRampGenFollows) { + if(amc->afterRampGen == NULL) { + res = AMCGenCreate(&newGen, amc, AMCRampGenFollows + 1); + if(res != ResOK) + return res; + } + BufferDetach(gen->forward, pool); + AMCBufferSetGen(gen->forward, amc->afterRampGen); + AVER(amc->rampGen != NULL); + BufferDetach(amc->rampGen->forward, pool); + AMCBufferSetGen(amc->rampGen->forward, amc->afterRampGen); + amc->rampMode = collectingRamp; + } + + /* see design.mps.poolamc.forward.gen */ + if(AMCBufferGen(gen->forward) == NULL) { if(gen->serial == AMCTopGen) { /* top generation forwards into itself */ - gen->forward->p = gen; + AMCBufferSetGen(gen->forward, gen); } else { - AMC amc; - AMCGen newGen; - - amc = PoolPoolAMC(pool); - AVERT(AMC, amc); - res = AMCGenCreate(&newGen, amc); + /* Because we switch when condemning AMCRampGenFollows, the gen */ + /* that AMCRampGen is set to forward into must already exist */ + /* when we come to condemn it. */ + AVER(gen->serial != AMCRampGen); + res = AMCGenCreate(&newGen, amc, gen->serial + 1); if(res != ResOK) return res; - gen->forward->p = newGen; + AMCBufferSetGen(gen->forward, newGen); } } @@ -768,6 +878,7 @@ static Res AMCAct(Pool pool, Action action) Ring node, nextNode; AMCGen gen; RefSet condemnedSet; + Serial genNum; AVERT(Pool, pool); amc = PoolPoolAMC(pool); @@ -778,6 +889,7 @@ static Res AMCAct(Pool pool, Action action) AVER(gen->amc == amc); arena = PoolArena(pool); + genNum = gen->serial; res = TraceCreate(&trace, arena); if(res != ResOK) @@ -788,12 +900,17 @@ static Res AMCAct(Pool pool, Action action) goto failBegin; /* Identify the condemned set in this pool, and find its zone set */ - /* @@@@ Could accumulate actual ref set for generation. */ + /* @@@@ Could accumulate actual refset for generation. */ condemnedSet = RefSetEMPTY; RING_FOR(node, PoolSegRing(pool), nextNode) { Seg seg = SegOfPoolRing(node); + Serial segGenNum = AMCSegGen(seg)->serial; - if(AMCSegGen(seg)->serial <= gen->serial) + /* Condemn the given generation and all previous ones; note the */ + /* unusual numbering of the ramp gen (.ramp.generation). */ + if(genNum == AMCRampGen + ? (segGenNum <= AMCRampGenFollows || segGenNum == AMCRampGen) + : segGenNum <= genNum) condemnedSet = RefSetUnion(condemnedSet, RefSetOfSeg(arena, seg)); } @@ -1312,14 +1429,18 @@ adjustColour: static void AMCReclaim(Pool pool, Trace trace, Seg seg) { + AMC amc; AMCGen gen; Size size; AVERT_CRITICAL(Pool, pool); + amc = PoolPoolAMC(pool); + AVERT_CRITICAL(AMC, amc); AVERT_CRITICAL(Trace, trace); AVERT_CRITICAL(Seg, seg); gen = AMCSegGen(seg); + AVERT_CRITICAL(AMCGen, gen); EVENT_PPP(AMCReclaim, gen, trace, seg); @@ -1328,6 +1449,15 @@ static void AMCReclaim(Pool pool, Trace trace, Seg seg) gen->collected = ArenaMutatorAllocSize(PoolArena(pool)); } + /* This switching needs to be more complex for multiple traces. */ + AVER_CRITICAL(TraceSetIsSingle(PoolArena(pool)->busyTraces)); + if(amc->rampMode == collectingRamp) + if(amc->rampCount > 0) + /* Entered ramp mode before previous one was cleaned up */ + amc->rampMode = beginRamp; + else + amc->rampMode = outsideRamp; + if(SegNailed(seg) != TraceSetEMPTY) { AMCReclaimNailed(pool, trace, seg); return; @@ -1367,7 +1497,8 @@ static Res AMCSegDescribe(AMC amc, Seg seg, mps_lib_FILE *stream) init = limit; res = WriteF(stream, - "AMC Seg $P {\n", (WriteFP)seg, " base $A\n", base, + "AMC seg $P [$A,$A){\n", + (WriteFP)seg, (WriteFA)base, (WriteFA)limit, " Map\n", NULL); if(res != ResOK) @@ -1499,14 +1630,15 @@ static Res AMCDescribe(Pool pool, mps_lib_FILE *stream) Res res; AMC amc; Ring ring, node, nextNode; + char *rampmode; if(!CHECKT(Pool, pool)) return ResFAIL; amc = PoolPoolAMC(pool); if(!CHECKT(AMC, amc)) return ResFAIL; res = WriteF(stream, - "AMC $P {\n", (WriteFP)amc, - " pool $P ($U) ", + (amc->rankSet == RankSetEMPTY) ? "AMCZ" : "AMC", + " $P {\n", (WriteFP)amc, " pool $P ($U) ", (WriteFP)AMCPool(amc), (WriteFU)AMCPool(amc)->serial, " format $P ($U)\n", (WriteFP)amc->format, (WriteFU)amc->format->serial, @@ -1514,6 +1646,22 @@ static Res AMCDescribe(Pool pool, mps_lib_FILE *stream) if(res != ResOK) return res; + /* @@@@ should add something about generations */ + + switch(amc->rampMode) { + case outsideRamp: rampmode = "outside ramp"; break; + case beginRamp: rampmode = "begin ramp"; break; + case ramping: rampmode = "ramping"; break; + case finishRamp: rampmode = "finish ramp"; break; + case collectingRamp: rampmode = "collecting ramp"; break; + default: rampmode = "unknown ramp mode"; break; + } + res = WriteF(stream, + " ", rampmode, " ($U)", (WriteFU)amc->rampCount, + NULL); + if(res != ResOK) + return res; + ring = PoolSegRing(pool); RING_FOR(node, ring, nextNode) { Seg seg = SegOfPoolRing(node); @@ -1556,6 +1704,8 @@ static PoolClassStruct PoolClassAMCStruct = { AMCReclaim, /* reclaim */ AMCBenefit, /* benefit */ AMCAct, /* act */ + AMCRampBegin, + AMCRampEnd, AMCWalk, /* walk */ AMCDescribe, /* describe */ PoolClassSig /* impl.h.mpm.class.end-sig */ @@ -1590,6 +1740,8 @@ static PoolClassStruct PoolClassAMCZStruct = { AMCReclaim, /* reclaim */ AMCBenefit, /* benefit */ AMCAct, /* act */ + AMCRampBegin, + AMCRampEnd, AMCWalk, /* walk */ AMCDescribe, /* describe */ PoolClassSig /* impl.h.mpm.class.end-sig */ @@ -1692,8 +1844,16 @@ static Bool AMCCheck(AMC amc) CHECKL(RingCheck(&amc->genRing)); if(amc->nursery != NULL) CHECKD(AMCGen, amc->nursery); + if(amc->rampGen != NULL) + CHECKD(AMCGen, amc->rampGen); + if(amc->afterRampGen != NULL) + CHECKD(AMCGen, amc->afterRampGen); + /* nothing to check for rampCount */ CHECKL((unsigned long)(Serial)AMCTopGen == AMCTopGen); + CHECKL(AMCTopGen >= 2); /* AMCBenefit assumes three gens */ + CHECKL(AMCGenFinal <= AMCTopGen); + CHECKL(AMCTopGen + 1 > 0); /* we can represent the ramp gen */ return TRUE; } diff --git a/mps/src/poolams.c b/mps/src/poolams.c index 2a59f7346b4..169602135ed 100644 --- a/mps/src/poolams.c +++ b/mps/src/poolams.c @@ -1,6 +1,6 @@ /* impl.c.poolams: AUTOMATIC MARK & SWEEP POOL CLASS * - * $HopeName: MMsrc!poolams.c(trunk.25) $ + * $HopeName: MMsrc!poolams.c(trunk.26) $ * Copyright (C) 1998. Harlequin Group plc. All rights reserved. * * .readership: any MPS developer. @@ -23,7 +23,7 @@ #include "mpm.h" #include -SRCID(poolams, "$HopeName: MMsrc!poolams.c(trunk.25) $"); +SRCID(poolams, "$HopeName: MMsrc!poolams.c(trunk.26) $"); #define AMSSig ((Sig)0x519A3599) /* SIGnature AMS */ @@ -857,7 +857,9 @@ Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) /* d.m.p.fix.to-black */ Addr next; + ShieldExpose(PoolArena(pool), seg); next = (*group->ams->format->skip)(ref); + ShieldCover(PoolArena(pool), seg); /* Part of the object might be grey, because of ambiguous */ /* fixes, but that's OK, because scan will ignore that. */ AMSRangeWhiteBlacken(group, i, AMS_ADDR_INDEX(group, next)); @@ -1084,8 +1086,6 @@ static Res AMSDescribe(Pool pool, mps_lib_FILE *stream) if(stream == NULL) return ResFAIL; res = WriteF(stream, - "AMS $P {\n", (WriteFP)ams, - " pool $P ($U)\n", (WriteFP)pool, (WriteFU)pool->serial, " size $W, lastReclaimed $W\n", (WriteFW)ams->size, (WriteFW)ams->lastReclaimed, @@ -1109,11 +1109,11 @@ static Res AMSDescribe(Pool pool, mps_lib_FILE *stream) RING_FOR(node, &ams->groupRing, nextNode) { AMSGroup group = RING_ELT(AMSGroup, groupRing, node); - AMSGroupDescribe(group, stream); + res = AMSGroupDescribe(group, stream); + if(res != ResOK) + return res; } - - res = WriteF(stream, "} AMS $P\n",(WriteFP)ams, NULL); - return res; + return ResOK; } @@ -1144,6 +1144,8 @@ static PoolClassStruct PoolClassAMSStruct = { AMSReclaim, AMSBenefit, PoolCollectAct, + PoolNoRampBegin, + PoolNoRampEnd, PoolNoWalk, AMSDescribe, PoolClassSig /* impl.h.mpm.class.end-sig */ diff --git a/mps/src/poolawl.c b/mps/src/poolawl.c index 04f1a32a3fc..4995f6b3f29 100644 --- a/mps/src/poolawl.c +++ b/mps/src/poolawl.c @@ -1,6 +1,6 @@ /* impl.c.poolawl: AUTOMATIC WEAK LINKED POOL CLASS * - * $HopeName: MMsrc!poolawl.c(trunk.48) $ + * $HopeName: MMsrc!poolawl.c(trunk.49) $ * Copyright (C) 1998. Harlequin Group plc. All rights reserved. * * READERSHIP @@ -39,14 +39,13 @@ * .assume.alltraceable: The pool assumes that all objects are entirely * traceable. This must be documented elsewhere for the benefit of the * client. - * */ #include "mpscawl.h" #include "mpm.h" -SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.48) $"); +SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.49) $"); #define AWLSig ((Sig)0x519b7a37) /* SIGPooLAWL */ @@ -1181,6 +1180,8 @@ struct PoolClassStruct PoolClassAWLStruct = { AWLReclaim, AWLBenefit, PoolCollectAct, + PoolNoRampBegin, + PoolNoRampEnd, AWLWalk, PoolTrivDescribe, PoolClassSig diff --git a/mps/src/poollo.c b/mps/src/poollo.c index fbdbd84e604..b2018f179ee 100644 --- a/mps/src/poollo.c +++ b/mps/src/poollo.c @@ -1,6 +1,6 @@ /* impl.c.poollo: LEAF POOL CLASS * - * $HopeName: MMsrc!poollo.c(trunk.3) $ + * $HopeName: MMsrc!poollo.c(trunk.4) $ * Copyright (C) 1997,1998 Harlequin Group plc, all rights reserved. * * READERSHIP @@ -15,11 +15,11 @@ */ +#include "mpsclo.h" #include "mpm.h" #include "mps.h" -#include "mpsclo.h" -SRCID(poollo, "$HopeName: MMsrc!poollo.c(trunk.3) $"); +SRCID(poollo, "$HopeName: MMsrc!poollo.c(trunk.4) $"); /* MACROS */ @@ -769,6 +769,8 @@ static struct PoolClassStruct PoolClassLOStruct = { LOReclaim, /* reclaim */ LOBenefit, /* benefit */ PoolCollectAct, /* act */ + PoolNoRampBegin, + PoolNoRampEnd, LOWalk, /* walk */ PoolTrivDescribe, /* describe */ PoolClassSig /* impl.h.mpmst.class.end-sig */ diff --git a/mps/src/poolmfs.c b/mps/src/poolmfs.c index c98248fb0df..fd5a1ef7b1f 100644 --- a/mps/src/poolmfs.c +++ b/mps/src/poolmfs.c @@ -1,7 +1,7 @@ /* impl.c.poolmfs: MANUAL FIXED SMALL UNIT POOL * - * $HopeName: MMsrc!poolmfs.c(trunk.27) $ - * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. + * $HopeName: MMsrc!poolmfs.c(trunk.28) $ + * Copyright (C) 1997 Harlequin Group plc. All rights reserved. * * This is the implementation of the MFS pool class. * @@ -32,24 +32,24 @@ */ -#include "mpm.h" #include "poolmfs.h" +#include "mpm.h" -SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.27) $"); +SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.28) $"); -/* == Round up == +/* ROUND -- Round up * * Rounds n up to the nearest multiple of unit. */ #define ROUND(unit, n) ((n)+(unit)-1 - ((n)+(unit)-1)%(unit)) + #define PoolPoolMFS(pool) PARENT(MFSStruct, poolStruct, pool) -/* == Free List Structure == - */ +/* HeaderStruct -- Freelist structure */ typedef struct MFSHeaderStruct { struct MFSHeaderStruct *next; @@ -279,12 +279,14 @@ static PoolClassStruct PoolClassMFSStruct = { PoolNoBlacken, /* blacken */ PoolNoScan, /* scan */ PoolNoFix, /* fix */ - PoolNoFix, /* fix */ + PoolNoFix, /* emergency fix */ PoolNoReclaim, /* reclaim */ PoolNoBenefit, /* benefit */ PoolNoAct, /* act */ - PoolNoWalk, /* walk */ - MFSDescribe, /* describe */ + PoolNoRampBegin, + PoolNoRampEnd, + PoolNoWalk, + MFSDescribe, PoolClassSig /* impl.h.mpmst.class.end-sig */ }; diff --git a/mps/src/poolmrg.c b/mps/src/poolmrg.c index fb5852aa116..a88ac94926b 100644 --- a/mps/src/poolmrg.c +++ b/mps/src/poolmrg.c @@ -1,9 +1,7 @@ -/* impl.c.poolmrg +/* impl.c.poolmrg: MANUAL RANK GUARDIAN POOL * - * MANUAL RANK GUARDIAN POOL - * - * $HopeName: MMsrc!poolmrg.c(trunk.26) $ - * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. + * $HopeName: MMsrc!poolmrg.c(trunk.27) $ + * Copyright (C) 1997 Harlequin Group plc. All rights reserved. * * READERSHIP * @@ -36,7 +34,7 @@ #include "mpm.h" #include "poolmrg.h" -SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(trunk.26) $"); +SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(trunk.27) $"); /* Types */ @@ -712,6 +710,8 @@ static PoolClassStruct PoolClassMRGStruct = { PoolNoReclaim, PoolNoBenefit, PoolNoAct, + PoolNoRampBegin, + PoolNoRampEnd, PoolNoWalk, MRGDescribe, PoolClassSig /* impl.h.mpmst.class.end-sig */ diff --git a/mps/src/poolmv.c b/mps/src/poolmv.c index 41d1f3f919b..7e485000284 100644 --- a/mps/src/poolmv.c +++ b/mps/src/poolmv.c @@ -1,7 +1,7 @@ /* impl.c.poolmv: MANUAL VARIABLE POOL * - * $HopeName: MMsrc!poolmv.c(trunk.29) $ - * Copyright (C) 1997 The Harlequin Group Limited. All rights reserved. + * $HopeName: MMsrc!poolmv.c(trunk.30) $ + * Copyright (C) 1997 Harlequin Group plc. All rights reserved. * * **** RESTRICTION: This pool may not allocate from the arena control * pool, since it is used to implement that pool. @@ -24,12 +24,12 @@ * 1994-11-10 */ -#include "mpm.h" +#include "mpscmv.h" #include "poolmv.h" #include "poolmfs.h" -#include "mpscmv.h" +#include "mpm.h" -SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(trunk.29) $"); +SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(trunk.30) $"); #define BLOCKPOOL(mv) (MFSPool(&(mv)->blockPoolStruct)) @@ -709,6 +709,8 @@ static PoolClassStruct PoolClassMVStruct = { PoolNoReclaim, /* relcaim */ PoolNoBenefit, /* benefit */ PoolNoAct, /* act */ + PoolNoRampBegin, + PoolNoRampEnd, PoolNoWalk, /* walk */ MVDescribe, /* describe */ PoolClassSig /* impl.h.mpmst.class.end-sig */ diff --git a/mps/src/poolmv2.c b/mps/src/poolmv2.c index aba810c41e4..d0fcd8182de 100644 --- a/mps/src/poolmv2.c +++ b/mps/src/poolmv2.c @@ -1,6 +1,6 @@ /* impl.c.poolmv2: MANUAL VARIABLE POOL, II * - * $HopeName: MMsrc!poolmv2.c(MMdevel_gavinm_splay.18) $ + * $HopeName: MMsrc!poolmv2.c(trunk.2) $ * Copyright (C) 1998 Harlequin Group plc. All rights reserved. * * .readership: any MPS developer @@ -17,19 +17,16 @@ #include "abq.h" #include "meter.h" -SRCID(poolmv2, "$HopeName: MMsrc!poolmv2.c(MMdevel_gavinm_splay.18) $"); - +SRCID(poolmv2, "$HopeName: MMsrc!poolmv2.c(trunk.2) $"); /* Signatures */ - #define MV2Sig ((Sig)0x5193F299) /* SIGnature MV2 */ /* Private prototypes */ - typedef struct MV2Struct *MV2; static Res MV2Init(Pool pool, va_list arg); static Bool MV2Check(MV2 mv2); @@ -168,6 +165,8 @@ static PoolClassStruct PoolClassMV2Struct = PoolNoReclaim, /* relcaim */ PoolNoBenefit, /* benefit */ PoolNoAct, /* act */ + PoolNoRampBegin, + PoolNoRampEnd, PoolNoWalk, /* walk */ MV2Describe, /* describe */ PoolClassSig /* impl.h.mpmst.class.end-sig */ @@ -1168,10 +1167,3 @@ static Bool MV2CheckFit(CBSBlock block, Size min, Arena arena) return FALSE; } - - - - - - - diff --git a/mps/src/pooln.c b/mps/src/pooln.c index 3358c7271e8..648fa14bae2 100644 --- a/mps/src/pooln.c +++ b/mps/src/pooln.c @@ -1,15 +1,15 @@ /* impl.c.pooln: NULL POOL CLASS * - * $HopeName: MMsrc!pooln.c(trunk.19) $ - * Copyright(C) 1997 The Harlequin Group Limited. All rights reserved. + * $HopeName: MMsrc!pooln.c(trunk.20) $ + * Copyright (C) 1997 Harlequin Group plc. All rights reserved. * * .readership: MPS developers */ -#include "mpm.h" #include "pooln.h" +#include "mpm.h" -SRCID(pooln, "$HopeName: MMsrc!pooln.c(trunk.19) $"); +SRCID(pooln, "$HopeName: MMsrc!pooln.c(trunk.20) $"); typedef struct PoolNStruct { @@ -246,32 +246,34 @@ static void NReclaim(Pool pool, Trace trace, Seg seg) static PoolClassStruct PoolClassNStruct = { - PoolClassSig, /* sig */ + PoolClassSig, "N", /* name */ sizeof(PoolNStruct), /* size */ offsetof(PoolNStruct, poolStruct), /* offset */ AttrSCAN | AttrALLOC | AttrFREE | AttrBUF | AttrBUF_RESERVE | AttrGC, - NInit, /* init */ - NFinish, /* finish */ - NAlloc, /* alloc */ - NFree, /* free */ - NBufferInit, /* bufferInit */ - NBufferFill, /* bufferFill */ - NBufferEmpty, /* bufferEmpty */ - NBufferFinish, /* bufferFinish */ - PoolNoTraceBegin, /* traceBegin */ - PoolNoAccess, /* access */ - NWhiten, /* whiten */ - NGrey, /* grey */ - NBlacken, /* blacken */ - NScan, /* scan */ + NInit, + NFinish, + NAlloc, + NFree, + NBufferInit, + NBufferFill, + NBufferEmpty, + NBufferFinish, + PoolNoTraceBegin, + PoolNoAccess, + NWhiten, /* whiten/condemn */ + NGrey, + NBlacken, + NScan, NFix, /* fix */ NFix, /* emergency fix */ - NReclaim, /* reclaim */ - PoolNoBenefit, /* benefit */ - PoolNoAct, /* act */ - PoolNoWalk, /* walk */ - NDescribe, /* describe */ + NReclaim, + PoolNoBenefit, + PoolNoAct, + PoolNoRampBegin, + PoolNoRampEnd, + PoolNoWalk, + NDescribe, PoolClassSig /* impl.h.mpmst.class.end-sig */ }; diff --git a/mps/src/testlib.c b/mps/src/testlib.c index 923d6febda6..9b55cabb6e7 100644 --- a/mps/src/testlib.c +++ b/mps/src/testlib.c @@ -1,21 +1,22 @@ -/* impl.c.testlib: Test library +/* impl.c.testlib: Test library * - * $HopeName: MMsrc!testlib.c(trunk.8) $ + * $HopeName: MMsrc!testlib.c(trunk.9) $ + * Copyright (C) 1995, 1998 Harlequin Group plc. All rights reserved. * - * Copyright (C) 1995, 1998 Harlequin Group, all rights reserved - * - * .purpose: A library of functions that may be of use to unit tests. + * .purpose: A library of functions that may be of use to unit tests. */ -#include "mps.h" #include "testlib.h" +#include "mps.h" +#include "mpm.h" +#include "mpstd.h" #ifdef MPS_OS_SU #include "ossu.h" #endif - #include #include #include +#include /* rnd -- a random number generator @@ -47,3 +48,43 @@ void die(mps_res_t res, const char *s) exit(1); } } + + +/* adjust_collection_freq -- multiply all collection frequencies by + * a given factor + * + * If frequencies are adjusted too low, they are corrected so that all are + * non-zero and larger than the ones for lower generations. + */ + +void adjust_collection_freq(double multiplier) +{ + AMCGen0Frequency *= multiplier; + if(AMCGen0Frequency == 0) + AMCGen0Frequency = 1; + AMCGen1Frequency *= multiplier; + if(AMCGen1Frequency <= AMCGen0Frequency) + AMCGen1Frequency = AMCGen0Frequency + 1; + AMCGen2Frequency *= multiplier; + if(AMCGen2Frequency <= AMCGen1Frequency) + AMCGen2Frequency = AMCGen1Frequency + 1; + AMCGen2plusFrequencyMultiplier *= multiplier; + if(AMCGen2plusFrequencyMultiplier == 0) + AMCGen2plusFrequencyMultiplier = 1; + AMCGen0RampmodeFrequency *= multiplier; + if(AMCGen0RampmodeFrequency == 0) + AMCGen0RampmodeFrequency = 1; + AMCGen1RampmodeFrequency *= multiplier; + if(AMCGen1RampmodeFrequency == AMCGen0RampmodeFrequency) + AMCGen1RampmodeFrequency = AMCGen0RampmodeFrequency + 1; + AMCRampGenFrequency *= multiplier; + assert(AMCRampGenFollows == 1); + if(AMCRampGenFrequency <= AMCGen1RampmodeFrequency) + AMCRampGenFrequency = AMCGen1RampmodeFrequency + 1; + AMCGen2RampmodeFrequency *= multiplier; + if(AMCGen2RampmodeFrequency <= AMCRampGenFrequency) + AMCGen2RampmodeFrequency = AMCRampGenFrequency * 2; + AMCGen2plusRampmodeFrequencyMultiplier *= multiplier; + if(AMCGen2plusRampmodeFrequencyMultiplier == 0) + AMCGen2plusRampmodeFrequencyMultiplier = 1; +} diff --git a/mps/src/testlib.h b/mps/src/testlib.h index e95f4667800..35eb985f26d 100644 --- a/mps/src/testlib.h +++ b/mps/src/testlib.h @@ -1,15 +1,11 @@ -/* ==== TEST LIBRARY ==== +/* impl.h.testlib: TEST LIBRARY * - * $HopeName: MMsrc!testlib.h(trunk.9) $ + * $HopeName: MMsrc!testlib.h(trunk.9) $ + * Copyright (C) 1995, 1998 Harlequin Group plc. All rights reserved. * - * Copyright (C) 1995, 1998. Harlequin Group plc. All rights reserved. + * .purpose: A library of functions that may be of use to unit tests. * - * This is a library of functions that unit test developers might find - * useful. We hope they enhance your programming pleasure. - * - * Notes - * 1. There is no way to set the seed for rnd. - * 1995-03-14 drj + * .notes: There is no way to set the seed for rnd. 1995-03-14 drj */ #ifndef testlib_h @@ -72,35 +68,40 @@ #endif /* MPS_BUILD_MV */ -/* == MISC == */ - -/* == UNUSED == +/* testlib_unused -- declares that a variable is unused * - * The testlib_unused macro declares that a variable is unused. - * It should be used to prevent compiler warnings about unused - * variables. Care should be exercised; the fact that a variable - * is unused may need justification. + * It should be used to prevent compiler warnings about unused + * variables. Care should be exercised; the fact that a variable + * is unused may need justification. */ #define testlib_unused(v) ((void)(v)) -/* == SUCCEED OR DIE == +/* die -- succeed or die * - * If the first argument is not ResOK then prints the second - * argument on stderr and exits the program. Otherwise does nothing. + * If the first argument is not ResOK then prints the second + * argument on stderr and exits the program. Otherwise does nothing. * - * Typical use: + * Typical use: * die(mps_space_create(&space), "SpaceCreate"); */ extern void die(mps_res_t res, const char *s); -/* == RANDOM NUMBER GENERATOR == +/* rnd -- random number generator * - * rnd() generates a sequence of integers in the range [0, 2^31-2] + * rnd() generates a sequence of integers in the range [0, 2^31-2]. */ extern unsigned long rnd(void); + +/* adjust_collection_freq -- multiply all collection frequencies by + * a given factor + */ + +extern void adjust_collection_freq(double multiplier); + + #endif /* testlib_h */ diff --git a/mps/src/trace.c b/mps/src/trace.c index 637b69d8e53..f6ed126f369 100644 --- a/mps/src/trace.c +++ b/mps/src/trace.c @@ -1,6 +1,6 @@ /* impl.c.trace: GENERIC TRACER IMPLEMENTATION * - * $HopeName: MMsrc!trace.c(trunk.73) $ + * $HopeName: MMsrc!trace.c(trunk.74) $ * Copyright (C) 1998. Harlequin Group plc. All rights reserved. * * .design: design.mps.trace. @@ -10,7 +10,7 @@ #include -SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.73) $"); +SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.74) $"); /* Types @@ -208,8 +208,14 @@ static void TraceUpdateCounts(Trace trace, ScanState ss, unsigned long AMCGen0Frequency = 4; unsigned long AMCGen1Frequency = 32; -unsigned long AMCGen2Frequency = 300; +unsigned long AMCGen2Frequency = 200; unsigned long AMCGen2plusFrequencyMultiplier = 1000; +unsigned long AMCGen0RampmodeFrequency = 4; +unsigned long AMCGen1RampmodeFrequency = 20; +unsigned long AMCRampGenFrequency = 300; +unsigned long AMCGen2RampmodeFrequency = 1000; +unsigned long AMCGen2plusRampmodeFrequencyMultiplier = 1000; +Serial AMCRampGenFollows = 1; Serial AMCGenFinal = 0; /* default: no final generation */ double TraceGen0IncrementalityMultiple = 0.5; diff --git a/mps/src/vmw3.c b/mps/src/vmw3.c index 453aa3d5ac6..9487da35b5f 100644 --- a/mps/src/vmw3.c +++ b/mps/src/vmw3.c @@ -1,7 +1,7 @@ /* impl.c.vmw3: VIRTUAL MEMORY MAPPING FOR WIN32 * - * $HopeName: MMsrc!vmw3.c(trunk.25) $ - * Copyright (C) 1997, 1998 Harlequin Group, all rights reserved + * $HopeName: MMsrc!vmw3.c(trunk.26) $ + * Copyright (C) 1997, 1998 Harlequin Group plc. All rights reserved. * * Design: design.mps.vm * @@ -55,7 +55,7 @@ #include "mpswin.h" -SRCID(vmw3, "$HopeName: MMsrc!vmw3.c(trunk.25) $"); +SRCID(vmw3, "$HopeName: MMsrc!vmw3.c(trunk.26) $"); /* VMStruct -- virtual memory structure */ @@ -131,19 +131,31 @@ static Res VMSetCollectionStrategy(VM vm) /* Source: drj's test data, 1998-03-30 */ AMCGen0Frequency = 16; AMCGen1Frequency = 160; - AMCGen2Frequency = 1000; + AMCGen2Frequency = 700; + AMCGen0RampmodeFrequency = 16; + AMCGen1RampmodeFrequency = 160; + AMCRampGenFrequency = 1000; + AMCGen2RampmodeFrequency = 4000; } else if (vmRAMSize >= 60*1024*1024) { /* Parameters optimized for 64 MB machines */ /* Source: RIT's test data, 1998-03-26 */ AMCGen0Frequency = 6; - AMCGen1Frequency = 48; - AMCGen2Frequency = 480; + AMCGen1Frequency = 60; + AMCGen2Frequency = 360; + AMCGen0RampmodeFrequency = 6; + AMCGen1RampmodeFrequency = 48; + AMCRampGenFrequency = 480; + AMCGen2RampmodeFrequency = 1600; } else { /* Parameters optimized for 32 MB machines */ /* Source: Tony's test data, 1998-03-26 */ AMCGen0Frequency = 4; - AMCGen1Frequency = 20; - AMCGen2Frequency = 300; + AMCGen1Frequency = 32; + AMCGen2Frequency = 200; + AMCGen0RampmodeFrequency = 4; + AMCGen1RampmodeFrequency = 20; + AMCRampGenFrequency = 300; + AMCGen2RampmodeFrequency = 1000; } } return res;