Commit 6f83fbc0 authored by simonmar's avatar simonmar

[project @ 2001-07-23 10:47:16 by simonmar]

Small changes to improve GC performance slightly:

  - store the generation *number* in the block descriptor rather
    than a pointer to the generation structure, since the most
    common operation is to pull out the generation number, and
    it's one less indirection this way.

  - cache the generation number in the step structure too, which
    avoids an extra indirection in several places.
parent 9a6296aa
/* -----------------------------------------------------------------------------
* $Id: Block.h,v 1.7 2000/04/05 14:26:31 panne Exp $
* $Id: Block.h,v 1.8 2001/07/23 10:47:16 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -45,7 +45,7 @@ typedef struct _bdescr {
StgPtr free; /* first free byte of memory */
struct _bdescr *link; /* used for chaining blocks together */
struct _bdescr *back; /* used (occasionally) for doubly-linked lists*/
struct _generation *gen; /* generation */
unsigned int gen_no; /* generation */
struct _step *step; /* step */
StgWord32 blocks; /* no. of blocks (if grp head, 0 otherwise) */
StgWord32 evacuated; /* block is in to-space */
......
/* -----------------------------------------------------------------------------
* $Id: StgStorage.h,v 1.7 2000/04/11 16:36:53 sewardj Exp $
* $Id: StgStorage.h,v 1.8 2001/07/23 10:47:16 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -53,6 +53,7 @@ typedef struct _step {
unsigned int n_blocks; /* number of blocks */
struct _step *to; /* where collected objects from this step go */
struct _generation *gen; /* generation this step belongs to */
unsigned int gen_no; /* generation number (cached) */
bdescr *large_objects; /* large objects (doubly linked) */
/* temporary use during GC: */
......
/* -----------------------------------------------------------------------------
* $Id: BlockAlloc.c,v 1.7 2000/01/30 10:17:44 simonmar Exp $
* $Id: BlockAlloc.c,v 1.8 2001/07/23 10:47:16 simonmar Exp $
*
* (c) The GHC Team 1998-2000
*
......@@ -222,7 +222,7 @@ freeGroup(bdescr *p)
#ifdef DEBUG
p->free = (void *)-1; /* indicates that this block is free */
p->step = NULL;
p->gen = NULL;
p->gen_no = 0;
/* fill the block group with garbage if sanity checking is on */
IF_DEBUG(sanity,memset(p->start, 0xaa, p->blocks * BLOCK_SIZE));
#endif
......
/* -----------------------------------------------------------------------------
* $Id: GC.c,v 1.102 2001/04/03 16:35:12 sewardj Exp $
* $Id: GC.c,v 1.103 2001/07/23 10:47:16 simonmar Exp $
*
* (c) The GHC Team 1998-1999
*
......@@ -301,9 +301,9 @@ void GarbageCollect ( void (*get_roots)(void), rtsBool force_major_gc )
*/
bd = allocBlock();
stp = &generations[g].steps[s];
ASSERT(stp->gen->no == g);
ASSERT(stp->gen_no == g);
ASSERT(stp->hp ? Bdescr(stp->hp)->step == stp : rtsTrue);
bd->gen = &generations[g];
bd->gen_no = g;
bd->step = stp;
bd->link = NULL;
bd->evacuated = 1; /* it's a to-space block */
......@@ -332,7 +332,7 @@ void GarbageCollect ( void (*get_roots)(void), rtsBool force_major_gc )
stp = &generations[g].steps[s];
if (stp->hp_bd == NULL) {
bd = allocBlock();
bd->gen = &generations[g];
bd->gen_no = g;
bd->step = stp;
bd->link = NULL;
bd->evacuated = 0; /* *not* a to-space block */
......@@ -1014,7 +1014,7 @@ isAlive(StgClosure *p)
*/
/* ignore closures in generations that we're not collecting. */
if (LOOKS_LIKE_STATIC(p) || Bdescr((P_)p)->gen->no > N) {
if (LOOKS_LIKE_STATIC(p) || Bdescr((P_)p)->gen_no > N) {
return p;
}
......@@ -1081,10 +1081,10 @@ MarkRoot(StgClosure *root)
static void addBlock(step *stp)
{
bdescr *bd = allocBlock();
bd->gen = stp->gen;
bd->gen_no = stp->gen_no;
bd->step = stp;
if (stp->gen->no <= N) {
if (stp->gen_no <= N) {
bd->evacuated = 1;
} else {
bd->evacuated = 0;
......@@ -1121,7 +1121,7 @@ copy(StgClosure *src, nat size, step *stp)
* evacuate to an older generation, adjust it here (see comment
* by evacuate()).
*/
if (stp->gen->no < evac_gen) {
if (stp->gen_no < evac_gen) {
#ifdef NO_EAGER_PROMOTION
failed_to_evac = rtsTrue;
#else
......@@ -1159,7 +1159,7 @@ copyPart(StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
P_ dest, to, from;
TICK_GC_WORDS_COPIED(size_to_copy);
if (stp->gen->no < evac_gen) {
if (stp->gen_no < evac_gen) {
#ifdef NO_EAGER_PROMOTION
failed_to_evac = rtsTrue;
#else
......@@ -1211,7 +1211,7 @@ evacuate_large(StgPtr p, rtsBool mutable)
/* Don't forget to set the failed_to_evac flag if we didn't get
* the desired destination (see comments in evacuate()).
*/
if (bd->gen->no < evac_gen) {
if (bd->gen_no < evac_gen) {
failed_to_evac = rtsTrue;
TICK_GC_FAILED_PROMOTION();
}
......@@ -1232,7 +1232,7 @@ evacuate_large(StgPtr p, rtsBool mutable)
/* link it on to the evacuated large object list of the destination step
*/
stp = bd->step->to;
if (stp->gen->no < evac_gen) {
if (stp->gen_no < evac_gen) {
#ifdef NO_EAGER_PROMOTION
failed_to_evac = rtsTrue;
#else
......@@ -1241,7 +1241,7 @@ evacuate_large(StgPtr p, rtsBool mutable)
}
bd->step = stp;
bd->gen = stp->gen;
bd->gen_no = stp->gen_no;
bd->link = stp->new_large_objects;
stp->new_large_objects = bd;
bd->evacuated = 1;
......@@ -1323,12 +1323,12 @@ evacuate(StgClosure *q)
loop:
if (HEAP_ALLOCED(q)) {
bd = Bdescr((P_)q);
if (bd->gen->no > N) {
if (bd->gen_no > N) {
/* Can't evacuate this object, because it's in a generation
* older than the ones we're collecting. Let's hope that it's
* in evac_gen or older, or we will have to make an IND_OLDGEN object.
*/
if (bd->gen->no < evac_gen) {
if (bd->gen_no < evac_gen) {
/* nope */
failed_to_evac = rtsTrue;
TICK_GC_FAILED_PROMOTION();
......@@ -1389,9 +1389,9 @@ loop:
case THUNK_0_2:
case THUNK_2_0:
#ifdef NO_PROMOTE_THUNKS
if (bd->gen->no == 0 &&
if (bd->gen_no == 0 &&
bd->step->no != 0 &&
bd->step->no == bd->gen->n_steps-1) {
bd->step->no == generations[bd->gen_no].n_steps-1) {
stp = bd->step;
}
#endif
......@@ -1460,7 +1460,7 @@ loop:
if (HEAP_ALLOCED(q)) {
bdescr *bd = Bdescr((P_)q);
if (bd->evacuated) {
if (bd->gen->no < evac_gen) {
if (bd->gen_no < evac_gen) {
failed_to_evac = rtsTrue;
TICK_GC_FAILED_PROMOTION();
}
......@@ -1655,7 +1655,7 @@ loop:
*/
if (evac_gen > 0) { /* optimisation */
StgClosure *p = ((StgEvacuated*)q)->evacuee;
if (Bdescr((P_)p)->gen->no < evac_gen) {
if (Bdescr((P_)p)->gen_no < evac_gen) {
IF_DEBUG(gc, belch("@@ evacuate: evac of EVACUATED node %p failed!", p));
failed_to_evac = rtsTrue;
TICK_GC_FAILED_PROMOTION();
......@@ -2037,7 +2037,7 @@ scavenge(step *stp)
}
case IND_PERM:
if (stp->gen->no != 0) {
if (stp->gen_no != 0) {
SET_INFO(((StgClosure *)p), &stg_IND_OLDGEN_PERM_info);
}
/* fall through */
......@@ -2858,8 +2858,8 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
} else {
bdescr *bd = Bdescr((P_)frame->updatee);
step *stp;
if (bd->gen->no > N) {
if (bd->gen->no < evac_gen) {
if (bd->gen_no > N) {
if (bd->gen_no < evac_gen) {
failed_to_evac = rtsTrue;
}
continue;
......@@ -2867,7 +2867,7 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
/* Don't promote blackholes */
stp = bd->step;
if (!(stp->gen->no == 0 &&
if (!(stp->gen_no == 0 &&
stp->no != 0 &&
stp->no == stp->gen->n_steps-1)) {
stp = stp->to;
......
/* -----------------------------------------------------------------------------
* $Id: Storage.c,v 1.39 2001/07/19 07:28:00 andy Exp $
* $Id: Storage.c,v 1.40 2001/07/23 10:47:16 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -139,6 +139,7 @@ initStorage (void)
stp->blocks = NULL;
stp->n_blocks = 0;
stp->gen = &generations[g];
stp->gen_no = g;
stp->hp = NULL;
stp->hpLim = NULL;
stp->hp_bd = NULL;
......@@ -324,7 +325,7 @@ resetNurseries( void )
for (cap = free_capabilities; cap != NULL; cap = cap->link) {
for (bd = cap->rNursery; bd; bd = bd->link) {
bd->free = bd->start;
ASSERT(bd->gen == g0);
ASSERT(bd->gen_no == 0);
ASSERT(bd->step == g0s0);
IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
}
......@@ -333,7 +334,7 @@ resetNurseries( void )
#else
for (bd = g0s0->blocks; bd; bd = bd->link) {
bd->free = bd->start;
ASSERT(bd->gen == g0);
ASSERT(bd->gen_no == 0);
ASSERT(bd->step == g0s0);
IF_DEBUG(sanity,memset(bd->start, 0xaa, BLOCK_SIZE));
}
......@@ -353,7 +354,7 @@ allocNursery (bdescr *last_bd, nat blocks)
bd = allocBlock();
bd->link = last_bd;
bd->step = g0s0;
bd->gen = g0;
bd->gen_no = 0;
bd->evacuated = 0;
bd->free = bd->start;
last_bd = bd;
......@@ -422,7 +423,7 @@ allocate(nat n)
nat req_blocks = (lnat)BLOCK_ROUND_UP(n*sizeof(W_)) / BLOCK_SIZE;
bd = allocGroup(req_blocks);
dbl_link_onto(bd, &g0s0->large_objects);
bd->gen = g0;
bd->gen_no = 0;
bd->step = g0s0;
bd->evacuated = 0;
bd->free = bd->start;
......@@ -443,7 +444,7 @@ allocate(nat n)
bd = allocBlock();
bd->link = small_alloc_list;
small_alloc_list = bd;
bd->gen = g0;
bd->gen_no = 0;
bd->step = g0s0;
bd->evacuated = 0;
alloc_Hp = bd->start;
......
/* -----------------------------------------------------------------------------
* $Id: Storage.h,v 1.32 2001/05/03 16:33:27 simonmar Exp $
* $Id: Storage.h,v 1.33 2001/07/23 10:47:16 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -120,9 +120,9 @@ recordMutable(StgMutClosure *p)
#endif
bd = Bdescr((P_)p);
if (bd->gen->no > 0) {
p->mut_link = bd->gen->mut_list;
bd->gen->mut_list = p;
if (bd->gen_no > 0) {
p->mut_link = generations[bd->gen_no].mut_list;
generations[bd->gen_no].mut_list = p;
}
}
......@@ -132,9 +132,9 @@ recordOldToNewPtrs(StgMutClosure *p)
bdescr *bd;
bd = Bdescr((P_)p);
if (bd->gen->no > 0) {
p->mut_link = bd->gen->mut_once_list;
bd->gen->mut_once_list = p;
if (bd->gen_no > 0) {
p->mut_link = generations[bd->gen_no].mut_once_list;
generations[bd->gen_no].mut_once_list = p;
}
}
......@@ -144,7 +144,7 @@ recordOldToNewPtrs(StgMutClosure *p)
bdescr *bd; \
\
bd = Bdescr((P_)p1); \
if (bd->gen->no == 0) { \
if (bd->gen_no == 0) { \
((StgInd *)p1)->indirectee = p2; \
SET_INFO(p1,&stg_IND_info); \
TICK_UPD_NEW_IND(); \
......@@ -152,8 +152,8 @@ recordOldToNewPtrs(StgMutClosure *p)
((StgIndOldGen *)p1)->indirectee = p2; \
if (info != &stg_BLACKHOLE_BQ_info) { \
ACQUIRE_LOCK(&sm_mutex); \
((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list; \
bd->gen->mut_once_list = (StgMutClosure *)p1; \
((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1; \
RELEASE_LOCK(&sm_mutex); \
} \
SET_INFO(p1,&stg_IND_OLDGEN_info); \
......@@ -176,7 +176,7 @@ recordOldToNewPtrs(StgMutClosure *p)
\
ASSERT( p1 != p2 && !closure_IND(p1) ); \
bd = Bdescr((P_)p1); \
if (bd->gen->no == 0) { \
if (bd->gen_no == 0) { \
((StgInd *)p1)->indirectee = p2; \
SET_INFO(p1,&stg_IND_info); \
TICK_UPD_NEW_IND(); \
......@@ -193,8 +193,8 @@ recordOldToNewPtrs(StgMutClosure *p)
} \
} \
ACQUIRE_LOCK(&sm_mutex); \
((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list; \
bd->gen->mut_once_list = (StgMutClosure *)p1; \
((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1; \
RELEASE_LOCK(&sm_mutex); \
} \
((StgIndOldGen *)p1)->indirectee = p2; \
......@@ -229,7 +229,7 @@ updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *
ASSERT( p1 != p2 && !closure_IND(p1) );
bd = Bdescr((P_)p1);
if (bd->gen->no == 0) {
if (bd->gen_no == 0) {
((StgInd *)p1)->indirectee = p2;
SET_INFO(p1,&stg_IND_PERM_info);
TICK_UPD_NEW_PERM_IND(p1);
......@@ -237,8 +237,8 @@ updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *
((StgIndOldGen *)p1)->indirectee = p2;
if (info != &stg_BLACKHOLE_BQ_info) {
ACQUIRE_LOCK(&sm_mutex);
((StgIndOldGen *)p1)->mut_link = bd->gen->mut_once_list;
bd->gen->mut_once_list = (StgMutClosure *)p1;
((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list;
generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1;
RELEASE_LOCK(&sm_mutex);
}
SET_INFO(p1,&stg_IND_OLDGEN_PERM_info);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment