http://sourceware.org/ml/gdb-patches/2014-10/msg00524.html Subject: [patch 1/2] Accelerate iter_match_first_hashed 1.8x --17pEHd4RhPHOinZp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, very simple caching. dict_hash() is being called again and again for the same string. #0 in skip_spaces_const (chp=0x7fffb10f9bb6 "ts, std::allocator >::npos") at ./cli/cli-utils.c:244 #1 in msymbol_hash_iw (string=0x7fffb10f9bb6 "ts, std::allocator >::npos") at minsyms.c:89 #2 in dict_hash ( string0=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos") at dictionary.c:840 #3 in iter_match_first_hashed (dict=0x105a7840, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", compare=0x8b82f8 , iterator=0x7fffb10f9970) at dictionary.c:659 #4 in dict_iter_match_first (dict=0x105a7840, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", compare=0x8b82f8 , iterator=0x7fffb10f9970) at dictionary.c:555 #5 in dict_iter_name_first (dict=0x105a7840, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", iterator=0x7fffb10f9970) at dictionary.c:541 #6 in block_iter_name_step (iterator=0x7fffb10f9960, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", first=1) at block.c:580 #7 in block_iter_name_first (block=0x10593e10, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", iterator=0x7fffb10f9960) at block.c:609 #8 in lookup_block_symbol (block=0x10593e10, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", domain=VAR_DOMAIN) at symtab.c:2062 #9 in lookup_symbol_aux_objfile (objfile=0x466f870, block_index=0, name=0x7fffb10f9b90 "std::basic_string, std::allocator >::npos", domain=VAR_DOMAIN) at symtab.c:1664 #10 in lookup_symbol_global_iterator_cb (objfile=0x466f870, cb_data=0x7fffb10f9ad0) at symtab.c:1868 Maybe it could get cached at the caller but: * We would need to pass the hash value along the whole {dict,block}_iter_* call chain. * The DICT_VECTOR virtualization would get violated as dict_linear*_vector do not use any hash values. Jan --17pEHd4RhPHOinZp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="idxcache1.patch" gdb/ 2014-10-20 Jan Kratochvil * dictionary.c (iter_match_first_hashed): Provide state cache for hash_index from NAME. diff --git a/gdb/dictionary.c b/gdb/dictionary.c index 055c87e..90bcd6d 100644 --- a/gdb/dictionary.c +++ b/gdb/dictionary.c @@ -656,9 +656,26 @@ iter_match_first_hashed (const struct dictionary *dict, const char *name, symbol_compare_ftype *compare, struct dict_iterator *iterator) { - unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict); + unsigned int hash_index; struct symbol *sym; + /* Cache HASH_INDEX. */ + { + static const char *name_ptr_cached; + static char *name_content_cached; + static unsigned int dict_hash_cached; + + if (name_ptr_cached != name || strcmp (name_content_cached, name) != 0) + { + dict_hash_cached = dict_hash (name); + name_ptr_cached = name; + xfree (name_content_cached); + name_content_cached = xstrdup (name); + } + hash_index = dict_hash_cached; + } + hash_index %= DICT_HASHED_NBUCKETS (dict); + DICT_ITERATOR_DICT (iterator) = dict; /* Loop through the symbols in the given bucket, breaking when SYM --17pEHd4RhPHOinZp-- http://sourceware.org/ml/gdb-patches/2014-10/msg00525.html Subject: [patch 2/2] Accelerate lookup_symbol_aux_objfile 8x --K8nIJk4ghYZn606h Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, lookup_symbol_aux_objfile() processing is very ineffective. For each primary symtab it searches it and also all its secondary symtabs. But that means that secondary symtabs included in many primary symtabs get needlessly searched many times during one lookup_symbol_aux_objfile() run. lookup_symbol_aux_objfile does not care in which primary/secondary symtab the symbol is found. Jan --K8nIJk4ghYZn606h Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="idxcache2.patch" gdb/ 2014-10-20 Jan Kratochvil * symtab.c (lookup_symbol_aux_objfile): Use ALL_OBJFILE_SYMTABS, inline lookup_block_symbol. diff --git a/gdb/symtab.c b/gdb/symtab.c index c530d50..bc800ef 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1657,15 +1657,25 @@ lookup_symbol_aux_objfile (struct objfile *objfile, int block_index, const struct block *block; struct symtab *s; - ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s) + gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK); + + ALL_OBJFILE_SYMTABS (objfile, s) { + struct dict_iterator dict_iter; + bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, block_index); - sym = lookup_block_symbol (block, name, domain); - if (sym) + + for (sym = dict_iter_name_first (block->dict, name, &dict_iter); + sym != NULL; + sym = dict_iter_name_next (name, &dict_iter)) { - block_found = block; - return fixup_symbol_section (sym, objfile); + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain)) + { + block_found = block; + return fixup_symbol_section (sym, objfile); + } } } --K8nIJk4ghYZn606h--