Skip to content

Commit bb00189

Browse files
committed
Call post_sweep_page after freeing all deferred objects.
This is so that garbage_object_p() will work correctly.
1 parent 6f9dc2e commit bb00189

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

gc/default/default.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4015,9 +4015,7 @@ gc_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, uintptr_t p, bits_t bit
40154015

40164016
rb_gc_event_hook(vp, RUBY_INTERNAL_EVENT_FREEOBJ);
40174017

4018-
if (BUILTIN_TYPE(vp) != T_ZOMBIE) {
4019-
rb_gc_obj_free_vm_weak_references(vp);
4020-
}
4018+
rb_gc_obj_free_vm_weak_references(vp);
40214019
if (rb_gc_obj_free(objspace, vp)) {
40224020
(void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, BASE_SLOT_SIZE);
40234021
RVALUE_AGE_SET_BITMAP(vp, 0);
@@ -4111,10 +4109,12 @@ deferred_free(rb_objspace_t *objspace, VALUE obj)
41114109
ASSERT_vm_locking_with_barrier();
41124110
bool result;
41134111
MAYBE_UNUSED(const char *obj_info) = rb_obj_info(obj);
4114-
rb_gc_obj_free_vm_weak_references(obj);
4112+
bool freed_weakrefs = rb_gc_obj_free_vm_weak_references(obj);
4113+
GC_ASSERT(freed_weakrefs);
41154114
if (rb_gc_obj_free(objspace, obj)) {
41164115
struct heap_page *page = GET_HEAP_PAGE(obj);
41174116
psweep_debug(1, "[gc] deferred free: page(%p) obj(%p) %s (success)\n", page, (void*)obj, obj_info);
4117+
RVALUE_AGE_SET_BITMAP(obj, 0); // mainly for assertions, it will also get cleared in gc_post_sweep_page
41184118
heap_page_add_freeobj(objspace, page, obj);
41194119
result = true;
41204120
}
@@ -5226,12 +5226,13 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
52265226
bool dequeued_unswept_page = false;
52275227
// NOTE: pages we dequeue from the sweep thread need to be AFTER the list of heap->free_pages so we don't free from pages
52285228
// we've allocated from since sweep started.
5229-
struct heap_page *sweep_page = gc_sweep_dequeue_page(objspace, heap, free_in_user_thread_p, &free_in_user_thread_p);
5229+
struct heap_page *sweep_page = gc_sweep_dequeue_page(objspace, heap, free_in_user_thread_p, &dequeued_unswept_page);
52305230
if (RB_UNLIKELY(!sweep_page)) {
52315231
psweep_debug(-2, "[gc] gc_sweep_step heap:%p (%ld) deq() = nil, break\n", heap, heap - heaps);
52325232
break;
52335233
}
52345234
if (dequeued_unswept_page) {
5235+
free_in_user_thread_p = true;
52355236
psweep_debug(-2, "[gc] gc_sweep_step heap:%p (%ld) deq unswept page\n", heap, heap - heaps);
52365237
}
52375238
else {
@@ -5251,8 +5252,6 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
52515252
GC_ASSERT(sweep_page->pre_deferred_free_slots == 0);
52525253
}
52535254
else {
5254-
gc_post_sweep_page(objspace, heap, sweep_page); // clear bits
5255-
// Process deferred free objects
52565255
unsigned short deferred_free_freed = 0;
52575256
unsigned short deferred_to_free = sweep_page->pre_deferred_free_slots;
52585257

@@ -5284,6 +5283,8 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
52845283
ctx.final_slots = sweep_page->pre_final_slots + deferred_free_final_slots;
52855284
ctx.freed_slots = sweep_page->pre_freed_slots + deferred_free_freed;
52865285
ctx.empty_slots = sweep_page->pre_empty_slots;
5286+
5287+
gc_post_sweep_page(objspace, heap, sweep_page); // clear bits
52875288
}
52885289

52895290
if (0) fprintf(stderr, "gc_sweep_page(%"PRIdSIZE"): total_slots: %d, freed_slots: %d, empty_slots: %d, final_slots: %d\n",

0 commit comments

Comments
 (0)