diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-09-21 13:18:49 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-09-21 13:46:47 +0100 |
commit | 016fd74d6517512b62b36ff12cdccf2e723a0fb3 (patch) | |
tree | f5be8ca85dc2651ca63932b064f04baf9b7fe01f /rts/sm/GC.c | |
parent | 1f5d83648dfda39d999eb8a9e8192339b3eea540 (diff) | |
download | haskell-016fd74d6517512b62b36ff12cdccf2e723a0fb3.tar.gz |
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).
Diffstat (limited to 'rts/sm/GC.c')
-rw-r--r-- | rts/sm/GC.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 93606451cf..03c306857e 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -578,6 +578,7 @@ GarbageCollect (nat collect_gen, 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 @@ -589,13 +590,15 @@ GarbageCollect (nat collect_gen, 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; |