diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2020-03-10 16:44:03 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-11 08:20:27 -0400 |
commit | 3aa9b35fcc417ab39d8da633482fe64dc9f898b1 (patch) | |
tree | 95014bf686a263a34349092f3c7b1e5a82de0570 /rts/sm/Compact.c | |
parent | c61b9b02925acf248cde1ec0f67730c1a6f6c6e5 (diff) | |
download | haskell-3aa9b35fcc417ab39d8da633482fe64dc9f898b1.tar.gz |
Zero any slop after compaction in compacting GC
In copying GC, with the relevant debug flags enabled, we release the old
blocks after a GC, and the block allocator zeroes the space before
releasing a block. This effectively zeros the old heap.
In compacting GC we reuse the blocks and previously we didn't zero the
unused space in a compacting generation after compaction. With this
patch we zero the slop between the free pointer and the end of the block
when we're done with compaction and when switching to a new block
(because the current block doesn't have enough space for the next object
we're shifting).
Diffstat (limited to 'rts/sm/Compact.c')
-rw-r--r-- | rts/sm/Compact.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c index 1193fd765c..fee9cf02fa 100644 --- a/rts/sm/Compact.c +++ b/rts/sm/Compact.c @@ -829,18 +829,27 @@ update_bkwd_compact( generation *gen ) for (; bd != NULL; bd = bd->link) { P_ p = bd->start; - while (p < bd->free ) { + while (p < bd->free) { - while ( p < bd->free && !is_marked(p,bd) ) { + while (p < bd->free && !is_marked(p,bd)) { p++; } + if (p >= bd->free) { break; } if (is_marked(p+1,bd)) { - // don't forget to update the free ptr in the block desc. + // Don't forget to update the free ptr in the block desc free_bd->free = free; + + // Zero the remaining bytes of this block before moving on to + // the next block + IF_DEBUG(zero_on_gc, { + memset(free_bd->free, 0xaa, + BLOCK_SIZE - ((W_)(free_bd->free - free_bd->start) * sizeof(W_))); + }); + free_bd = free_bd->link; free = free_bd->start; free_blocks++; @@ -867,13 +876,21 @@ update_bkwd_compact( generation *gen ) } } - // free the remaining blocks and count what's left. + // Free the remaining blocks and count what's left. free_bd->free = free; if (free_bd->link != NULL) { freeChain(free_bd->link); free_bd->link = NULL; } + // Zero the free bits of the last used block. + IF_DEBUG(zero_on_gc, { + W_ block_size_bytes = free_bd->blocks * BLOCK_SIZE; + W_ block_in_use_bytes = (free_bd->free - free_bd->start) * sizeof(W_); + W_ block_free_bytes = block_size_bytes - block_in_use_bytes; + memset(free_bd->free, 0xaa, block_free_bytes); + }); + return free_blocks; } |