Skip to content

Commit

Permalink
Fix slowdown about partial linking (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
ywgrit authored Jan 20, 2025
1 parent 9a16a45 commit 7373dec
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
binutils (2.41-6deepin7) unstable; urgency=medium

* Fix slowdown about partial linking.

-- Xin Wang <[email protected]> Tue, 16 Jan 2025 15:33 +0800

binutils (2.41-6deepin6) unstable; urgency=medium

* Disable gold linker for MIPS targets as they are broken as of 2.41.
Expand Down
144 changes: 144 additions & 0 deletions debian/patches/PR32238-ld-r-slowdown-since-21401fc7bf.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
From 8455910b34f9fbf0bc43915418617641db55f883 Mon Sep 17 00:00:00 2001
From: Alan Modra <[email protected]>
Date: Sat, 4 Jan 2025 11:33:27 +1030
Subject: [PATCH] PR32238, ld -r slowdown since 21401fc7bf

PR 32238
* ldlang.c (struct out_section_hash_entry): Add "tail".
(output_section_statement_newfunc_1): New, extracted from..
(output_section_statement_newfunc): ..here. Init tail.
(lang_output_section_statement_lookup): Use tail to avoid
list traversal.
---
ld/ldlang.c | 66 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 21 deletions(-)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index a357f80235f..3b6b8563c49 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1246,6 +1246,7 @@ struct out_section_hash_entry
{
struct bfd_hash_entry root;
lang_statement_union_type s;
+ struct out_section_hash_entry *tail;
};

/* The hash table. */
@@ -1255,10 +1256,10 @@ static struct bfd_hash_table output_section_statement_table;
/* Support routines for the hash table used by lang_output_section_find,
initialize the table, fill in an entry and remove the table. */

-static struct bfd_hash_entry *
-output_section_statement_newfunc (struct bfd_hash_entry *entry,
- struct bfd_hash_table *table,
- const char *string)
+static struct out_section_hash_entry *
+output_section_statement_newfunc_1 (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
{
lang_output_section_statement_type **nextp;
struct out_section_hash_entry *ret;
@@ -1268,12 +1269,12 @@ output_section_statement_newfunc (struct bfd_hash_entry *entry,
entry = (struct bfd_hash_entry *) bfd_hash_allocate (table,
sizeof (*ret));
if (entry == NULL)
- return entry;
+ return NULL;
}

entry = bfd_hash_newfunc (entry, table, string);
if (entry == NULL)
- return entry;
+ return NULL;

ret = (struct out_section_hash_entry *) entry;
memset (&ret->s, 0, sizeof (ret->s));
@@ -1298,6 +1299,20 @@ output_section_statement_newfunc (struct bfd_hash_entry *entry,
instead. */
nextp = &ret->s.output_section_statement.next;
lang_statement_append (&lang_os_list, &ret->s, nextp);
+ return ret;
+}
+
+static struct bfd_hash_entry *
+output_section_statement_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct out_section_hash_entry *ret;
+
+ ret = output_section_statement_newfunc_1 (entry, table, string);
+ if (ret == NULL)
+ return NULL;
+ ret->tail = ret;
return &ret->root;
}

@@ -1523,31 +1538,39 @@ lang_output_section_statement_lookup (const char *name,
{
/* We have a section of this name, but it might not have the correct
constraint. */
+ struct out_section_hash_entry *first_ent = entry;
struct out_section_hash_entry *last_ent;

name = entry->s.output_section_statement.name;
- do
+ if (create != 2
+ && !(create && constraint == SPECIAL))
{
- if (create != 2
- && !(create && constraint == SPECIAL)
- && (constraint == entry->s.output_section_statement.constraint
+ do
+ {
+ if (constraint == entry->s.output_section_statement.constraint
|| (constraint == 0
- && entry->s.output_section_statement.constraint >= 0)))
- return &entry->s.output_section_statement;
- last_ent = entry;
- entry = (struct out_section_hash_entry *) entry->root.next;
+ && entry->s.output_section_statement.constraint >= 0))
+ return &entry->s.output_section_statement;
+ last_ent = entry;
+ entry = (struct out_section_hash_entry *) entry->root.next;
+ }
+ while (entry != NULL
+ && name == entry->s.output_section_statement.name);
}
- while (entry != NULL
- && name == entry->s.output_section_statement.name);
+ else
+ last_ent = first_ent->tail;

if (!create)
return NULL;

- entry
- = ((struct out_section_hash_entry *)
- output_section_statement_newfunc (NULL,
- &output_section_statement_table,
- name));
+ /* Only the first entry needs the tail pointer. */
+ entry = bfd_hash_allocate (&output_section_statement_table,
+ offsetof (struct out_section_hash_entry, tail));
+ if (entry != NULL)
+ entry
+ = output_section_statement_newfunc_1 (&entry->root,
+ &output_section_statement_table,
+ name);
if (entry == NULL)
{
einfo (_("%F%P: failed creating section `%s': %E\n"), name);
@@ -1555,6 +1578,7 @@ lang_output_section_statement_lookup (const char *name,
}
entry->root = last_ent->root;
last_ent->root.next = &entry->root;
+ first_ent->tail = entry;
}

entry->s.output_section_statement.name = name;
--
2.45.2

1 change: 1 addition & 0 deletions debian/patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,4 @@ remove-file-produced-by-bison.patch
replace-space-with-tab.patch
LoongArch-binutils-compatible-with-older-gcc.diff
LoongArch-remove-test-cases-for-compatibility.patch
PR32238-ld-r-slowdown-since-21401fc7bf.patch

0 comments on commit 7373dec

Please sign in to comment.