binutils-gdb/gas/hash.h
Alan Modra 0edfd2985b gas: use notes_calloc in string hash
Using notes_calloc means all of the string hash table memory should
now be freed before gas exits, even though htab_delete isn't called.
This also means that the hash table free_f and del_f must be NULL,
because freeing notes obstack memory results in all more recently
allocated notes memory being freed too.  So hash table resizing won't
free any memory, and will be a little faster.  Also, htab_delete won't
do anything (and be quick about it).

Since htab_traverse can also resize hash tables (to make another
traversal faster if the table is largely empty), stop that happening
when only one traversal is done.

	* as.h: Reorder hash.h after symbols.h for notes_calloc decl.
	* hash.h (str_htab_create): Use notes_calloc.  Do not free.
	* symbols.c (resolve_local_symbol_values): Don't resize
	during hash table traversal.
	* config/obj-elf.c (elf_frob_file_after_relocs): Likewise.
	* config/tc-ia64.c (ia64_adjust_symtab, ia64_frob_file): Likewise.
	* config/tc-nds32.c (nds32_elf_analysis_relax_hint): Likewise.
2022-07-09 21:47:24 +09:30

106 lines
3.0 KiB
C

/* hash.h -- header file for gas hash table routines
Copyright (C) 1987-2022 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#ifndef HASH_H
#define HASH_H
struct string_tuple
{
const char *key;
const void *value;
};
typedef struct string_tuple string_tuple_t;
/* Hash function for a string_tuple. */
extern hashval_t hash_string_tuple (const void *);
/* Equality function for a string_tuple. */
extern int eq_string_tuple (const void *, const void *);
/* Insert ELEMENT into HTAB. If REPLACE is non-zero existing elements
are overwritten. If ELEMENT already exists, a pointer to the slot
is returned. Otherwise NULL is returned. */
extern void **htab_insert (htab_t, void * /* element */, int /* replace */);
/* Print statistics about a hash table. */
extern void htab_print_statistics (FILE *f, const char *name, htab_t table);
/* Inline string hash table functions. */
static inline string_tuple_t *
string_tuple_alloc (htab_t table, const char *key, const void *value)
{
string_tuple_t *tuple = table->alloc_f (1, sizeof (*tuple));
tuple->key = key;
tuple->value = value;
return tuple;
}
static inline void *
str_hash_find (htab_t table, const char *key)
{
string_tuple_t needle = { key, NULL };
string_tuple_t *tuple = htab_find (table, &needle);
return tuple != NULL ? (void *) tuple->value : NULL;
}
static inline void *
str_hash_find_n (htab_t table, const char *key, size_t n)
{
char *tmp = XNEWVEC (char, n + 1);
memcpy (tmp, key, n);
tmp[n] = '\0';
string_tuple_t needle = { tmp, NULL };
string_tuple_t *tuple = htab_find (table, &needle);
free (tmp);
return tuple != NULL ? (void *) tuple->value : NULL;
}
static inline void
str_hash_delete (htab_t table, const char *key)
{
string_tuple_t needle = { key, NULL };
htab_remove_elt (table, &needle);
}
static inline void **
str_hash_insert (htab_t table, const char *key, const void *value, int replace)
{
string_tuple_t *elt = string_tuple_alloc (table, key, value);
void **slot = htab_insert (table, elt, replace);
if (slot && !replace && table->free_f)
table->free_f (elt);
return slot;
}
static inline htab_t
str_htab_create (void)
{
return htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
NULL, notes_calloc, NULL);
}
#endif /* HASH_H */