summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-10-05 14:47:35 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-10-05 14:47:35 +0000
commit4a05e6139d756c0473df7a6dcb257074201f843d (patch)
treefe856f1144746b96522f74e3002d794b58560c28 /rts/sm
parentc4c2f7ecc229de0059018aebac1f6a444a382900 (diff)
downloadhaskell-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.c24
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;
- }
+ }
}
}