Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [patch] Eliminate quadratic slow-down on number of solibs (part   2).
@ 2009-05-12 19:43 Paul Pluzhnikov
  2009-05-13  9:25 ` Joel Brobecker
  0 siblings, 1 reply; 17+ messages in thread
From: Paul Pluzhnikov @ 2009-05-12 19:43 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches, Tom Tromey

[-- Attachment #1: Type: text/plain, Size: 5238 bytes --]

On Tue, May 12, 2009 at 2:10 AM, Joel Brobecker <brobecker@adacore.com> wrote:

> Looks good to me. If I may, would you mind adding a comment explaining
> *why* you count the number of symbols? I think it can help understanding
> the added code a little bit faster...
>
>    /* If we haven't done so for this objfile yet, count the number
>       of objc methods that this objfile defines and save it as a private
>       objfile data.  That way, if have already determined that this
>       objfile provides no objc methods, we can skip it entirely.  */

I've slightly reworded and added this. Thanks.

> I wonder how well support for ObjC works. It looks like this file hasn't
> really be worked on for a long time... Did you have an objc compiler in
> your path when you did the testing, by any chance?

Yes, I tested with objc-enabled gcc. Here are results from current
CVS Head:

$ grep '\.objc' gdb.sum
Running ../../../gdb/testsuite/gdb.objc/basicclass.exp ...
PASS: gdb.objc/basicclass.exp: successfully compiled objc with posix
threads test case
PASS: gdb.objc/basicclass.exp: deduced language is Objective-C, before
full symbols
PASS: gdb.objc/basicclass.exp: deduced language is Objective-C, after
full symbols
PASS: gdb.objc/basicclass.exp: breakpoint method
PASS: gdb.objc/basicclass.exp: breakpoint method with colon
PASS: gdb.objc/basicclass.exp: breakpoint class method with colon
PASS: gdb.objc/basicclass.exp: continue until method breakpoint
PASS: gdb.objc/basicclass.exp: resetting breakpoints when rerunning
PASS: gdb.objc/basicclass.exp: continue until method breakpoint
PASS: gdb.objc/basicclass.exp: print an ivar of self
PASS: gdb.objc/basicclass.exp: print self
PASS: gdb.objc/basicclass.exp: print contents of self
PASS: gdb.objc/basicclass.exp: breakpoint in category method
PASS: gdb.objc/basicclass.exp: continue until category method
PASS: gdb.objc/basicclass.exp: Call an Objective-C method with no arguments
PASS: gdb.objc/basicclass.exp: Call an Objective-C method with one argument
PASS: gdb.objc/basicclass.exp: Use of the print-object command
PASS: gdb.objc/basicclass.exp: Use of the po (print-object) command
Running ../../../gdb/testsuite/gdb.objc/nondebug.exp ...
PASS: gdb.objc/nondebug.exp: successfully compiled objc with posix
threads test case
KFAIL: gdb.objc/nondebug.exp: break on non-debuggable method (PRMS: gdb/1236)
Running ../../../gdb/testsuite/gdb.objc/objcdecode.exp ...
PASS: gdb.objc/objcdecode.exp: successfully compiled objc with posix
threads test case
PASS: gdb.objc/objcdecode.exp: break on multiply defined method
FAIL: gdb.objc/objcdecode.exp: continue after break on multiply
defined symbol (GDB internal error)

No changes after the patch.

Here is 'diff -w' again:

diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 9b8d801..aa55baf 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -76,6 +76,8 @@ struct objc_method {
   CORE_ADDR imp;
 };

+static const struct objfile_data *objc_objfile_data;
+
 /* Lookup a structure type named "struct NAME", visible in lexical
    block BLOCK.  If NOERR is nonzero, return zero if NAME is not
    suitably defined.  */
@@ -1154,7 +1156,23 @@ find_methods (struct symtab *symtab, char type,
   if (symtab)
     block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);

-  ALL_MSYMBOLS (objfile, msymbol)
+  ALL_OBJFILES (objfile)
+    {
+      unsigned int *objc_csym;
+
+      /* The objfile_csym variable counts the number of ObjC methods
+	 that this objfile defines.  We save that count as a private
+	 objfile data.	If we have already determined that this objfile
+	 provides no ObjC methods, we can skip it entirely.  */
+
+      unsigned int objfile_csym = 0;
+
+      objc_csym = objfile_data (objfile, objc_objfile_data);
+      if (objc_csym != NULL && *objc_csym == 0)
+	/* There are no ObjC symbols in this objfile.  Skip it entirely.  */
+	continue;
+
+      ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
     {
       QUIT;

@@ -1187,6 +1205,8 @@ find_methods (struct symtab *symtab, char type,
       if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
 	continue;

+	  objfile_csym++;
+
       if ((type != '\0') && (ntype != type))
 	continue;

@@ -1237,6 +1257,16 @@ find_methods (struct symtab *symtab, char type,
 	  csym++;
 	}
     }
+      if (objc_csym == NULL)
+	{
+	  objc_csym = xmalloc (sizeof (*objc_csym));
+	  *objc_csym = objfile_csym;
+	  set_objfile_data (objfile, objc_objfile_data, objc_csym);
+	}
+      else
+	/* Count of ObjC methods in this objfile should be constant.  */
+	gdb_assert (*objc_csym == objfile_csym);
+    }

   if (nsym != NULL)
     *nsym = csym;
@@ -1792,3 +1822,9 @@ resolve_msgsend_super_stret (CORE_ADDR pc,
CORE_ADDR *new_pc)
     return 1;
   return 0;
 }
+
+void
+_initialize_objc_lang (void)
+{
+  objc_objfile_data = register_objfile_data ();
+}


OK to commit?

Thanks,
-- 
Paul Pluzhnikov

2009-05-12  Paul Pluzhnikov  <ppluzhnikov@google.com>

	* objc-lang.c (objc_objfile_data): New variable.
	(find_methods): Skip objfiles without Obj-C methods.
	(_initialize_objc_lang): New function.

[-- Attachment #2: gdb-objc-20090512.txt --]
[-- Type: text/plain, Size: 6086 bytes --]

diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 9b8d801..aa55baf 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -76,6 +76,8 @@ struct objc_method {
   CORE_ADDR imp;
 };
 
+static const struct objfile_data *objc_objfile_data;
+
 /* Lookup a structure type named "struct NAME", visible in lexical
    block BLOCK.  If NOERR is nonzero, return zero if NAME is not
    suitably defined.  */
@@ -1154,88 +1156,116 @@ find_methods (struct symtab *symtab, char type,
   if (symtab)
     block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
 
-  ALL_MSYMBOLS (objfile, msymbol)
+  ALL_OBJFILES (objfile)
     {
-      QUIT;
+      unsigned int *objc_csym;
 
-      if ((MSYMBOL_TYPE (msymbol) != mst_text)
-	  && (MSYMBOL_TYPE (msymbol) != mst_file_text))
-	/* Not a function or method.  */
-	continue;
+      /* The objfile_csym variable counts the number of ObjC methods
+	 that this objfile defines.  We save that count as a private
+	 objfile data.	If we have already determined that this objfile
+	 provides no ObjC methods, we can skip it entirely.  */
 
-      if (symtab)
-	if ((SYMBOL_VALUE_ADDRESS (msymbol) <  BLOCK_START (block)) ||
-	    (SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block)))
-	  /* Not in the specified symtab.  */
-	  continue;
+      unsigned int objfile_csym = 0;
 
-      symname = SYMBOL_NATURAL_NAME (msymbol);
-      if (symname == NULL)
+      objc_csym = objfile_data (objfile, objc_objfile_data);
+      if (objc_csym != NULL && *objc_csym == 0)
+	/* There are no ObjC symbols in this objfile.  Skip it entirely.  */
 	continue;
 
-      if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
-	/* Not a method name.  */
-	continue;
-      
-      while ((strlen (symname) + 1) >= tmplen)
+      ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
 	{
-	  tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
-	  tmp = xrealloc (tmp, tmplen);
-	}
-      strcpy (tmp, symname);
+	  QUIT;
 
-      if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
-	continue;
+	  if ((MSYMBOL_TYPE (msymbol) != mst_text)
+	      && (MSYMBOL_TYPE (msymbol) != mst_file_text))
+	    /* Not a function or method.  */
+	    continue;
+
+	  if (symtab)
+	    if ((SYMBOL_VALUE_ADDRESS (msymbol) <  BLOCK_START (block)) ||
+		(SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block)))
+	      /* Not in the specified symtab.  */
+	      continue;
+
+	  symname = SYMBOL_NATURAL_NAME (msymbol);
+	  if (symname == NULL)
+	    continue;
+
+	  if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
+	    /* Not a method name.  */
+	    continue;
       
-      if ((type != '\0') && (ntype != type))
-	continue;
+	  while ((strlen (symname) + 1) >= tmplen)
+	    {
+	      tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
+	      tmp = xrealloc (tmp, tmplen);
+	    }
+	  strcpy (tmp, symname);
 
-      if ((class != NULL) 
-	  && ((nclass == NULL) || (strcmp (class, nclass) != 0)))
-	continue;
+	  if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
+	    continue;
+      
+	  objfile_csym++;
 
-      if ((category != NULL) && 
-	  ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
-	continue;
+	  if ((type != '\0') && (ntype != type))
+	    continue;
 
-      if ((selector != NULL) && 
-	  ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
-	continue;
+	  if ((class != NULL) 
+	      && ((nclass == NULL) || (strcmp (class, nclass) != 0)))
+	    continue;
+
+	  if ((category != NULL) && 
+	      ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
+	    continue;
 
-      sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
-      if (sym != NULL)
-        {
-          const char *newsymname = SYMBOL_NATURAL_NAME (sym);
+	  if ((selector != NULL) && 
+	      ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
+	    continue;
+
+	  sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
+	  if (sym != NULL)
+	    {
+	      const char *newsymname = SYMBOL_NATURAL_NAME (sym);
 	  
-          if (strcmp (symname, newsymname) == 0)
-            {
-              /* Found a high-level method sym: swap it into the
-                 lower part of sym_arr (below num_debuggable).  */
-              if (syms != NULL)
-                {
-                  syms[csym] = syms[cdebug];
-                  syms[cdebug] = sym;
-                }
-              csym++;
-              cdebug++;
-            }
-          else
-            {
-              warning (
+	      if (strcmp (symname, newsymname) == 0)
+		{
+		  /* Found a high-level method sym: swap it into the
+		     lower part of sym_arr (below num_debuggable).  */
+		  if (syms != NULL)
+		    {
+		      syms[csym] = syms[cdebug];
+		      syms[cdebug] = sym;
+		    }
+		  csym++;
+		  cdebug++;
+		}
+	      else
+		{
+		  warning (
 "debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
-                       newsymname, symname);
-              if (syms != NULL)
-                syms[csym] = (struct symbol *) msymbol;
-              csym++;
-            }
-        }
-      else 
+                           newsymname, symname);
+		  if (syms != NULL)
+		    syms[csym] = (struct symbol *) msymbol;
+		  csym++;
+		}
+	    }
+	  else
+	    {
+	      /* Found a non-debuggable method symbol.  */
+	      if (syms != NULL)
+		syms[csym] = (struct symbol *) msymbol;
+	      csym++;
+	    }
+	}
+      if (objc_csym == NULL)
 	{
-	  /* Found a non-debuggable method symbol.  */
-	  if (syms != NULL)
-	    syms[csym] = (struct symbol *) msymbol;
-	  csym++;
+	  objc_csym = xmalloc (sizeof (*objc_csym));
+	  *objc_csym = objfile_csym;
+	  set_objfile_data (objfile, objc_objfile_data, objc_csym);
 	}
+      else
+	/* Count of ObjC methods in this objfile should be constant.  */
+	gdb_assert (*objc_csym == objfile_csym);
     }
 
   if (nsym != NULL)
@@ -1792,3 +1822,9 @@ resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
     return 1;
   return 0;
 }
+
+void
+_initialize_objc_lang (void)
+{
+  objc_objfile_data = register_objfile_data ();
+}

^ permalink raw reply	[flat|nested] 17+ messages in thread
* Re: [patch] Eliminate quadratic slow-down on number of solibs (part   2).
@ 2009-05-06  0:50 Paul Pluzhnikov
  2009-05-12  8:25 ` Joel Brobecker
  2009-05-30  1:59 ` Tom Tromey
  0 siblings, 2 replies; 17+ messages in thread
From: Paul Pluzhnikov @ 2009-05-06  0:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

[-- Attachment #1: Type: text/plain, Size: 1029 bytes --]

On Fri, May 1, 2009 at 3:16 PM, Paul Pluzhnikov <ppluzhnikov@google.com> wrote:

> This is the patch to eliminate repeated iteration over the same objfile
> looking for Objective-C methods, as Tom suggested here:
>  http://sourceware.org/ml/gdb-patches/2009-04/msg00551.html

Even after the two patches above, there is still some repeated
and unnecessary setting and resetting of the breakpoints as each
solib is added :-(

Attached is an alternative patch which subsumes the other two,
and kills additional 15% of wasted CPU time.

It feels like a hack, but I don't see how to achieve the same
result in a cleaner way :-(

Timing on my 2780-solib test (just running ldd on that takes 15s):

time gdb -ex 'break main' -ex run -ex kill -ex quit request_test

=== current CVS Head ===
real    11m16.762s
user    11m5.530s
sys     0m9.697s

=== with attached patch ===
real    2m43.595s
user    2m33.350s
sys     0m9.353s

Tested on Linux/x86_64 without regressions.

Comments?
--
Paul Pluzhnikov

[-- Attachment #2: gdb-breakpoint-20090505.txt --]
[-- Type: text/plain, Size: 2309 bytes --]

? foof.12580
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.393
diff -u -p -u -r1.393 breakpoint.c
--- breakpoint.c	5 May 2009 13:24:48 -0000	1.393
+++ breakpoint.c	6 May 2009 00:46:59 -0000
@@ -72,6 +72,9 @@
 #define CATCH_PERMANENT ((void *) (uintptr_t) 0)
 #define CATCH_TEMPORARY ((void *) (uintptr_t) 1)
 
+/* If non-zero, breakpoin_re_set() is a no-op.  */
+int suppress_breakpoint_reset;
+
 /* Prototypes for local functions. */
 
 static void enable_delete_command (char *, int);
@@ -7723,6 +7726,9 @@ breakpoint_re_set (void)
   enum language save_language;
   int save_input_radix;
 
+  if (suppress_breakpoint_reset)
+    return;
+
   save_language = current_language->la_language;
   save_input_radix = input_radix;
   ALL_BREAKPOINTS_SAFE (b, temp)
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.90
diff -u -p -u -r1.90 breakpoint.h
--- breakpoint.h	31 Mar 2009 16:44:17 -0000	1.90
+++ breakpoint.h	6 May 2009 00:46:59 -0000
@@ -669,6 +669,8 @@ enum breakpoint_here
     permanent_breakpoint_here
   };
 \f
+/* If non-zero, breakpoin_re_set() is a no-op.  */
+extern int suppress_breakpoint_reset;
 
 /* Prototypes for breakpoint-related functions.  */
 
Index: solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.115
diff -u -p -u -r1.115 solib.c
--- solib.c	9 Mar 2009 22:38:37 -0000	1.115
+++ solib.c	6 May 2009 00:46:59 -0000
@@ -738,6 +738,9 @@ solib_add (char *pattern, int from_tty, 
     int any_matches = 0;
     int loaded_any_symbols = 0;
 
+    /* Delay resetting breakpoints until after we added all solibs.  */
+    suppress_breakpoint_reset += 1;
+
     for (gdb = so_list_head; gdb; gdb = gdb->next)
       if (! pattern || re_exec (gdb->so_name))
 	{
@@ -754,6 +757,10 @@ solib_add (char *pattern, int from_tty, 
 	    loaded_any_symbols = 1;
 	}
 
+    suppress_breakpoint_reset -= 1;
+    if (loaded_any_symbols)
+      breakpoint_re_set ();
+
     if (from_tty && pattern && ! any_matches)
       printf_unfiltered
 	("No loaded shared libraries match the pattern `%s'.\n", pattern);

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2009-06-03 21:36 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-12 19:43 [patch] Eliminate quadratic slow-down on number of solibs (part 2) Paul Pluzhnikov
2009-05-13  9:25 ` Joel Brobecker
  -- strict thread matches above, loose matches on Subject: below --
2009-05-06  0:50 Paul Pluzhnikov
2009-05-12  8:25 ` Joel Brobecker
2009-05-12 20:53   ` Paul Pluzhnikov
2009-05-13  9:27     ` Joel Brobecker
2009-05-13 18:11       ` Paul Pluzhnikov
2009-05-14  8:14         ` Joel Brobecker
2009-05-14 17:45           ` Paul Pluzhnikov
2009-05-14 19:23             ` Joel Brobecker
2009-05-14 23:35               ` Paul Pluzhnikov
     [not found]             ` <20090521151540.GH16152@adacore.com>
2009-05-21 16:17               ` Paul Pluzhnikov
2009-05-21 16:40                 ` Joel Brobecker
2009-05-30  2:08             ` Tom Tromey
2009-05-30  1:59 ` Tom Tromey
2009-06-03 19:46   ` Paul Pluzhnikov
2009-06-03 21:36     ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox