[PATCH][v2] vtv: Fix Memory Leak and Other Improvements

Léo Hardt <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
vtv: Fix Memory Leak and Other Improvements

Since there is only one listed maintainer for libvtv, who doesn't
seem active in recent years, is it possible for global reviewers
to take a look at this patch?

Currently, vtable_find_or_create_map_decl, given a class decl,
calls get_mangled_vtable_map_var_name (from mangle.cc) to:

   (1) create a VTV map entry for the given class; and
   (2) return the expected DECL_ASSEMBLER_NAME of its VTV tracker.

Here are some issues and improvements for that logic:

a. (2) was only needed once for each class, and in that case, we
call get_identifier (var_name). Now we only generate the identifier
iff it is needed.

b. Since get_identifier copies data, (and when it wasn't called,
we didn't free (var_name)), var_name was always leaked.
var_name is now computed without heap allocation.

c. get_identifier was called twice for the same symbol, which
costs an extra hash table lookup. Now we store it in a variable.

d. "vtable-class-hierarchy" and "mangle" depended on each other.
This is just because (1) is done inside mangle.cc. By moving that
statement to vtable-class-hierarchy, we untangle one circular
dependency.

The effect of vtable_find_or_create_map_decl has not changed.
Successfully bootstrapped with "--enable-vtable-verify".

gcc/cp/ChangeLog:

	* cp-tree.h (get_mangled_vtable_map_var_name): Only get the name,
	without side effects.
	(get_mangled_type_name_if_anon): Split off from function above.
	* mangle.cc (get_mangled_vtable_map_var_name): Only get the name,
	without side effects.
	(get_mangled_type_name_if_anon): Split off from function above.
	* vtable-class-hierarchy.cc (vtable_find_or_create_map_decl):
	Fix memory leak.

Signed-off-by: Léo Hardt <[email protected]>
---
  gcc/cp/cp-tree.h                 |  3 +-
  gcc/cp/mangle.cc                 | 53 ++++++++++++++++----------------
  gcc/cp/vtable-class-hierarchy.cc | 23 ++++++++------
  3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 87245184461..2d2db9db113 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -9226,7 +9226,8 @@ extern tree mangle_tls_wrapper_fn		(tree);
  extern bool decl_tls_wrapper_p			(tree);
  extern tree mangle_ref_init_variable		(tree);
  extern tree mangle_template_parm_object		(tree);
-extern char *get_mangled_vtable_map_var_name    (tree);
+extern tree get_mangled_type_name_if_anon	(tree);
+extern tree get_mangled_vtable_map_var_name	(tree);
  extern bool mangle_return_type_p		(tree);
  extern tree mangle_decomp			(tree, vec<tree> &);
  extern void mangle_module_substitution		(int);
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 4ec57a54c34..5d4126f3bb4 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -48,7 +48,6 @@ along with GCC; see the file COPYING3.  If not see
  #include "system.h"
  #include "coretypes.h"
  #include "target.h"
-#include "vtable-verify.h"
  #include "cp-tree.h"
  #include "stringpool.h"
  #include "cgraph.h"
@@ -5378,41 +5377,43 @@ mangle_template_parm_object (tree expr)
    return finish_mangling_get_identifier ();
  }
  
-/* Given a CLASS_TYPE, such as a record for std::bad_exception this
-   function generates a mangled name for the vtable map variable of
-   the class type.  For example, if the class type is
-   "std::bad_exception", the mangled name for the class is
-   "St13bad_exception".  This function would generate the name
-   "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE", which unmangles as:
-   "_VTV<std::bad_exception>::__vtable_map".  */

+/* Given a CLASS_TYPE, such as a record for std::bad_exception this
+   function returns NULL_TREE if TYPE_NAME (CLASS_TYPE) is not from
+   an anonymous namespace. Otherwise, returns the mangled type name.
+   */

-char *
-get_mangled_vtable_map_var_name (tree class_type)
+tree
+get_mangled_type_name_if_anon(tree class_type)
  {
-  char *var_name = NULL;
-  const char *prefix = "_ZN4_VTVI";
-  const char *postfix = "E12__vtable_mapE";
-
    gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
-
    tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type));
+  bool is_anon = strstr (IDENTIFIER_POINTER (class_id), "<anon>") != NULL;
+  return is_anon ? get_mangled_id (TYPE_NAME (class_type)) : NULL_TREE;
+}

-  if (strstr (IDENTIFIER_POINTER (class_id), "<anon>") != NULL)
-    {
-      class_id = get_mangled_id (TYPE_NAME (class_type));
-      vtbl_register_mangled_name (TYPE_NAME (class_type), class_id);
-    }
+/* Given a CLASS_TYPE_ASSEMBLER_NAME, such as of the TYPE_NAME of a
+   record for std::bad_exception, this function generates a mangled
+   identifier for the vtable map variable of the class type.
+   For example, if the class type is "std::bad_exception", the mangled
+   name for the class is "St13bad_exception".  This function would
+   generate the name "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE",
+   which unmangles as "_VTV<std::bad_exception>::__vtable_map".  */
+
+tree
+get_mangled_vtable_map_var_name (tree class_type_assembler_name)
+{
+  const char *prefix = "_ZN4_VTVI";
+  const char *postfix = "E12__vtable_mapE";

-  unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) +
-                     strlen (prefix) +
-                     strlen (postfix) + 1;
+  const char * class_name =
+    IDENTIFIER_POINTER (class_type_assembler_name);

-  var_name = (char *) xmalloc (len);
+  gcc_assert (strstr (class_name, "<anon>") == NULL);

-  sprintf (var_name, "%s%s%s", prefix, IDENTIFIER_POINTER (class_id), 
postfix);
+  char *var_name = ACONCAT ((prefix, class_name, postfix, NULL));

-  return var_name;
+  return get_identifier(var_name);
  }

  #include "gt-cp-mangle.h"
diff --git a/gcc/cp/vtable-class-hierarchy.cc 
b/gcc/cp/vtable-class-hierarchy.cc
index 2e52ea3c4a0..7b80d82035b 100644
--- a/gcc/cp/vtable-class-hierarchy.cc
+++ b/gcc/cp/vtable-class-hierarchy.cc
@@ -1204,15 +1204,22 @@ vtv_generate_init_routine (void)
  struct vtbl_map_node *
  vtable_find_or_create_map_decl (tree base_type)
  {
-  char *var_name = NULL;
    struct vtbl_map_node *vtable_map_node = NULL;
+  tree base_type_name = DECL_ASSEMBLER_NAME (TYPE_NAME (base_type));

    /* Verify the type has an associated vtable.  */
    if (!TYPE_BINFO (base_type) || !BINFO_VTABLE (TYPE_BINFO (base_type)))
      return NULL;

    /* Create map lookup symbol for base class */
-  var_name = get_mangled_vtable_map_var_name (base_type);
+  tree mangled_base_type_name = get_mangled_type_name_if_anon (base_type);
+
+  if (mangled_base_type_name != NULL_TREE)
+    {
+      vtbl_register_mangled_name
+	(TYPE_NAME (base_type), mangled_base_type_name);
+      base_type_name = mangled_base_type_name;
+    }

    /* We've already created the variable; just look it.  */
    vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_type));
@@ -1223,17 +1230,15 @@ vtable_find_or_create_map_decl (tree base_type)
           variable for this class, do so now, and add it to the
           varpool, to make sure it gets saved and written out.  */

-      tree var_decl = NULL;
+      tree var_name = get_mangled_vtable_map_var_name (base_type_name);
        tree var_type = build_pointer_type (void_type_node);
-      tree initial_value = integer_zero_node;
-
-      var_decl  = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-                              get_identifier (var_name), var_type);
+      tree var_decl =
+	build_decl (UNKNOWN_LOCATION, VAR_DECL, var_name, var_type);

        DECL_EXTERNAL (var_decl) = 0;
        TREE_STATIC (var_decl) = 1;
        DECL_VISIBILITY (var_decl) = VISIBILITY_HIDDEN;
-      SET_DECL_ASSEMBLER_NAME (var_decl, get_identifier (var_name));
+      SET_DECL_ASSEMBLER_NAME (var_decl, var_name);
        DECL_ARTIFICIAL (var_decl) = 1;
        /* We cannot mark this variable as read-only because we want to be
           able to write to it at runtime.  */
@@ -1246,7 +1251,7 @@ vtable_find_or_create_map_decl (tree base_type)

        set_decl_section_name (var_decl, ".vtable_map_vars");
        symtab_node::get (var_decl)->implicit_section = true;
-      DECL_INITIAL (var_decl) = initial_value;
+      DECL_INITIAL (var_decl) = integer_zero_node;

        comdat_linkage (var_decl);

-- 
2.39.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.