From: simonmar Date: Mon, 23 Jul 2001 10:47:16 +0000 (+0000) Subject: [project @ 2001-07-23 10:47:16 by simonmar] X-Git-Tag: Approximately_9120_patches~1484 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=6f83fbc0a8b201a3d2ad20e4d8c707613d45cf2a;p=ghc-hetmet.git [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. --- diff --git a/ghc/includes/Block.h b/ghc/includes/Block.h index bf21ba3..d6bfdfe 100644 --- a/ghc/includes/Block.h +++ b/ghc/includes/Block.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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 */ diff --git a/ghc/includes/StgStorage.h b/ghc/includes/StgStorage.h index a6c88f5..1b9c61a 100644 --- a/ghc/includes/StgStorage.h +++ b/ghc/includes/StgStorage.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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: */ diff --git a/ghc/rts/BlockAlloc.c b/ghc/rts/BlockAlloc.c index 6819463..e6a176b 100644 --- a/ghc/rts/BlockAlloc.c +++ b/ghc/rts/BlockAlloc.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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 diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 120f02a..3f7e5ec 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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; diff --git a/ghc/rts/Storage.c b/ghc/rts/Storage.c index b2f9593..aec6f7f 100644 --- a/ghc/rts/Storage.c +++ b/ghc/rts/Storage.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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; diff --git a/ghc/rts/Storage.h b/ghc/rts/Storage.h index 6bd9be2..e32d207 100644 --- a/ghc/rts/Storage.h +++ b/ghc/rts/Storage.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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);