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