]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Optimize libdw reloc sorting.
authorRoland McGrath <roland@redhat.com>
Wed, 30 Jun 2010 09:16:39 +0000 (02:16 -0700)
committerRoland McGrath <roland@redhat.com>
Wed, 30 Jun 2010 09:16:39 +0000 (02:16 -0700)
libdw/ChangeLog
libdw/relocate.c

index c51abc60483e856006715b8e6f3ac89265a29a11..113ba7a84387fbc2928e3219aef8967a4984aba5 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-30  Roland McGrath  <roland@redhat.com>
+
+       * relocate.c (digest_relocs, compare_digested_reloc): Use qsort on an
+       array of pointers, not structs.
+
 2010-06-29  Roland McGrath  <roland@redhat.com>
 
        * libdwP.h (dwarf_file_reloc): Remove resolve_symbol member,
index 8ac07ff929e34d30e1d884d8f43b86ef9ce15d45..ae4211a5e90df65cf468a591aafce6c5efcceaf7 100644 (file)
@@ -216,9 +216,9 @@ digest_one_reloc (const int *rel8_types, const int *rel4_types,
 static int
 compare_digested_reloc (const void *a, const void *b)
 {
-  const struct digested_reloc *r1 = a;
-  const struct digested_reloc *r2 = b;
-  return r1->datum > r2->datum ? 1 : r1->datum < r2->datum ? -1 : 0;
+  const struct digested_reloc *const *r1 = a;
+  const struct digested_reloc *const *r2 = b;
+  return (*r1)->datum > (*r2)->datum ? 1 : (*r1)->datum < (*r2)->datum ? -1 : 0;
 }
 
 static int
@@ -291,8 +291,16 @@ digest_relocs (Dwarf *dbg, Elf_Data *data, struct dwarf_section_reloc *r)
   if (ret)
     return ret;
 
+  /* qsort is much faster when it only copies pointers.
+     So make another array of pointers for the sorting.  */
+
+  struct digested_reloc *sort_digest[d - digest];
+  for (size_t i = 0; i < (size_t) (d - digest); ++i)
+    sort_digest[i] = &digest[i];
+
   /* Sort by datum address.  */
-  qsort (digest, d - digest, sizeof digest[0], &compare_digested_reloc);
+  qsort (sort_digest, d - digest, sizeof sort_digest[0],
+        &compare_digested_reloc);
 
   if (r->rel8.n > 0)
     {
@@ -322,23 +330,27 @@ digest_relocs (Dwarf *dbg, Elf_Data *data, struct dwarf_section_reloc *r)
 
   size_t n8 = 0;
   size_t n4 = 0;
-  for (struct digested_reloc *dr = digest; dr < d; ++dr)
-    if (dr->rel8)
-      {
-       r->rel8.datum[n8] = dr->datum;
-       r->rel8.symndx[n8] = dr->symndx;
-       if (shdr.sh_type == SHT_RELA)
-         r->rela8[n8] = dr->addend;
-       ++n8;
-      }
-    else
-      {
-       r->rel4.datum[n4] = dr->datum;
-       r->rel4.symndx[n4] = dr->symndx;
-       if (shdr.sh_type == SHT_RELA)
-         r->rela4[n4] = dr->addend;
-       ++n4;
-      }
+
+  for (size_t i = 0; i < (size_t) (d - digest); ++i)
+    {
+      struct digested_reloc *dr = sort_digest[i];
+      if (dr->rel8)
+       {
+         r->rel8.datum[n8] = dr->datum;
+         r->rel8.symndx[n8] = dr->symndx;
+         if (shdr.sh_type == SHT_RELA)
+           r->rela8[n8] = dr->addend;
+         ++n8;
+       }
+      else
+       {
+         r->rel4.datum[n4] = dr->datum;
+         r->rel4.symndx[n4] = dr->symndx;
+         if (shdr.sh_type == SHT_RELA)
+           r->rela4[n4] = dr->addend;
+         ++n4;
+       }
+    }
   assert (n8 == r->rel8.n);
   assert (n4 == r->rel4.n);