Interesting.  My first reaction is that this is an invalid use of the
garbage collector.  I think there is really only one valid function
that can be used as an if_marked function: one which checks
ggc_marked_p on the structure.
        
Then how about tree_map_base_marked_p, the if_marked function for value_expr_for_decl?

tree.h:
...
struct GTY(()) tree_map_base {
  tree from;
};

struct GTY(()) tree_decl_map {
  struct tree_map_base base;
  tree to;
};

#define tree_decl_map_marked_p tree_map_base_marked_p
...

tree.c:
...
static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
     htab_t value_expr_for_decl;

int
tree_map_base_marked_p (const void *p)
{
  return ggc_marked_p (((const struct tree_map_base *) p)->from);
}
...

The tree_map_base_marked_p checks ggc_marked_p on the from field. During ggc_scan_cache_tab, if the from field is live, also the to field is marked live. I wrote some code to do sanity testing and found a similar scenario as before:
- a register attribute is not marked live during root marking
- reg_attrs_htab is traversed, and the hash table entry corresponding to the register attribute is removed - value_expr_for_decl is traversed, a from field is found live, so the to field is also marked live, marking the register attribute live.

Is this valid use of the garbage collector?

Reply via email to