From e624d0d202ef691f5c75841b90bf44a624e3cdcc Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 13 Sep 2021 09:12:08 -0400 Subject: Update the free_slots count of the original page When invalidating a page during compaction, the free_slots count should be updated for the page of the object and not the page of the forwarding address (since the object gets moved back to the forwarding address). --- gc.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) (limited to 'gc.c') diff --git a/gc.c b/gc.c index b5656c59f3..47762c2bfc 100644 --- a/gc.c +++ b/gc.c @@ -5818,7 +5818,7 @@ gc_sweep_continue(rb_objspace_t *objspace, rb_size_pool_t *sweep_size_pool, rb_h } static void -invalidate_moved_plane(rb_objspace_t *objspace, struct heap_page *page, uintptr_t p, bits_t bitset, struct gc_sweep_context *ctx) +invalidate_moved_plane(rb_objspace_t *objspace, struct heap_page *page, uintptr_t p, bits_t bitset) { if (bitset) { do { @@ -5834,17 +5834,15 @@ invalidate_moved_plane(rb_objspace_t *objspace, struct heap_page *page, uintptr_ object = rb_gc_location(forwarding_object); - if (FL_TEST(forwarding_object, FL_FROM_FREELIST)) { - ctx->empty_slots++; /* already freed */ - } - else { - ctx->freed_slots++; - } - gc_move(objspace, object, forwarding_object, page->size_pool->slot_size); /* forwarding_object is now our actual object, and "object" * is the free slot for the original page */ - heap_page_add_freeobj(objspace, GET_HEAP_PAGE(object), object); + struct heap_page *orig_page = GET_HEAP_PAGE(object); + orig_page->free_slots++; + if (!FL_TEST_RAW(object, FL_FROM_FREELIST)) { + objspace->profile.total_freed_objects++; + } + heap_page_add_freeobj(objspace, orig_page, object); GC_ASSERT(MARKED_IN_BITMAP(GET_HEAP_MARK_BITS(forwarding_object), forwarding_object)); GC_ASSERT(BUILTIN_TYPE(forwarding_object) != T_MOVED); @@ -5870,16 +5868,10 @@ invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page) p = page->start; - struct gc_sweep_context ctx; - ctx.page = page; - ctx.final_slots = 0; - ctx.freed_slots = 0; - ctx.empty_slots = 0; - // Skip out of range slots at the head of the page bitset = pin_bits[0] & ~mark_bits[0]; bitset >>= NUM_IN_PAGE(p); - invalidate_moved_plane(objspace, page, (uintptr_t)p, bitset, &ctx); + invalidate_moved_plane(objspace, page, (uintptr_t)p, bitset); p += (BITS_BITLENGTH - NUM_IN_PAGE(p)); for (i=1; i < HEAP_PAGE_BITMAP_LIMIT; i++) { @@ -5887,12 +5879,9 @@ invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page) * to indicate there is a moved object in this slot. */ bitset = pin_bits[i] & ~mark_bits[i]; - invalidate_moved_plane(objspace, page, (uintptr_t)p, bitset, &ctx); + invalidate_moved_plane(objspace, page, (uintptr_t)p, bitset); p += BITS_BITLENGTH; } - - page->free_slots += (ctx.empty_slots + ctx.freed_slots); - objspace->profile.total_freed_objects += ctx.freed_slots; } static void -- cgit v1.2.3