summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-05-24 16:56:23 +0100
committerSimon Marlow <marlowsd@gmail.com>2011-05-25 08:49:17 +0100
commitaf9e96991659185821632ff96383480c9dc9cbda (patch)
tree7918e80cbdbdc15a18c05abca941961b50ecc978
parent18a0ead12b605fd20c13f5255d78cfbf699fe0c4 (diff)
downloadhaskell-af9e96991659185821632ff96383480c9dc9cbda.tar.gz
fix an integer overflow (#5086), and pre-emptively avoid more of these
in the future.
-rw-r--r--includes/rts/storage/GC.h26
-rw-r--r--rts/Stats.c2
-rw-r--r--rts/sm/GC.c2
3 files changed, 19 insertions, 11 deletions
diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index bbed2165a2..3c6e6f6e26 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -53,24 +53,32 @@
*
* ------------------------------------------------------------------------- */
+// A count of blocks needs to store anything up to the size of memory
+// divided by the block size. The safest thing is therefore to use a
+// type that can store the full range of memory addresses,
+// ie. StgWord. Note that we have had some tricky int overflows in a
+// couple of cases caused by using ints rather than longs (e.g. #5086)
+
+typedef StgWord memcount;
+
typedef struct nursery_ {
bdescr * blocks;
- unsigned int n_blocks;
+ memcount n_blocks;
} nursery;
typedef struct generation_ {
unsigned int no; // generation number
bdescr * blocks; // blocks in this gen
- unsigned int n_blocks; // number of blocks
- unsigned int n_words; // number of used words
+ memcount n_blocks; // number of blocks
+ memcount n_words; // number of used words
bdescr * large_objects; // large objects (doubly linked)
- unsigned int n_large_blocks; // no. of blocks used by large objs
- unsigned long n_new_large_words; // words of new large objects
+ memcount n_large_blocks; // no. of blocks used by large objs
+ memcount n_new_large_words; // words of new large objects
// (for allocation stats)
- unsigned int max_blocks; // max blocks
+ memcount max_blocks; // max blocks
StgTSO * threads; // threads in this gen
// linked via global_link
@@ -98,11 +106,11 @@ typedef struct generation_ {
// are copied into the following two fields. After GC, these blocks
// are freed.
bdescr * old_blocks; // bdescr of first from-space block
- unsigned int n_old_blocks; // number of blocks in from-space
- unsigned int live_estimate; // for sweeping: estimate of live data
+ memcount n_old_blocks; // number of blocks in from-space
+ memcount live_estimate; // for sweeping: estimate of live data
bdescr * scavenged_large_objects; // live large objs after GC (d-link)
- unsigned int n_scavenged_large_blocks; // size (not count) of above
+ memcount n_scavenged_large_blocks; // size (not count) of above
bdescr * bitmap; // bitmap for compacting collection
diff --git a/rts/Stats.c b/rts/Stats.c
index 3036ed7265..8366bf47b2 100644
--- a/rts/Stats.c
+++ b/rts/Stats.c
@@ -817,7 +817,7 @@ statDescribeGens(void)
gen_blocks += gcThreadLiveBlocks(i,g);
}
- debugBelch("%5d %7d %9d", g, gen->max_blocks, mut);
+ debugBelch("%5d %7ld %9d", g, (lnat)gen->max_blocks, mut);
gen_slop = gen_blocks * BLOCK_SIZE_W - gen_live;
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index fb73180d0f..51eab4e2be 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -1247,7 +1247,7 @@ prepare_collected_gen (generation *gen)
// for a compacted generation, we need to allocate the bitmap
if (gen->mark) {
- nat bitmap_size; // in bytes
+ lnat bitmap_size; // in bytes
bdescr *bitmap_bdescr;
StgWord *bitmap;