aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2024-10-21 17:58:32 +0200
committerMichael Matz <matz@suse.de>2024-10-22 14:14:32 +0200
commit8483536dea6e36e9f4a0949ecad0fcaafd62cf54 (patch)
tree4005f101eaac7be6b39e51468b513511fd4049c0 /bfd
parent4689c9b94690b2cd7c3494d31939afea6594ed8b (diff)
downloadgdb-8483536dea6e36e9f4a0949ecad0fcaafd62cf54.zip
gdb-8483536dea6e36e9f4a0949ecad0fcaafd62cf54.tar.gz
gdb-8483536dea6e36e9f4a0949ecad0fcaafd62cf54.tar.bz2
stringmerge: don't presize hash table
originally the reason for pre-sizing was that that's easier for a multi-threaded use of the hash table. That hasn't materialized yet, so there's not much sense in using the very very conservative estimates for pre-sizing. Doing the resize on-demand, whenever we actually need to add a new entry doesn't change performance. bfd/ merge.c (sec_merge_hash_insert): Resize as needed from here ... (record_section): ... not from here. Don't calculate estimates, return bool instead of three-state, regard all errors as soft errors. (_bfd_merge_sections): Adjust.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/merge.c70
1 files changed, 31 insertions, 39 deletions
diff --git a/bfd/merge.c b/bfd/merge.c
index abb0269..cb8251c 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -244,8 +244,23 @@ sec_merge_hash_insert (struct sec_merge_hash *table,
hashp->alignment = 0;
hashp->u.suffix = NULL;
hashp->next = NULL;
- // We must not need resizing, otherwise the estimation was wrong
- BFD_ASSERT (!NEEDS_RESIZE (bfdtab->count + 1, table->nbuckets));
+
+ if (NEEDS_RESIZE (bfdtab->count + 1, table->nbuckets))
+ {
+ if (!sec_merge_maybe_resize (table, 1))
+ return NULL;
+ uint64_t *key_lens = table->key_lens;
+ unsigned int nbuckets = table->nbuckets;
+ _index = hash & (nbuckets - 1);
+ while (1)
+ {
+ uint64_t candlen = key_lens[_index];
+ if (!(candlen & (uint32_t)-1))
+ break;
+ _index = (_index + 1) & (nbuckets - 1);
+ }
+ }
+
bfdtab->count++;
table->key_lens[_index] = (hash << 32) | (uint32_t)len;
table->values[_index] = hashp;
@@ -699,12 +714,11 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
}
/* Record one whole input section (described by SECINFO) into the hash table
- SINFO. Returns 0 on hard errors (no sense in continuing link),
- 1 when section is completely recorded, and 2 when the section wasn't
- recorded but we can continue (e.g. by simply not deduplicating this
- section). */
+ SINFO. Returns true when section is completely recorded, and false when
+ it wasn't recorded but we can continue (e.g. by simply not deduplicating
+ this section). */
-static int
+static bool
record_section (struct sec_merge_info *sinfo,
struct sec_merge_sec_info *secinfo)
{
@@ -736,15 +750,6 @@ record_section (struct sec_merge_info *sinfo,
/* Now populate the hash table and offset mapping. */
- /* Presize the hash table for what we're going to add. We overestimate
- quite a bit, but if it turns out to be too much then other sections
- merged into this area will make use of that as well. */
- if (!sec_merge_maybe_resize (sinfo->htab, 1 + sec->size / 2))
- {
- free (contents);
- return 2;
- }
-
/* Walk through the contents, calculate hashes and length of all
blobs (strings or fixed-size entries) we find and fill the
hash and offset tables. */
@@ -792,14 +797,12 @@ record_section (struct sec_merge_info *sinfo,
/*printf ("ZZZ %s:%s %u entries\n", sec->owner->filename, sec->name,
(unsigned)secinfo->noffsetmap);*/
- return 1;
+ return true;
error_return:
free (contents);
contents = NULL;
- for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
- *secinfo->psecinfo = NULL;
- return 0;
+ return false;
}
/* qsort comparison function. Won't ever return zero as all entries
@@ -987,31 +990,20 @@ _bfd_merge_sections (bfd *abfd,
/* Record the sections into the hash table. */
align = 1;
for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
- if (secinfo->sec->flags & SEC_EXCLUDE)
+ if (secinfo->sec->flags & SEC_EXCLUDE
+ || !record_section (sinfo, secinfo))
{
*secinfo->psecinfo = NULL;
if (remove_hook)
(*remove_hook) (abfd, secinfo->sec);
}
- else
+ else if (align)
{
- int e = record_section (sinfo, secinfo);
- if (e == 0)
- return false;
- if (e == 2)
- {
- *secinfo->psecinfo = NULL;
- if (remove_hook)
- (*remove_hook) (abfd, secinfo->sec);
- }
- else if (align)
- {
- unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
-
- align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
- if (((secinfo->sec->size / opb) & (align - 1)) != 0)
- align = 0;
- }
+ unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
+
+ align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
+ if (((secinfo->sec->size / opb) & (align - 1)) != 0)
+ align = 0;
}
if (sinfo->htab->first == NULL)