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]

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


This might be interesting.
	Andrew
--- Begin Message ---
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

--- End Message ---

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