[commit: ghc] ghc-7.6: Cache the result of countOccupied(gen->large_objects) as gen->n_large_words (#7257) (1596107)

Paolo Capriotti <[email protected]>
Newsgroups gmane.comp.lang.haskell.cvs.ghc
Message-ID <[email protected]>
Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : ghc-7.6

http://hackage.haskell.org/trac/ghc/changeset/1596107f9cfc877cef4485f035417723cf1e9d97

>---------------------------------------------------------------

commit 1596107f9cfc877cef4485f035417723cf1e9d97
Author: Simon Marlow <[email protected]>
Date:   Fri Sep 21 13:18:49 2012 +0100

    Cache the result of countOccupied(gen->large_objects) as gen->n_large_words (#7257)
    
    The program in #7257 was spending 90% of its time counting the live
    data in gen->large_objects.  We already avoid doing this for small
    objects, but in this example the old generation was full of large
    objects (actually pinned ByteStrings).
    
    MERGED from commit 016fd74d6517512b62b36ff12cdccf2e723a0fb3

>---------------------------------------------------------------

 includes/rts/storage/GC.h |    1 +
 rts/sm/GC.c               |    5 ++++-
 rts/sm/Storage.c          |    3 ++-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index fadaa8c..a5f4ed6 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -75,6 +75,7 @@ typedef struct generation_ {
 
     bdescr *       large_objects;	// large objects (doubly linked)
     memcount       n_large_blocks;      // no. of blocks used by large objs
+    memcount       n_large_words;       // no. of words used by large objs
     memcount       n_new_large_words;   // words of new large objects
                                         // (for allocation stats)
 
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 21b80ea..fa44be2 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -572,6 +572,7 @@ GarbageCollect (rtsBool force_major_gc,
         freeChain(gen->large_objects);
         gen->large_objects  = gen->scavenged_large_objects;
         gen->n_large_blocks = gen->n_scavenged_large_blocks;
+        gen->n_large_words  = countOccupied(gen->large_objects);
         gen->n_new_large_words = 0;
     }
     else // for generations > N
@@ -583,13 +584,15 @@ GarbageCollect (rtsBool force_major_gc,
 	for (bd = gen->scavenged_large_objects; bd; bd = next) {
             next = bd->link;
             dbl_link_onto(bd, &gen->large_objects);
-	}
+            gen->n_large_words += bd->free - bd->start;
+        }
         
 	// add the new blocks we promoted during this GC 
 	gen->n_large_blocks += gen->n_scavenged_large_blocks;
     }
 
     ASSERT(countBlocks(gen->large_objects) == gen->n_large_blocks);
+    ASSERT(countOccupied(gen->large_objects) == gen->n_large_words);
 
     gen->scavenged_large_objects = NULL;
     gen->n_scavenged_large_blocks = 0;
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index f645cd4..a07a872 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -78,6 +78,7 @@ initGeneration (generation *gen, int g)
     gen->n_old_blocks = 0;
     gen->large_objects = NULL;
     gen->n_large_blocks = 0;
+    gen->n_large_words = 0;
     gen->n_new_large_words = 0;
     gen->scavenged_large_objects = NULL;
     gen->n_scavenged_large_blocks = 0;
@@ -947,7 +948,7 @@ W_ countOccupied (bdescr *bd)
 
 W_ genLiveWords (generation *gen)
 {
-    return gen->n_words + countOccupied(gen->large_objects);
+    return gen->n_words + gen->n_large_words;
 }
 
 W_ genLiveBlocks (generation *gen)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.