Skip to content

Commit f7ff576

Browse files
committed
assert all unmarked slots are freed if RGENGC_CHECK_MODE > 0
Make popcount_bits work for all platforms
1 parent 0189543 commit f7ff576

File tree

1 file changed

+11
-29
lines changed

1 file changed

+11
-29
lines changed

gc/default/default.c

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -947,14 +947,10 @@ slot_index_for_offset(size_t offset, uint32_t div_magic)
947947
return (size_t)(((uint64_t)offset * div_magic) >> 32);
948948
}
949949

950-
static inline int
950+
static inline unsigned
951951
popcount_bits(bits_t x)
952952
{
953-
#if SIZEOF_VOIDP == 8
954-
return __builtin_popcountl(x);
955-
#else
956-
return __builtin_popcount(x);
957-
#endif
953+
return rb_popcount_intptr((uintptr_t)x);
958954
}
959955

960956
#define SLOT_INDEX(page, p) slot_index_for_offset((uintptr_t)(p) - (page)->start, (page)->slot_div_magic)
@@ -4219,21 +4215,13 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
42194215
}
42204216
}
42214217

4222-
#ifdef DEBUG_SWEEP_BOOKKEEPING
4218+
#if RGENGC_CHECK_MODE
42234219
{
4224-
/* Assert that all unmarked slots with live objects were either freed or made into zombies.
4225-
* Count unmarked slot-aligned bits the same way the sweep loop does. */
4220+
/* Assert that all unmarked slots with live objects were either freed or made into zombies. */
42264221
int unmarked_slots = 0;
4227-
uintptr_t vp = (uintptr_t)sweep_page->start;
4228-
4229-
bits_t bs = ~bits[0];
4230-
bs >>= NUM_IN_PAGE(vp);
4231-
bs &= slot_mask;
4232-
unmarked_slots += popcount_bits(bs);
4233-
4234-
for (int i = 1; i < bitmap_plane_count; i++) {
4235-
bs = ~bits[i] & slot_mask;
4236-
unmarked_slots += popcount_bits(bs);
4222+
for (int i = 0; i < bitmap_plane_count; i++) {
4223+
bits_t unmarked = ~bits[i];
4224+
unmarked_slots += (int)popcount_bits(unmarked);
42374225
}
42384226

42394227
int freed_or_zombie = ctx->freed_slots + ctx->final_slots;
@@ -4569,20 +4557,14 @@ gc_pre_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pa
45694557
objspace->profile.pages_swept_by_sweep_thread_had_deferred_free_objects++;
45704558
}
45714559

4572-
#ifdef DEBUG_SWEEP_BOOKKEEPING
4560+
#if RGENGC_CHECK_MODE
45734561
{
45744562
/* Assert that all unmarked slots with live objects were either freed, made into
45754563
* zombies, or deferred to the Ruby thread. */
45764564
int unmarked_slots = 0;
4577-
4578-
bits_t bs = ~bits[0];
4579-
bs >>= NUM_IN_PAGE((uintptr_t)page->start);
4580-
bs &= slot_mask;
4581-
unmarked_slots += popcount_bits(bs);
4582-
4583-
for (int i = 1; i < bitmap_plane_count; i++) {
4584-
bs = ~bits[i] & slot_mask;
4585-
unmarked_slots += popcount_bits(bs);
4565+
for (int i = 0; i < bitmap_plane_count; i++) {
4566+
bits_t unmarked = ~bits[i];
4567+
unmarked_slots += (int)popcount_bits(unmarked);
45864568
}
45874569

45884570
int freed_or_zombie = page->pre_freed_slots + page->pre_final_slots + page->pre_deferred_free_slots;

0 commit comments

Comments
 (0)