From: David Malcolm <dmalcolm@redhat.com>
To: "Marc Nieper-Wißkirchen" <marc@nieper-wisskirchen.de>,
gcc-patches@gcc.gnu.org
Cc: jit@gcc.gnu.org
Subject: Re: [PATCH] gcc: pass-manager: Fix memory leak. [PR jit/63854]
Date: Thu, 06 Jan 2022 08:53:01 -0500 [thread overview]
Message-ID: <2a54fac9b37d87afb009b8eb339d5ad6927454dd.camel@redhat.com> (raw)
In-Reply-To: <20211219213010.17113-1-marc@nieper-wisskirchen.de>
On Sun, 2021-12-19 at 22:30 +0100, Marc Nieper-Wißkirchen wrote:
> This patch fixes a memory leak in the pass manager. In the existing
> code,
> the m_name_to_pass_map is allocated in
> pass_manager::register_pass_name, but
> never deallocated. This is fixed by adding a deletion in
> pass_manager::~pass_manager. Moreover the string keys in
> m_name_to_pass_map are
> all dynamically allocated. To free them, this patch adds a new hash
> trait for
> string hashes that are to be freed when the corresponding hash entry
> is removed.
>
> This fix is particularly relevant for using GCC as a library through
> libgccjit.
> The memory leak also occurs when libgccjit is instructed to use an
> external
> driver.
>
> 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.
Thanks for the patch.
It looks correct to me, given that pass_manager::register_pass_name
does an xstrdup and puts the result in the map.
That said:
- I'm not officially a reviewer for this part of gcc (though I probably
touched this code last)
- is it cleaner to instead change m_name_to_pass_map's key type from
const char * to char *, to convey that the map "owns" the name? That
way we probably wouldn't need struct typed_const_free_remove, and (I
hope) works better with the type system.
Dave
>
> 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.c (pass_manager::register_pass_name): Use
> free_string_hash.
> (pass_manager::~pass_manager): Delete allocated
> m_name_to_pass_map.
> ---
> gcc/hash-traits.h | 17 +++++++++++++++++
> gcc/pass_manager.h | 3 +--
> gcc/passes.c | 5 +++--
> 3 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/hash-traits.h b/gcc/hash-traits.h
> index 6f0373ec27f..1c08d6874ab 100644
> --- a/gcc/hash-traits.h
> +++ b/gcc/hash-traits.h
> @@ -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. */
>
> diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
> index aaf72cf6803..f5615e1fda8 100644
> --- a/gcc/pass_manager.h
> +++ b/gcc/pass_manager.h
> @@ -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 */
> -
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 4bea6ae5b6a..0c70ece5321 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -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)
> {
next prev parent reply other threads:[~2022-01-06 13:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-19 21:30 Marc Nieper-Wißkirchen
2022-01-06 13:53 ` David Malcolm [this message]
2022-01-06 13:57 ` David Malcolm
2022-01-08 9:26 ` Marc Nieper-Wißkirchen
2022-01-08 10:07 ` Marc Nieper-Wißkirchen
2022-01-08 16:32 ` Jeff Law
2022-01-15 13:56 ` Marc Nieper-Wißkirchen
2022-01-23 13:18 ` Marc Nieper-Wißkirchen
2022-01-31 11:42 ` Marc Nieper-Wißkirchen
2022-03-11 16:31 ` Marc Nieper-Wißkirchen
2022-03-19 17:43 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2a54fac9b37d87afb009b8eb339d5ad6927454dd.camel@redhat.com \
--to=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jit@gcc.gnu.org \
--cc=marc@nieper-wisskirchen.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).