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).
This commit is contained in:
Peter Zhu 2021-09-13 09:12:08 -04:00 committed by Peter Zhu
parent 92ac1721c2
commit e624d0d202
Notes: git 2021-09-15 22:01:02 +09:00

29
gc.c
View File

@ -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