This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: [Patch, Fortran, committed] free gfc_code of EXEC_END_PROCEDURE
- From: Mikael Morin <mikael dot morin at sfr dot fr>
- To: Tobias Burnus <burnus at net-b dot de>
- Cc: Thomas Koenig <tkoenig at netcologne dot de>, gfortran <fortran at gcc dot gnu dot org>
- Date: Wed, 22 Aug 2012 14:01:14 +0200
- Subject: Re: [Patch, Fortran, committed] free gfc_code of EXEC_END_PROCEDURE
- References: <50340B0D.4080406@net-b.de> <50346E17.7090603@netcologne.de> <50348E80.90701@net-b.de>
On 22/08/2012 09:47, Tobias Burnus wrote:
> Dear Thomas, dear all,
>
> On 08/22/2012 07:28 AM, Thomas Koenig wrote:
>> Am 22.08.2012 00:26, schrieb Tobias Burnus:
>>
>>> I think we should join in an try to remove some leakage - and try to not
>>> introduce new ones.
>>
>> What about using C++ constructors/destructors that allocate/deallocate
>> the necessary memory? This should simplify the code for memory
>> allocation a lot.
>
> I don't see how. GCC operates on lists - and the main problem is to keep
> track about them to free them when they aren't needed. Only when the
> scope is limited, it could help to free pointer components; still, one
> needs to be careful whether the same pointer is used elsewhere.
>
> If you have time, maybe you are able to find out why the following
> program leaks memory:
>
> !subroutine foo()
> call bar()
> contains
> subroutine bar()
> end subroutine bar
> end
>
> It doesn't if one comments in the "subroutine foo()" line. According to
> valgrind, the memory is allocated in parse_contained:
> gfc_current_ns = gfc_get_namespace (parent_ns, 1);
> However, my impression is that the namespace for ST_END_PROGRAM is
> properly freed in that function ("gfc_free_namespace (ns);") and the
> rest (namespace for MAIN__ and its contained "bar" namespace) is
> properly freed via translate_all_program_units's call to gfc_done_2
> which calls gfc_symbol_done_2 and in turn gfc_free_namespace.
>
I think it is the bar namespace that is not freed, because the bar
symbol's reference count doesn't drop to zero.
There is this code in gfc_release_symbol which is not entered because
sym->formal_ns == NULL (sym->refs == 2 at this point for `bar'):
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);
}
With a dummy argument for `bar', the code above is entered, but it
doesn't help either as sym->formal_ns->refs == 2, so that the formal
namespace (and the symbol as a result) is not freed anyway.
Maybe we could take this hunk from one of the old pr43829 patches:
http://gcc.gnu.org/bugzilla/attachment.cgi?id=21016&action=diff#a/symbol.c_sec13
I don't know if it would work as the patch this is extracted from
contains many more memory fixes, and it may depend on them. To update to
current trunk I would have to rewrite them from scratch unfortunately.
Actually, I think the uncommented variant leaks more memory. From
running it in a debugger the `foo' namespace's reference count is 2 when
entering gfc_free_namespace, compared to 1 for the `__MAIN' case.
So the __MAIN namespace is freed, but foo isn't. I have the feeling that
the namespace remains reachable somehow, so that valgrind doesn't regard
the attached pointers as lost memory.
Unfortunately, valgrind tells me nothing more than `unhandled
instruction', so it's difficult to test patches.
Mikael