2011/10/11 Gary Funck <g...@intrepid.com>: > static GTY ((if_marked ("tree_map_marked_p"), > param_is (struct tree_map))) > htab_t upc_block_factor_for_type; > [...] > upc_block_factor_for_type = htab_create_ggc (512, tree_map_hash, > tree_map_eq, 0); > > I had hoped that this would be sufficient to ensure that all > integer constant references recorded in this hash table would > be considered "live" by the GC. Reading the code in tree_map_marked_p(), > however, I see the following: > > #define tree_map_marked_p tree_map_base_marked_p > [...] > /* Return true if this tree map structure is marked for garbage collection > purposes. We simply return true if the from tree is marked, so that this > structure goes away when the from tree goes away. */ > > int > tree_map_base_marked_p (const void *p) > { > return ggc_marked_p (((const struct tree_map_base *) p)->from); > } > > This takes care of recycling an entry when the '->from' reference > goes away, but it doesn't make sure that the '->to' reference is > considered "live". I don't understand the GC well enough to > know when/where the '->to' entry should be marked as "live".
If "->from" is marked, then GC will mark the whole hash table entry, including the tree_map::to field. Currently I believe that your issue is one hash table pointing to another one. Basically all the objects that need to be live must be known before the hash table marking starts, either by being already marked in that GC run, either by having mark bits set somewhere where if_marked option will check them correctly. In your case (correct me if I misunderstood something) you have one hash table, marking of which will mark more objects which are required for the correct marking of the second hash table. GC might be simply walking the second one first. -- Laurynas