]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] gcc: pass-manager: Fix memory leak. [PR jit/63854]
authorMarc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
Sat, 19 Mar 2022 17:42:26 +0000 (13:42 -0400)
committerJeff Law <jeffreyalaw@gmail.com>
Sat, 19 Mar 2022 17:43:02 +0000 (13:43 -0400)
Before the patch, compiling the hello world example of libgccjit with
the external driver under Valgrind shows a loss of 12,611 (48 direct)
bytes.  After the patch, no memory leaks are reported anymore.
(Memory leaks occurring when using the internal driver are mostly in
the driver code in gcc/gcc.c and have to be fixed separately.)

The patch has been tested by fully bootstrapping the compiler with the
frontends C, C++, Fortran, LTO, ObjC, JIT and running the test suite
under a x86_64-pc-linux-gnu host.

gcc/ChangeLog:

PR jit/63854
* hash-traits.h (struct typed_const_free_remove): New.
(struct free_string_hash): New.
* pass_manager.h: Use free_string_hash.
* passes.cc (pass_manager::register_pass_name): Use free_string_hash.
(pass_manager::~pass_manager): Delete allocated m_name_to_pass_map.

gcc/hash-traits.h
gcc/pass_manager.h
gcc/passes.cc

index b16975cfeb34cd156635ef3bbb587f36f0d5043b..bef0bd42d04e30381cf93192badc188721a1a58e 100644 (file)
@@ -28,6 +28,11 @@ struct typed_free_remove
   static inline void remove (Type *p);
 };
 
+template <typename Type>
+struct typed_const_free_remove
+{
+  static inline void remove (const Type *p);
+};
 
 /* Remove with free.  */
 
@@ -38,6 +43,13 @@ typed_free_remove <Type>::remove (Type *p)
   free (p);
 }
 
+template <typename Type>
+inline void
+typed_const_free_remove <Type>::remove (const Type *p)
+{
+  free (const_cast <Type *> (p));
+}
+
 /* Helpful type for removing with delete.  */
 
 template <typename Type>
@@ -305,6 +317,11 @@ struct ggc_ptr_hash : pointer_hash <T>, ggc_remove <T *> {};
 template <typename T>
 struct ggc_cache_ptr_hash : pointer_hash <T>, ggc_cache_remove <T *> {};
 
+/* Traits for string elements that should be freed when an element is
+   deleted.  */
+
+struct free_string_hash : string_hash, typed_const_free_remove <char> {};
+
 /* Traits for string elements that should not be freed when an element
    is deleted.  */
 
index 6484d2c8ebc6ec54c845079e175a875ddcd6b0c0..43484da2700128b7d374af491f9cfb34e902e45f 100644 (file)
@@ -106,7 +106,7 @@ private:
 
 private:
   context *m_ctxt;
-  hash_map<nofree_string_hash, opt_pass *> *m_name_to_pass_map;
+  hash_map<free_string_hash, opt_pass *> *m_name_to_pass_map;
 
   /* References to all of the individual passes.
      These fields are generated via macro expansion.
@@ -146,4 +146,3 @@ private:
 } // namespace gcc
 
 #endif /* ! GCC_PASS_MANAGER_H */
-
index 00f856e07548636a5b06a0f06605798ee12afb5b..36e5b4ac45fd8a17aa064b01d46ef8618d3fae20 100644 (file)
@@ -903,7 +903,7 @@ void
 pass_manager::register_pass_name (opt_pass *pass, const char *name)
 {
   if (!m_name_to_pass_map)
-    m_name_to_pass_map = new hash_map<nofree_string_hash, opt_pass *> (256);
+    m_name_to_pass_map = new hash_map<free_string_hash, opt_pass *> (256);
 
   if (m_name_to_pass_map->get (name))
     return; /* Ignore plugin passes.  */
@@ -1674,6 +1674,7 @@ pass_manager::~pass_manager ()
   GCC_PASS_LISTS
 #undef DEF_PASS_LIST
 
+  delete m_name_to_pass_map;
 }
 
 /* If we are in IPA mode (i.e., current_function_decl is NULL), call
@@ -1943,7 +1944,7 @@ pass_manager::dump_profile_report () const
           "                                 |in count     |out prob     "
           "|in count                  |out prob                  "
           "|size               |time                      |\n");
-          
+
   for (int i = 1; i < passes_by_id_size; i++)
     if (profile_record[i].run)
       {