This is the mail archive of the
mailing list for the GCC project.
Re: int_cst_hash_table mapping persistence and the garbage collector
- From: Gary Funck <gary at intrepid dot com>
- To: Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Jakub Jelinek <jakub at redhat dot com>, Joseph Myers <joseph at codesourcery dot com>, Richard Henderson <rth at redhat dot com>, Tom Tromey <tromey at redhat dot com>
- Date: Wed, 12 Oct 2011 00:55:25 -0700
- Subject: Re: int_cst_hash_table mapping persistence and the garbage collector
- References: <20100708061704.GA8748@intrepid.com> <email@example.com> <20111012063714.GN20424@intrepid.com> <firstname.lastname@example.org>
On 10/12/11 09:27:43, Eric Botcazou wrote:
> > The problem is that the references to object C1 and C2 live in
> > a hash table, and that although the referenced nodes will be retained
> > by the garbage collector, their mapping in int_cst_hash_table is
> > deleted by the GC.
> This isn't a simple hash table, is it?
At the moment, it is a simple garbage collected hash table, yes.
It maps a type node into a corresponding integer node that is
the "blocking factor" associated with the type node. Before
the advent of this hash table the blocking factor was stored
in a dedicated field in the tree type node. The suggestion was
made to move this into a hash table to save space. I chose
the "tree map" hash table because I thought it could do the job.
And does work well, except when the GC steps in and decides
to remove a node from int_cst_hash_table, because it thinks
that the integer constant is no longer needed.
> This is a map so it is garbage-collected as a map: if the key isn't marked,
> then the value isn't either.
The keys are valid. In the example discussed in this thread,
there is a pointer to type node that used in a parameter declaration
of a function prototype and also in the similarly named parameter
of the function definition. Both tree pointers are used as keys,
and they are "live" at the point that the GC runs.
> Hence 2 questions:
> - why using a map and not a simple hash table?
I had thought that the garbage collected nature of the
map would perhaps save some space and better track the
lifetimes of the type nodes that have a UPC blocking factor.
It would be easy enough to switch to a hash table that is
not garbage collected and where entries once allocated
remain that way until the end of the compilation.
> - what is the key and why isn't it marked?
The key is a type. The value is an "sizetype" integer constant.
/* Return the UPC blocking factor of the type given by NODE.
The default block factor is one. The additional flag bits
over-ride the default. */
#define TYPE_BLOCK_FACTOR(NODE) \
(TYPE_SHARED (NODE) \
? (TYPE_HAS_BLOCK_FACTOR_0 (NODE) ? size_zero_node \
: TYPE_HAS_BLOCK_FACTOR_X (NODE) ? upc_block_factor_lookup (NODE) \
: NULL_TREE) \
A blocking factor of 0 is a special case, it is encoded
as a flag. Otherwise, if the blocking factor has been set,
then TYPE_HAS_BLOCK_FACTOR_X() is true, and the blocking
factor for NODE is looked up in a hash table.