[review v3] Don't make an extra copy + allocation of the demangled name

Christian Biesinger (Code Review) gerrit@gnutoolchain-gerrit.osci.io
Wed Oct 23 16:51:00 GMT 2019


Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/132
......................................................................

Don't make an extra copy + allocation of the demangled name

We can just keep around the malloc()-ed name we got from bfd and free
it later.

gdb/ChangeLog:

2019-10-02  Christian Biesinger  <cbiesinger@google.com>

	* symtab.c (struct demangled_name_entry): Change demangled name
	to a unique_xmalloc_ptr<char>, now that we don't allocate it as
	part of the struct anymore.
	(symbol_set_names): No longer obstack allocate + copy the demangled
	name, just store the allocated name from bfd.

Change-Id: Ie6ad50e1e1e73509f55d756f0a437897bb93e3b0
---
M gdb/symtab.c
1 file changed, 13 insertions(+), 25 deletions(-)



diff --git a/gdb/symtab.c b/gdb/symtab.c
index 160a4c0..8553fc9 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -723,7 +723,7 @@
 
   gdb::string_view mangled;
   enum language language;
-  char demangled[1];
+  gdb::unique_xmalloc_ptr<char> demangled;
 };
 
 /* Hash function for the demangled name hash.  */
@@ -880,64 +880,52 @@
   if (*slot == NULL
       /* A C version of the symbol may have already snuck into the table.
 	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
-      || (gsymbol->language == language_go
-	  && (*slot)->demangled[0] == '\0'))
+      || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
     {
-      char *demangled_name_ptr
-	= symbol_find_demangled_name (gsymbol, linkage_name_copy);
-      gdb::unique_xmalloc_ptr<char> demangled_name (demangled_name_ptr);
-      int demangled_len = demangled_name ? strlen (demangled_name.get ()) : 0;
+      gdb::unique_xmalloc_ptr<char> demangled_name_ptr
+	(symbol_find_demangled_name (gsymbol, linkage_name_copy));
 
       /* Suppose we have demangled_name==NULL, copy_name==0, and
 	 linkage_name_copy==linkage_name.  In this case, we already have the
 	 mangled name saved, and we don't have a demangled name.  So,
 	 you might think we could save a little space by not recording
 	 this in the hash table at all.
-	 
+
 	 It turns out that it is actually important to still save such
 	 an entry in the hash table, because storing this name gives
 	 us better bcache hit rates for partial symbols.  */
-      if (!copy_name && linkage_name_copy == linkage_name)
+      if (!copy_name)
 	{
 	  *slot
 	    = ((struct demangled_name_entry *)
 	       obstack_alloc (&per_bfd->storage_obstack,
-			      offsetof (struct demangled_name_entry, demangled)
-			      + demangled_len + 1));
+			      sizeof (demangled_name_entry)));
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (linkage_name, len));
 	}
       else
 	{
-	  char *mangled_ptr;
-
 	  /* If we must copy the mangled name, put it directly after
-	     the demangled name so we can have a single
-	     allocation.  */
+	     the struct so we can have a single allocation.  */
 	  *slot
 	    = ((struct demangled_name_entry *)
 	       obstack_alloc (&per_bfd->storage_obstack,
-			      offsetof (struct demangled_name_entry, demangled)
-			      + len + demangled_len + 2));
-	  mangled_ptr = &((*slot)->demangled[demangled_len + 1]);
+			      sizeof (demangled_name_entry) + len + 1));
+	  char *mangled_ptr = reinterpret_cast<char*> (*slot + 1);
 	  strcpy (mangled_ptr, linkage_name_copy);
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (mangled_ptr, len));
 	}
+      (*slot)->demangled = std::move (demangled_name_ptr);
       (*slot)->language = gsymbol->language;
-
-      if (demangled_name != NULL)
-	strcpy ((*slot)->demangled, demangled_name.get ());
-      else
-	(*slot)->demangled[0] = '\0';
     }
   else if (gsymbol->language == language_unknown
 	   || gsymbol->language == language_auto)
     gsymbol->language = (*slot)->language;
 
   gsymbol->name = (*slot)->mangled.data ();
-  if ((*slot)->demangled[0] != '\0')
-    symbol_set_demangled_name (gsymbol, (*slot)->demangled,
+  if ((*slot)->demangled != nullptr)
+    symbol_set_demangled_name (gsymbol, (*slot)->demangled.get (),
 			       &per_bfd->storage_obstack);
   else
     symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);



More information about the Gdb-patches mailing list