public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] elf: Always keep symbol table and relocation info for eh_frame
@ 2024-04-03 16:17 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2024-04-03 16:17 UTC (permalink / raw)
  To: binutils-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3428c771aef0cebe229ac0f02a654d2ef78f2427

commit 3428c771aef0cebe229ac0f02a654d2ef78f2427
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Mar 8 16:21:42 2024 -0800

    elf: Always keep symbol table and relocation info for eh_frame
    
    When --no-keep-memory is used, the symbol table and relocation info for
    eh_frame are freed after they are retrieved for each text section in the
    input object.  If an input object has many text sections, the same data
    is retrieved and freed many times which can take a very long time.
    Update _bfd_elf_gc_mark to keep the symbol table and relocation info for
    eh_frame to avoid it.  Data to link the 3.5GB clang executable in LLVM
    17 debug build on Linux/x86-64 with 32GB RAM is:
    
                    before          after           improvement
    user            86.31           86.44           -0.2%
    system          8.77            8.63            1.6%
    total           95.58           96.81           -1.3%
    maximum set(GB) 13.1            13.1            0%
    page faults     3024752         3028699         -1.3%
    
    and data to link the 275M cc1plus executable in GCC 14 stage 1 build is:
    
    user            5.49            5.46            -0.5%
    system          0.73            0.73            0%
    total           6.26            6.25            0.3%
    maximum set(MB) 964             964             0%
    page faults     235173          235796          -0.3%
    
    The memory usage impact is minimum and the link time of the Rust binary
    in
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=31466
    
    is reduced from 500+ seconds to 1.44 seconds, a 300x speedup.
    
            PR ld/31466
            * elflink.c (init_reloc_cookie): Add a bool argument, keep_memory,
            for keeping memory.  Always keep memory if keep_memory is true.
            (init_reloc_cookie_rels): Likewise
            (init_reloc_cookie_for_section): Add a bool argument for keeping
            memory and pass it to init_reloc_cookie and
            init_reloc_cookie_rels.
            (_bfd_elf_gc_mark_reloc): Pass false to _bfd_elf_gc_mark.
            (_bfd_elf_gc_mark): Pass true to init_reloc_cookie_for_section
            for the eh_frame section.  Pass false to
            init_reloc_cookie_for_section for other sections.
            (_bfd_elf_gc_mark_extra_sections): Add Add a bool argument for
            keeping memory and pass it to _bfd_elf_gc_mark.
            (bfd_elf_parse_eh_frame_entries): Pass false to init_reloc_cookie
            and init_reloc_cookie_rels.
            (bfd_elf_gc_sections): Pass false to init_reloc_cookie_for_section
            and _bfd_elf_gc_mark.
            (bfd_elf_discard_info): Pass false to
            init_reloc_cookie_for_section and init_reloc_cookie.

Diff:
---
 bfd/elflink.c | 43 +++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7a33da0a96c..a7b50bfcaf9 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13623,7 +13623,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
 static bool
 init_reloc_cookie (struct elf_reloc_cookie *cookie,
-		   struct bfd_link_info *info, bfd *abfd)
+		   struct bfd_link_info *info, bfd *abfd,
+		   bool keep_memory)
 {
   Elf_Internal_Shdr *symtab_hdr;
   const struct elf_backend_data *bed;
@@ -13661,7 +13662,7 @@ init_reloc_cookie (struct elf_reloc_cookie *cookie,
 	  info->callbacks->einfo (_("%P%X: can not read symbols: %E\n"));
 	  return false;
 	}
-      if (_bfd_elf_link_keep_memory (info) )
+      if (keep_memory || _bfd_elf_link_keep_memory (info))
 	{
 	  symtab_hdr->contents = (bfd_byte *) cookie->locsyms;
 	  info->cache_size += (cookie->locsymcount
@@ -13689,7 +13690,7 @@ fini_reloc_cookie (struct elf_reloc_cookie *cookie, bfd *abfd)
 static bool
 init_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
 			struct bfd_link_info *info, bfd *abfd,
-			asection *sec)
+			asection *sec, bool keep_memory)
 {
   if (sec->reloc_count == 0)
     {
@@ -13700,7 +13701,7 @@ init_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
     {
       cookie->rels = _bfd_elf_link_info_read_relocs
 	(abfd, info, sec, NULL, NULL,
-	 _bfd_elf_link_keep_memory (info));
+	 keep_memory || _bfd_elf_link_keep_memory (info));
       if (cookie->rels == NULL)
 	return false;
       cookie->rel = cookie->rels;
@@ -13726,11 +13727,12 @@ fini_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
 static bool
 init_reloc_cookie_for_section (struct elf_reloc_cookie *cookie,
 			       struct bfd_link_info *info,
-			       asection *sec)
+			       asection *sec, bool keep_memory)
 {
-  if (!init_reloc_cookie (cookie, info, sec->owner))
+  if (!init_reloc_cookie (cookie, info, sec->owner, keep_memory))
     goto error1;
-  if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec))
+  if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec,
+			       keep_memory))
     goto error2;
   return true;
 
@@ -13941,7 +13943,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
     {
       struct elf_reloc_cookie cookie;
 
-      if (!init_reloc_cookie_for_section (&cookie, info, sec))
+      if (!init_reloc_cookie_for_section (&cookie, info, sec, false))
 	ret = false;
       else
 	{
@@ -13959,7 +13961,14 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
     {
       struct elf_reloc_cookie cookie;
 
-      if (!init_reloc_cookie_for_section (&cookie, info, eh_frame))
+      /* NB: When --no-keep-memory is used, the symbol table and
+	 relocation info for eh_frame are freed after they are retrieved
+	 for each text section in the input object.  If an input object
+	 has many text sections, the same data is retrieved and freed
+	 many times which can take a very long time.  Always keep the
+	 symbol table and relocation info for eh_frame to avoid it.  */
+      if (!init_reloc_cookie_for_section (&cookie, info, eh_frame,
+					  true))
 	ret = false;
       else
 	{
@@ -14399,13 +14408,14 @@ bfd_elf_parse_eh_frame_entries (bfd *abfd ATTRIBUTE_UNUSED,
       if (sec == NULL || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
 	continue;
 
-      if (!init_reloc_cookie (&cookie, info, ibfd))
+      if (!init_reloc_cookie (&cookie, info, ibfd, false))
 	return false;
 
       for (sec = ibfd->sections; sec; sec = sec->next)
 	{
 	  if (startswith (bfd_section_name (sec), ".eh_frame_entry")
-	      && init_reloc_cookie_rels (&cookie, info, ibfd, sec))
+	      && init_reloc_cookie_rels (&cookie, info, ibfd, sec,
+					 false))
 	    {
 	      _bfd_elf_parse_eh_frame_entry (info, sec, &cookie);
 	      fini_reloc_cookie_rels (&cookie, sec);
@@ -14450,7 +14460,8 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
       if (sec == NULL || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
 	continue;
       sec = bfd_get_section_by_name (sub, ".eh_frame");
-      while (sec && init_reloc_cookie_for_section (&cookie, info, sec))
+      while (sec && init_reloc_cookie_for_section (&cookie, info, sec,
+						   false))
 	{
 	  _bfd_elf_parse_eh_frame (sub, info, sec, &cookie);
 	  if (elf_section_data (sec)->sec_info
@@ -14962,7 +14973,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 	  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
 	    continue;
 
-	  if (!init_reloc_cookie_for_section (&cookie, info, i))
+	  if (!init_reloc_cookie_for_section (&cookie, info, i, false))
 	    return -1;
 
 	  if (_bfd_discard_section_stabs (abfd, i,
@@ -14993,7 +15004,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 	  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
 	    continue;
 
-	  if (!init_reloc_cookie_for_section (&cookie, info, i))
+	  if (!init_reloc_cookie_for_section (&cookie, info, i, false))
 	    return -1;
 
 	  _bfd_elf_parse_eh_frame (abfd, info, i, &cookie);
@@ -15058,7 +15069,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 	  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
 	    continue;
 
-	  if (!init_reloc_cookie_for_section (&cookie, info, i))
+	  if (!init_reloc_cookie_for_section (&cookie, info, i, false))
 	    return -1;
 
 	  if (_bfd_elf_parse_sframe (abfd, info, i, &cookie))
@@ -15094,7 +15105,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
 
       if (bed->elf_backend_discard_info != NULL)
 	{
-	  if (!init_reloc_cookie (&cookie, info, abfd))
+	  if (!init_reloc_cookie (&cookie, info, abfd, false))
 	    return -1;
 
 	  if ((*bed->elf_backend_discard_info) (abfd, &cookie, info))

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-03 16:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-03 16:17 [binutils-gdb] elf: Always keep symbol table and relocation info for eh_frame H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).