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 коммит произвёл Peter Zhu
Родитель 92ac1721c2
Коммит e624d0d202
1 изменённых файлов: 9 добавлений и 20 удалений

29
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