Make bcache more type-safe

The bcache uses memcpy to make copies of the data passed to it.  In
C++, this is only safe for trivially-copyable types.

This patch changes bcache to require this property, and slightly
changes the API to make it easier to use when copying a single object.
It also makes the new 'insert' template methods return the correct
type.
This commit is contained in:
Tom Tromey
2024-03-20 13:24:33 -06:00
parent 56fefe83f7
commit 7149dfe819
4 changed files with 33 additions and 12 deletions

View File

@@ -152,7 +152,26 @@ struct bcache
were newly added to the cache, or to false if the bytes were were newly added to the cache, or to false if the bytes were
found in the cache. */ found in the cache. */
const void *insert (const void *addr, int length, bool *added = nullptr); template<typename T, typename = gdb::Requires<std::is_trivially_copyable<T>>>
const T *insert (const T *addr, int length, bool *added = nullptr)
{
return (const T *) this->insert ((const void *) addr, length, added);
}
/* Find a copy of OBJECT in this bcache. If BCACHE has never seen
those bytes before, add a copy of them to BCACHE. In either
case, return a pointer to BCACHE's copy of that string. Since
the cached value is meant to be read-only, return a const buffer.
If ADDED is not NULL, set *ADDED to true if the bytes were newly
added to the cache, or to false if the bytes were found in the
cache. */
template<typename T, typename = gdb::Requires<std::is_trivially_copyable<T>>>
const T *insert (const T &object, bool *added = nullptr)
{
return (const T *) this->insert ((const void *) &object, sizeof (object),
added);
}
/* Print statistics on this bcache's memory usage and efficacity at /* Print statistics on this bcache's memory usage and efficacity at
eliminating duplication. TYPE should be a string describing the eliminating duplication. TYPE should be a string describing the
@@ -173,6 +192,10 @@ protected:
private: private:
/* Implementation of the templated 'insert' methods. */
const void *insert (const void *addr, int length, bool *added);
/* All the bstrings are allocated here. */ /* All the bstrings are allocated here. */
struct obstack m_cache {}; struct obstack m_cache {};

View File

@@ -4372,7 +4372,7 @@ check_types_worklist (std::vector<type_equality_entry> *worklist,
/* If the type pair has already been visited, we know it is /* If the type pair has already been visited, we know it is
ok. */ ok. */
cache->insert (&entry, sizeof (entry), &added); cache->insert (entry, &added);
if (!added) if (!added)
continue; continue;

View File

@@ -109,8 +109,9 @@ macro_free (void *object, struct macro_table *t)
/* If the macro table T has a bcache, then cache the LEN bytes at ADDR /* If the macro table T has a bcache, then cache the LEN bytes at ADDR
there, and return the cached copy. Otherwise, just xmalloc a copy there, and return the cached copy. Otherwise, just xmalloc a copy
of the bytes, and return a pointer to that. */ of the bytes, and return a pointer to that. */
static const void * template<typename U>
macro_bcache (struct macro_table *t, const void *addr, int len) static const U *
macro_bcache (struct macro_table *t, const U *addr, int len)
{ {
if (t->bcache) if (t->bcache)
return t->bcache->insert (addr, len); return t->bcache->insert (addr, len);
@@ -119,7 +120,7 @@ macro_bcache (struct macro_table *t, const void *addr, int len)
void *copy = xmalloc (len); void *copy = xmalloc (len);
memcpy (copy, addr, len); memcpy (copy, addr, len);
return copy; return (const U *) copy;
} }
} }
@@ -130,7 +131,7 @@ macro_bcache (struct macro_table *t, const void *addr, int len)
static const char * static const char *
macro_bcache_str (struct macro_table *t, const char *s) macro_bcache_str (struct macro_table *t, const char *s)
{ {
return (const char *) macro_bcache (t, s, strlen (s) + 1); return macro_bcache (t, s, strlen (s) + 1);
} }
@@ -571,8 +572,7 @@ new_macro_definition (struct macro_table *t,
cached_argv[i] = macro_bcache_str (t, argv[i]); cached_argv[i] = macro_bcache_str (t, argv[i]);
/* Now bcache the array of argument pointers itself. */ /* Now bcache the array of argument pointers itself. */
d->argv = ((const char * const *) d->argv = macro_bcache (t, cached_argv, cached_argv_size);
macro_bcache (t, cached_argv, cached_argv_size));
} }
/* We don't bcache the entire definition structure because it's got /* We don't bcache the entire definition structure because it's got

View File

@@ -1062,10 +1062,8 @@ partial_symtab::add_psymbol (const partial_symbol &psymbol,
bool added; bool added;
/* Stash the partial symbol away in the cache. */ /* Stash the partial symbol away in the cache. */
partial_symbol *psym const partial_symbol *psym = partial_symtabs->psymbol_cache.insert (psymbol,
= ((struct partial_symbol *) &added);
partial_symtabs->psymbol_cache.insert
(&psymbol, sizeof (struct partial_symbol), &added));
/* Do not duplicate global partial symbols. */ /* Do not duplicate global partial symbols. */
if (where == psymbol_placement::GLOBAL && !added) if (where == psymbol_placement::GLOBAL && !added)