Avoid copying in lookup_name_info

lookup_name_info always copies the name that is passed in.  However,
normally a copy is not needed.  This patch changes this class to avoid
copying.  This required changing the "name" method to return something
else; I chose a gdb::string_view, to avoid excessive calls to strlen
in the code using the lookup_name_info.  However, as this class does
not allow an arbitrary string_view, I've also added a c_str method
that guarantees a \0-terminated result -- a pedantic difference but
one that respects the string_view contract, IMO.

gdb/ChangeLog
2020-04-01  Tom Tromey  <tromey@adacore.com>

	* symtab.h (class lookup_name_info) <lookup_name_info>: Change
	"name" parameter to rvalue reference.  Initialize m_name_holder.
	<lookup_name_info>: New overloads.
	<name>: Return gdb::string_view.
	<c_str>: New method.
	<make_ignore_params>: Update.
	<search_name_hash>: Update.
	<language_lookup_name>: Return const char *.
	<m_name>: Change type.
	* symtab.c (demangle_for_lookup_info::demangle_for_lookup_info)
	(demangle_for_lookup_info::demangle_for_lookup_info): Update.
	(lookup_name_info::match_any): Update.
	* psymtab.c (match_partial_symbol, lookup_partial_symbol):
	Update.
	* minsyms.c (linkage_name_str): Update.
	* language.c (default_symbol_name_matcher): Update.
	* dwarf2/read.c (mapped_index_base::find_name_components_bounds):
	Update.
	* ada-lang.c (ada_fold_name): Change parameter to string_view.
	(ada_lookup_name_info::ada_lookup_name_info): Update.
	(literal_symbol_name_matcher): Update.
This commit is contained in:
Tom Tromey 2020-04-01 07:47:13 -06:00
parent 8c072cb6a1
commit e0802d5996
8 changed files with 95 additions and 41 deletions

View file

@ -1,3 +1,27 @@
2020-04-01 Tom Tromey <tromey@adacore.com>
* symtab.h (class lookup_name_info) <lookup_name_info>: Change
"name" parameter to rvalue reference. Initialize m_name_holder.
<lookup_name_info>: New overloads.
<name>: Return gdb::string_view.
<c_str>: New method.
<make_ignore_params>: Update.
<search_name_hash>: Update.
<language_lookup_name>: Return const char *.
<m_name>: Change type.
* symtab.c (demangle_for_lookup_info::demangle_for_lookup_info)
(demangle_for_lookup_info::demangle_for_lookup_info): Update.
(lookup_name_info::match_any): Update.
* psymtab.c (match_partial_symbol, lookup_partial_symbol):
Update.
* minsyms.c (linkage_name_str): Update.
* language.c (default_symbol_name_matcher): Update.
* dwarf2/read.c (mapped_index_base::find_name_components_bounds):
Update.
* ada-lang.c (ada_fold_name): Change parameter to string_view.
(ada_lookup_name_info::ada_lookup_name_info): Update.
(literal_symbol_name_matcher): Update.
2020-04-01 Tom Tromey <tromey@adacore.com> 2020-04-01 Tom Tromey <tromey@adacore.com>
* psymtab.c (psymtab_search_name): Remove function. * psymtab.c (psymtab_search_name): Remove function.

View file

@ -1016,17 +1016,17 @@ ada_encode (const char *decoded)
to next call. */ to next call. */
static char * static char *
ada_fold_name (const char *name) ada_fold_name (gdb::string_view name)
{ {
static char *fold_buffer = NULL; static char *fold_buffer = NULL;
static size_t fold_buffer_size = 0; static size_t fold_buffer_size = 0;
int len = strlen (name); int len = name.size ();
GROW_VECT (fold_buffer, fold_buffer_size, len + 1); GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
if (name[0] == '\'') if (name[0] == '\'')
{ {
strncpy (fold_buffer, name + 1, len - 2); strncpy (fold_buffer, name.data () + 1, len - 2);
fold_buffer[len - 2] = '\000'; fold_buffer[len - 2] = '\000';
} }
else else
@ -5657,8 +5657,8 @@ add_nonlocal_symbols (struct obstack *obstackp,
if (num_defns_collected (obstackp) == 0 && global && !is_wild_match) if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
{ {
const char *name = ada_lookup_name (lookup_name); const char *name = ada_lookup_name (lookup_name);
lookup_name_info name1 (std::string ("<_ada_") + name + '>', std::string bracket_name = std::string ("<_ada_") + name + '>';
symbol_name_match_type::FULL); lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);
for (objfile *objfile : current_program_space->objfiles ()) for (objfile *objfile : current_program_space->objfiles ())
{ {
@ -13946,14 +13946,16 @@ do_exact_match (const char *symbol_search_name,
ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name) ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
{ {
const std::string &user_name = lookup_name.name (); gdb::string_view user_name = lookup_name.name ();
if (user_name[0] == '<') if (user_name[0] == '<')
{ {
if (user_name.back () == '>') if (user_name.back () == '>')
m_encoded_name = user_name.substr (1, user_name.size () - 2); m_encoded_name
= user_name.substr (1, user_name.size () - 2).to_string ();
else else
m_encoded_name = user_name.substr (1, user_name.size () - 1); m_encoded_name
= user_name.substr (1, user_name.size () - 1).to_string ();
m_encoded_p = true; m_encoded_p = true;
m_verbatim_p = true; m_verbatim_p = true;
m_wild_match_p = false; m_wild_match_p = false;
@ -13963,19 +13965,19 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
{ {
m_verbatim_p = false; m_verbatim_p = false;
m_encoded_p = user_name.find ("__") != std::string::npos; m_encoded_p = user_name.find ("__") != gdb::string_view::npos;
if (!m_encoded_p) if (!m_encoded_p)
{ {
const char *folded = ada_fold_name (user_name.c_str ()); const char *folded = ada_fold_name (user_name);
const char *encoded = ada_encode_1 (folded, false); const char *encoded = ada_encode_1 (folded, false);
if (encoded != NULL) if (encoded != NULL)
m_encoded_name = encoded; m_encoded_name = encoded;
else else
m_encoded_name = user_name; m_encoded_name = user_name.to_string ();
} }
else else
m_encoded_name = user_name; m_encoded_name = user_name.to_string ();
/* Handle the 'package Standard' special case. See description /* Handle the 'package Standard' special case. See description
of m_standard_p. */ of m_standard_p. */
@ -14022,12 +14024,12 @@ literal_symbol_name_matcher (const char *symbol_search_name,
const lookup_name_info &lookup_name, const lookup_name_info &lookup_name,
completion_match_result *comp_match_res) completion_match_result *comp_match_res)
{ {
const std::string &name = lookup_name.name (); gdb::string_view name_view = lookup_name.name ();
int cmp = (lookup_name.completion_mode () if (lookup_name.completion_mode ()
? strncmp (symbol_search_name, name.c_str (), name.size ()) ? (strncmp (symbol_search_name, name_view.data (),
: strcmp (symbol_search_name, name.c_str ())); name_view.size ()) == 0)
if (cmp == 0) : symbol_search_name == name_view)
{ {
if (comp_match_res != NULL) if (comp_match_res != NULL)
comp_match_res->set_match (symbol_search_name); comp_match_res->set_match (symbol_search_name);

View file

@ -3681,7 +3681,7 @@ mapped_index_base::find_name_components_bounds
= this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp; = this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
const char *lang_name const char *lang_name
= lookup_name_without_params.language_lookup_name (lang).c_str (); = lookup_name_without_params.language_lookup_name (lang);
/* Comparison function object for lower_bound that matches against a /* Comparison function object for lower_bound that matches against a
given symbol name. */ given symbol name. */

View file

@ -699,14 +699,14 @@ default_symbol_name_matcher (const char *symbol_search_name,
const lookup_name_info &lookup_name, const lookup_name_info &lookup_name,
completion_match_result *comp_match_res) completion_match_result *comp_match_res)
{ {
const std::string &name = lookup_name.name (); gdb::string_view name = lookup_name.name ();
completion_match_for_lcd *match_for_lcd completion_match_for_lcd *match_for_lcd
= (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL); = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
strncmp_iw_mode mode = (lookup_name.completion_mode () strncmp_iw_mode mode = (lookup_name.completion_mode ()
? strncmp_iw_mode::NORMAL ? strncmp_iw_mode::NORMAL
: strncmp_iw_mode::MATCH_PARAMS); : strncmp_iw_mode::MATCH_PARAMS);
if (strncmp_iw_with_mode (symbol_search_name, name.c_str (), name.size (), if (strncmp_iw_with_mode (symbol_search_name, name.data (), name.size (),
mode, language_minimal, match_for_lcd) == 0) mode, language_minimal, match_for_lcd) == 0)
{ {
if (comp_match_res != NULL) if (comp_match_res != NULL)

View file

@ -467,7 +467,7 @@ linkage_name_str (const lookup_name_info &lookup_name)
if (current_language->la_language == language_ada) if (current_language->la_language == language_ada)
return lookup_name.ada ().lookup_name ().c_str (); return lookup_name.ada ().lookup_name ().c_str ();
return lookup_name.name ().c_str (); return lookup_name.c_str ();
} }
/* See minsyms.h. */ /* See minsyms.h. */

View file

@ -578,8 +578,7 @@ match_partial_symbol (struct objfile *objfile,
gdb_assert (center < top); gdb_assert (center < top);
enum language lang = (*center)->ginfo.language (); enum language lang = (*center)->ginfo.language ();
const char *lang_ln const char *lang_ln = name.language_lookup_name (lang);
= name.language_lookup_name (lang).c_str ();
if (ordered_compare ((*center)->ginfo.search_name (), if (ordered_compare ((*center)->ginfo.search_name (),
lang_ln) >= 0) lang_ln) >= 0)
@ -658,7 +657,7 @@ lookup_partial_symbol (struct objfile *objfile,
internal_error (__FILE__, __LINE__, internal_error (__FILE__, __LINE__,
_("failed internal consistency check")); _("failed internal consistency check"));
if (strcmp_iw_ordered ((*center)->ginfo.search_name (), if (strcmp_iw_ordered ((*center)->ginfo.search_name (),
lookup_name.name ().c_str ()) >= 0) lookup_name.c_str ()) >= 0)
{ {
top = center; top = center;
} }

View file

@ -1790,7 +1790,7 @@ demangle_for_lookup_info::demangle_for_lookup_info
if (lookup_name.ignore_parameters () && lang == language_cplus) if (lookup_name.ignore_parameters () && lang == language_cplus)
{ {
gdb::unique_xmalloc_ptr<char> without_params gdb::unique_xmalloc_ptr<char> without_params
= cp_remove_params_if_any (lookup_name.name ().c_str (), = cp_remove_params_if_any (lookup_name.c_str (),
lookup_name.completion_mode ()); lookup_name.completion_mode ());
if (without_params != NULL) if (without_params != NULL)
@ -1803,9 +1803,9 @@ demangle_for_lookup_info::demangle_for_lookup_info
} }
if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME) if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
m_demangled_name = lookup_name.name (); m_demangled_name = lookup_name.c_str ();
else else
m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (), m_demangled_name = demangle_for_lookup (lookup_name.c_str (),
lang, storage); lang, storage);
} }
@ -1816,7 +1816,7 @@ lookup_name_info::match_any ()
{ {
/* Lookup any symbol that "" would complete. I.e., this matches all /* Lookup any symbol that "" would complete. I.e., this matches all
symbol names. */ symbol names. */
static const lookup_name_info lookup_name ({}, symbol_name_match_type::FULL, static const lookup_name_info lookup_name ("", symbol_name_match_type::FULL,
true); true);
return lookup_name; return lookup_name;

View file

@ -185,29 +185,58 @@ private:
class lookup_name_info final class lookup_name_info final
{ {
public: public:
/* Create a new object. */ /* We delete this overload so that the callers are required to
lookup_name_info (std::string name, explicitly handle the lifetime of the name. */
lookup_name_info (std::string &&name,
symbol_name_match_type match_type,
bool completion_mode = false,
bool ignore_parameters = false) = delete;
/* This overload requires that NAME have a lifetime at least as long
as the lifetime of this object. */
lookup_name_info (const std::string &name,
symbol_name_match_type match_type, symbol_name_match_type match_type,
bool completion_mode = false, bool completion_mode = false,
bool ignore_parameters = false) bool ignore_parameters = false)
: m_match_type (match_type), : m_match_type (match_type),
m_completion_mode (completion_mode), m_completion_mode (completion_mode),
m_ignore_parameters (ignore_parameters), m_ignore_parameters (ignore_parameters),
m_name (std::move (name)) m_name (name)
{}
/* This overload requires that NAME have a lifetime at least as long
as the lifetime of this object. */
lookup_name_info (const char *name,
symbol_name_match_type match_type,
bool completion_mode = false,
bool ignore_parameters = false)
: m_match_type (match_type),
m_completion_mode (completion_mode),
m_ignore_parameters (ignore_parameters),
m_name (name)
{} {}
/* Getters. See description of each corresponding field. */ /* Getters. See description of each corresponding field. */
symbol_name_match_type match_type () const { return m_match_type; } symbol_name_match_type match_type () const { return m_match_type; }
bool completion_mode () const { return m_completion_mode; } bool completion_mode () const { return m_completion_mode; }
const std::string &name () const { return m_name; } gdb::string_view name () const { return m_name; }
const bool ignore_parameters () const { return m_ignore_parameters; } const bool ignore_parameters () const { return m_ignore_parameters; }
/* Like the "name" method but guarantees that the returned string is
\0-terminated. */
const char *c_str () const
{
/* Actually this is always guaranteed due to how the class is
constructed. */
return m_name.data ();
}
/* Return a version of this lookup name that is usable with /* Return a version of this lookup name that is usable with
comparisons against symbols have no parameter info, such as comparisons against symbols have no parameter info, such as
psymbols and GDB index symbols. */ psymbols and GDB index symbols. */
lookup_name_info make_ignore_params () const lookup_name_info make_ignore_params () const
{ {
return lookup_name_info (m_name, m_match_type, m_completion_mode, return lookup_name_info (c_str (), m_match_type, m_completion_mode,
true /* ignore params */); true /* ignore params */);
} }
@ -218,27 +247,27 @@ class lookup_name_info final
if (!m_demangled_hashes_p[lang]) if (!m_demangled_hashes_p[lang])
{ {
m_demangled_hashes[lang] m_demangled_hashes[lang]
= ::search_name_hash (lang, language_lookup_name (lang).c_str ()); = ::search_name_hash (lang, language_lookup_name (lang));
m_demangled_hashes_p[lang] = true; m_demangled_hashes_p[lang] = true;
} }
return m_demangled_hashes[lang]; return m_demangled_hashes[lang];
} }
/* Get the search name for searches in language LANG. */ /* Get the search name for searches in language LANG. */
const std::string &language_lookup_name (language lang) const const char *language_lookup_name (language lang) const
{ {
switch (lang) switch (lang)
{ {
case language_ada: case language_ada:
return ada ().lookup_name (); return ada ().lookup_name ().c_str ();
case language_cplus: case language_cplus:
return cplus ().lookup_name (); return cplus ().lookup_name ().c_str ();
case language_d: case language_d:
return d ().lookup_name (); return d ().lookup_name ().c_str ();
case language_go: case language_go:
return go ().lookup_name (); return go ().lookup_name ().c_str ();
default: default:
return m_name; return m_name.data ();
} }
} }
@ -287,7 +316,7 @@ private:
symbol_name_match_type m_match_type; symbol_name_match_type m_match_type;
bool m_completion_mode; bool m_completion_mode;
bool m_ignore_parameters; bool m_ignore_parameters;
std::string m_name; gdb::string_view m_name;
/* Language-specific info. These fields are filled lazily the first /* Language-specific info. These fields are filled lazily the first
time a lookup is done in the corresponding language. They're time a lookup is done in the corresponding language. They're