Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Paul Pluzhnikov <ppluzhnikov@google.com>
To: gdb-patches ml <gdb-patches@sourceware.org>
Cc: Paul Pluzhnikov <ppluzhnikov@google.com>
Subject: [patch] Speed up find_pc_section
Date: Fri, 17 Jul 2009 07:34:00 -0000	[thread overview]
Message-ID: <8ac60eac0907161724v40e5bd8bg7877d8901b8d7b6e@mail.gmail.com> (raw)

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

Greetings,

While working on something else, I noticed find_pc_section consuming 90%+
of CPU in my GDB profiles :-(

It is called from quite a number of places, and is surprisingly
inefficient. Further, it exhibits yet another quadratic slowdown on number
of objfiles, as the attached test case demonstrates.

Running "perl gen.pl NNN" generates NNN shared libs, and a main executable,
which crashes with NNN+C levels in stack trace, crossing all shared libs.

I then collected timing like this:
time gdb64-cvs -ex run -ex where -ex quit ./a.out > /dev/null

Here are user-time results before the patch (clearly showing non-linear
slowdown):

32:  0m0.426s
64:  0m1.344s
128: 0m5.254s
256: 0m35.792s
512: 4m55.999s

Attached patch turns linear search into binary search, speeding up
find_pc_section drastically :-)

Here are the same user-time results after the patch:

128: 0m1.064s
256: 0m3.062s
512: 0m10.675s

Tested on Linux/x86_64 with no regressions.

Comments?
--
Paul Pluzhnikov

[-- Attachment #2: gdb-find_pc_section-20090716.txt --]
[-- Type: text/plain, Size: 4570 bytes --]

Index: objfiles.c
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.c,v
retrieving revision 1.85
diff -u -p -u -r1.85 objfiles.c
--- objfiles.c	14 Jul 2009 14:55:06 -0000	1.85
+++ objfiles.c	17 Jul 2009 00:21:13 -0000
@@ -64,6 +64,18 @@ struct objfile *current_objfile;	/* For 
 struct objfile *symfile_objfile;	/* Main symbol table loaded from */
 struct objfile *rt_common_objfile;	/* For runtime common symbols */
 
+struct address_to_obj_section
+{
+  CORE_ADDR addr;
+  CORE_ADDR endaddr;
+  struct obj_section *section;
+};
+
+/* Records whether any objfiles appeared or disappeared since we last updated
+   address to obj section map.  */
+
+static int objfiles_updated_p;
+
 /* Locate all mappable sections of a BFD file. 
    objfile_p_char is a char * to get it through
    bfd_map_over_sections; we cast it back to its proper type.  */
@@ -94,6 +106,7 @@ add_to_objfile_sections (struct bfd *abf
   obstack_grow (&objfile->objfile_obstack, (char *) &section, sizeof (section));
   objfile->sections_end
     = (struct obj_section *) (((size_t) objfile->sections_end) + 1);
+  objfiles_updated_p += 1;  /* Rebuild section map next time we need it.  */
 }
 
 /* Builds a section table for OBJFILE.
@@ -394,6 +407,7 @@ unlink_objfile (struct objfile *objfile)
 void
 free_objfile (struct objfile *objfile)
 {
+  objfiles_updated_p += 1;  /* Rebuild section map next time we need it.  */
   if (objfile->separate_debug_objfile)
     {
       free_objfile (objfile->separate_debug_objfile);
@@ -757,22 +771,121 @@ have_minimal_symbols (void)
   return 0;
 }
 
+/* Qsort comparison function.  */
+static int
+section_map_compare (const void *a, const void *b)
+{
+  const struct address_to_obj_section *aa =
+      (const struct address_to_obj_section *) a;
+  const struct address_to_obj_section *bb =
+      (const struct address_to_obj_section *) b;
+
+  if (aa->addr < bb->addr)
+    {
+      gdb_assert (aa->endaddr <= bb->addr);
+      return -1;
+    }
+  else if (aa->addr > bb->addr)
+    {
+      gdb_assert (aa->addr >= bb->endaddr);
+      return 1;
+    }
+  /* This can happen for separate debug-info files.  */
+  gdb_assert (aa->endaddr == bb->endaddr);
+
+  return 0;
+}
+
+/* Update PMAP, PMAP_SIZE with non-TLS sections from all objfiles.  */
+
+static void
+update_section_map (struct address_to_obj_section **pmap,
+                    int *pmap_size)
+{
+  int map_size, idx;
+  struct obj_section *s;
+  struct objfile *objfile;
+  struct address_to_obj_section *map;
+
+  gdb_assert (objfiles_updated_p != 0);
+
+  map = *pmap;
+  xfree (map);
+
+#define insert_p(objf, sec) \
+  ((bfd_get_section_flags ((objf)->obfd, (sec)->the_bfd_section) \
+    & SEC_THREAD_LOCAL) == 0)
+
+  map_size = 0;
+  ALL_OBJSECTIONS (objfile, s)
+    if (insert_p (objfile, s))
+      map_size += 1;
+
+  map = xmalloc (map_size * sizeof (*map));
+
+  idx = 0;
+  ALL_OBJSECTIONS (objfile, s)
+    if (insert_p (objfile, s))
+      {
+        map[idx].section = s;
+        map[idx].addr = obj_section_addr (s);
+        map[idx].endaddr = obj_section_endaddr (s);
+        idx += 1;
+      }
+
+#undef insert_p
+
+  qsort (map, map_size, sizeof (*map), section_map_compare);
+
+  *pmap = map;
+  *pmap_size = map_size;
+}
+
+/* Bsearch comparison function. */
+
+int
+find_pc_section_cmp (const void *key, const void *elt)
+{
+  CORE_ADDR pc = *(CORE_ADDR *) key;
+  const struct address_to_obj_section *entry =
+      (const struct address_to_obj_section *) elt;
+
+  if (pc < entry->addr)
+    return -1;
+  if (pc < entry->endaddr)
+    return 0;
+  return 1;
+}
+
 /* Returns a section whose range includes PC or NULL if none found.   */
 
 struct obj_section *
 find_pc_section (CORE_ADDR pc)
 {
+  static struct address_to_obj_section *sections;
+  static int num_sections;
+
   struct obj_section *s;
-  struct objfile *objfile;
+  struct address_to_obj_section *aos;
 
   /* Check for mapped overlay section first.  */
   s = find_pc_mapped_section (pc);
   if (s)
     return s;
 
-  ALL_OBJSECTIONS (objfile, s)
-    if (obj_section_addr (s) <= pc && pc < obj_section_endaddr (s))
-      return s;
+  if (objfiles_updated_p != 0)
+    {
+      update_section_map (&sections, &num_sections);
+
+      /* Don't need updates to section map until objfiles are added
+         or removed.  */
+      objfiles_updated_p = 0;
+    }
+
+  aos = bsearch (&pc, sections, num_sections, sizeof (*sections),
+                 find_pc_section_cmp);
+  if (aos)
+    return aos->section;
 
   return NULL;
 }

[-- Attachment #3: gen.pl --]
[-- Type: application/x-perl, Size: 633 bytes --]

             reply	other threads:[~2009-07-17  0:24 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-17  7:34 Paul Pluzhnikov [this message]
2009-07-17 15:59 ` Paul Pluzhnikov
2009-07-17 16:27 ` Tom Tromey
2009-07-17 17:19   ` Paul Pluzhnikov
2009-07-21 17:57     ` Tom Tromey
2009-07-21 20:51       ` Paul Pluzhnikov
2009-07-21 21:03         ` Tom Tromey
2009-07-22 15:23         ` Pedro Alves
2009-07-22 16:33           ` Tom Tromey
2009-07-22 17:02             ` Paul Pluzhnikov
2009-07-22 17:02               ` Pedro Alves
2009-07-22 17:16                 ` Paul Pluzhnikov
2009-07-22 18:08                   ` Paul Pluzhnikov
2009-07-22 18:10                   ` Pedro Alves
2009-07-22 18:12                   ` Paul Pluzhnikov
2009-07-22 19:19                     ` Pedro Alves
2009-07-22 19:34                       ` Paul Pluzhnikov
2009-07-22 19:54                         ` Pedro Alves
2009-08-17 21:15                         ` [commit] Fix reread_symbols crash (Re: [patch] Speed up find_pc_section) Ulrich Weigand
2009-08-04 14:22         ` [patch] Speed up find_pc_section Tom Tromey
2009-08-04 15:06           ` Paul Pluzhnikov
2009-08-04 15:38             ` Tom Tromey
     [not found]               ` <8ac60eac0908042358q4d2061d2md3c49cf4aab26398@mail.gmail.com>
     [not found]                 ` <m34osmi5jx.fsf@fleche.redhat.com>
     [not found]                   ` <8ac60eac0908050940we3dc478rd182f4367a650f1b@mail.gmail.com>
     [not found]                     ` <8ac60eac0908052259l7b1c21d1t212991886a5f8b18@mail.gmail.com>
     [not found]                       ` <m3eirofxwh.fsf@fleche.redhat.com>
     [not found]                         ` <8ac60eac0908070030g7500a5ack3fcc81862e2a5b0a@mail.gmail.com>
2009-08-07 23:30                           ` Paul Pluzhnikov
2009-08-09 21:37                             ` Paul Pluzhnikov
2009-08-10 18:09                               ` Tom Tromey
2009-08-10 20:39                                 ` Paul Pluzhnikov
2009-08-17 19:45                               ` Ulrich Weigand
2009-08-17 19:57                                 ` Ulrich Weigand
2009-08-17 22:55                                   ` Paul Pluzhnikov
2009-08-18 13:48                                     ` Ulrich Weigand
2009-08-20 18:03                                       ` Paul Pluzhnikov
2009-08-20 18:39                                         ` Ulrich Weigand
2009-08-20 21:06                                           ` Paul Pluzhnikov
2009-08-20 22:34                                             ` Daniel Jacobowitz
2009-08-21 12:36                                             ` Ulrich Weigand
2009-08-23 23:25                                               ` Paul Pluzhnikov
2009-08-26  7:21                                                 ` Paul Pluzhnikov
2009-08-26 14:37                                                   ` Jan Kratochvil
2009-08-26 14:38                                                     ` Paul Pluzhnikov
2009-08-26 15:17                                                       ` Paul Pluzhnikov
2009-08-26 23:45                                                       ` Jan Kratochvil
2009-08-27  2:56                                                         ` Paul Pluzhnikov
2009-09-02 17:02                                                   ` Paul Pluzhnikov
2009-09-08 18:37                                                     ` What should we do re: "[patch] Speed up find_pc_section" Joel Brobecker
2009-09-08 20:16                                                       ` Paul Pluzhnikov
2009-09-08 21:17                                                         ` Joel Brobecker
2009-09-09  5:58                                                   ` [patch] Speed up find_pc_section Joel Brobecker
2009-09-09  7:56                                                     ` Tristan Gingold
2009-09-09 15:04                                                       ` Joel Brobecker
2009-09-11  7:44                                                         ` Tristan Gingold
2009-09-10 17:36                                                     ` Paul Pluzhnikov
2009-09-10 18:30                                                       ` Joel Brobecker
2009-09-11  1:30                                                         ` Paul Pluzhnikov
2009-09-11  6:51                                                           ` Pierre Muller
2009-09-11  7:29                                                             ` Paul Pluzhnikov
2009-09-11  7:40                                                               ` Mark Kettenis
2009-09-11  7:51                                                                 ` Paul Pluzhnikov
2009-09-11  7:41                                                               ` Pierre Muller
2009-09-11  8:03                                                                 ` Paul Pluzhnikov
2009-09-11  8:41                                                                   ` Pierre Muller
2009-09-11 17:47                                                                     ` Paul Pluzhnikov
2009-09-11 21:15                                                                       ` Joel Brobecker
2009-09-13 21:47                                                                         ` Paul Pluzhnikov
2009-09-14 16:43                                                                           ` Ulrich Weigand
2009-09-14 17:19                                                                             ` Paul Pluzhnikov
2009-09-14 17:36                                                                               ` Joel Brobecker
2009-09-14 18:10                                                                                 ` Paul Pluzhnikov
2009-09-14 18:21                                                                                   ` Joel Brobecker
2009-09-11 20:51                                                               ` Tom Tromey
2009-09-11 21:04                                                                 ` Paul Pluzhnikov
2009-09-11 21:14                                                                   ` Tom Tromey
2009-09-11  7:53                                                       ` Tristan Gingold
2009-09-11  8:33                                                         ` Paul Pluzhnikov
2009-09-11  8:39                                                           ` Tristan Gingold
2009-09-11 16:23                                                             ` Paul Pluzhnikov
2009-09-09  5:39                                                 ` Joel Brobecker
2009-09-10 16:18                                                   ` Paul Pluzhnikov
2009-09-11 21:06                                                     ` Joel Brobecker
2009-09-14 16:41                                                     ` Ulrich Weigand
2009-08-18 18:18                                     ` Michael Snyder
2009-07-17 18:56 ` Paul Pluzhnikov
2009-07-21  3:34   ` Paul Pluzhnikov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8ac60eac0907161724v40e5bd8bg7877d8901b8d7b6e@mail.gmail.com \
    --to=ppluzhnikov@google.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox