This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 5/9] introduce per-bfd data for the objfile


>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> This patch introduces a struct objfile_per_bfd_storage to store such
Tom> data.  Then it changes objfiles to refer to it; when a BFD is shared,
Tom> multiple objfiles will just share one of these objects.

This patch needed a small test suite fix, because it added some output
to "maint print statistics".

Tom

	* elfread.c (elf_symtab_read): Update.
	* objfiles.c (objfiles_bfd_data): New global.
	(get_objfile_bfd_data, free_objfile_per_bfd_storage)
	(objfile_bfd_data_free, set_objfile_per_bfd): New functions.
	(allocate_objfile, free_objfile): Update.
	(_initialize_objfiles): Initialize objfiles_bfd_data.
	* objfiles.h (struct objfile_per_bfd_storage): New.
	(struct objfile) <per_bfd>: New field.
	<filename_cache>: Remove.
	(set_objfile_per_bfd): Declare.
	* symfile.c (reread_symbols): Update.  Call
	set_objfile_per_bfd.
	(allocate_symtab): Update.
	* symmisc.c (print_symbol_bcache_statistics): Update.
	(print_objfile_statistics): Print the size of the BFD obstack.

	* gdb.base/maint.exp: Update.
---
 gdb/elfread.c                    |    2 +-
 gdb/objfiles.c                   |   79 ++++++++++++++++++++++++++++++++++++-
 gdb/objfiles.h                   |   26 ++++++++++++-
 gdb/symfile.c                    |    6 +-
 gdb/symmisc.c                    |    7 ++-
 gdb/testsuite/gdb.base/maint.exp |    2 +-
 6 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/gdb/elfread.c b/gdb/elfread.c
index 22ac158..f3967d7 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -353,7 +353,7 @@ elf_symtab_read (struct objfile *objfile, int type,
 	    }
 	  filesym = sym;
 	  filesymname = bcache (filesym->name, strlen (filesym->name) + 1,
-				objfile->filename_cache);
+				objfile->per_bfd->filename_cache);
 	}
       else if (sym->flags & BSF_SECTION_SYM)
 	continue;
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 57dd594..250cf35 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -106,6 +106,74 @@ get_objfile_pspace_data (struct program_space *pspace)
   return info;
 }
 
+
+
+/* Per-BFD data key.  */
+
+static const struct bfd_data *objfiles_bfd_data;
+
+/* Create the per-BFD storage object for OBJFILE.  If ABFD is not
+   NULL, and it already has a per-BFD storage object, use that.
+   Otherwise, allocate a new per-BFD storage object.  If ABFD is not
+   NULL, the object is allocated on the BFD; otherwise it is allocated
+   on OBJFILE's obstack.  Note that it is not safe to call this
+   multiple times for a given OBJFILE -- it can only be called when
+   allocating or re-initializing OBJFILE.  */
+
+static struct objfile_per_bfd_storage *
+get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd)
+{
+  struct objfile_per_bfd_storage *storage = NULL;
+
+  if (abfd != NULL)
+    storage = bfd_data (abfd, objfiles_bfd_data);
+
+  if (storage == NULL)
+    {
+      if (abfd != NULL)
+	{
+	  storage = bfd_zalloc (abfd, sizeof (struct objfile_per_bfd_storage));
+	  set_bfd_data (abfd, objfiles_bfd_data, storage);
+	}
+      else
+	storage = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+				  struct objfile_per_bfd_storage);
+
+      obstack_init (&storage->storage_obstack);
+      storage->filename_cache = bcache_xmalloc (NULL, NULL);
+    }
+
+  return storage;
+}
+
+/* Free STORAGE.  */
+
+static void
+free_objfile_per_bfd_storage (struct objfile_per_bfd_storage *storage)
+{
+  bcache_xfree (storage->filename_cache);
+  obstack_free (&storage->storage_obstack, 0);
+}
+
+/* A wrapper for free_objfile_per_bfd_storage that can be passed as a
+   cleanup function to the BFD registry.  */
+
+static void
+objfile_bfd_data_free (struct bfd *unused, void *d)
+{
+  free_objfile_per_bfd_storage (d);
+}
+
+/* See objfiles.h.  */
+
+void
+set_objfile_per_bfd (struct objfile *objfile)
+{
+  objfile->per_bfd = get_objfile_bfd_data (objfile, objfile->obfd);
+}
+
+
+
 /* Called via bfd_map_over_sections to build up the section table that
    the objfile references.  The objfile contains pointers to the start
    of the table (objfile->sections) and to the first location after
@@ -184,7 +252,6 @@ allocate_objfile (bfd *abfd, int flags)
   objfile = (struct objfile *) xzalloc (sizeof (struct objfile));
   objfile->psymbol_cache = psymbol_bcache_init ();
   objfile->macro_cache = bcache_xmalloc (NULL, NULL);
-  objfile->filename_cache = bcache_xmalloc (NULL, NULL);
   /* We could use obstack_specify_allocation here instead, but
      gdb_obstack.h specifies the alloc/dealloc functions.  */
   obstack_init (&objfile->objfile_obstack);
@@ -214,6 +281,7 @@ allocate_objfile (bfd *abfd, int flags)
       objfile->name = xstrdup ("<<anonymous objfile>>");
     }
 
+  objfile->per_bfd = get_objfile_bfd_data (objfile, abfd);
   objfile->pspace = current_program_space;
 
   /* Initialize the section indexes for this objfile, so that we can
@@ -557,7 +625,10 @@ free_objfile (struct objfile *objfile)
      still may reference objfile->obfd.  */
   objfile_free_data (objfile);
 
-  gdb_bfd_unref (objfile->obfd);
+  if (objfile->obfd)
+    gdb_bfd_unref (objfile->obfd);
+  else
+    free_objfile_per_bfd_storage (objfile->per_bfd);
 
   /* Remove it from the chain of all objfiles.  */
 
@@ -606,7 +677,6 @@ free_objfile (struct objfile *objfile)
   /* Free the obstacks for non-reusable objfiles.  */
   psymbol_bcache_free (objfile->psymbol_cache);
   bcache_xfree (objfile->macro_cache);
-  bcache_xfree (objfile->filename_cache);
   if (objfile->demangled_names_hash)
     htab_delete (objfile->demangled_names_hash);
   obstack_free (&objfile->objfile_obstack, 0);
@@ -1383,4 +1453,7 @@ _initialize_objfiles (void)
   objfiles_pspace_data
     = register_program_space_data_with_cleanup (NULL,
 						objfiles_pspace_data_cleanup);
+
+  objfiles_bfd_data = register_bfd_data_with_cleanup (NULL,
+						      objfile_bfd_data_free);
 }
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 097f4db..2b95ce4 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -160,6 +160,22 @@ extern void print_symbol_bcache_statistics (void);
 /* Number of entries in the minimal symbol hash table.  */
 #define MINIMAL_SYMBOL_HASH_SIZE 2039
 
+/* Some objfile data is hung off the BFD.  This enables sharing of the
+   data across all objfiles using the BFD.  The data is stored in an
+   instance of this structure, and associated with the BFD using the
+   registry system.  */
+
+struct objfile_per_bfd_storage
+{
+  /* The storage has an obstack of its own.  */
+
+  struct obstack storage_obstack;
+  
+  /* Byte cache for file names.  */
+
+  struct bcache *filename_cache;
+};
+
 /* Master structure for keeping track of each file from which
    gdb reads symbols.  There are several ways these get allocated: 1.
    The main symbol file, symfile_objfile, set by the symbol-file command,
@@ -222,6 +238,11 @@ struct objfile
 
     bfd *obfd;
 
+    /* The per-BFD data.  Note that this is treated specially if OBFD
+       is NULL.  */
+
+    struct objfile_per_bfd_storage *per_bfd;
+
     /* The gdbarch associated with the BFD.  Note that this gdbarch is
        determined solely from BFD information, without looking at target
        information.  The gdbarch determined from a running target may
@@ -249,7 +270,6 @@ struct objfile
 
     struct psymbol_bcache *psymbol_cache; /* Byte cache for partial syms.  */
     struct bcache *macro_cache;           /* Byte cache for macros.  */
-    struct bcache *filename_cache;	  /* Byte cache for file names.  */
 
     /* Hash table for mapping symbol names to demangled names.  Each
        entry in the hash table is actually two consecutive strings,
@@ -649,4 +669,8 @@ extern void default_iterate_over_objfiles_in_search_order
 
 #define MULTI_OBJFILE_P() (object_files && object_files->next)
 
+/* Reset the per-BFD storage area on OBJ.  */
+
+void set_objfile_per_bfd (struct objfile *obj);
+
 #endif /* !defined (OBJFILES_H) */
diff --git a/gdb/symfile.c b/gdb/symfile.c
index d070e48..6ef1ac1 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2550,8 +2550,6 @@ reread_symbols (void)
 	  objfile->psymbol_cache = psymbol_bcache_init ();
 	  bcache_xfree (objfile->macro_cache);
 	  objfile->macro_cache = bcache_xmalloc (NULL, NULL);
-	  bcache_xfree (objfile->filename_cache);
-	  objfile->filename_cache = bcache_xmalloc (NULL,NULL);
 	  if (objfile->demangled_names_hash != NULL)
 	    {
 	      htab_delete (objfile->demangled_names_hash);
@@ -2572,6 +2570,8 @@ reread_symbols (void)
 	  memset (&objfile->msymbol_demangled_hash, 0,
 		  sizeof (objfile->msymbol_demangled_hash));
 
+	  set_objfile_per_bfd (objfile);
+
 	  /* obstack_init also initializes the obstack so it is
 	     empty.  We could use obstack_specify_allocation but
 	     gdb_obstack.h specifies the alloc/dealloc functions.  */
@@ -2856,7 +2856,7 @@ allocate_symtab (const char *filename, struct objfile *objfile)
     obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab));
   memset (symtab, 0, sizeof (*symtab));
   symtab->filename = (char *) bcache (filename, strlen (filename) + 1,
-				      objfile->filename_cache);
+				      objfile->per_bfd->filename_cache);
   symtab->fullname = NULL;
   symtab->language = deduce_language_from_filename (filename);
   symtab->debugformat = "unknown";
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index d3028e6..3e9ca82 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -93,7 +93,8 @@ print_symbol_bcache_statistics (void)
     print_bcache_statistics (psymbol_bcache_get_bcache (objfile->psymbol_cache),
                              "partial symbol cache");
     print_bcache_statistics (objfile->macro_cache, "preprocessor macro cache");
-    print_bcache_statistics (objfile->filename_cache, "file name cache");
+    print_bcache_statistics (objfile->per_bfd->filename_cache,
+			     "file name cache");
   }
 }
 
@@ -147,13 +148,15 @@ print_objfile_statistics (void)
 		       OBJSTAT (objfile, sz_strtab));
     printf_filtered (_("  Total memory used for objfile obstack: %d\n"),
 		     obstack_memory_used (&objfile->objfile_obstack));
+    printf_filtered (_("  Total memory used for BFD obstack: %d\n"),
+		     obstack_memory_used (&objfile->per_bfd->storage_obstack));
     printf_filtered (_("  Total memory used for psymbol cache: %d\n"),
 		     bcache_memory_used (psymbol_bcache_get_bcache
 		                          (objfile->psymbol_cache)));
     printf_filtered (_("  Total memory used for macro cache: %d\n"),
 		     bcache_memory_used (objfile->macro_cache));
     printf_filtered (_("  Total memory used for file name cache: %d\n"),
-		     bcache_memory_used (objfile->filename_cache));
+		     bcache_memory_used (objfile->per_bfd->filename_cache));
   }
 }
 
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index 1c99150..2dc25f4 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -150,7 +150,7 @@ if [istarget "*-*-cygwin*"] {
 
 send_gdb "maint print statistics\n"
 gdb_expect  {
-    -re "Statistics for\[^\n\r\]*break\[^\n\r\]*:\r\n  Number of \"minimal\" symbols read: $decimal\r\n  Number of \"partial\" symbols read: $decimal\r\n  Number of \"full\" symbols read: $decimal\r\n  Number of \"types\" defined: $decimal\r\n  Number of psym tables \\(not yet expanded\\): $decimal\r\n  Number of symbol tables: $decimal\r\n  Number of symbol tables with line tables: $decimal\r\n  Number of symbol tables with blockvectors: $decimal\r\n  Total memory used for objfile obstack: $decimal\r\n  Total memory used for psymbol cache: $decimal\r\n  Total memory used for macro cache: $decimal\r\n  Total memory used for file name cache: $decimal\r\n" {
+    -re "Statistics for\[^\n\r\]*break\[^\n\r\]*:\r\n  Number of \"minimal\" symbols read: $decimal\r\n  Number of \"partial\" symbols read: $decimal\r\n  Number of \"full\" symbols read: $decimal\r\n  Number of \"types\" defined: $decimal\r\n  Number of psym tables \\(not yet expanded\\): $decimal\r\n  Number of symbol tables: $decimal\r\n  Number of symbol tables with line tables: $decimal\r\n  Number of symbol tables with blockvectors: $decimal\r\n  Total memory used for objfile obstack: $decimal\r\n  Total memory used for BFD obstack: $decimal\r\n  Total memory used for psymbol cache: $decimal\r\n  Total memory used for macro cache: $decimal\r\n  Total memory used for file name cache: $decimal\r\n" {
 	gdb_expect {
 	    -re "$gdb_prompt $" {
 		pass "maint print statistics"
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]