diff options
| author | John Hawthorn <john@hawthorn.email> | 2026-01-20 11:55:36 -0800 |
|---|---|---|
| committer | John Hawthorn <john@hawthorn.email> | 2026-01-30 19:42:26 -0800 |
| commit | e8d8f50fa82f1f05cc6fa927be7c3415f028e73c (patch) | |
| tree | 01616a4395db218b1ae7f07828e37aae2e588399 | |
| parent | 6327f59307d8cd62438ed1fee80058b8c7cc5fab (diff) | |
Clear age and unprotected bits for page at once
This aims to speed up sweeping by clearing all age and wb_unprotected
bits for unmarked objects. This should be faster because we can clear
up to a whole plane of objects (64 slots) at once.
| -rw-r--r-- | gc/default/default.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/gc/default/default.c b/gc/default/default.c index 60e5d624c9..90232c7618 100644 --- a/gc/default/default.c +++ b/gc/default/default.c @@ -3510,7 +3510,6 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit } gc_report(3, objspace, "page_sweep: %s is added to freelist\n", rb_obj_info(vp)); ctx->empty_slots++; - RVALUE_AGE_SET_BITMAP(vp, 0); heap_page_add_freeobj(objspace, sweep_page, vp); break; case T_ZOMBIE: @@ -3527,7 +3526,6 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit if (RVALUE_REMEMBERED(objspace, vp)) rb_bug("page_sweep: %p - remembered.", (void *)p); } #endif - if (RVALUE_WB_UNPROTECTED(objspace, vp)) CLEAR_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(vp), vp); #if RGENGC_CHECK_MODE #define CHECK(x) if (x(objspace, vp) != FALSE) rb_bug("obj_free: " #x "(%s) != FALSE", rb_obj_info(vp)) @@ -3544,7 +3542,6 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit } (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, BASE_SLOT_SIZE); - RVALUE_AGE_SET_BITMAP(vp, 0); heap_page_add_freeobj(objspace, sweep_page, vp); gc_report(3, objspace, "page_sweep: %s (fast path) added to freelist\n", rb_obj_info(vp)); ctx->freed_slots++; @@ -3557,7 +3554,6 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit rb_gc_obj_free_vm_weak_references(vp); if (rb_gc_obj_free(objspace, vp)) { (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, BASE_SLOT_SIZE); - RVALUE_AGE_SET_BITMAP(vp, 0); heap_page_add_freeobj(objspace, sweep_page, vp); gc_report(3, objspace, "page_sweep: %s is added to freelist\n", rb_obj_info(vp)); ctx->freed_slots++; @@ -3611,6 +3607,18 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context bits_t slot_mask = heap->slot_bits_mask; + // Clear wb_unprotected and age bits for all unmarked slots + { + bits_t *wb_unprotected_bits = sweep_page->wb_unprotected_bits; + bits_t *age_bits = sweep_page->age_bits; + for (int i = 0; i < bitmap_plane_count; i++) { + bits_t unmarked = ~bits[i] & slot_mask; + wb_unprotected_bits[i] &= ~unmarked; + age_bits[i * 2] &= ~unmarked; + age_bits[i * 2 + 1] &= ~unmarked; + } + } + // Skip out of range slots at the head of the page bitset = ~bits[0]; bitset >>= NUM_IN_PAGE(p); |
