Speed up lookup of "type_specific_data"

Message ID 20240214203910.3875303-1-tromey@adacore.com
State New
Headers
Series Speed up lookup of "type_specific_data" |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 fail Testing failed
linaro-tcwg-bot/tcwg_gdb_check--master-arm fail Testing failed

Commit Message

Tom Tromey Feb. 14, 2024, 8:39 p.m. UTC
  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.
---
 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      | 60 ++++++++++++++++++++
 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, 203 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
  

Patch

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..e5afde495a4
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/tagged-lookup.exp
@@ -0,0 +1,60 @@ 
+# 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}
+
+if {![runto "foo"]} {
+  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..5148aa79f63
--- /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
+   Value : access Top_T2 := new Top_T2'(N => 2);
+begin
+   Inspect (new Top_T'(N => 2));
+   Inspect2 (Value);
+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;