On 2019-02-04 11:39 a.m., Richard Biener wrote: > On February 4, 2019 5:07:00 PM GMT+01:00, Jeff Law <l...@redhat.com> wrote: >> On 2/4/19 6:15 AM, Richard Biener 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've also maked the obstack member GTY skip >>> (and prevent bitmap_obstack from gengtype processing) because >>> the obstack isn't used for GC allocated bitmaps. >>> >>> Bootstrap & regtest running on x86_64-unknown-linux-gnu. >>> >>> Richard. >>> >>> 2019-02-04 Richard Biener <rguent...@suse.de> >>> >>> PR middle-end/89150 >>> * bitmap.h (struct bitmap_obstack): Do not mark GTY. >>> (struct bitmap_element): Drop chain_prev so we properly recurse on >>> the prev member, supporting tree views. >>> (struct bitmap_head): GTY skip the obstack member. >> Was there a particular failure mode you observed or was this discovered >> by inspection. > > It was discovered via an out of tree patch, the issue is only latent on trunk > (together with another unfixed pch issue of bitmaps).
My apologies for not noticing this thread/PR earlier. I originally discovered this issue while working on an experimental patch, but since then I've also come up with a test case for this specific issue. Is it worth adding it to trunk? - Michael
From 9f1049a1e24cd1aa9852c5dddd1342dce0226416 Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov <michael.ploujni...@oracle.com> Date: Thu, 7 Feb 2019 14:43:40 -0500 Subject: [PATCH] Add a test for GC marking bitmaps in tree view mode gcc/ChangeLog: 2019-02-07 Michael Ploujnikov <michael.ploujni...@oracle.com> PR middle-end/89150 * bitmap.c (test_bitmap_tree_marking): New test. (NOT_NULL_OR_GARBAGE): For shortening test_bitmap_tree_marking. (bitmap_c_tests): Add test_bitmap_tree_marking. --- gcc/bitmap.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git gcc/bitmap.c gcc/bitmap.c index 5a8236de75..7e802a1600 100644 --- gcc/bitmap.c +++ gcc/bitmap.c @@ -2626,6 +2626,11 @@ bitmap_head::dump () #if CHECKING_P +static GTY(()) bitmap selftest_test_bitmap; + +/* From ggc-internal.h */ +extern bool ggc_force_collect; + namespace selftest { /* Selftests for bitmaps. */ @@ -2722,6 +2727,82 @@ test_bitmap_single_bit_set_p () ASSERT_EQ (1066, bitmap_first_set_bit (b)); } +#define NOT_NULL_OR_GARBAGE(NODE) \ + (NODE != NULL && (unsigned long)(NODE) != 0xa5a5a5a5UL) + +static void +test_bitmap_tree_marking () +{ + selftest_test_bitmap = BITMAP_GGC_ALLOC (); + bitmap_tree_view (selftest_test_bitmap); + + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 1*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 5*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 10*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 15*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 30*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 25*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 3*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 4*BITMAP_ELEMENT_ALL_BITS)); + ASSERT_TRUE (bitmap_set_bit (selftest_test_bitmap, 26*BITMAP_ELEMENT_ALL_BITS)); + /* At this point it should look like: + 26 + / \ + 25 30 + / + 5 + / \ + 4 15 + / / + 3 10 + / + 1 + + */ + ggc_force_collect = true; + ggc_collect (); + ggc_force_collect = false; + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first)); + ASSERT_TRUE (selftest_test_bitmap->first->indx == 26); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->next)); + ASSERT_TRUE (selftest_test_bitmap->first->next->indx == 30); + ASSERT_TRUE (selftest_test_bitmap->first->next->next == NULL); + ASSERT_TRUE (selftest_test_bitmap->first->next->prev == NULL); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->indx == 25); + ASSERT_TRUE (selftest_test_bitmap->first->prev->next == NULL); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev->prev)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->indx == 5); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev->prev->next)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->next->indx == 15); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->next->next == NULL); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev->prev->next->prev)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->next->prev->indx == 10); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->next->prev->prev == NULL); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->next->prev->next == NULL); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev->prev->prev)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->indx == 4); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->next == NULL); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev->prev->prev->prev)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->prev->indx == 3); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->prev->next == NULL); + + ASSERT_TRUE (NOT_NULL_OR_GARBAGE (selftest_test_bitmap->first->prev->prev->prev->prev->prev)); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->prev->prev->indx == 1); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->prev->prev->prev == NULL); + ASSERT_TRUE (selftest_test_bitmap->first->prev->prev->prev->prev->prev->next == NULL); + + ASSERT_TRUE (bitmap_bit_p (selftest_test_bitmap, 15*BITMAP_ELEMENT_ALL_BITS)); +} + /* Run all of the selftests within this file. */ void @@ -2732,6 +2813,7 @@ bitmap_c_tests () test_clear_bit_in_middle (); test_copying (); test_bitmap_single_bit_set_p (); + test_bitmap_tree_marking (); } } // namespace selftest -- 2.19.1
signature.asc
Description: OpenPGP digital signature