Remove redundant section merge hash table field

sec_merge_hash.size duplicates sec_merge_hash.table.count, albeit using
bfd_size_type rather than unsigned int.  The only reason to have the
duplicate field is to catch unsigned int overflows, and that can be
done easily enough when and if required.  Overflow isn't possible at
the moment.  See the needs_resize comment.

	* merge.c (sec_merge_hash): Remove "size" field.
	(NEEDS_RESIZE): Delete macro, replacing with..
	(needs_resize): ..this inline function.
	(sec_merge_resize): Rename from sec_merge_maybe_resize,
	removing redundant check.
	(sec_merge_hash_insert, sec_merge_hash_lookup): Adjust to suit.
	(sec_merge_init, merge_strings): Likewise.
This commit is contained in:
Alan Modra
2024-10-31 08:50:22 +10:30
parent a3741bc6c7
commit 510fa4aadb

View File

@@ -73,8 +73,6 @@ struct sec_merge_hash_entry
struct sec_merge_hash
{
struct bfd_hash_table table;
/* Next available index. */
bfd_size_type size;
/* First entity in the SEC_MERGE sections of this type. */
struct sec_merge_hash_entry *first;
/* Last entity in the SEC_MERGE sections of this type. */
@@ -94,10 +92,6 @@ struct sec_merge_hash
struct sec_merge_hash_entry **values;
};
/* True when given NEWCOUNT and NBUCKETS indicate that the hash table needs
resizing. */
#define NEEDS_RESIZE(newcount, nbuckets) ((newcount) > (nbuckets) / 3 * 2)
struct sec_merge_sec_info;
/* Information per merged blob. This is the unit of merging and is
@@ -163,63 +157,75 @@ struct sec_merge_sec_info
};
/* True when COUNT+ADDED and NBUCKETS indicate that the hash table
needs resizing. */
static inline bool
needs_resize (unsigned int count, unsigned int added, unsigned int nbuckets)
{
/* This doesn't consider the possibility of "count" + "added"
overflowing, because that can't happen given current usage. If
code calling this function changes then that assumption may no
longer be correct. Currently "added" is always 1 and "nbuckets"
is limited to 0x80000000. We'll attempt and fail resizing at
"count" of 0x55555555. */
return count + added > nbuckets / 3 * 2;
}
/* Given a merge hash table TABLE and a number of entries to be
ADDED, possibly resize the table for this to fit without further
resizing. Returns false if that can't be done for whatever reason. */
ADDED, resize the table for this to fit.
Returns false if that can't be done for whatever reason. */
static bool
sec_merge_maybe_resize (struct sec_merge_hash *table, unsigned added)
sec_merge_resize (struct sec_merge_hash *table, unsigned added)
{
struct bfd_hash_table *bfdtab = &table->table;
if (NEEDS_RESIZE (bfdtab->count + added, table->nbuckets))
unsigned i;
unsigned long newnb = table->nbuckets;
struct sec_merge_hash_entry **newv;
uint64_t *newl;
unsigned long alloc;
do
{
unsigned i;
unsigned long newnb = table->nbuckets;
struct sec_merge_hash_entry **newv;
uint64_t *newl;
unsigned long alloc;
do
{
if (newnb >> (8 * sizeof(mapofs_type) - 1))
return false;
newnb *= 2;
}
while (NEEDS_RESIZE (bfdtab->count + added, newnb));
alloc = newnb * sizeof (newl[0]);
if (alloc / sizeof (newl[0]) != newnb)
if (newnb >> (8 * sizeof(mapofs_type) - 1))
return false;
newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
if (newl == NULL)
return false;
memset (newl, 0, alloc);
alloc = newnb * sizeof (newv[0]);
if (alloc / sizeof (newv[0]) != newnb)
return false;
newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
if (newv == NULL)
return false;
memset (newv, 0, alloc);
for (i = 0; i < table->nbuckets; i++)
{
struct sec_merge_hash_entry *v = table->values[i];
if (v)
{
uint32_t thishash = table->key_lens[i] >> 32;
unsigned idx = thishash & (newnb - 1);
while (newv[idx])
idx = (idx + 1) & (newnb - 1);
newl[idx] = table->key_lens[i];
newv[idx] = v;
}
}
table->key_lens = newl;
table->values = newv;
table->nbuckets = newnb;
newnb *= 2;
}
while (needs_resize (bfdtab->count, added, newnb));
alloc = newnb * sizeof (newl[0]);
if (alloc / sizeof (newl[0]) != newnb)
return false;
newl = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
if (newl == NULL)
return false;
memset (newl, 0, alloc);
alloc = newnb * sizeof (newv[0]);
if (alloc / sizeof (newv[0]) != newnb)
return false;
newv = objalloc_alloc ((struct objalloc *) table->table.memory, alloc);
if (newv == NULL)
return false;
memset (newv, 0, alloc);
for (i = 0; i < table->nbuckets; i++)
{
struct sec_merge_hash_entry *v = table->values[i];
if (v)
{
uint32_t thishash = table->key_lens[i] >> 32;
unsigned idx = thishash & (newnb - 1);
while (newv[idx])
idx = (idx + 1) & (newnb - 1);
newl[idx] = table->key_lens[i];
newv[idx] = v;
}
}
table->key_lens = newl;
table->values = newv;
table->nbuckets = newnb;
return true;
}
@@ -245,9 +251,9 @@ sec_merge_hash_insert (struct sec_merge_hash *table,
hashp->u.suffix = NULL;
hashp->next = NULL;
if (NEEDS_RESIZE (bfdtab->count + 1, table->nbuckets))
if (needs_resize (bfdtab->count, 1, table->nbuckets))
{
if (!sec_merge_maybe_resize (table, 1))
if (!sec_merge_resize (table, 1))
return NULL;
uint64_t *key_lens = table->key_lens;
unsigned int nbuckets = table->nbuckets;
@@ -422,8 +428,6 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
return NULL;
hashp->alignment = alignment;
table->size++;
BFD_ASSERT (table->size == table->table.count);
if (table->first == NULL)
table->first = hashp;
else
@@ -451,7 +455,6 @@ sec_merge_init (unsigned int entsize, bool strings)
return NULL;
}
table->size = 0;
table->first = NULL;
table->last = NULL;
table->entsize = entsize;
@@ -883,7 +886,7 @@ merge_strings (struct sec_merge_info *sinfo)
unsigned int alignment = 0;
/* Now sort the strings */
amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
amt = sinfo->htab->table.count * sizeof (struct sec_merge_hash_entry *);
array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
if (array == NULL)
return NULL;
@@ -903,10 +906,10 @@ merge_strings (struct sec_merge_info *sinfo)
}
}
sinfo->htab->size = a - array;
if (sinfo->htab->size != 0)
size_t asize = a - array;
if (asize != 0)
{
qsort (array, (size_t) sinfo->htab->size,
qsort (array, asize,
sizeof (struct sec_merge_hash_entry *),
(alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
? strrevcmp_align : strrevcmp));