From c9da53d6987af5f8ff68b58dd76a9fbc900a6a21 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 24 Sep 2020 08:28:09 +0200 Subject: Fix memory allocations in ipa-modref. Pair ggc_delete with ggc_alloc_no_dtor. I copy same scheme as used by Martin in ipa-fnsummary, that is creating a static member function create_ggc hidding the ugly bits and using it in ipa-modref.c. I also noticed that modref-tree leaks memory on destruction/collapse method and fixed that. Bootstrapped/regtested x86_64-linux. gcc/ChangeLog: 2020-09-24 Jan Hubicka * ipa-modref-tree.h (modref_base::collapse): Release memory. (modref_tree::create_ggc): New member function. (modref_tree::colapse): Release memory. (modref_tree::~modref_tree): New destructor. * ipa-modref.c (modref_summaries::create_ggc): New function. (analyze_function): Use create_ggc. (modref_summaries::duplicate): Likewise. (read_modref_records): Likewise. (modref_read): Likewise. --- gcc/ipa-modref-tree.h | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-modref-tree.h') diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h index 3bdd305..82e959a 100644 --- a/gcc/ipa-modref-tree.h +++ b/gcc/ipa-modref-tree.h @@ -95,7 +95,15 @@ struct GTY((user)) modref_base_node void collapse () { - vec_free (refs); + size_t i; + modref_ref_node *r; + + if (refs) + { + FOR_EACH_VEC_SAFE_ELT (refs, i, r) + ggc_free (r); + vec_free (refs); + } refs = NULL; every_ref = true; } @@ -214,12 +222,36 @@ struct GTY((user)) modref_tree return NULL; } + /* Return ggc allocated instance. We explicitly call destructors via + ggc_delete and do not want finalizers to be registered and + called at the garbage collection time. */ + static modref_tree *create_ggc (size_t max_bases, size_t max_refs) + { + return new (ggc_alloc_no_dtor> ()) + modref_tree (max_bases, max_refs); + } + void collapse () { - vec_free (bases); + size_t i; + modref_base_node *n; + + if (bases) + { + FOR_EACH_VEC_SAFE_ELT (bases, i, n) + { + n->collapse (); + ggc_free (n); + } + vec_free (bases); + } bases = NULL; every_base = true; } + ~modref_tree () + { + collapse (); + } }; void modref_c_tests (); -- cgit v1.1