From 7dc0cd52f216da7a46c4832da0a68f2ec1f181f0 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Thu, 24 Jun 2010 10:57:00 +0000 Subject: [PATCH] Cast some more nats to StgWord to be on the safe side And add a comment about the dangers of int overflow --- rts/sm/BlockAlloc.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c index 484c0d4..ba9220a 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); -- 1.7.10.4