Skip to content

Commit 8378219

Browse files
committed
Fix age_bits
1 parent fdbb204 commit 8378219

1 file changed

Lines changed: 42 additions & 6 deletions

File tree

gc/default/default.c

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -948,9 +948,15 @@ RVALUE_AGE_SET_BITMAP(VALUE obj, int age)
948948
RUBY_ASSERT(age <= RVALUE_OLD_AGE);
949949
bits_t *age_bits = GET_HEAP_PAGE(obj)->age_bits;
950950
// clear the bits
951-
age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] &= ~(RVALUE_AGE_BIT_MASK << (RVALUE_AGE_BITMAP_OFFSET(obj)));
951+
/*age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] &= ~(RVALUE_AGE_BIT_MASK << (RVALUE_AGE_BITMAP_OFFSET(obj)));*/
952+
/*// shift the correct value in*/
953+
/*age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] |= ((bits_t)age << RVALUE_AGE_BITMAP_OFFSET(obj));*/
954+
bits_t clear_mask = RVALUE_AGE_BIT_MASK << RVALUE_AGE_BITMAP_OFFSET(obj);
955+
bits_t set_mask = (bits_t)age << RVALUE_AGE_BITMAP_OFFSET(obj);
956+
// clear the bits
957+
RUBY_ATOMIC_VALUE_AND(age_bits[RVALUE_AGE_BITMAP_INDEX(obj)], ~clear_mask);
952958
// shift the correct value in
953-
age_bits[RVALUE_AGE_BITMAP_INDEX(obj)] |= ((bits_t)age << RVALUE_AGE_BITMAP_OFFSET(obj));
959+
RUBY_ATOMIC_VALUE_OR(age_bits[RVALUE_AGE_BITMAP_INDEX(obj)], set_mask);
954960
}
955961

956962
static void
@@ -4098,6 +4104,20 @@ deferred_free(rb_objspace_t *objspace, VALUE obj)
40984104
return result;
40994105
}
41004106

4107+
// Spread N bits into 2N bits: bit k → bits 2k and 2k+1.
4108+
// e.g. 0b1010 → 0b11001100
4109+
static inline bits_t
4110+
spread_bits(bits_t x)
4111+
{
4112+
bits_t result = 0;
4113+
for (int b = 0; b < BITS_BITLENGTH / 2; b++) {
4114+
if (x & ((bits_t)1 << b)) {
4115+
result |= (bits_t)RVALUE_AGE_BIT_MASK << (b * RVALUE_AGE_BIT_COUNT);
4116+
}
4117+
}
4118+
return result;
4119+
}
4120+
41014121
// Clear bits for the page that was swept by the background thread.
41024122
static inline void
41034123
gc_post_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_page, bool force_setup_mark_bits)
@@ -4143,8 +4163,16 @@ gc_post_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *s
41434163
for (int i = 0; i < bitmap_plane_count; i++) {
41444164
bits_t unmarked = ~bits[i] & slot_mask;
41454165
RUBY_ATOMIC_VALUE_AND(wb_unprotected_bits[i], ~unmarked);
4146-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2], ~unmarked);
4147-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2 + 1], ~unmarked);
4166+
// Expand 1-bit-per-slot unmarked mask to 2-bit-per-slot age mask.
4167+
// age_bits[i*2] covers the lower half of slots in mark_bits[i],
4168+
// age_bits[i*2+1] covers the upper half.
4169+
bits_t unmarked_lo = unmarked & (((bits_t)1 << (BITS_BITLENGTH / 2)) - 1);
4170+
bits_t unmarked_hi = unmarked >> (BITS_BITLENGTH / 2);
4171+
// Spread each bit into 2 adjacent bits: bit N -> bits 2N and 2N+1
4172+
bits_t age_mask_lo = spread_bits(unmarked_lo);
4173+
bits_t age_mask_hi = spread_bits(unmarked_hi);
4174+
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2], ~age_mask_lo);
4175+
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2 + 1], ~age_mask_hi);
41484176
}
41494177
}
41504178

@@ -4217,8 +4245,16 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
42174245
for (int i = 0; i < bitmap_plane_count; i++) {
42184246
bits_t unmarked = ~bits[i] & slot_mask;
42194247
RUBY_ATOMIC_VALUE_AND(wb_unprotected_bits[i], ~unmarked);
4220-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2], ~unmarked);
4221-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2 + 1], ~unmarked);
4248+
// Expand 1-bit-per-slot unmarked mask to 2-bit-per-slot age mask.
4249+
// age_bits[i*2] covers the lower half of slots in mark_bits[i],
4250+
// age_bits[i*2+1] covers the upper half.
4251+
bits_t unmarked_lo = unmarked & (((bits_t)1 << (BITS_BITLENGTH / 2)) - 1);
4252+
bits_t unmarked_hi = unmarked >> (BITS_BITLENGTH / 2);
4253+
// Spread each bit into 2 adjacent bits: bit N -> bits 2N and 2N+1
4254+
bits_t age_mask_lo = spread_bits(unmarked_lo);
4255+
bits_t age_mask_hi = spread_bits(unmarked_hi);
4256+
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2], ~age_mask_lo);
4257+
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2 + 1], ~age_mask_hi);
42224258
}
42234259
}
42244260

0 commit comments

Comments
 (0)