@@ -426,6 +426,7 @@ typedef int (*gc_compact_compare_func)(const void *l, const void *r, void *d);
426426
427427typedef struct rb_heap_struct {
428428 short slot_size ;
429+ bits_t slot_bits_mask ;
429430
430431 /* Basic statistics */
431432 size_t total_allocated_pages ;
@@ -3570,16 +3571,20 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
35703571 GC_ASSERT (bitmap_plane_count == HEAP_PAGE_BITMAP_LIMIT - 1 ||
35713572 bitmap_plane_count == HEAP_PAGE_BITMAP_LIMIT );
35723573
3574+ bits_t slot_mask = heap -> slot_bits_mask ;
3575+
35733576 // Skip out of range slots at the head of the page
35743577 bitset = ~bits [0 ];
35753578 bitset >>= NUM_IN_PAGE (p );
3579+ bitset &= slot_mask ;
35763580 if (bitset ) {
35773581 gc_sweep_plane (objspace , heap , p , bitset , ctx );
35783582 }
35793583 p += (BITS_BITLENGTH - NUM_IN_PAGE (p )) * BASE_SLOT_SIZE ;
35803584
35813585 for (int i = 1 ; i < bitmap_plane_count ; i ++ ) {
35823586 bitset = ~bits [i ];
3587+ bitset &= slot_mask ;
35833588 if (bitset ) {
35843589 gc_sweep_plane (objspace , heap , p , bitset , ctx );
35853590 }
@@ -9435,6 +9440,17 @@ rb_gc_impl_objspace_init(void *objspace_ptr)
94359440
94369441 heap -> slot_size = (1 << i ) * BASE_SLOT_SIZE ;
94379442
9443+ // Bitmask with every (1 << i)th bit set, representing aligned slot positions
9444+ static const bits_t slot_bits_masks [] = {
9445+ ~(bits_t )0 , // i=0: every 1st bit
9446+ (bits_t )0x5555555555555555ULL , // i=1: every 2nd bit
9447+ (bits_t )0x1111111111111111ULL , // i=2: every 4th bit
9448+ (bits_t )0x0101010101010101ULL , // i=3: every 8th bit
9449+ (bits_t )0x0001000100010001ULL , // i=4: every 16th bit
9450+ };
9451+ GC_ASSERT (i < numberof (slot_bits_masks ));
9452+ heap -> slot_bits_mask = slot_bits_masks [i ];
9453+
94389454 ccan_list_head_init (& heap -> pages );
94399455 }
94409456
0 commit comments