[PATCH v2] Speed up lookup of "type_specific_data"
Tom Tromey
tromey@adacore.com
Thu Feb 15 16:07:10 GMT 2024
I noticed that "info locals" on a certain large Ada program was very
slow. I tracked this down to ada_get_tsd_type expanding nearly every
CU in the program.
This patch fixes the problem by changing this code to use the more
efficient lookup_transparent_type which, unlike the Ada-specific
lookup functions, does not try to find all matching instances.
Note that I first tried fixing this by changing ada_find_any_type, but
this did not work -- I may revisit this approach at some later date.
Also note that the copyright dates on the test files are set that way
because I copied them from another test.
New in v2: the new test failed on the Linaro regression tester.
Looking at the logs, it seems that gdb was picking up a 'value' from
libgnat:
$1 = {<text variable, no debug info>} 0xf7e227a4 <ada.calendar.formatting.value>
This version renames the local variable in an attempt to work around
this.
---
gdb/ada-lang.c | 4 +-
gdb/c-lang.c | 6 +-
gdb/cp-namespace.c | 4 +-
gdb/cp-support.h | 3 +-
gdb/language.h | 5 +-
gdb/symtab.c | 27 +++++----
gdb/symtab.h | 6 +-
gdb/testsuite/gdb.ada/tagged-lookup.exp | 61 ++++++++++++++++++++
gdb/testsuite/gdb.ada/tagged-lookup/foo.adb | 23 ++++++++
gdb/testsuite/gdb.ada/tagged-lookup/pck.adb | 22 +++++++
gdb/testsuite/gdb.ada/tagged-lookup/pck.ads | 21 +++++++
gdb/testsuite/gdb.ada/tagged-lookup/pck2.adb | 21 +++++++
gdb/testsuite/gdb.ada/tagged-lookup/pck2.ads | 22 +++++++
13 files changed, 204 insertions(+), 21 deletions(-)
create mode 100644 gdb/testsuite/gdb.ada/tagged-lookup.exp
create mode 100644 gdb/testsuite/gdb.ada/tagged-lookup/foo.adb
create mode 100644 gdb/testsuite/gdb.ada/tagged-lookup/pck.adb
create mode 100644 gdb/testsuite/gdb.ada/tagged-lookup/pck.ads
create mode 100644 gdb/testsuite/gdb.ada/tagged-lookup/pck2.adb
create mode 100644 gdb/testsuite/gdb.ada/tagged-lookup/pck2.ads
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index a3fd695e003..59bb64bfb63 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -6469,7 +6469,9 @@ ada_get_tsd_type (struct inferior *inf)
struct ada_inferior_data *data = get_ada_inferior_data (inf);
if (data->tsd_type == 0)
- data->tsd_type = ada_find_any_type ("ada__tags__type_specific_data");
+ data->tsd_type
+ = lookup_transparent_type ("<ada__tags__type_specific_data>",
+ SEARCH_TYPE_DOMAIN);
return data->tsd_type;
}
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index ce711c4b4f6..cc33aad088e 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -935,9 +935,11 @@ class cplus_language : public language_defn
}
/* See language.h. */
- struct type *lookup_transparent_type (const char *name) const override
+ struct type *lookup_transparent_type (const char *name,
+ domain_search_flags flags)
+ const override
{
- return cp_lookup_transparent_type (name);
+ return cp_lookup_transparent_type (name, flags);
}
/* See language.h. */
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 41ab52de54a..fb9fcf8ed6e 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -1024,10 +1024,10 @@ cp_lookup_nested_symbol (struct type *parent_type,
released version of GCC with such information.) */
struct type *
-cp_lookup_transparent_type (const char *name)
+cp_lookup_transparent_type (const char *name, domain_search_flags flags)
{
/* First, try the honest way of looking up the definition. */
- struct type *t = basic_lookup_transparent_type (name);
+ struct type *t = basic_lookup_transparent_type (name, flags);
const char *scope;
if (t != NULL)
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index f95b6f0f0e2..4015126154b 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -161,7 +161,8 @@ extern struct block_symbol
const struct block *block,
const domain_search_flags domain);
-struct type *cp_lookup_transparent_type (const char *name);
+struct type *cp_lookup_transparent_type (const char *name,
+ domain_search_flags flags);
/* See description in cp-namespace.c. */
diff --git a/gdb/language.h b/gdb/language.h
index 5bef965c2c8..19bffcc3a7a 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -349,9 +349,10 @@ struct language_defn
/* Find the definition of the type with the given name. */
- virtual struct type *lookup_transparent_type (const char *name) const
+ virtual struct type *lookup_transparent_type (const char *name,
+ domain_search_flags flags) const
{
- return basic_lookup_transparent_type (name);
+ return basic_lookup_transparent_type (name, flags);
}
/* Find all symbols in the current program space matching NAME in
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 02f5d4f1b3d..aa2de7121cd 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2692,9 +2692,9 @@ symbol::matches (domain_search_flags flags) const
/* See symtab.h. */
struct type *
-lookup_transparent_type (const char *name)
+lookup_transparent_type (const char *name, domain_search_flags flags)
{
- return current_language->lookup_transparent_type (name);
+ return current_language->lookup_transparent_type (name, flags);
}
/* A helper for basic_lookup_transparent_type that interfaces with the
@@ -2703,6 +2703,7 @@ lookup_transparent_type (const char *name)
static struct type *
basic_lookup_transparent_type_quick (struct objfile *objfile,
enum block_enum block_index,
+ domain_search_flags flags,
const char *name)
{
struct compunit_symtab *cust;
@@ -2710,7 +2711,7 @@ basic_lookup_transparent_type_quick (struct objfile *objfile,
const struct block *block;
struct symbol *sym;
- cust = objfile->lookup_symbol (block_index, name, SEARCH_STRUCT_DOMAIN);
+ cust = objfile->lookup_symbol (block_index, name, flags);
if (cust == NULL)
return NULL;
@@ -2718,7 +2719,7 @@ basic_lookup_transparent_type_quick (struct objfile *objfile,
block = bv->block (block_index);
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
- sym = block_find_symbol (block, lookup_name, SEARCH_STRUCT_DOMAIN, nullptr);
+ sym = block_find_symbol (block, lookup_name, flags, nullptr);
if (sym == nullptr)
error_in_psymtab_expansion (block_index, name, cust);
gdb_assert (!TYPE_IS_OPAQUE (sym->type ()));
@@ -2732,6 +2733,7 @@ basic_lookup_transparent_type_quick (struct objfile *objfile,
static struct type *
basic_lookup_transparent_type_1 (struct objfile *objfile,
enum block_enum block_index,
+ domain_search_flags flags,
const char *name)
{
const struct blockvector *bv;
@@ -2743,8 +2745,7 @@ basic_lookup_transparent_type_1 (struct objfile *objfile,
{
bv = cust->blockvector ();
block = bv->block (block_index);
- sym = block_find_symbol (block, lookup_name, SEARCH_STRUCT_DOMAIN,
- nullptr);
+ sym = block_find_symbol (block, lookup_name, flags, nullptr);
if (sym != nullptr)
{
gdb_assert (!TYPE_IS_OPAQUE (sym->type ()));
@@ -2762,7 +2763,7 @@ basic_lookup_transparent_type_1 (struct objfile *objfile,
global blocks. */
struct type *
-basic_lookup_transparent_type (const char *name)
+basic_lookup_transparent_type (const char *name, domain_search_flags flags)
{
struct type *t;
@@ -2773,14 +2774,16 @@ basic_lookup_transparent_type (const char *name)
for (objfile *objfile : current_program_space->objfiles ())
{
- t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK, name);
+ t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK,
+ flags, name);
if (t)
return t;
}
for (objfile *objfile : current_program_space->objfiles ())
{
- t = basic_lookup_transparent_type_quick (objfile, GLOBAL_BLOCK, name);
+ t = basic_lookup_transparent_type_quick (objfile, GLOBAL_BLOCK,
+ flags, name);
if (t)
return t;
}
@@ -2794,14 +2797,16 @@ basic_lookup_transparent_type (const char *name)
for (objfile *objfile : current_program_space->objfiles ())
{
- t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK, name);
+ t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK,
+ flags, name);
if (t)
return t;
}
for (objfile *objfile : current_program_space->objfiles ())
{
- t = basic_lookup_transparent_type_quick (objfile, STATIC_BLOCK, name);
+ t = basic_lookup_transparent_type_quick (objfile, STATIC_BLOCK,
+ flags, name);
if (t)
return t;
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index ca5a5b0f7fd..9c20a20f062 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2307,9 +2307,11 @@ extern void reread_symbols (int from_tty);
The type returned must not be opaque -- i.e., must have at least one field
defined. */
-extern struct type *lookup_transparent_type (const char *);
+extern struct type *lookup_transparent_type
+ (const char *name, domain_search_flags flags = SEARCH_STRUCT_DOMAIN);
-extern struct type *basic_lookup_transparent_type (const char *);
+extern struct type *basic_lookup_transparent_type
+ (const char *name, domain_search_flags flags = SEARCH_STRUCT_DOMAIN);
/* Macro for name of symbol to indicate a file compiled with gcc. */
#ifndef GCC_COMPILED_FLAG_SYMBOL
diff --git a/gdb/testsuite/gdb.ada/tagged-lookup.exp b/gdb/testsuite/gdb.ada/tagged-lookup.exp
new file mode 100644
index 00000000000..708b8aac19e
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup.exp
@@ -0,0 +1,61 @@
+# Copyright 2024 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Check that we can print values of parameters of type 'pointer
+# (access) to tagged type'. See PR gdb/22670.
+
+load_lib "ada.exp"
+
+require allow_ada_tests
+
+standard_ada_testfile foo
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+ return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb]
+if {![runto "foo.adb:$bp_location"]} {
+ return
+}
+
+gdb_test_no_output "set debug symtab-create 1"
+
+# The idea here is that just a single CU should be expanded while
+# searching for the tsd type.
+set found_pck 0
+set found_pck2 0
+gdb_test_multiple "print *value" "only one CU expanded" -lbl {
+ -re ".symtab-create. start_subfile: name = \[^,\]*pck\\.adb, name_for_id = \[^\r\n\]*\r\n" {
+ set found_pck 1
+ exp_continue
+ }
+ -re ".symtab-create. start_subfile: name = \[^,\]*pck2\\.adb, name_for_id = \[^\r\n\]*\r\n" {
+ set found_pck2 1
+ exp_continue
+ }
+ -re ".symtab-create. start_subfile: name = \[^,\]*, name_for_id = \[^\r\n\]*\r\n" {
+ exp_continue
+ }
+ -re -wrap ".* = \\\(n => $decimal\\\)" {
+ if {$found_pck + $found_pck2 == 1} {
+ pass $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
+ }
+}
diff --git a/gdb/testsuite/gdb.ada/tagged-lookup/foo.adb b/gdb/testsuite/gdb.ada/tagged-lookup/foo.adb
new file mode 100644
index 00000000000..35e1aa3a12a
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup/foo.adb
@@ -0,0 +1,23 @@
+-- Copyright 2017-2024 Free Software Foundation, Inc.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+with Pck; use Pck;
+with Pck2; use Pck2;
+procedure Foo is
+ The_Local_Var : access Top_T2 := new Top_T2'(N => 2);
+begin
+ Inspect (new Top_T'(N => 2)); -- STOP
+ Inspect2 (The_Local_Var);
+end Foo;
diff --git a/gdb/testsuite/gdb.ada/tagged-lookup/pck.adb b/gdb/testsuite/gdb.ada/tagged-lookup/pck.adb
new file mode 100644
index 00000000000..d5f843a0a29
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup/pck.adb
@@ -0,0 +1,22 @@
+-- Copyright 2017-2024 Free Software Foundation, Inc.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+with Pck2; use Pck2;
+package body Pck is
+ procedure Inspect (Obj: access Top_T'Class) is
+ begin
+ null;
+ end Inspect;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/tagged-lookup/pck.ads b/gdb/testsuite/gdb.ada/tagged-lookup/pck.ads
new file mode 100644
index 00000000000..7731fe29886
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup/pck.ads
@@ -0,0 +1,21 @@
+-- Copyright 2017-2024 Free Software Foundation, Inc.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package Pck is
+ type Top_T is tagged record
+ N : Integer := 1;
+ end record;
+ procedure Inspect (Obj: access Top_T'Class);
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/tagged-lookup/pck2.adb b/gdb/testsuite/gdb.ada/tagged-lookup/pck2.adb
new file mode 100644
index 00000000000..87f77e503da
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup/pck2.adb
@@ -0,0 +1,21 @@
+-- Copyright 2017-2024 Free Software Foundation, Inc.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package body Pck2 is
+ procedure Inspect2 (Obj: access Top_T2'Class) is
+ begin
+ null;
+ end Inspect2;
+end Pck2;
diff --git a/gdb/testsuite/gdb.ada/tagged-lookup/pck2.ads b/gdb/testsuite/gdb.ada/tagged-lookup/pck2.ads
new file mode 100644
index 00000000000..c45962b3c5c
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup/pck2.ads
@@ -0,0 +1,22 @@
+-- Copyright 2017-2024 Free Software Foundation, Inc.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+with Pck; use Pck;
+package Pck2 is
+ type Top_T2 is tagged record
+ N : Integer := 1;
+ end record;
+ procedure Inspect2 (Obj: access Top_T2'Class);
+end Pck2;
--
2.43.0
More information about the Gdb-patches
mailing list