From c5848e6dddaabc8e43313f44e1058ed059bee005 Mon Sep 17 00:00:00 2001
From: Ben Gamari <ben@smart-cactus.org>
Date: Thu, 29 Nov 2018 14:05:35 -0500
Subject: [PATCH] Drop bdescr.gen

It's ultimately just a much less space-efficient encoding of bdescr.gen_no.
---
 includes/rts/storage/Block.h | 6 ++----
 includes/rts/storage/GC.h    | 1 -
 rts/Arena.c                  | 1 -
 rts/Schedule.c               | 2 +-
 rts/sm/BlockAlloc.c          | 2 --
 rts/sm/CNF.c                 | 4 ++--
 rts/sm/Evac.c                | 4 ++--
 rts/sm/GC.c                  | 1 -
 rts/sm/GCUtils.c             | 4 ++--
 rts/sm/MarkWeak.c            | 4 ++--
 rts/sm/NonMovingMark.c       | 8 ++++----
 rts/sm/NonMovingSweep.c      | 2 +-
 rts/sm/Sanity.c              | 2 +-
 rts/sm/Scav.c                | 2 +-
 rts/sm/Storage.c             | 1 -
 15 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/includes/rts/storage/Block.h b/includes/rts/storage/Block.h
index d6b440d862bf..d46e8e6282d3 100644
--- a/includes/rts/storage/Block.h
+++ b/includes/rts/storage/Block.h
@@ -112,8 +112,6 @@ typedef struct bdescr_ {
         StgPtr  scan;          // scan pointer for copying GC
     } u;
 
-    struct generation_ *gen;   // generation
-
     StgWord16 gen_no;          // gen->no, cached
     StgWord16 dest_no;         // number of destination generation
     StgWord16 node;            // which memory node does this block live on?
@@ -124,9 +122,9 @@ typedef struct bdescr_ {
                                // (if group head, 0 otherwise)
 
 #if SIZEOF_VOID_P == 8
-    StgWord32 _padding[5];
+    StgWord32 _padding[7];
 #else
-    StgWord32 _padding[1];
+    StgWord32 _padding[2];
 #endif
 } bdescr;
 #endif
diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index 793143301986..45e5142ba5e8 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -244,7 +244,6 @@ extern bool keepCAFs;
 
 INLINE_HEADER void initBdescr(bdescr *bd, generation *gen, generation *dest)
 {
-    bd->gen     = gen;
     bd->gen_no  = gen->no;
     bd->dest_no = dest->no;
 
diff --git a/rts/Arena.c b/rts/Arena.c
index 799106981a4d..7435c44307fc 100644
--- a/rts/Arena.c
+++ b/rts/Arena.c
@@ -85,7 +85,6 @@ arenaAlloc( Arena *arena, size_t size )
         arena_blocks += req_blocks;
 
         bd->gen_no  = 0;
-        bd->gen     = NULL;
         bd->dest_no = 0;
         bd->flags   = 0;
         bd->free    = bdescr_start(bd);
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 77aca0072af0..fc081a6c8f3d 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -3140,7 +3140,7 @@ resurrectThreads (StgTSO *threads)
     for (tso = threads; tso != END_TSO_QUEUE; tso = next) {
         next = tso->global_link;
 
-        gen = Bdescr((P_)tso)->gen;
+        gen = &generations[Bdescr((P_)tso)->gen_no];
         tso->global_link = gen->threads;
         gen->threads = tso;
 
diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c
index bc60d2969eef..37a517f285fa 100644
--- a/rts/sm/BlockAlloc.c
+++ b/rts/sm/BlockAlloc.c
@@ -56,7 +56,6 @@ static void  initMBlock(void *mblock, uint32_t node);
    The following fields are not used by the allocator:
      bd->flags
      bd->gen_no
-     bd->gen
      bd->dest
 
   Exceptions: we don't maintain invariants for all the blocks within a
@@ -792,7 +791,6 @@ freeGroup(bdescr *p)
   node = p->node;
 
   p->free = (void *)-1;  /* indicates that this block is free */
-  p->gen = NULL;
   p->gen_no = 0;
   /* fill the block group with garbage if sanity checking is on */
   IF_DEBUG(zero_on_gc, memset(bdescr_start(p), 0xaa, (W_)p->blocks * BLOCK_SIZE));
diff --git a/rts/sm/CNF.c b/rts/sm/CNF.c
index c15b1cfc978f..8b66dabce8c5 100644
--- a/rts/sm/CNF.c
+++ b/rts/sm/CNF.c
@@ -194,7 +194,7 @@ compactAllocateBlockInternal(Capability            *cap,
     // wrong and crash in Sanity)
     if (first != NULL) {
         block = Bdescr((P_)first);
-        g = block->gen;
+        g = &generations[block->gen_no];
     } else {
         g = g0;
     }
@@ -1172,7 +1172,7 @@ compactFixupPointers(StgCompactNFData *str,
     total_blocks = str->totalW / BLOCK_SIZE_W;
 
     ACQUIRE_SM_LOCK;
-    ASSERT(bd->gen == g0);
+    ASSERT(bd->gen_no == 0);
     ASSERT(g0->n_compact_blocks_in_import >= total_blocks);
     g0->n_compact_blocks_in_import -= total_blocks;
     g0->n_compact_blocks += total_blocks;
diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c
index 71bd59dea800..99b95203562e 100644
--- a/rts/sm/Evac.c
+++ b/rts/sm/Evac.c
@@ -307,8 +307,8 @@ evacuate_large(StgPtr p)
   gen_workspace *ws;
 
   bd = Bdescr(p);
-  gen = bd->gen;
   gen_no = bd->gen_no;
+  gen = &generations[gen_no];
   ACQUIRE_SPIN_LOCK(&gen->sync);
 
   // already evacuated?
@@ -458,7 +458,7 @@ evacuate_compact (StgPtr p)
         return;
     }
 
-    gen = bd->gen;
+    gen = &generations[gen_no];
     ACQUIRE_SPIN_LOCK(&gen->sync);
 
     // already evacuated?
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 40a6d4d0b3b2..0c150ec26058 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -1642,7 +1642,6 @@ collect_pinned_object_blocks (void)
             // Mark objects as belonging to the nonmoving heap
             for (bdescr *bd = capabilities[n]->pinned_object_blocks; bd != NULL; bd = bd->link) {
                 bd->flags |= BF_NONMOVING;
-                bd->gen = oldest_gen;
                 bd->gen_no = oldest_gen->no;
                 oldest_gen->n_large_words += bd->free - bdescr_start(bd);
                 oldest_gen->n_large_blocks += bd->blocks;
diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c
index 918bc3469102..58f7ff7c9f0a 100644
--- a/rts/sm/GCUtils.c
+++ b/rts/sm/GCUtils.c
@@ -141,7 +141,7 @@ push_scanned_block (bdescr *bd, gen_workspace *ws)
 {
     ASSERT(bd != NULL);
     ASSERT(bd->link == NULL);
-    ASSERT(bd->gen == ws->gen);
+    ASSERT(bd->gen_no == ws->gen->no);
     ASSERT(bd->u.scan == bd->free);
 
     if (bd->blocks == 1 &&
@@ -212,7 +212,7 @@ todo_block_full (uint32_t size, gen_workspace *ws)
 
     ASSERT(bd != NULL);
     ASSERT(bd->link == NULL);
-    ASSERT(bd->gen == ws->gen);
+    ASSERT(bd->gen_no == ws->gen->no);
 
     // We intentionally set ws->todo_lim lower than the full size of
     // the block, so that we can push out some work to the global list
diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c
index 7475b5e6256d..c2e9ec260174 100644
--- a/rts/sm/MarkWeak.c
+++ b/rts/sm/MarkWeak.c
@@ -264,7 +264,7 @@ static bool tidyWeakList(generation *gen)
                 // Find out which generation this weak ptr is in, and
                 // move it onto the weak ptr list of that generation.
 
-                new_gen = Bdescr((P_)w)->gen;
+                new_gen = &generations[Bdescr((P_)w)->gen_no];
                 gct->evac_gen_no = new_gen->no;
                 gct->failed_to_evac = false;
 
@@ -351,7 +351,7 @@ static void tidyThreadList (generation *gen)
 
             // move this thread onto the correct threads list.
             generation *new_gen;
-            new_gen = Bdescr((P_)t)->gen;
+            new_gen = &generations[Bdescr((P_)t)->gen_no];
             t->global_link = new_gen->threads;
             new_gen->threads  = t;
         }
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index f07c8df84981..a8491eb646a0 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -481,7 +481,7 @@ void push_closure (MarkQueue *q,
                    StgClosure **origin)
 {
 #if defined(DEBUG)
-    ASSERT(!HEAP_ALLOCED_GC(p) || (Bdescr((StgPtr) p)->gen == oldest_gen));
+    ASSERT(!HEAP_ALLOCED_GC(p) || (&generations[Bdescr((StgPtr) p)->gen_no] == oldest_gen));
     ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
     // Commenting out: too slow
     // if (RtsFlags.DebugFlags.sanity) {
@@ -511,7 +511,7 @@ void push_array (MarkQueue *q,
                  StgWord start_index)
 {
     // TODO: Push this into callers where they already have the Bdescr
-    if (HEAP_ALLOCED_GC(array) && (Bdescr((StgPtr) array)->gen != oldest_gen))
+    if (HEAP_ALLOCED_GC(array) && (&generations[Bdescr((StgPtr) array)->gen_no] != oldest_gen))
         return;
 
     MarkQueueEnt ent = {
@@ -663,7 +663,7 @@ STATIC_INLINE bool needs_upd_rem_set_mark(StgClosure *p)
 {
     // TODO: Deduplicate with mark_closure
     bdescr *bd = Bdescr((StgPtr) p);
-    if (bd->gen != oldest_gen) {
+    if (&generations[bd->gen_no] != oldest_gen) {
         return false;
     } else if (bd->flags & BF_LARGE) {
         if (! (bd->flags & BF_NONMOVING_SWEEPING)) {
@@ -1249,7 +1249,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin)
 
     bd = Bdescr((StgPtr) p);
 
-    if (bd->gen != oldest_gen) {
+    if (&generations[bd->gen_no] != oldest_gen) {
         // Here we have an object living outside of the non-moving heap. While
         // we likely evacuated nearly everything to the nonmoving heap during
         // preparation there are nevertheless a few ways in which we might trace
diff --git a/rts/sm/NonMovingSweep.c b/rts/sm/NonMovingSweep.c
index 20b2f6b9a847..190ebe722956 100644
--- a/rts/sm/NonMovingSweep.c
+++ b/rts/sm/NonMovingSweep.c
@@ -166,7 +166,7 @@ static bool is_closure_clean(StgClosure *p)
 {
     const StgInfoTable *info = get_itbl(p);
 
-#define CLEAN(ptr) (!HEAP_ALLOCED((StgClosure*) ptr) || Bdescr((StgPtr) ptr)->gen == oldest_gen)
+#define CLEAN(ptr) (!HEAP_ALLOCED((StgClosure*) ptr) || &generations[Bdescr((StgPtr) ptr)->gen_no] == oldest_gen)
 
     switch (info->type) {
     case MVAR_CLEAN:
diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c
index ce179d86a351..87eb53f43926 100644
--- a/rts/sm/Sanity.c
+++ b/rts/sm/Sanity.c
@@ -792,7 +792,7 @@ checkNurserySanity (nursery *nursery)
 
     prev = NULL;
     for (bd = nursery->blocks; bd != NULL; bd = bd->link) {
-        ASSERT(bd->gen == g0);
+        ASSERT(bd->gen_no == 0);
         ASSERT(bd->u.back == prev);
         prev = bd;
         blocks += bd->blocks;
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
index 5fbf4fd70e2b..3293adaf6adc 100644
--- a/rts/sm/Scav.c
+++ b/rts/sm/Scav.c
@@ -434,7 +434,7 @@ scavenge_block (bdescr *bd)
   saved_eager_promotion = gct->eager_promotion;
   gct->failed_to_evac = false;
 
-  ws = &gct->gens[bd->gen->no];
+  ws = &gct->gens[bd->gen_no];
 
   p = bd->u.scan;
 
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 2ecab78b5b16..a077529acc39 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -744,7 +744,6 @@ resetNurseries (void)
     for (n = 0; n < n_nurseries; n++) {
         for (bd = nurseries[n].blocks; bd; bd = bd->link) {
             ASSERT(bd->gen_no == 0);
-            ASSERT(bd->gen == g0);
             ASSERT(bd->node == capNoToNumaNode(n));
             IF_DEBUG(zero_on_gc, memset(bdescr_start(bd), 0xaa, BLOCK_SIZE));
         }
-- 
GitLab