From patchwork Thu Jul 29 14:37:11 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Morin X-Patchwork-Id: 60269 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 27DF91007EC for ; Fri, 30 Jul 2010 00:37:46 +1000 (EST) Received: (qmail 12806 invoked by alias); 29 Jul 2010 14:37:44 -0000 Received: (qmail 12786 invoked by uid 22791); 29 Jul 2010 14:37:41 -0000 X-SWARE-Spam-Status: No, hits=-0.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_NEUTRAL, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp22.services.sfr.fr (HELO smtp22.services.sfr.fr) (93.17.128.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 29 Jul 2010 14:37:32 +0000 Received: from filter.sfr.fr (localhost [127.0.0.1]) by msfrf2201.sfr.fr (SMTP Server) with ESMTP id 1BBBB700008D; Thu, 29 Jul 2010 16:37:30 +0200 (CEST) Received: from gimli.local (110.123.193-77.rev.gaoland.net [77.193.123.110]) by msfrf2201.sfr.fr (SMTP Server) with ESMTP id B2F527000089; Thu, 29 Jul 2010 16:37:29 +0200 (CEST) X-SFR-UUID: 20100729143729733.B2F527000089@msfrf2201.sfr.fr Message-ID: <4C519217.4060002@sfr.fr> Date: Thu, 29 Jul 2010 16:37:11 +0200 From: Mikael Morin User-Agent: Mozilla/5.0 (X11; U; FreeBSD amd64; fr-FR; rv:1.9.1.11) Gecko/20100725 Thunderbird/3.0.6 MIME-Version: 1.0 To: "fortran@gcc.gnu.org" , gcc-patches Subject: [patch, fortran] Factorize symbol refcounting. X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello, this takes the symbol reference count management code from free_sym_tree into its own function so that it can be shared. I have made the gfc_internal_error (in case reference count becomes negative) a gcc_assert as the error message was not very informative/useful from a user point of view. OK for trunk when regression test finishes ? Mikael 2010-07-29 Mikael Morin * gfortran.h (gfc_release_symbol): New prototype. * symbol.c (gfc_release_symbol): New. Code taken from free_sym_tree. (gfc_undo_symbols, free_sym_tree, gfc_free_finalizer): Use gfc_release_symbol. * parse.c (gfc_fixup_sibling_symbols): Ditto. * resolve.c (resolve_symbol): Ditto. diff --git a/gfortran.h b/gfortran.h index d35a040..d623d0d 100644 --- a/gfortran.h +++ b/gfortran.h @@ -2523,6 +2523,7 @@ gfc_symtree *gfc_get_unique_symtree (gfc_namespace *); gfc_user_op *gfc_get_uop (const char *); gfc_user_op *gfc_find_uop (const char *, gfc_namespace *); void gfc_free_symbol (gfc_symbol *); +void gfc_release_symbol (gfc_symbol *); gfc_symbol *gfc_new_symbol (const char *, gfc_namespace *); gfc_symtree* gfc_find_symtree_in_proc (const char *, gfc_namespace *); int gfc_find_symbol (const char *, gfc_namespace *, int, gfc_symbol **); diff --git a/parse.c b/parse.c index 1575b2b..989d644 100644 --- a/parse.c +++ b/parse.c @@ -3792,10 +3792,7 @@ gfc_fixup_sibling_symbols (gfc_symbol *sym, gfc_namespace *siblings) st->n.sym = sym; sym->refs++; - /* Free the old (local) symbol. */ - old_sym->refs--; - if (old_sym->refs == 0) - gfc_free_symbol (old_sym); + gfc_release_symbol (old_sym); } fixup_contained: diff --git a/resolve.c b/resolve.c index dab533d..d14de9e 100644 --- a/resolve.c +++ b/resolve.c @@ -11398,9 +11398,7 @@ resolve_symbol (gfc_symbol *sym) { this_symtree = gfc_find_symtree (gfc_current_ns->sym_root, sym->name); - sym->refs--; - if (!sym->refs) - gfc_free_symbol (sym); + gfc_release_symbol (sym); symtree->n.sym->refs++; this_symtree->n.sym = symtree->n.sym; return; diff --git a/symbol.c b/symbol.c index 18f7b25..e713cd8 100644 --- a/symbol.c +++ b/symbol.c @@ -2502,6 +2502,31 @@ gfc_free_symbol (gfc_symbol *sym) } +/* Decrease the reference counter and free memory when we reach zero. */ +void +gfc_release_symbol (gfc_symbol *sym) +{ + if (sym == NULL) + return; + + if (sym->formal_ns != NULL && sym->refs == 2) + { + /* As formal_ns contains a reference to sym, delete formal_ns just + before the deletion of sym. */ + gfc_namespace *ns = sym->formal_ns; + sym->formal_ns = NULL; + gfc_free_namespace (ns); + } + + sym->refs--; + if (sym->refs > 0) + return; + + gcc_assert (sym->refs == 0); + gfc_free_symbol (sym); +} + + /* Allocate and initialize a new symbol node. */ gfc_symbol * @@ -2893,11 +2918,7 @@ gfc_undo_symbols (void) gfc_delete_symtree (&p->ns->sym_root, p->name); - p->refs--; - if (p->refs < 0) - gfc_internal_error ("gfc_undo_symbols(): Negative refs"); - if (p->refs == 0) - gfc_free_symbol (p); + gfc_release_symbol (p); continue; } @@ -3107,35 +3128,13 @@ free_uop_tree (gfc_symtree *uop_tree) static void free_sym_tree (gfc_symtree *sym_tree) { - gfc_namespace *ns; - gfc_symbol *sym; - if (sym_tree == NULL) return; free_sym_tree (sym_tree->left); free_sym_tree (sym_tree->right); - sym = sym_tree->n.sym; - - sym->refs--; - if (sym->refs < 0) - gfc_internal_error ("free_sym_tree(): Negative refs"); - - if (sym->formal_ns != NULL && sym->refs == 1) - { - /* As formal_ns contains a reference to sym, delete formal_ns just - before the deletion of sym. */ - ns = sym->formal_ns; - sym->formal_ns = NULL; - gfc_free_namespace (ns); - } - else if (sym->refs == 0) - { - /* Go ahead and delete the symbol. */ - gfc_free_symbol (sym); - } - + gfc_release_symbol (sym_tree->n.sym); gfc_free (sym_tree); } @@ -3189,13 +3188,7 @@ gfc_free_finalizer (gfc_finalizer* el) { if (el) { - if (el->proc_sym) - { - --el->proc_sym->refs; - if (!el->proc_sym->refs) - gfc_free_symbol (el->proc_sym); - } - + gfc_release_symbol (el->proc_sym); gfc_free (el); } }