Rewrite Ada symbol cache

In an experiment I'm trying, I needed Ada symbol cache entries to be
allocated with 'new'.  This patch reimplements the symbol cache to use
the libiberty hash table and to use new and delete.  A couple of other
minor cleanups are done.
This commit is contained in:
Tom Tromey
2023-03-15 11:47:32 -06:00
parent 565059a282
commit 9d1c303d52

View File

@@ -235,44 +235,6 @@ static const utf8_entry ada_case_fold[] =
/* The result of a symbol lookup to be stored in our symbol cache. */
struct cache_entry
{
/* The name used to perform the lookup. */
const char *name;
/* The namespace used during the lookup. */
domain_enum domain;
/* The symbol returned by the lookup, or NULL if no matching symbol
was found. */
struct symbol *sym;
/* The block where the symbol was found, or NULL if no matching
symbol was found. */
const struct block *block;
/* A pointer to the next entry with the same hash. */
struct cache_entry *next;
};
/* The Ada symbol cache, used to store the result of Ada-mode symbol
lookups in the course of executing the user's commands.
The cache is implemented using a simple, fixed-sized hash.
The size is fixed on the grounds that there are not likely to be
all that many symbols looked up during any given session, regardless
of the size of the symbol table. If we decide to go to a resizable
table, let's just use the stuff from libiberty instead. */
#define HASH_SIZE 1009
struct ada_symbol_cache
{
/* An obstack used to store the entries in our cache. */
struct auto_obstack cache_space;
/* The root of the hash table used to implement our symbol cache. */
struct cache_entry *root[HASH_SIZE] {};
};
static const char ada_completer_word_break_characters[] =
#ifdef VMS
" \t\n!@#%^&*()+=|~`}{[]\";:?/,-";
@@ -361,15 +323,58 @@ ada_inferior_exit (struct inferior *inf)
/* program-space-specific data. */
/* This module's per-program-space data. */
struct ada_pspace_data
/* The result of a symbol lookup to be stored in our symbol cache. */
struct cache_entry
{
/* The Ada symbol cache. */
std::unique_ptr<ada_symbol_cache> sym_cache;
/* The name used to perform the lookup. */
std::string name;
/* The namespace used during the lookup. */
domain_enum domain = UNDEF_DOMAIN;
/* The symbol returned by the lookup, or NULL if no matching symbol
was found. */
struct symbol *sym = nullptr;
/* The block where the symbol was found, or NULL if no matching
symbol was found. */
const struct block *block = nullptr;
};
/* The symbol cache uses this type when searching. */
struct cache_entry_search
{
const char *name;
domain_enum domain;
hashval_t hash () const
{
/* This must agree with hash_cache_entry, below. */
return htab_hash_string (name);
}
};
/* Hash function for cache_entry. */
static hashval_t
hash_cache_entry (const void *v)
{
const cache_entry *entry = (const cache_entry *) v;
return htab_hash_string (entry->name.c_str ());
}
/* Equality function for cache_entry. */
static int
eq_cache_entry (const void *a, const void *b)
{
const cache_entry *entrya = (const cache_entry *) a;
const cache_entry_search *entryb = (const cache_entry_search *) b;
return entrya->domain == entryb->domain && entrya->name == entryb->name;
}
/* Key to our per-program-space data. */
static const registry<program_space>::key<ada_pspace_data>
static const registry<program_space>::key<htab, htab_deleter>
ada_pspace_data_handle;
/* Return this module's data for the given program space (PSPACE).
@@ -377,14 +382,17 @@ static const registry<program_space>::key<ada_pspace_data>
This function always returns a valid object. */
static struct ada_pspace_data *
static htab_t
get_ada_pspace_data (struct program_space *pspace)
{
struct ada_pspace_data *data;
data = ada_pspace_data_handle.get (pspace);
if (data == NULL)
data = ada_pspace_data_handle.emplace (pspace);
htab_t data = ada_pspace_data_handle.get (pspace);
if (data == nullptr)
{
data = htab_create_alloc (10, hash_cache_entry, eq_cache_entry,
htab_delete_entry<cache_entry>,
xcalloc, xfree);
ada_pspace_data_handle.set (pspace, data);
}
return data;
}
@@ -4635,49 +4643,12 @@ make_array_descriptor (struct type *type, struct value *arr)
even in this case, some expensive name-based symbol searches are still
sometimes necessary - to find an XVZ variable, mostly. */
/* Return the symbol cache associated to the given program space PSPACE.
If not allocated for this PSPACE yet, allocate and initialize one. */
static struct ada_symbol_cache *
ada_get_symbol_cache (struct program_space *pspace)
{
struct ada_pspace_data *pspace_data = get_ada_pspace_data (pspace);
if (pspace_data->sym_cache == nullptr)
pspace_data->sym_cache.reset (new ada_symbol_cache);
return pspace_data->sym_cache.get ();
}
/* Clear all entries from the symbol cache. */
static void
ada_clear_symbol_cache ()
{
struct ada_pspace_data *pspace_data
= get_ada_pspace_data (current_program_space);
if (pspace_data->sym_cache != nullptr)
pspace_data->sym_cache.reset ();
}
/* Search our cache for an entry matching NAME and DOMAIN.
Return it if found, or NULL otherwise. */
static struct cache_entry **
find_entry (const char *name, domain_enum domain)
{
struct ada_symbol_cache *sym_cache
= ada_get_symbol_cache (current_program_space);
int h = msymbol_hash (name) % HASH_SIZE;
struct cache_entry **e;
for (e = &sym_cache->root[h]; *e != NULL; e = &(*e)->next)
{
if (domain == (*e)->domain && strcmp (name, (*e)->name) == 0)
return e;
}
return NULL;
ada_pspace_data_handle.clear (current_program_space);
}
/* Search the symbol cache for an entry matching NAME and DOMAIN.
@@ -4690,14 +4661,19 @@ static int
lookup_cached_symbol (const char *name, domain_enum domain,
struct symbol **sym, const struct block **block)
{
struct cache_entry **e = find_entry (name, domain);
htab_t tab = get_ada_pspace_data (current_program_space);
cache_entry_search search;
search.name = name;
search.domain = domain;
if (e == NULL)
cache_entry *e = (cache_entry *) htab_find_with_hash (tab, &search,
search.hash ());
if (e == nullptr)
return 0;
if (sym != NULL)
*sym = (*e)->sym;
if (block != NULL)
*block = (*e)->block;
if (sym != nullptr)
*sym = e->sym;
if (block != nullptr)
*block = e->block;
return 1;
}
@@ -4708,11 +4684,6 @@ static void
cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
const struct block *block)
{
struct ada_symbol_cache *sym_cache
= ada_get_symbol_cache (current_program_space);
int h;
struct cache_entry *e;
/* Symbols for builtin types don't have a block.
For now don't cache such symbols. */
if (sym != NULL && !sym->is_objfile_owned ())
@@ -4730,14 +4701,21 @@ cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
return;
}
h = msymbol_hash (name) % HASH_SIZE;
e = XOBNEW (&sym_cache->cache_space, cache_entry);
e->next = sym_cache->root[h];
sym_cache->root[h] = e;
e->name = obstack_strdup (&sym_cache->cache_space, name);
e->sym = sym;
htab_t tab = get_ada_pspace_data (current_program_space);
cache_entry_search search;
search.name = name;
search.domain = domain;
void **slot = htab_find_slot_with_hash (tab, &search,
search.hash (), INSERT);
cache_entry *e = new cache_entry;
e->name = name;
e->domain = domain;
e->sym = sym;
e->block = block;
*slot = e;
}
/* Symbol Lookup */