On Thu, Jan 09, 2014 at 08:25:31AM -0800, Richard Henderson wrote: > > + p = (struct target_globals_extra *) > > + ggc_internal_cleared_alloc_stat (sizeof (struct target_globals_extra) > > + PASS_MEM_STAT); > > + g = (struct target_globals *) p; > > + g->flag_state = &p->flag_state; > > + g->regs = &p->regs; > > g->rtl = ggc_alloc_cleared_target_rtl (); > > So, we're relying on something pointing to G, thus keeping the whole P alive? > I suppose that works but it's fairly ugly that's for sure.
The separate structures aren't really installed individually, they are always installed together through restore_target_globals. As long as the any FUNCTION_DECL with such TARGET_OPTION_NODE exists, it will be reachable. The reason why it needs to be GC is: 1) in two of these target_* structures there are embedded rtxes etc. the GC needs to see 2) if all FUNCTION_DECL with such combination of target attributes are GCed, we'd leak memory > As for the extra ~500k wasted on x86_64, we can either fix our gc allocator to > do something sensible with these high-order allocations, or we can do nearly > this same trick only with libc. I.e. > > struct target_globals_extra { > struct target_flag_state flag_state; > struct target_regs regs; > struct target_hard_regs hard_regs; > struct target_reload reload; > struct target_expmed expmed; > struct target_optabs optabs; > struct target_cfgloop cfgloop; > struct target_ira ira; > struct target_ira_int ira_int; > struct target_lra_int lra_int; > struct target_builtins builtins; > struct target_gcse gcse; > struct target_bb_reorder bb_reorder; > struct target_lower_subreg lower_subreg; > } *p; > > g = ggc_alloc_target_globals (); > p = XCNEW (target_globals_extra); > ... That would be fine for 1), but would mean 2). It is also fine to GC allocate each structure individually, but some (like bb_reorder) are say just 4 bytes long, so it might be overkill. As noted by Richard S., IRA/LRA still puts pointers to heap allocated objects into some of the structures, so there is some leak anyway, but not as big. Jakub