aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-open.c
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2023-12-18 17:47:48 +0000
committerNick Alcock <nick.alcock@oracle.com>2024-04-19 16:14:46 +0100
commit54a0219150d9dd2b0034e9682072900d4ec403b3 (patch)
treee27705e3a8e7045f642e26330bacb5020b415d79 /libctf/ctf-open.c
parentca019227843f62f5ac0a1c432680e3ca05c4377b (diff)
downloadgdb-54a0219150d9dd2b0034e9682072900d4ec403b3.zip
gdb-54a0219150d9dd2b0034e9682072900d4ec403b3.tar.gz
gdb-54a0219150d9dd2b0034e9682072900d4ec403b3.tar.bz2
libctf: remove static/dynamic name lookup distinction
libctf internally maintains a set of hash tables for type name lookups, one for each valid C type namespace (struct, union, enum, and everything else). Or, rather, it maintains *two* sets of hash tables: one, a ctf_hash *, is meant for lookups in ctf_(buf)open()ed dicts with fixed content; the other, a ctf_dynhash *, is meant for lookups in ctf_create()d dicts. This distinction was somewhat valuable in the far pre-binutils past when two different hashtable implementations were used (one expanding, the other fixed-size), but those days are long gone: the hash table implementations are almost identical, both wrappers around the libiberty hashtab. The ctf_dynhash has many more capabilities than the ctf_hash (iteration, deletion, etc etc) and has no downsides other than starting at a fixed, arbitrary small size. That limitation is easy to lift (via a new ctf_dynhash_create_sized()), following which we can throw away nearly all the ctf_hash implementation, and all the code to choose between readable and writable hashtabs; the few convenience functions that are still useful (for insertion of name -> type mappings) can also be generalized a bit so that the extra string verification they do is potentially available to other string lookups as well. (libctf still has two hashtable implementations, ctf_dynhash, above, and ctf_dynset, which is a key-only hashtab that can avoid a great many malloc()s, used for high-volume applications in the deduplicator.) libctf/ * ctf-create.c (ctf_create): Eliminate ctn_writable. (ctf_dtd_insert): Likewise. (ctf_dtd_delete): Likewise. (ctf_rollback): Likewise. (ctf_name_table): Eliminate ctf_names_t. * ctf-hash.c (ctf_dynhash_create): Comment update. Reimplement in terms of... (ctf_dynhash_create_sized): ... this new function. (ctf_hash_create): Remove. (ctf_hash_size): Remove. (ctf_hash_define_type): Remove. (ctf_hash_destroy): Remove. (ctf_hash_lookup_type): Rename to... (ctf_dynhash_lookup_type): ... this. (ctf_hash_insert_type): Rename to... (ctf_dynhash_insert_type): ... this, moving validation to... * ctf-string.c (ctf_strptr_validate): ... this new function. * ctf-impl.h (struct ctf_names): Extirpate. (struct ctf_lookup.ctl_hash): Now a ctf_dynhash_t. (struct ctf_dict): All ctf_names_t fields are now ctf_dynhash_t. (ctf_name_table): Now returns a ctf_dynhash_t. (ctf_lookup_by_rawhash): Remove. (ctf_hash_create): Likewise. (ctf_hash_insert_type): Likewise. (ctf_hash_define_type): Likewise. (ctf_hash_lookup_type): Likewise. (ctf_hash_size): Likewise. (ctf_hash_destroy): Likewise. (ctf_dynhash_create_sized): New. (ctf_dynhash_insert_type): New. (ctf_dynhash_lookup_type): New. (ctf_strptr_validate): New. * ctf-lookup.c (ctf_lookup_by_name_internal): Adapt. * ctf-open.c (init_types): Adapt. (ctf_set_ctl_hashes): Adapt. (ctf_dict_close): Adapt. * ctf-serialize.c (ctf_serialize): Adapt. * ctf-types.c (ctf_lookup_by_rawhash): Remove.
Diffstat (limited to 'libctf/ctf-open.c')
-rw-r--r--libctf/ctf-open.c137
1 files changed, 63 insertions, 74 deletions
diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c
index cf0cb54..2945228 100644
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -740,33 +740,33 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
/* Now that we've counted up the number of each type, we can allocate
the hash tables, type translation table, and pointer table. */
- if ((fp->ctf_structs.ctn_readonly
- = ctf_hash_create (pop[CTF_K_STRUCT], ctf_hash_string,
- ctf_hash_eq_string)) == NULL)
+ if ((fp->ctf_structs
+ = ctf_dynhash_create_sized (pop[CTF_K_STRUCT], ctf_hash_string,
+ ctf_hash_eq_string, NULL, NULL)) == NULL)
return ENOMEM;
- if ((fp->ctf_unions.ctn_readonly
- = ctf_hash_create (pop[CTF_K_UNION], ctf_hash_string,
- ctf_hash_eq_string)) == NULL)
+ if ((fp->ctf_unions
+ = ctf_dynhash_create_sized (pop[CTF_K_UNION], ctf_hash_string,
+ ctf_hash_eq_string, NULL, NULL)) == NULL)
return ENOMEM;
- if ((fp->ctf_enums.ctn_readonly
- = ctf_hash_create (pop[CTF_K_ENUM], ctf_hash_string,
- ctf_hash_eq_string)) == NULL)
+ if ((fp->ctf_enums
+ = ctf_dynhash_create_sized (pop[CTF_K_ENUM], ctf_hash_string,
+ ctf_hash_eq_string, NULL, NULL)) == NULL)
return ENOMEM;
- if ((fp->ctf_names.ctn_readonly
- = ctf_hash_create (pop[CTF_K_UNKNOWN] +
- pop[CTF_K_INTEGER] +
- pop[CTF_K_FLOAT] +
- pop[CTF_K_FUNCTION] +
- pop[CTF_K_TYPEDEF] +
- pop[CTF_K_POINTER] +
- pop[CTF_K_VOLATILE] +
- pop[CTF_K_CONST] +
- pop[CTF_K_RESTRICT],
- ctf_hash_string,
- ctf_hash_eq_string)) == NULL)
+ if ((fp->ctf_names
+ = ctf_dynhash_create_sized (pop[CTF_K_UNKNOWN] +
+ pop[CTF_K_INTEGER] +
+ pop[CTF_K_FLOAT] +
+ pop[CTF_K_FUNCTION] +
+ pop[CTF_K_TYPEDEF] +
+ pop[CTF_K_POINTER] +
+ pop[CTF_K_VOLATILE] +
+ pop[CTF_K_CONST] +
+ pop[CTF_K_RESTRICT],
+ ctf_hash_string,
+ ctf_hash_eq_string, NULL, NULL)) == NULL)
return ENOMEM;
fp->ctf_txlate = malloc (sizeof (uint32_t) * (fp->ctf_typemax + 1));
@@ -810,11 +810,10 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
root-visible version so that we can be sure to find it when
checking for conflicting definitions in ctf_add_type(). */
- if (((ctf_hash_lookup_type (fp->ctf_names.ctn_readonly,
- fp, name)) == 0)
+ if (((ctf_dynhash_lookup_type (fp->ctf_names, name)) == 0)
|| isroot)
{
- err = ctf_hash_define_type (fp->ctf_names.ctn_readonly, fp,
+ err = ctf_dynhash_insert_type (fp, fp->ctf_names,
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
if (err != 0)
@@ -832,9 +831,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
if (!isroot)
break;
- err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, fp->ctf_names,
+ LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
break;
@@ -846,9 +845,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
if (!isroot)
break;
- err = ctf_hash_define_type (fp->ctf_structs.ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, fp->ctf_structs,
+ LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
@@ -862,9 +861,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
if (!isroot)
break;
- err = ctf_hash_define_type (fp->ctf_unions.ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, fp->ctf_unions,
+ LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
@@ -874,9 +873,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
if (!isroot)
break;
- err = ctf_hash_define_type (fp->ctf_enums.ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, fp->ctf_enums,
+ LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
@@ -886,27 +885,26 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
if (!isroot)
break;
- err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, fp->ctf_names,
+ LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
break;
case CTF_K_FORWARD:
{
- ctf_names_t *np = ctf_name_table (fp, tp->ctt_type);
+ ctf_dynhash_t *h = ctf_name_table (fp, tp->ctt_type);
if (!isroot)
break;
/* Only insert forward tags into the given hash if the type or tag
name is not already present. */
- if (ctf_hash_lookup_type (np->ctn_readonly, fp, name) == 0)
+ if (ctf_dynhash_lookup_type (h, name) == 0)
{
- err = ctf_hash_insert_type (np->ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, h, LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
}
@@ -929,15 +927,15 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
if (!isroot)
break;
- err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
- LCTF_INDEX_TO_TYPE (fp, id, child),
- tp->ctt_name);
+ err = ctf_dynhash_insert_type (fp, fp->ctf_names,
+ LCTF_INDEX_TO_TYPE (fp, id, child),
+ tp->ctt_name);
if (err != 0)
return err;
break;
default:
ctf_err_warn (fp, 0, ECTF_CORRUPT,
- _("init_types(): unhandled CTF kind: %x"), kind);
+ _("init_static_types(): unhandled CTF kind: %x"), kind);
return ECTF_CORRUPT;
}
@@ -946,14 +944,14 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
}
ctf_dprintf ("%lu total types processed\n", fp->ctf_typemax);
- ctf_dprintf ("%u enum names hashed\n",
- ctf_hash_size (fp->ctf_enums.ctn_readonly));
- ctf_dprintf ("%u struct names hashed (%d long)\n",
- ctf_hash_size (fp->ctf_structs.ctn_readonly), nlstructs);
- ctf_dprintf ("%u union names hashed (%d long)\n",
- ctf_hash_size (fp->ctf_unions.ctn_readonly), nlunions);
- ctf_dprintf ("%u base type names hashed\n",
- ctf_hash_size (fp->ctf_names.ctn_readonly));
+ ctf_dprintf ("%zu enum names hashed\n",
+ ctf_dynhash_elements (fp->ctf_enums));
+ ctf_dprintf ("%zu struct names hashed (%d long)\n",
+ ctf_dynhash_elements (fp->ctf_structs), nlstructs);
+ ctf_dprintf ("%zu union names hashed (%d long)\n",
+ ctf_dynhash_elements (fp->ctf_unions), nlunions);
+ ctf_dprintf ("%zu base type names hashed\n",
+ ctf_dynhash_elements (fp->ctf_names));
return 0;
}
@@ -1235,16 +1233,16 @@ void ctf_set_ctl_hashes (ctf_dict_t *fp)
array of type name prefixes and the corresponding ctf_hash to use. */
fp->ctf_lookups[0].ctl_prefix = "struct";
fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix);
- fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
+ fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
fp->ctf_lookups[1].ctl_prefix = "union";
fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix);
- fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
+ fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
fp->ctf_lookups[2].ctl_prefix = "enum";
fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix);
- fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
+ fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix);
- fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
+ fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
fp->ctf_lookups[4].ctl_prefix = NULL;
fp->ctf_lookups[4].ctl_len = 0;
fp->ctf_lookups[4].ctl_hash = NULL;
@@ -1764,20 +1762,11 @@ ctf_dict_close (ctf_dict_t *fp)
ctf_dtd_delete (fp, dtd);
}
ctf_dynhash_destroy (fp->ctf_dthash);
- if (fp->ctf_flags & LCTF_RDWR)
- {
- ctf_dynhash_destroy (fp->ctf_structs.ctn_writable);
- ctf_dynhash_destroy (fp->ctf_unions.ctn_writable);
- ctf_dynhash_destroy (fp->ctf_enums.ctn_writable);
- ctf_dynhash_destroy (fp->ctf_names.ctn_writable);
- }
- else
- {
- ctf_hash_destroy (fp->ctf_structs.ctn_readonly);
- ctf_hash_destroy (fp->ctf_unions.ctn_readonly);
- ctf_hash_destroy (fp->ctf_enums.ctn_readonly);
- ctf_hash_destroy (fp->ctf_names.ctn_readonly);
- }
+
+ ctf_dynhash_destroy (fp->ctf_structs);
+ ctf_dynhash_destroy (fp->ctf_unions);
+ ctf_dynhash_destroy (fp->ctf_enums);
+ ctf_dynhash_destroy (fp->ctf_names);
for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
{