From: Nicholas Nethercote Date: Sun, 3 Jul 2005 17:53:11 +0000 (+0000) Subject: Changed m_hashtable.c to allow the size of the hash table to be specified X-Git-Tag: svn/VALGRIND_3_0_0~218 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e67b65d0eb5842d23bb79b058e45ed83d4a60a81;p=thirdparty%2Fvalgrind.git Changed m_hashtable.c to allow the size of the hash table to be specified when it is created. Fortunately this didn't affect code outside this module except for the calls to VG_(HT_construct)(). As a result, we save some memory because not all tables have to be as big as the ones needed for malloc/free tracking. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4100 --- diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 06dd4c9f42..d9f4c9f328 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -118,7 +118,7 @@ struct _fileCC { static fileCC *CC_table[N_FILE_ENTRIES]; //------------------------------------------------------------ -// Primary data structre #2: Instr-info table +// Primary data structure #2: Instr-info table // - Holds the cached info about each instr that is used for simulation. // - table(BB_start_addr, list(instr_info)) // - For each BB, each instr_info in the list holds info about the @@ -1160,11 +1160,11 @@ static void cg_pre_clo_init(void) VG_(sprintf)(cachegrind_out_file, "%s/cachegrind.out.%d", base_dir, VG_(getpid)()); - instr_info_table = VG_(HT_construct)(); + instr_info_table = VG_(HT_construct)( 4999 ); // prime, biggish } VG_DETERMINE_INTERFACE_VERSION(cg_pre_clo_init, 0) /*--------------------------------------------------------------------*/ -/*--- end cg_main.c ---*/ +/*--- end ---*/ /*--------------------------------------------------------------------*/ diff --git a/coregrind/m_hashtable.c b/coregrind/m_hashtable.c index 4e6a59924b..9c925fb1ae 100644 --- a/coregrind/m_hashtable.c +++ b/coregrind/m_hashtable.c @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------*/ -/*--- A separately chained hash table. m_hashtable.c ---*/ +/*--- A separately-chained hash table. m_hashtable.c ---*/ /*--------------------------------------------------------------------*/ /* @@ -37,19 +37,12 @@ /*--- Declarations ---*/ /*--------------------------------------------------------------------*/ -/* Holds malloc'd but not freed blocks. Static, so zero-inited by default. */ - -//#define VG_N_CHAINS 80021 /*4999*/ /* a prime number */ - #define CHAIN_NO(key,tbl) (((UWord)(key)) % tbl->n_chains) -struct { +struct _VgHashTable { UInt n_chains; // should be prime VgHashNode* chains[0]; -} -_VgHashTable; - -typedef (struct _VgHashTable *) VgHashTable; +}; /*--------------------------------------------------------------------*/ /*--- Functions ---*/ @@ -58,9 +51,10 @@ typedef (struct _VgHashTable *) VgHashTable; VgHashTable VG_(HT_construct)(UInt n_chains) { /* Initialises to zero, ie. all entries NULL */ - VgHashTable* table = - VG_(calloc)(sizeof(struct _VgHashTable) + n_chains*sizeof(VgHashNode*)); + SizeT sz = sizeof(struct _VgHashTable) + n_chains*sizeof(VgHashNode*); + VgHashTable table = VG_(calloc)(1, sz); table->n_chains = n_chains; + return table; } Int VG_(HT_count_nodes) ( VgHashTable table ) @@ -75,12 +69,13 @@ Int VG_(HT_count_nodes) ( VgHashTable table ) return n; } -/* Puts a new, heap allocated VgHashNode, into the malloclist. */ +/* Puts a new, heap allocated VgHashNode, into the VgHashTable. Prepends + the node to the appropriate chain. */ void VG_(HT_add_node) ( VgHashTable table, VgHashNode* node ) { - UInt chain = CHAIN_NO(node->key); - node->next = table->chains[chain]; - table[chain] = node; + UInt chain = CHAIN_NO(node->key, table); + node->next = table->chains[chain]; + table->chains[chain] = node; } /* Looks up a VgHashNode in the table. Also returns the address of @@ -92,7 +87,7 @@ VgHashNode* VG_(HT_get_node) ( VgHashTable table, UWord key, VgHashNode *prev, *curr; Int chain; - chain = CHAIN_NO(key); + chain = CHAIN_NO(key, table); prev = NULL; curr = table->chains[chain]; @@ -106,7 +101,7 @@ VgHashNode* VG_(HT_get_node) ( VgHashTable table, UWord key, } if (NULL == prev) - *next_ptr = & (table->chain[chain]); + *next_ptr = & (table->chains[chain]); else *next_ptr = & (prev->next); diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index 2b7bac80d2..889d1d8aab 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -3446,7 +3446,7 @@ static void hg_pre_clo_init(void) } init_shadow_memory(); - hg_malloc_list = VG_(HT_construct)(); + hg_malloc_list = VG_(HT_construct)( 80021 ); // prime, big } /* Uses a 1:1 mapping */ diff --git a/include/pub_tool_hashtable.h b/include/pub_tool_hashtable.h index d53f0d860d..6aa7efae55 100644 --- a/include/pub_tool_hashtable.h +++ b/include/pub_tool_hashtable.h @@ -36,8 +36,7 @@ as the first two fields match the sizes of these two fields. Requires a bit of casting by the tool. */ -// Problems with this type: -// - Table is fixed-size. +// Problems with this data structure: // - Separate chaining gives bad cache behaviour. Hash tables with linear // probing give better cache behaviour. // - It's not very abstract, eg. deleting nodes exposes more internals than @@ -50,13 +49,11 @@ typedef } VgHashNode; -typedef - VgHashNode** - VgHashTable; +typedef struct _VgHashTable * VgHashTable; /* Make a new table. Allocates the memory with VG_(calloc)(), so can be freed - * with VG_(free)(). */ -extern VgHashTable VG_(HT_construct) ( void ); + with VG_(free)(). n_chains should be prime. */ +extern VgHashTable VG_(HT_construct) ( UInt n_chains ); /* Count the number of nodes in a table. */ extern Int VG_(HT_count_nodes) ( VgHashTable table ); diff --git a/massif/ms_main.c b/massif/ms_main.c index 2877d14b0f..f436d0f625 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -1830,7 +1830,7 @@ static void ms_pre_clo_init() VG_(register_profile_event)(VgpPrintXPts, "print-XPts"); // HP_Chunks - malloc_list = VG_(HT_construct)(); + malloc_list = VG_(HT_construct)( 80021 ); // prime, big // Dummy node at top of the context structure. alloc_xpt = new_XPt(0, NULL, /*is_bottom*/False); diff --git a/memcheck/mac_malloc_wrappers.c b/memcheck/mac_malloc_wrappers.c index ae7635997e..003c6fa79b 100644 --- a/memcheck/mac_malloc_wrappers.c +++ b/memcheck/mac_malloc_wrappers.c @@ -441,7 +441,7 @@ void MAC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed) mp->pool = pool; mp->rzB = rzB; mp->is_zeroed = is_zeroed; - mp->chunks = VG_(HT_construct)(); + mp->chunks = VG_(HT_construct)( 3001 ); // prime, not so big /* Paranoia ... ensure this area is off-limits to the client, so the mp->data field isn't visible to the leak checker. If memory diff --git a/memcheck/mac_shared.c b/memcheck/mac_shared.c index 6c56ca2442..28e85794ff 100644 --- a/memcheck/mac_shared.c +++ b/memcheck/mac_shared.c @@ -899,8 +899,8 @@ static void done_prof_mem ( void ) { } void MAC_(common_pre_clo_init)(void) { - MAC_(malloc_list) = VG_(HT_construct)(); - MAC_(mempool_list) = VG_(HT_construct)(); + MAC_(malloc_list) = VG_(HT_construct)( 80021 ); // prime, big + MAC_(mempool_list) = VG_(HT_construct)( 1009 ); // prime, not so big init_prof_mem(); }