This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [PR c++/80290] recycle tinst garbage sooner


Ok, thanks.

On Tue, Apr 17, 2018, 9:29 PM Alexandre Oliva <aoliva@redhat.com> wrote:

> On Apr 17, 2018, Jason Merrill <jason@redhat.com> wrote:
>
> >> Any objections to making dec_refcount_use a friend of tinst_level's?
> >> Otherwise, I'd rather add a free() member function (or maybe static
> >> member function) to free both the TREE_LIST and the tinst_level objects.
>
> > Either of those sounds fine.
>
> Here's the additional incremental patch I'm testing.
>
> I've added a number of line breaks before opening braces in function
> definitions, that had escaped my attention in the initial patch
> submission.
>
> ---
>  gcc/cp/cp-tree.h |    5 ++++-
>  gcc/cp/mangle.c  |    2 +-
>  gcc/cp/pt.c      |   56
> ++++++++++++++++++++++++++++++++++++------------------
>  3 files changed, 42 insertions(+), 21 deletions(-)
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 26a50ac136dd..7031c79b35db 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -5903,6 +5903,9 @@ struct GTY((chain_next ("%h.next"))) tinst_level {
>    tree to_list ();
>
>   public:
> +  /* Release storage for OBJ and node, if it's a TREE_LIST.  */
> +  static void free(tinst_level *obj);
> +
>    /* Return TRUE iff the original node is a list, split or not.  */
>    bool list_p () const { return !not_list_p (); }
>
> @@ -5916,7 +5919,7 @@ struct GTY((chain_next ("%h.next"))) tinst_level {
>
>    /* Return the original node if it's a DECL or a TREE_LIST, but do
>       NOT convert a split list to a TREE_LIST: return NULL instead.  */
> -  tree get_decl_maybe () const {
> +  tree maybe_get_node () const {
>      if (!split_list_p ()) return tldcl;
>      else return NULL_TREE;
>    }
> diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
> index 940f7ed87e20..2f65709d7d8c 100644
> --- a/gcc/cp/mangle.c
> +++ b/gcc/cp/mangle.c
> @@ -3777,7 +3777,7 @@ mangle_decl_string (const tree decl)
>    if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
>      {
>        struct tinst_level *tl = current_instantiation ();
> -      if ((!tl || tl->get_decl_maybe () != decl)
> +      if ((!tl || tl->maybe_get_node () != decl)
>           && push_tinst_level (decl))
>         {
>           template_p = true;
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 2442f07095ca..79563dfa5334 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -50,7 +50,8 @@ typedef int (*tree_fn_t) (tree, void*);
>  /* The PENDING_TEMPLATES is a TREE_LIST of templates whose
>     instantiations have been deferred, either because their definitions
>     were not yet available, or because we were putting off doing the
> work.  */
> -struct GTY ((chain_next ("%h.next"))) pending_template {
> +struct GTY ((chain_next ("%h.next"))) pending_template
> +{
>    struct pending_template *next;
>    struct tinst_level *tinst;
>  };
> @@ -8839,17 +8840,20 @@ public:
>     build_tree_list logic in reinit, so this could go out of sync.  */
>  template <>
>  inline tree &
> -freelist<tree_node>::next (tree obj) {
> +freelist<tree_node>::next (tree obj)
> +{
>    return TREE_CHAIN (obj);
>  }
>  template <>
>  inline tree
> -freelist<tree_node>::anew () {
> +freelist<tree_node>::anew ()
> +{
>    return build_tree_list (NULL, NULL);
>  }
>  template <>
>  inline void
> -freelist<tree_node>::poison (tree obj ATTRIBUTE_UNUSED) {
> +freelist<tree_node>::poison (tree obj ATTRIBUTE_UNUSED)
> +{
>    int size ATTRIBUTE_UNUSED = sizeof (tree_list);
>    tree p ATTRIBUTE_UNUSED = obj;
>    tree_base *b ATTRIBUTE_UNUSED = &obj->base;
> @@ -8878,7 +8882,8 @@ freelist<tree_node>::poison (tree obj
> ATTRIBUTE_UNUSED) {
>  }
>  template <>
>  inline void
> -freelist<tree_node>::reinit (tree obj ATTRIBUTE_UNUSED) {
> +freelist<tree_node>::reinit (tree obj ATTRIBUTE_UNUSED)
> +{
>    tree_base *b ATTRIBUTE_UNUSED = &obj->base;
>
>  #ifdef ENABLE_GC_CHECKING
> @@ -8902,7 +8907,8 @@ freelist<tree_node>::reinit (tree obj
> ATTRIBUTE_UNUSED) {
>  static GTY((deletable)) tree tree_list_freelist_head;
>  /* Return the/an actual TREE_LIST freelist.  */
>  static inline freelist<tree_node>
> -tree_list_freelist () {
> +tree_list_freelist ()
> +{
>    return tree_list_freelist_head;
>  }
>
> @@ -8910,7 +8916,8 @@ tree_list_freelist () {
>  static GTY((deletable)) tinst_level *tinst_level_freelist_head;
>  /* Return the/an actual tinst_level freelist.  */
>  static inline freelist<tinst_level>
> -tinst_level_freelist () {
> +tinst_level_freelist ()
> +{
>    return tinst_level_freelist_head;
>  }
>
> @@ -8918,7 +8925,8 @@ tinst_level_freelist () {
>  static GTY((deletable)) pending_template *pending_template_freelist_head;
>  /* Return the/an actual pending_template freelist.  */
>  static inline freelist<pending_template>
> -pending_template_freelist () {
> +pending_template_freelist ()
> +{
>    return pending_template_freelist_head;
>  }
>
> @@ -8939,7 +8947,8 @@ tinst_level::to_list ()
>
>  /* Increment OBJ's refcount.  */
>  static tinst_level *
> -inc_refcount_use (tinst_level *obj) {
> +inc_refcount_use (tinst_level *obj)
> +{
>    if (obj)
>      {
>        ++obj->refcount;
> @@ -8948,18 +8957,26 @@ inc_refcount_use (tinst_level *obj) {
>    return obj;
>  }
>
> +/* Release storage for OBJ and node, if it's a TREE_LIST.  */
> +void
> +tinst_level::free (tinst_level *obj)
> +{
> +  if (obj->tree_list_p ())
> +    tree_list_freelist ().free (obj->get_node ());
> +  tinst_level_freelist ().free (obj);
> +}
> +
>  /* Decrement OBJ's refcount.  If it reaches zero, release OBJ's DECL
>     and OBJ, and start over with the tinst_level object that used to be
>     referenced by OBJ's NEXT.  */
>  static void
> -dec_refcount_use (tinst_level *obj) {
> +dec_refcount_use (tinst_level *obj)
> +{
>    while (obj && !--obj->refcount)
>      {
>        gcc_assert (obj->refcount+1 != 0);
>        tinst_level *next = obj->next;
> -      if (obj->list_p () && obj->get_decl_maybe ())
> -       tree_list_freelist ().free (obj->get_node ());
> -      tinst_level_freelist ().free (obj);
> +      tinst_level::free (obj);
>        obj = next;
>      }
>  }
> @@ -8971,7 +8988,8 @@ dec_refcount_use (tinst_level *obj) {
>     overload resolution.  */
>  template <typename T>
>  static void
> -set_refcount_ptr (T *& ptr, T *obj = NULL) {
> +set_refcount_ptr (T *& ptr, T *obj = NULL)
> +{
>    T *save = ptr;
>    ptr = inc_refcount_use (obj);
>    dec_refcount_use (save);
> @@ -8994,7 +9012,7 @@ add_pending_template (tree d)
>       Compensate.  */
>    gcc_assert (TREE_CODE (d) != TREE_LIST);
>    level = !current_tinst_level
> -    || current_tinst_level->get_decl_maybe () != d;
> +    || current_tinst_level->maybe_get_node () != d;
>
>    if (level)
>      push_tinst_level (d);
> @@ -10077,7 +10095,7 @@ limit_bad_template_recursion (tree decl)
>      return false;
>
>    for (; lev; lev = lev->next)
> -    if (neglectable_inst_p (lev->get_decl_maybe ()))
> +    if (neglectable_inst_p (lev->maybe_get_node ()))
>        break;
>
>    return (lev && errs > lev->errors);
> @@ -10197,7 +10215,7 @@ reopen_tinst_level (struct tinst_level *level)
>    pop_tinst_level ();
>    if (current_tinst_level)
>      current_tinst_level->errors = errorcount+sorrycount;
> -  return level->get_decl_maybe ();
> +  return level->maybe_get_node ();
>  }
>
>  /* Returns the TINST_LEVEL which gives the original instantiation
> @@ -24010,7 +24028,7 @@ instantiate_pending_templates (int retries)
>       to avoid infinite loop.  */
>    if (pending_templates && retries >= max_tinst_depth)
>      {
> -      tree decl = pending_templates->tinst->get_decl_maybe ();
> +      tree decl = pending_templates->tinst->maybe_get_node ();
>
>        fatal_error (input_location,
>                    "template instantiation depth exceeds maximum of %d"
> @@ -24351,7 +24369,7 @@ bool
>  instantiating_current_function_p (void)
>  {
>    return (current_instantiation ()
> -         && (current_instantiation ()->get_decl_maybe ()
> +         && (current_instantiation ()->maybe_get_node ()
>               == current_function_decl));
>  }
>
> --
> Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
> You must be the change you wish to see in the world. -- Gandhi
> Be Free! -- http://FSFLA.org/   FSF Latin America board member
> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]