From: Roland McGrath Date: Wed, 30 Jun 2010 09:16:39 +0000 (-0700) Subject: Optimize libdw reloc sorting. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=00501d248a9712bfa0e0272b36e9db1725437c5c;p=thirdparty%2Felfutils.git Optimize libdw reloc sorting. --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index c51abc604..113ba7a84 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2010-06-30 Roland McGrath + + * relocate.c (digest_relocs, compare_digested_reloc): Use qsort on an + array of pointers, not structs. + 2010-06-29 Roland McGrath * libdwP.h (dwarf_file_reloc): Remove resolve_symbol member, diff --git a/libdw/relocate.c b/libdw/relocate.c index 8ac07ff92..ae4211a5e 100644 --- a/libdw/relocate.c +++ b/libdw/relocate.c @@ -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);