1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-17 00:30:37 -08:00

Merging mmdevel_ramp_alloc

Copied from Perforce
 Change: 19787
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Pekka Pirinen 1998-07-20 20:41:05 +01:00
parent 86c0d74835
commit da73c8afe2
21 changed files with 616 additions and 222 deletions

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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 */

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#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; i<exactRootsCOUNT; ++i)
exactRoots[i] = objNULL;
for(j = 0; j < exactRootsCOUNT; ++j)
exactRoots[j] = objNULL;
for(j = 0; j < ambigRootsCOUNT; ++j)
ambigRoots[j] = (mps_addr_t)rnd();
for(i=0; i<ambigRootsCOUNT; ++i)
ambigRoots[i] = (mps_addr_t)rnd();
die(mps_root_create_table(&exactRoot, arena,
MPS_RANK_EXACT, (mps_rm_t)0,
&exactRoots[0], exactRootsCOUNT),
die(mps_root_create_table_masked(&exactRoot, arena,
MPS_RANK_EXACT, (mps_rm_t)0,
&exactRoots[0], exactRootsCOUNT,
(mps_word_t)1),
"root_create_table(exact)");
die(mps_root_create_table(&ambigRoot, arena,
MPS_RANK_AMBIG, (mps_rm_t)0,
&ambigRoots[0], ambigRootsCOUNT),
@ -215,7 +220,6 @@ static void *test(void *arg, size_t s)
obj = make_no_inline();
die(mps_alloc(&alloced_obj, mv, asize), "mps_alloc");
die(dylan_init(alloced_obj, asize, exactRoots, exactRootsCOUNT),
"dylan_init(alloced_obj)");
@ -234,9 +238,9 @@ static void *test(void *arg, size_t s)
mps_ld_add(&ld, arena, obj);
}
collections = 0;
collections = mps_collections(arena);
for(i=0; i<OBJECTS; ++i) {
for(i = 0; i < OBJECTS; ++i) {
unsigned c;
size_t r;
@ -244,12 +248,18 @@ static void *test(void *arg, size_t s)
if(collections != c) {
collections = c;
printf("\nCollection %u, %lu objects.\n",
c, (unsigned long)i);
for(r=0; r<exactRootsCOUNT; ++r)
assert(dylan_check(exactRoots[r]));
printf("\nCollection %u, %lu objects.\n", c, i);
for(r = 0; r < exactRootsCOUNT; ++r)
assert(exactRoots[r] == objNULL || dylan_check(exactRoots[r]));
}
if(rnd() % patternFREQ == 0)
switch(rnd() % 4) {
case 0: case 1: mps_ap_alloc_pattern_begin(ap, ramp); break;
case 2: mps_ap_alloc_pattern_end(ap, ramp); break;
case 3: mps_ap_alloc_pattern_reset(ap); break;
}
if(rnd() & 1)
exactRoots[rnd() % exactRootsCOUNT] = make();
else
@ -262,6 +272,8 @@ static void *test(void *arg, size_t s)
arena_commit_test(arena);
mps_arena_collect(arena);
mps_free(mv, alloced_obj, 32);
alloc_v_test(mv);
mps_pool_destroy(mv);

View file

@ -1,6 +1,6 @@
/* impl.c.pool: POOL IMPLEMENTATION
*
* $HopeName: MMsrc!pool.c(trunk.54) $
* $HopeName: MMsrc!pool.c(trunk.55) $
* Copyright (C) 1997. Harlequin Group plc. All rights reserved.
*
* READERSHIP
@ -37,7 +37,7 @@
#include "mpm.h"
SRCID(pool, "$HopeName: MMsrc!pool.c(trunk.54) $");
SRCID(pool, "$HopeName: MMsrc!pool.c(trunk.55) $");
Bool PoolClassCheck(PoolClass class)
@ -1020,6 +1020,20 @@ failCreate:
}
void PoolNoRampBegin(Pool pool, Buffer buf)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
}
void PoolNoRampEnd(Pool pool, Buffer buf)
{
AVERT(Pool, pool);
AVERT(Buffer, buf);
}
void PoolNoWalk(Pool pool, Seg seg,
FormattedObjectsStepMethod f,
void *p, Size s)

View file

@ -1,6 +1,6 @@
/* impl.c.poolamc: AUTOMATIC MOSTLY-COPYING MEMORY POOL CLASS
*
* $HopeName: MMsrc!poolamc.c(trunk.10) $
* $HopeName: MMsrc!poolamc.c(trunk.11) $
* Copyright (C) 1998. Harlequin Group plc. All rights reserved.
*
* .sources: design.mps.poolamc.
@ -10,9 +10,12 @@
#include "mpscamc.h"
#include "mpm.h"
SRCID(poolamc, "$HopeName: MMsrc!poolamc.c(trunk.10) $");
SRCID(poolamc, "$HopeName: MMsrc!poolamc.c(trunk.11) $");
/* Binary i/f used by ASG (drj 1998-06-11) */
unsigned long AMCTopGen = 2;
/* PType enumeration -- distinguishes AMCGen and AMCNailBoard */
enum {AMCPTypeGen = 1, AMCPTypeNailBoard};
@ -28,7 +31,7 @@ extern PoolClass PoolClassAMCZ(void);
typedef struct AMCGenStruct *AMCGen;
typedef struct AMCGenStruct {
Sig sig; /* impl.h.misc.sig */
Serial serial; /* from amc->genSerial */
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;
}

View file

@ -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 <stdarg.h>
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 */

View file

@ -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

View file

@ -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 */

View file

@ -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 */
};

View file

@ -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 */

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 */
};

View file

@ -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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* 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;
}

View file

@ -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 */

View file

@ -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 <limits.h>
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;

View file

@ -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;