This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Fwd: gdb "call" very slow on large C++ program; 2 possible patches]


Andrew Cagney writes:
 > This might be interesting.
 > 	Andrew

Hmmm, I am sorry I looked. :-(
I discovered something very strange in symtab.c:make_symbol_overload_list().

What is this function supposed to do with those two for loops over the
psymbols? It is just calling QUIT, and PSYMTAB_TO_SYMTAB over and over
again.

I am afraid somebody did a cvs commit snafu at some point (this would predate
the creation of sourceware). 
Those two for loops are noops, as far as I can tell. 

I'll dig further, before I actually can make sense of all this.

Your cvs archaeologist,
Elena


 > From: Richard Sharman <richard_sharman@Mitel.COM>
 > To: bug-gdb@gnu.org
 > Cc: sharman@sharmanpc.software.Mitel.COM
 > Subject: gdb "call" very slow on large C++ program;  2 possible patches
 > Date: Sat, 17 Nov 2001 22:14:28 -0500
 > Content-Type: text
 > 
 > We have a largish C++ program, and when we use the gdb "call" function
 > it takes about 12 seconds for GDB to perform the operation.
 > (The function itself is very quick.   In the previous C version of the
 > program the call was virtually instantaneous.)
 > 
 > I have two patches.  The first patch reduced the time to about 5 seconds 
 > for the first call but 2 seconds for the second call; the second patch
 > reduced to time to about an eigth of a second.
 > 
 > The first patch was to "overload_list_add_symbol" in symtab.c .
 > This function was taking a lot of time demangling symbols that didn't
 > match.  The patch did two things:
 > 
 > * See if the name to search for matched the beginning of the
 >   mangled name.  If it did not, then exit immediately.  This saved the
 >   call to cplus_demangle and the xmalloc and free calls.
 > 
 > * Set the "readin" flag after the two for loops in the ALL_PSYMTABS
 >   loop.  This catches the cases of files that have no symbols and thus
 >   never get the readin flag set.   (This may seem trivial but happened 
 >   in 4860 files in our program so was quite significant.)
 > 
 > As mentioned above, this helped signficantly, especially on the second
 > call.
 > 
 > However,  there was still a noticable delay before the called function
 > was executed.  We noticed that the gdb "info func" on the command name
 > was executed immediately, and wondered why it didn't have the same
 > delay in finding the function name.  We found it was not using the
 > "make_symbol_overload_list" function, but instead calling
 > "search_symbols".   The second patch was then to "find_overload_match"
 > in valops.c,  to use the "search_symbols" function.
 > 
 > Both patches work for us but I am not at all familiar with the
 > workings of gdb so do not know how reliable they are.  I have no idea
 > why there appear to be two functions doing essentially the same thing
 > but one takes 12 seconds and one takes 0.125 seconds.
 > 
 > The second patch makes the first patch unncessary since
 > make_symbol_overload_list is not called other than in the original
 > valops.c.
 > 
 > Here are the two patches.  They are agains the cvs source as of
 > 14 November checked out using
 > 
 > cvs -z9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co -r \
 > 	gdb_5_0-2000-04-10-branch gdb+dejagnu
 > 
 > 
 > -------------------- Patch 1 --------------------
 > *** symtab.c.orig	Mon Apr  3 22:08:52 2000
 > --- symtab.c	Wed Nov 14 23:23:13 2001
 > ***************
 > *** 4460,4468 ****
 >   {
 >     int newsize;
 >     int i;
 >   
 >     /* Get the demangled name without parameters */
 > !   char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
 >     if (!sym_name)
 >       {
 >         sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
 > --- 4460,4476 ----
 >   {
 >     int newsize;
 >     int i;
 > +   char *sym_name;
 > + 
 > + 
 > +   /* skip symbols that cannot match */
 > +   if (strncmp(SYMBOL_NAME (sym), oload_name, strlen(oload_name)) != 0) 
 > +     {
 > +       return;
 > +     }
 >   
 >     /* Get the demangled name without parameters */
 > !   sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
 >     if (!sym_name)
 >       {
 >         sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
 > ***************
 > *** 4567,4574 ****
 > --- 4575,4590 ----
 >           /* This will cause the symbol table to be read if it has not yet been */
 >           s = PSYMTAB_TO_SYMTAB (ps);
 >         }
 > + 
 > +     /* If no symbols were found, mark it as read anyway so that
 > +        we skip it next time. */
 > +     if (ps && !ps->readin) 
 > +       {
 > + 	ps->readin = 1;
 > +       }
 >     }
 >   
 > + 
 >     /* Search upwards from currently selected frame (so that we can
 >        complete on local vars.  */
 >   
 > -------------------------------------------------
 > 
 > -------------------- Patch  --------------------
 > *** valops.c.orig	Sun Apr  9 09:02:10 2000
 > --- valops.c	Thu Nov 15 15:25:36 2001
 > ***************
 > *** 2739,2744 ****
 > --- 2739,2747 ----
 >     int boffset;
 >     register int jj;
 >     register int ix;
 > +   struct symbol_search *symbols;
 > +   struct symbol_search *p;
 > +   struct cleanup *old_chain;
 >   
 >     char *obj_type_name = NULL;
 >     char *func_name = NULL;
 > ***************
 > *** 2799,2807 ****
 >             return 0;
 >           }
 >   
 > !       oload_syms = make_symbol_overload_list (fsym);
 > !       while (oload_syms[++i])
 > ! 	num_fns++;
 >         if (!num_fns)
 >   	error ("Couldn't find function %s", func_name);
 >       }
 > --- 2802,2821 ----
 >             return 0;
 >           }
 >   
 > !       search_symbols (SYMBOL_NAME (fsym), FUNCTIONS_NAMESPACE, 0, (char **) NULL, &symbols);
 > !       old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, symbols);
 > !       for (p = symbols; p != NULL; p = p->next)
 > ! 	{
 > ! 	    num_fns++;
 > ! 	}
 > !       oload_syms = (struct symbol **) xmalloc ((num_fns + 1) * sizeof (struct symbol *));
 > !       i = -1;
 > !       for (p = symbols; p != NULL; p = p->next)
 > ! 	{
 > ! 	  oload_syms[++i] = p->symbol;
 > ! 	}
 > !       do_cleanups (old_chain);
 > ! 
 >         if (!num_fns)
 >   	error ("Couldn't find function %s", func_name);
 >       }
 > ***************
 > *** 2946,2952 ****
 >         *symp = oload_syms[oload_champ];
 >         free (func_name);
 >       }
 > ! 
 >     return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
 >   }
 >   
 > --- 2960,2966 ----
 >         *symp = oload_syms[oload_champ];
 >         free (func_name);
 >       }
 > !   free(oload_syms);
 >     return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
 >   }
 >   
 > -------------------------------------------------
 > 
 > 
 > Richard Sharman
 > 
 > _______________________________________________
 > Bug-gdb mailing list
 > Bug-gdb@gnu.org
 > http://mail.gnu.org/mailman/listinfo/bug-gdb
 > 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]