[project @ 2001-07-23 10:47:16 by simonmar]
authorsimonmar <unknown>
Mon, 23 Jul 2001 10:47:16 +0000 (10:47 +0000)
committersimonmar <unknown>
Mon, 23 Jul 2001 10:47:16 +0000 (10:47 +0000)
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.

ghc/includes/Block.h
ghc/includes/StgStorage.h
ghc/rts/BlockAlloc.c
ghc/rts/GC.c
ghc/rts/Storage.c
ghc/rts/Storage.h

index bf21ba3..d6bfdfe 100644 (file)
@@ -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 */
index a6c88f5..1b9c61a 100644 (file)
@@ -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: */
index 6819463..e6a176b 100644 (file)
@@ -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
index 120f02a..3f7e5ec 100644 (file)
@@ -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;
index b2f9593..aec6f7f 100644 (file)
@@ -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;
index 6bd9be2..e32d207 100644 (file)
@@ -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);