mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
0edfd2985b
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.
106 lines
3.0 KiB
C
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 */
|