This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH: Speed up _bfd_elf_make_section_from_shdr
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Sun, 8 May 2005 12:09:03 -0700
- Subject: PATCH: Speed up _bfd_elf_make_section_from_shdr
We are checking SEC_DEBUGGING for all sections and we call strlen on
const strings. This patch avoids those. For ranlib on libgcj.a, I got:
Before
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
13.82 0.55 0.55 4860 0.00 0.00 bfd_hash_table_init_n
12.31 1.04 0.49 102374 0.00 0.00 _bfd_elf_make_section_from_shdr
11.18 1.49 0.45 2429 0.00 0.00 bfd_elf32_slurp_symbol_table
After
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
18.33 0.44 0.44 4860 0.00 0.00 bfd_hash_table_init_n
10.42 0.69 0.25 2429 0.00 0.00 bfd_elf32_slurp_symbol_table
9.17 0.91 0.22 2171203 0.00 0.00 bfd_getl32
7.50 1.09 0.18 102374 0.00 0.00 _bfd_elf_make_section_from_shdr
H.J.
---
2005-05-08 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (_bfd_elf_make_section_from_shdr): Only check debug
section if SEC_ALLOC isn't set.
--- bfd/elf.c.debug 2005-05-07 06:58:09.000000000 -0700
+++ bfd/elf.c 2005-05-08 12:03:25.000000000 -0700
@@ -750,25 +750,45 @@ _bfd_elf_make_section_from_shdr (bfd *ab
if ((hdr->sh_flags & SHF_TLS) != 0)
flags |= SEC_THREAD_LOCAL;
- /* The debugging sections appear to be recognized only by name, not
- any sort of flag. */
- {
- static const char *debug_sec_names [] =
+ if ((flags & SEC_ALLOC) == 0)
{
- ".debug",
- ".gnu.linkonce.wi.",
- ".line",
- ".stab"
- };
- int i;
-
- for (i = ARRAY_SIZE (debug_sec_names); i--;)
- if (strncmp (name, debug_sec_names[i], strlen (debug_sec_names[i])) == 0)
- break;
-
- if (i >= 0)
- flags |= SEC_DEBUGGING;
- }
+ /* The debugging sections appear to be recognized only by name,
+ not any sort of flag. Their SEC_ALLOC bits are cleared. */
+ static const struct
+ {
+ const char *name;
+ int len;
+ } debug_sections [] =
+ {
+ { "debug", 5 }, /* 'd' */
+ { NULL, 0 }, /* 'e' */
+ { NULL, 0 }, /* 'f' */
+ { "gnu.linkonce.wi.", 17 }, /* 'g' */
+ { NULL, 0 }, /* 'h' */
+ { NULL, 0 }, /* 'i' */
+ { NULL, 0 }, /* 'j' */
+ { NULL, 0 }, /* 'k' */
+ { "line", 4 }, /* 'l' */
+ { NULL, 0 }, /* 'm' */
+ { NULL, 0 }, /* 'n' */
+ { NULL, 0 }, /* 'o' */
+ { NULL, 0 }, /* 'p' */
+ { NULL, 0 }, /* 'q' */
+ { NULL, 0 }, /* 'r' */
+ { "stab", 4 } /* 's' */
+ };
+
+ if (name [0] == '.')
+ {
+ int i = name [1] - 'd';
+ if (i >= 0
+ && i < (int) ARRAY_SIZE (debug_sections)
+ && debug_sections [i].name != NULL
+ && strncmp (&name [1], debug_sections [i].name,
+ debug_sections [i].len) == 0)
+ flags |= SEC_DEBUGGING;
+ }
+ }
/* As a GNU extension, if the name begins with .gnu.linkonce, we
only link a single copy of the section. This is used to support