summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-06-24 10:57:00 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-06-24 10:57:00 +0000
commit7dc0cd52f216da7a46c4832da0a68f2ec1f181f0 (patch)
tree8640ab3ad295eebab2021533a57ef4a86c28a777 /rts
parent897231aa5f150bfb11d1715b2dc5c9ac32be4af6 (diff)
downloadhaskell-7dc0cd52f216da7a46c4832da0a68f2ec1f181f0.tar.gz
Cast some more nats to StgWord to be on the safe side
And add a comment about the dangers of int overflow
Diffstat (limited to 'rts')
-rw-r--r--rts/sm/BlockAlloc.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c
index 484c0d4475..ba9220ac42 100644
--- a/rts/sm/BlockAlloc.c
+++ b/rts/sm/BlockAlloc.c
@@ -118,6 +118,16 @@ static void initMBlock(void *mblock);
--------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------
+ WATCH OUT FOR OVERFLOW
+
+ Be very careful with integer overflow here. If you have an
+ expression like (n_blocks * BLOCK_SIZE), and n_blocks is an int or
+ a nat, then it will very likely overflow on a 64-bit platform.
+ Always cast to StgWord (or W_ for short) first: ((W_)n_blocks * BLOCK_SIZE).
+
+ --------------------------------------------------------------------------- */
+
#define MAX_FREE_LIST 9
// In THREADED_RTS mode, the free list is protected by sm_mutex.
@@ -337,7 +347,7 @@ allocGroup (nat n)
if (ln == MAX_FREE_LIST) {
#if 0
- if ((mblocks_allocated * MBLOCK_SIZE_W - n_alloc_blocks * BLOCK_SIZE_W) > (1024*1024)/sizeof(W_)) {
+ if (((W_)mblocks_allocated * MBLOCK_SIZE_W - (W_)n_alloc_blocks * BLOCK_SIZE_W) > (1024*1024)/sizeof(W_)) {
debugBelch("Fragmentation, wanted %d blocks:", n);
RtsFlags.DebugFlags.block_alloc = 1;
checkFreeListSanity();
@@ -472,7 +482,7 @@ freeGroup(bdescr *p)
p->gen = NULL;
p->gen_no = 0;
/* fill the block group with garbage if sanity checking is on */
- IF_DEBUG(sanity,memset(p->start, 0xaa, p->blocks * BLOCK_SIZE));
+ IF_DEBUG(sanity,memset(p->start, 0xaa, (W_)p->blocks * BLOCK_SIZE));
if (p->blocks == 0) barf("freeGroup: block size is zero");
@@ -586,7 +596,7 @@ splitBlockGroup (bdescr *bd, nat blocks)
low_mblocks = 1 + (blocks - BLOCKS_PER_MBLOCK) / (MBLOCK_SIZE / BLOCK_SIZE);
high_mblocks = (bd->blocks - blocks) / (MBLOCK_SIZE / BLOCK_SIZE);
- new_mblock = (void *) ((P_)MBLOCK_ROUND_DOWN(bd) + low_mblocks * MBLOCK_SIZE_W);
+ new_mblock = (void *) ((P_)MBLOCK_ROUND_DOWN(bd) + (W_)low_mblocks * MBLOCK_SIZE_W);
initMBlock(new_mblock);
new_bd = FIRST_BDESCR(new_mblock);
new_bd->blocks = MBLOCK_GROUP_BLOCKS(high_mblocks);