diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-10-05 14:47:35 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-10-05 14:47:35 +0000 |
commit | 4a05e6139d756c0473df7a6dcb257074201f843d (patch) | |
tree | fe856f1144746b96522f74e3002d794b58560c28 /rts/sm | |
parent | c4c2f7ecc229de0059018aebac1f6a444a382900 (diff) | |
download | haskell-4a05e6139d756c0473df7a6dcb257074201f843d.tar.gz |
Fix a very rare crash in GHCi
When a BCO with a zero-length bitmap was right at the edge of
allocated memory, we were reading a word of non-existent memory.
This showed up as a segfault in T789(ghci) for me, but the crash was
extremely sensitive and went away with most changes.
Also, optimised scavenge_large_bitmap a bit while I was in there.
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/Scav.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c index e59fc754f3..d01442b34e 100644 --- a/rts/sm/Scav.c +++ b/rts/sm/Scav.c @@ -1534,23 +1534,21 @@ scavenge_static(void) static void scavenge_large_bitmap( StgPtr p, StgLargeBitmap *large_bitmap, nat size ) { - nat i, b; + nat i, j, b; StgWord bitmap; b = 0; - bitmap = large_bitmap->bitmap[b]; - for (i = 0; i < size; ) { - if ((bitmap & 1) == 0) { - evacuate((StgClosure **)p); - } - i++; - p++; - if (i % BITS_IN(W_) == 0) { - b++; - bitmap = large_bitmap->bitmap[b]; - } else { + + for (i = 0; i < size; b++) { + bitmap = large_bitmap->bitmap[b]; + j = stg_min(size-i, BITS_IN(W_)); + i += j; + for (; j > 0; j--, p++) { + if ((bitmap & 1) == 0) { + evacuate((StgClosure **)p); + } bitmap = bitmap >> 1; - } + } } } |