From: Joel Brobecker <brobecker@adacore.com>
To: gdb-patches@sourceware.org
Subject: [commit/Ada] Add a symbol lookup cache
Date: Mon, 10 Feb 2014 07:51:00 -0000 [thread overview]
Message-ID: <1392018685-15134-1-git-send-email-brobecker@adacore.com> (raw)
Hello,
This patch implements the caching mechanism alluded to in a comment
next to some stubbed functions.
gdb/ChangeLog:
* ada-lang.c (HASH_SIZE): New macro.
(struct cache_entry): New type.
(cache_space, cache): New static globals.
(ada_clear_symbol_cache, find_entry): New functions.
(lookup_cached_symbol, cache_symbol): Implement.
(ada_new_objfile_observer, ada_free_objfile_observer): New.
(_initialize_ada_language): Attach ada_new_objfile_observer
and ada_free_objfile_observer.
Tested on x86_64-linux and pushed.
Thanks,
--
Joel
---
gdb/ChangeLog | 11 +++++
gdb/ada-lang.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 143 insertions(+), 3 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 940c6a2..828cb6e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
2014-02-10 Joel Brobecker <brobecker@adacore.com>
+ * ada-lang.c (HASH_SIZE): New macro.
+ (struct cache_entry): New type.
+ (cache_space, cache): New static globals.
+ (ada_clear_symbol_cache, find_entry): New functions.
+ (lookup_cached_symbol, cache_symbol): Implement.
+ (ada_new_objfile_observer, ada_free_objfile_observer): New.
+ (_initialize_ada_language): Attach ada_new_objfile_observer
+ and ada_free_objfile_observer.
+
+2014-02-10 Joel Brobecker <brobecker@adacore.com>
+
* ada-lang.c (ada_add_block_symbols, add_defn_to_vec)
(lookup_cached_symbol, ada_add_local_symbols): Add "const" to
struct block * parameter.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 269112c..fc2c83b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -4245,20 +4245,129 @@ make_array_descriptor (struct type *type, struct value *arr)
return descriptor;
}
\f
-/* Dummy definitions for an experimental caching module that is not
- * used in the public sources. */
+ /* Symbol Cache Module */
+
+/* This section implements a simple, fixed-sized hash table for those
+ Ada-mode symbols that get looked up in the course of executing the user's
+ commands. 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. */
+
+/* Performance measurements made as of 2010-01-15 indicate that
+ this case does bring some noticeable improvements. Depending
+ on the type of entity being printed, the cache can make it as much
+ as an order of magnitude faster than without it.
+
+ The descriptive type DWARF extension has significantly reduced
+ the need for this cache, at least when DWARF is being used. However,
+ even in this case, some expensive name-based symbol searches are still
+ sometimes necessary - to find an XVZ variable, mostly. */
+
+#define HASH_SIZE 1009
+
+/* The result of a symbol lookup to be stored in our cache. */
+
+struct cache_entry
+{
+ /* The name used to perform the lookup. */
+ const char *name;
+ /* The namespace used during the lookup. */
+ domain_enum namespace;
+ /* 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;
+};
+
+/* An obstack used to store the entries in our cache. */
+static struct obstack cache_space;
+
+/* The root of the hash table used to implement our symbol cache. */
+static struct cache_entry *cache[HASH_SIZE];
+
+/* Clear all entries from the symbol cache. */
+
+static void
+ada_clear_symbol_cache (void)
+{
+ obstack_free (&cache_space, NULL);
+ obstack_init (&cache_space);
+ memset (cache, '\000', sizeof (cache));
+}
+
+/* Search our cache for an entry matching NAME and NAMESPACE.
+ Return it if found, or NULL otherwise. */
+
+static struct cache_entry **
+find_entry (const char *name, domain_enum namespace)
+{
+ int h = msymbol_hash (name) % HASH_SIZE;
+ struct cache_entry **e;
+
+ for (e = &cache[h]; *e != NULL; e = &(*e)->next)
+ {
+ if (namespace == (*e)->namespace && strcmp (name, (*e)->name) == 0)
+ return e;
+ }
+ return NULL;
+}
+
+/* Search the symbol cache for an entry matching NAME and NAMESPACE.
+ Return 1 if found, 0 otherwise.
+
+ If an entry was found and SYM is not NULL, set *SYM to the entry's
+ SYM. Same principle for BLOCK if not NULL. */
static int
lookup_cached_symbol (const char *name, domain_enum namespace,
struct symbol **sym, const struct block **block)
{
- return 0;
+ struct cache_entry **e = find_entry (name, namespace);
+
+ if (e == NULL)
+ return 0;
+ if (sym != NULL)
+ *sym = (*e)->sym;
+ if (block != NULL)
+ *block = (*e)->block;
+ return 1;
}
+/* Assuming that (SYM, BLOCK) is the result of the lookup of NAME
+ in domain NAMESPACE, save this result in our symbol cache. */
+
static void
cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
const struct block *block)
{
+ int h;
+ char *copy;
+ struct cache_entry *e;
+
+ /* If the symbol is a local symbol, then do not cache it, as a search
+ for that symbol depends on the context. To determine whether
+ the symbol is local or not, we check the block where we found it
+ against the global and static blocks of its associated symtab. */
+ if (sym
+ && BLOCKVECTOR_BLOCK (BLOCKVECTOR (sym->symtab), GLOBAL_BLOCK) != block
+ && BLOCKVECTOR_BLOCK (BLOCKVECTOR (sym->symtab), STATIC_BLOCK) != block)
+ return;
+
+ h = msymbol_hash (name) % HASH_SIZE;
+ e = (struct cache_entry *) obstack_alloc (&cache_space, sizeof (*e));
+ e->next = cache[h];
+ cache[h] = e;
+ e->name = copy = obstack_alloc (&cache_space, strlen (name) + 1);
+ strcpy (copy, name);
+ e->sym = sym;
+ e->namespace = namespace;
+ e->block = block;
}
\f
/* Symbol Lookup */
@@ -13295,6 +13404,22 @@ initialize_ada_catchpoint_ops (void)
ops->print_recreate = print_recreate_catch_assert;
}
+/* This module's 'new_objfile' observer. */
+
+static void
+ada_new_objfile_observer (struct objfile *objfile)
+{
+ ada_clear_symbol_cache ();
+}
+
+/* This module's 'free_objfile' observer. */
+
+static void
+ada_free_objfile_observer (struct objfile *objfile)
+{
+ ada_clear_symbol_cache ();
+}
+
void
_initialize_ada_language (void)
{
@@ -13373,6 +13498,10 @@ DWARF attribute."),
(256, htab_hash_string, (int (*)(const void *, const void *)) streq,
NULL, xcalloc, xfree);
+ /* The ada-lang observers. */
+ observer_attach_new_objfile (ada_new_objfile_observer);
+ observer_attach_free_objfile (ada_free_objfile_observer);
+
/* Setup per-inferior data. */
observer_attach_inferior_exit (ada_inferior_exit);
ada_inferior_data
--
1.8.3.2
next reply other threads:[~2014-02-10 7:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-10 7:51 Joel Brobecker [this message]
2014-02-10 10:02 ` Pedro Alves
2014-02-10 10:06 ` Joel Brobecker
2014-02-10 14:08 ` Joel Brobecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1392018685-15134-1-git-send-email-brobecker@adacore.com \
--to=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox