From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11425 invoked by alias); 10 Feb 2003 16:01:10 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 11418 invoked from network); 10 Feb 2003 16:01:10 -0000 Received: from unknown (HELO crack.them.org) (65.125.64.184) by 172.16.49.205 with SMTP; 10 Feb 2003 16:01:10 -0000 Received: from nevyn.them.org ([66.93.61.169] ident=mail) by crack.them.org with asmtp (Exim 3.12 #1 (Debian)) id 18iIFs-0007uH-00 for ; Mon, 10 Feb 2003 12:02:08 -0600 Received: from drow by nevyn.them.org with local (Exim 3.36 #1 (Debian)) id 18iGMl-0000BH-00 for ; Mon, 10 Feb 2003 11:01:07 -0500 Date: Mon, 10 Feb 2003 16:01:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: RFA/symtab: Let search_symbols find exact matches Message-ID: <20030210160107.GA587@nevyn.them.org> Mail-Followup-To: gdb-patches@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.1i X-SW-Source: 2003-02/txt/msg00258.txt.bz2 This patch renames search_symbols to search_symbols_aux, and lets it take an argument that specified regex or exact (well, strcmp_iw) matching. Then search_symbols becomes a wrapper. The new function is used by make_symbol_overload_list, which shaves 50% time off of some tests in the C++ directory if your system libc has debugging symbols; it removes the bogusity where all psymtabs were converted to symtabs during overload resolution. Whew. This cuts memory for namespace.exp from 70MB to 7MB, allowing some of my hardware to actually run the test without crashing. Hopefully at some point I can extend search_symbols_aux to also do prefix matching and use it to speed up make_symbol_completion_list, but there are some subtleties - like, in that context we don't need to read in psymbols. And the sorting requirements are different. Symtab maintainers, is this OK? -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer 2003-02-10 Daniel Jacobowitz * symtab.c (enum sym_match_kind): New. (symbol_matches_kind, symbol_matches_pattern): New functions. (search_symbols_aux): Renamed from search_symbols. Accept an enum sym_match_kind argument. Use symbol_matches_kind and symbol_matches_pattern. Move file_matches call out of the per-symbol loop. (search_symbols): New function, calling search_symbols_aux. (make_symbol_overload_list): Use search_symbols_aux. Index: symtab.c =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gdb/symtab.c,v retrieving revision 1.87 diff -u -p -r1.87 symtab.c --- symtab.c 4 Feb 2003 18:07:01 -0000 1.87 +++ symtab.c 10 Feb 2003 15:53:22 -0000 @@ -2787,8 +2787,77 @@ sort_search_symbols (struct symbol_searc return symp; } -/* Search the symbol table for matches to the regular expression REGEXP, - returning the results in *MATCHES. +/* Possible match styles for search_symbols_aux. */ + +enum sym_match_method { + sym_match_regex, + sym_match_exact +}; + +static inline int +symbol_matches_kind (enum address_class aclass, namespace_enum kind) +{ + /* If the address class does not match the requested namespace, return 0. */ + switch (kind) + { + case VARIABLES_NAMESPACE: + if (aclass == LOC_TYPEDEF || aclass == LOC_BLOCK || aclass == LOC_CONST) + return 0; + break; + + case FUNCTIONS_NAMESPACE: + if (aclass != LOC_BLOCK) + return 0; + break; + + case TYPES_NAMESPACE: + if (aclass != LOC_TYPEDEF) + return 0; + break; + + case METHODS_NAMESPACE: + if (aclass != LOC_BLOCK) + return 0; + break; + + default: + internal_error (__FILE__, __LINE__, + "Invalid kind passed to symbol_matches_pattern"); + } + + return 1; +} + +static inline int +symbol_matches_pattern (const char *sym_name, const char *sym_demangled_name, + const char *pattern, enum sym_match_method how) +{ + if (pattern == NULL) + return 1; + + switch (how) + { + case sym_match_regex: + if (re_exec (sym_name) + || (sym_demangled_name && re_exec (sym_demangled_name))) + return 1; + break; + + case sym_match_exact: + if (strcmp_iw (sym_name, pattern) == 0 + || (sym_demangled_name + && strcmp_iw (sym_demangled_name, pattern) == 0)) + return 1; + break; + } + + return 0; +} + +/* Search the symbol table for matches to the pattern PATTERN, + returning the results in *MATCHES. If HOW is sym_match_regex, + PATTERN is a regular expression; if HOW is sym_match_exact, PATTERN + is an exact string (almost: strcmp_iw is used). Only symbols of KIND are searched: FUNCTIONS_NAMESPACE - search all functions @@ -2800,11 +2869,12 @@ sort_search_symbols (struct symbol_searc free_search_symbols should be called when *MATCHES is no longer needed. The results are sorted locally; each symtab's global and static blocks are - separately alphabetized. - */ -void -search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[], - struct symbol_search **matches) + separately alphabetized. */ + +static void +search_symbols_aux (char *pattern, namespace_enum kind, int nfiles, + char *files[], struct symbol_search **matches, + enum sym_match_method how) { register struct symtab *s; register struct partial_symtab *ps; @@ -2851,14 +2921,14 @@ search_symbols (char *regexp, namespace_ sr = *matches = NULL; tail = NULL; - if (regexp != NULL) + if (pattern != NULL) { /* Make sure spacing is right for C++ operators. This is just a courtesy to make the matching less sensitive to how many spaces the user leaves between 'operator' and or . */ char *opend; - char *opname = operator_chars (regexp, &opend); + char *opname = operator_chars (pattern, &opend); if (*opname) { int fix = -1; /* -1 means ok; otherwise number of spaces needed. */ @@ -2879,16 +2949,17 @@ search_symbols (char *regexp, namespace_ { char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1); sprintf (tmp, "operator%.*s%s", fix, " ", opname); - regexp = tmp; + pattern = tmp; } } - if (0 != (val = re_comp (regexp))) - error ("Invalid regexp (%s): %s", val, regexp); + if (how == sym_match_regex) + if (0 != (val = re_comp (pattern))) + error ("Invalid regexp (%s): %s", val, pattern); } /* Search through the partial symtabs *first* for all symbols - matching the regexp. That way we don't have to reproduce all of + matching the pattern. That way we don't have to reproduce all of the machinery below. */ ALL_PSYMTABS (objfile, ps) @@ -2899,6 +2970,9 @@ search_symbols (char *regexp, namespace_ if (ps->readin) continue; + if (! file_matches (ps->filename, files, nfiles)) + continue; + gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms; sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms; bound = gbound; @@ -2925,13 +2999,10 @@ search_symbols (char *regexp, namespace_ /* If it would match (logic taken from loop below) load the file and go on to the next one */ - if (file_matches (ps->filename, files, nfiles) - && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym)) - && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF - && SYMBOL_CLASS (*psym) != LOC_BLOCK) - || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK) - || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF) - || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)))) + if (symbol_matches_kind (SYMBOL_CLASS (*psym), kind) + && symbol_matches_pattern (SYMBOL_NAME (*psym), + SYMBOL_DEMANGLED_NAME (*psym), + pattern, how)) { PSYMTAB_TO_SYMTAB (ps); keep_going = 0; @@ -2963,7 +3034,9 @@ search_symbols (char *regexp, namespace_ MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype4) { - if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol)) + if (symbol_matches_pattern (SYMBOL_NAME (msymbol), + SYMBOL_DEMANGLED_NAME (msymbol), + pattern, how)) { if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))) { @@ -3000,6 +3073,9 @@ search_symbols (char *regexp, namespace_ ALL_SYMTABS (objfile, s) { + if (! file_matches (s->filename, files, nfiles)) + continue; + bv = BLOCKVECTOR (s); /* Often many files share a blockvector. Scan each blockvector only once so that @@ -3015,14 +3091,10 @@ search_symbols (char *regexp, namespace_ ALL_BLOCK_SYMBOLS (b, j, sym) { QUIT; - if (file_matches (s->filename, files, nfiles) - && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym)) - && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF - && SYMBOL_CLASS (sym) != LOC_BLOCK - && SYMBOL_CLASS (sym) != LOC_CONST) - || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK) - || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF) - || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)))) + if (symbol_matches_kind (SYMBOL_CLASS (sym), kind) + && symbol_matches_pattern (SYMBOL_NAME (sym), + SYMBOL_DEMANGLED_NAME (sym), + pattern, how)) { /* match */ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); @@ -3070,7 +3142,9 @@ search_symbols (char *regexp, namespace_ MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype4) { - if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol)) + if (symbol_matches_pattern (SYMBOL_NAME (msymbol), + SYMBOL_DEMANGLED_NAME (msymbol), + pattern, how)) { /* Functions: Look up by address. */ if (kind != FUNCTIONS_NAMESPACE || @@ -3108,6 +3182,16 @@ search_symbols (char *regexp, namespace_ discard_cleanups (old_chain); } +/* A wrapper for search_symbols_aux, above, which treats PATTERN as a + regular expression. */ + +void +search_symbols (char *pattern, namespace_enum kind, int nfiles, + char *files[], struct symbol_search **matches) +{ + search_symbols_aux (pattern, kind, nfiles, files, matches, sym_match_regex); +} + /* Helper function for symtab_symbol_info, this function uses the data returned from search_symbols() to print information regarding the match to gdb_stdout. @@ -4005,6 +4089,8 @@ overload_list_add_symbol (struct symbol struct symbol ** make_symbol_overload_list (struct symbol *fsym) { + struct symbol_search *matches, *matchp; + register struct symbol *sym; register struct symtab *s; register struct partial_symtab *ps; @@ -4035,88 +4121,20 @@ make_symbol_overload_list (struct symbol sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *)); sym_return_val[0] = NULL; - /* Look through the partial symtabs for all symbols which begin - by matching OLOAD_NAME. Make sure we read that symbol table in. */ - - ALL_PSYMTABS (objfile, ps) - { - struct partial_symbol **psym; + search_symbols_aux (oload_name, FUNCTIONS_NAMESPACE, 0, NULL, &matches, + sym_match_exact); - /* If the psymtab's been read in we'll get it when we search - through the blockvector. */ - if (ps->readin) - continue; - - for (psym = objfile->global_psymbols.list + ps->globals_offset; - psym < (objfile->global_psymbols.list + ps->globals_offset - + ps->n_global_syms); - psym++) - { - /* If interrupted, then quit. */ - QUIT; - /* This will cause the symbol table to be read if it has not yet been */ - s = PSYMTAB_TO_SYMTAB (ps); - } - - for (psym = objfile->static_psymbols.list + ps->statics_offset; - psym < (objfile->static_psymbols.list + ps->statics_offset - + ps->n_static_syms); - psym++) - { - QUIT; - /* This will cause the symbol table to be read if it has not yet been */ - s = PSYMTAB_TO_SYMTAB (ps); - } - } - - /* Search upwards from currently selected frame (so that we can - complete on local vars. */ - - for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) + matchp = matches; + while (matchp) { - if (!BLOCK_SUPERBLOCK (b)) - { - surrounding_static_block = b; /* For elimination of dups */ - } - - /* Also catch fields of types defined in this places which match our - text string. Only complete on types visible from current context. */ - - ALL_BLOCK_SYMBOLS (b, i, sym) - { - overload_list_add_symbol (sym, oload_name); - } + if (matchp->symbol) + overload_list_add_symbol (matchp->symbol, oload_name); + matchp = matchp->next; } - /* Go through the symtabs and check the externs and statics for - symbols which match. */ - - ALL_SYMTABS (objfile, s) - { - QUIT; - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); - ALL_BLOCK_SYMBOLS (b, i, sym) - { - overload_list_add_symbol (sym, oload_name); - } - } - - ALL_SYMTABS (objfile, s) - { - QUIT; - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); - /* Don't do this block twice. */ - if (b == surrounding_static_block) - continue; - ALL_BLOCK_SYMBOLS (b, i, sym) - { - overload_list_add_symbol (sym, oload_name); - } - } - xfree (oload_name); - - return (sym_return_val); + free_search_symbols (matches); + return sym_return_val; } /* End of overload resolution functions */