diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-03-06 11:38:39 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-03-06 11:38:39 +0300 |
commit | 83e6b4196e84795183947c56e720c1ce5c30caf2 (patch) | |
tree | de092139917d540d4e1f0189a939f4e8e33e144e /reclaim.c | |
parent | 2e7f6b82f4271c521d73ffadd49c121ccc9d6163 (diff) | |
download | bdwgc-83e6b4196e84795183947c56e720c1ce5c30caf2.tar.gz |
Ensure GC_n_set_marks() does not count extra bits in hb_marks
* reclaim.c [!USE_MARK_BYTES] (GC_n_set_marks): Decrement result by
one (i.e. do not count the bit set past the end as in USE_MARK_BYTES
case); add assertion that the bit past the end is set.
* reclaim.c [!USE_MARK_BYTES && !MARK_BIT_PER_OBJ] (GC_n_set_marks):
Divide result by BYTES_TO_GRANULES(sz) with the assertion that the
reminder is zero; add comment.
* reclaim.c [!PARALLEL_MARK] (GC_print_block_descr): Add assertion that
n_marks is equal to hhdr->hb_n_marks.
* reclaim.c (GC_print_block_descr): Add assertion that max(n_objs,1)
is not less than n_marks; do not print hhdr->hb_n_marks value.
Diffstat (limited to 'reclaim.c')
-rw-r--r-- | reclaim.c | 33 |
1 files changed, 23 insertions, 10 deletions
@@ -522,20 +522,34 @@ static unsigned count_ones(word n) unsigned GC_n_set_marks(hdr *hhdr) { unsigned result = 0; + word sz = hhdr -> hb_sz; word i; # ifdef MARK_BIT_PER_OBJ - word n_objs = HBLK_OBJS(hhdr -> hb_sz); - word n_mark_words = divWORDSZ((n_objs > 0 ? n_objs : 1) + WORDSZ - 1); + word n_objs = HBLK_OBJS(sz); + word n_mark_words = divWORDSZ(n_objs > 0 ? n_objs : 1); /* round down */ - for (i = 0; i < n_mark_words; i++) { + for (i = 0; i <= n_mark_words; i++) { result += count_ones(hhdr -> hb_marks[i]); } # else /* MARK_BIT_PER_GRANULE */ + for (i = 0; i < MARK_BITS_SZ; i++) { result += count_ones(hhdr -> hb_marks[i]); } # endif - return result; /* the number of set bits excluding the one past the end */ + GC_ASSERT(result > 0); + result--; /* exclude the one bit set past the end */ +# ifndef MARK_BIT_PER_OBJ + if (IS_UNCOLLECTABLE(hhdr -> hb_obj_kind)) { + size_t ngranules = BYTES_TO_GRANULES(sz); + + /* As mentioned in GC_set_hdr_marks(), all the bits are set */ + /* instead of every n-th, thus the result should be adjusted. */ + GC_ASSERT(ngranules > 0 && result % ngranules == 0); + result /= ngranules; + } +# endif + return result; } #endif /* !USE_MARK_BYTES */ @@ -549,13 +563,12 @@ STATIC void GC_print_block_descr(struct hblk *h, unsigned n_marks = GC_n_set_marks(hhdr); unsigned n_objs = (unsigned)HBLK_OBJS(sz); - if (hhdr -> hb_n_marks != n_marks) { - GC_printf("%u,%u,%u!=%u,%u\n", hhdr->hb_obj_kind, (unsigned)sz, - (unsigned)hhdr->hb_n_marks, n_marks, n_objs); - } else { - GC_printf("%u,%u,%u,%u\n", +# ifndef PARALLEL_MARK + GC_ASSERT(hhdr -> hb_n_marks == n_marks); +# endif + GC_ASSERT((n_objs > 0 ? n_objs : 1) >= n_marks); + GC_printf("%u,%u,%u,%u\n", hhdr -> hb_obj_kind, (unsigned)sz, n_marks, n_objs); - } ps -> number_of_blocks++; ps -> total_bytes += (sz + (HBLKSIZE-1)) & ~(HBLKSIZE-1); /* round up */ } |