aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorJens Widell <jl@opera.com>2018-01-12 13:16:17 +0000
committerNick Clifton <nickc@redhat.com>2018-01-12 13:16:17 +0000
commit564e11c9a9d9570b233b38cd995f1b4eb7c757e8 (patch)
tree3282d9d08f64efc2e2f10ba13f89f3552b366050 /bfd/elf.c
parentb5b62006522c6d8d42028754bb1be165f00fe210 (diff)
downloadgdb-564e11c9a9d9570b233b38cd995f1b4eb7c757e8.zip
gdb-564e11c9a9d9570b233b38cd995f1b4eb7c757e8.tar.gz
gdb-564e11c9a9d9570b233b38cd995f1b4eb7c757e8.tar.bz2
Optimize the performance of the group_setup function.
When processing a section that is a member of a group, the group that contains it is looked up using a linear search. The resulting O(n^2) complexity causes significant performance issues when dealing with object files with very many groups. By remembering the index of the last found group and restarting the next search from that index, the search instead becomes O(n) in common cases. * elf.c (setup_group): Optimize search for group by remembering last found group and restarting search at that index. * elf-bfd.h (struct elf_obj_tdata): Add group_search_offset field.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 1d0eefd..90aef09 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -737,10 +737,14 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
if (num_group != (unsigned) -1)
{
- unsigned int i;
+ unsigned int search_offset = elf_tdata (abfd)->group_search_offset;
+ unsigned int j;
- for (i = 0; i < num_group; i++)
+ for (j = 0; j < num_group; j++)
{
+ /* Begin search from previous found group. */
+ unsigned i = (j + search_offset) % num_group;
+
Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
Elf_Internal_Group *idx;
bfd_size_type n_elt;
@@ -803,7 +807,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
if (shdr->bfd_section != NULL)
elf_next_in_group (shdr->bfd_section) = newsect;
- i = num_group - 1;
+ elf_tdata (abfd)->group_search_offset = i;
+ j = num_group - 1;
break;
}
}