diff --git a/callgrind/bbcc.c b/callgrind/bbcc.c index 9b08923d3..ff277923c 100644 --- a/callgrind/bbcc.c +++ b/callgrind/bbcc.c @@ -33,7 +33,7 @@ /*--- BBCC operations ---*/ /*------------------------------------------------------------*/ -#define N_BBCC_INITIAL_ENTRIES 10437 +#define N_BBCC_INITIAL_ENTRIES 16384 /* BBCC table (key is BB/Context), per thread, resizable */ bbcc_hash current_bbccs; @@ -147,7 +147,11 @@ UInt bbcc_hash_idx(BB* bb, Context* cxt, UInt size) CLG_ASSERT(bb != 0); CLG_ASSERT(cxt != 0); - return ((Addr)bb + (Addr)cxt) % size; + /* Use bit mixing instead of modular division for power-of-2 table sizes. + * Shift right to discard alignment zeros from heap pointers, use + * different shift amounts for bb and cxt to avoid cancellation on XOR. */ + UWord h = ((UWord)bb >> 4) ^ ((UWord)cxt >> 3); + return CLG_(hash_final)(h, size); } @@ -197,7 +201,7 @@ static void resize_bbcc_hash(void) UInt new_idx; BBCC *curr_BBCC, *next_BBCC; - new_size = 2*current_bbccs.size+3; + new_size = 2*current_bbccs.size; new_table = (BBCC**) CLG_MALLOC("cl.bbcc.rbh.1", new_size * sizeof(BBCC*)); diff --git a/callgrind/context.c b/callgrind/context.c index 55be82028..c5caaad1d 100644 --- a/callgrind/context.c +++ b/callgrind/context.c @@ -32,7 +32,7 @@ /*------------------------------------------------------------*/ #define N_FNSTACK_INITIAL_ENTRIES 500 -#define N_CXT_INITIAL_ENTRIES 2537 +#define N_CXT_INITIAL_ENTRIES 4096 fn_stack CLG_(current_fn_stack); @@ -87,7 +87,7 @@ static void resize_cxt_table(void) Context **new_table, *curr, *next; UInt new_idx; - new_size = 2* cxts.size +3; + new_size = 2* cxts.size; new_table = (Context**) CLG_MALLOC("cl.context.rct.1", new_size * sizeof(Context*)); @@ -101,7 +101,7 @@ static void resize_cxt_table(void) while (NULL != curr) { next = curr->next; - new_idx = (UInt) (curr->hash % new_size); + new_idx = (UInt) (curr->hash & (new_size - 1)); curr->next = new_table[new_idx]; new_table[new_idx] = curr; @@ -208,7 +208,7 @@ static Context* new_cxt(fn_node** fn) CLG_(stat).distinct_contexts++; /* insert into Context hash table */ - idx = (UInt) (hash % cxts.size); + idx = (UInt) (hash & (cxts.size - 1)); cxt->next = cxts.table[idx]; cxts.table[idx] = cxt; @@ -246,7 +246,7 @@ Context* CLG_(get_cxt)(fn_node** fn) CLG_(stat).cxt_lru_misses++; - idx = (UInt) (hash % cxts.size); + idx = (UInt) (hash & (cxts.size - 1)); cxt = cxts.table[idx]; while(cxt) { diff --git a/callgrind/global.h b/callgrind/global.h index 10d4c53b1..87c91ef2d 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -719,6 +719,13 @@ bb_hash* CLG_(get_bb_hash)(void); BB* CLG_(get_bb)(Addr addr, IRSB* bb_in, Bool *seen_before); void CLG_(delete_bb)(Addr addr); +/* Finalize a hash value for a power-of-2 sized table: fold the upper bits + * down for better distribution in the low bits, then mask to the table size. + * 'size' must be a power of 2. Shared by the callgrind hash tables. */ +static __inline__ UInt CLG_(hash_final)(UWord h, UInt size) + { h ^= h >> 16; + return (UInt)h & (size - 1); } + static __inline__ Addr bb_addr(BB* bb) { return bb->offset + bb->obj->offset; } static __inline__ Addr bb_jmpaddr(BB* bb) diff --git a/callgrind/jumps.c b/callgrind/jumps.c index c98806255..b6020d708 100644 --- a/callgrind/jumps.c +++ b/callgrind/jumps.c @@ -30,7 +30,7 @@ /*--- Jump Cost Center (JCC) operations, including Calls ---*/ /*------------------------------------------------------------*/ -#define N_JCC_INITIAL_ENTRIES 4437 +#define N_JCC_INITIAL_ENTRIES 8192 static jcc_hash current_jccs; @@ -77,7 +77,10 @@ void CLG_(set_current_jcc_hash)(jcc_hash* h) __inline__ static UInt jcc_hash_idx(BBCC* from, UInt jmp, BBCC* to, UInt size) { - return (UInt) ( (UWord)from + 7* (UWord)to + 13*jmp) % size; + /* Use bit mixing instead of modular division for power-of-2 table sizes. + * Shift right to discard alignment zeros from heap pointers. */ + UWord h = ((UWord)from >> 4) + 7 * ((UWord)to >> 4) + 13 * jmp; + return CLG_(hash_final)(h, size); } /* double size of jcc table */ @@ -88,7 +91,7 @@ static void resize_jcc_table(void) UInt new_idx; jCC *curr_jcc, *next_jcc; - new_size = 2* current_jccs.size +3; + new_size = 2* current_jccs.size; new_table = (jCC**) CLG_MALLOC("cl.jumps.rjt.1", new_size * sizeof(jCC*));