On Mon, 4 Feb 2019, Steven Bosscher wrote: > On Mon, Feb 4, 2019 at 2:16 PM Richard Biener <rguent...@suse.de> wrote: > > When I introduced tree-form bitmaps I forgot to think about GC. > > The following drops the chain_prev annotation to make the marker > > work for trees. > > I don't understand this patch. How are the nodes in a bitmap tree now > to be found for marking? > > This patch should cause an ICE on test cases with bitmaps as trees > with ENABLE_GC_ALWAYS_COLLECT.
After the patch the marker routines look like void gt_ggc_mx_bitmap_head (void *x_p) { struct bitmap_head * const x = (struct bitmap_head *)x_p; if (ggc_test_and_set_mark (x)) { gt_ggc_m_14bitmap_element ((*x).first); } } void gt_ggc_mx_bitmap_element (void *x_p) { struct bitmap_element * x = (struct bitmap_element *)x_p; struct bitmap_element * xlimit = x; while (ggc_test_and_set_mark (xlimit)) xlimit = ((*xlimit).next); while (x != xlimit) { gt_ggc_m_14bitmap_element ((*x).next); gt_ggc_m_14bitmap_element ((*x).prev); x = ((*x).next); } } gt_ggc_m_14bitmap_element just is a NULL protected call to gt_ggc_mx_bitmap_element. So bitmap elements are marked by marking the ->next chain until we hit an already marked node and then recurse on all prev and next members (where the recursion will not chain ->next because we've already marked it). Previously it was void gt_ggc_mx_bitmap_element (void *x_p) { struct bitmap_element * x = (struct bitmap_element *)x_p; struct bitmap_element * xlimit = x; while (ggc_test_and_set_mark (xlimit)) xlimit = ((*xlimit).next); if (x != xlimit) for (;;) { struct bitmap_element * const xprev = ((*x).prev); if (xprev == NULL) break; x = xprev; (void) ggc_test_and_set_mark (xprev); } while (x != xlimit) { gt_ggc_m_14bitmap_element ((*x).next); gt_ggc_m_14bitmap_element ((*x).prev); x = ((*x).next); } } where the prev_chain handling "wrecked" things for trees and didn't help for the list implementation (since we've only come here via the bitmap_head->first link). Richard.