@@ -4347,6 +4347,26 @@ zombie_needs_deferred_free(VALUE zombie)
43474347 return ZOMBIE_NEEDS_FREE_P (zombie );
43484348}
43494349
4350+ #if RGENGC_CHECK_MODE
4351+ static void
4352+ debug_free_check (rb_objspace_t * objspace , VALUE vp )
4353+ {
4354+ if (!is_full_marking (objspace )) {
4355+ if (RVALUE_OLD_P (objspace , vp )) rb_bug ("page_sweep: %p - old while minor GC." , (void * )p );
4356+ if (RVALUE_REMEMBERED (objspace , vp )) rb_bug ("page_sweep: %p - remembered." , (void * )p );
4357+ }
4358+ if (RVALUE_WB_UNPROTECTED (objspace , vp )) CLEAR_IN_BITMAP (GET_HEAP_WB_UNPROTECTED_BITS (vp ), vp );
4359+ #define CHECK (x ) if (x(objspace, vp) != FALSE) rb_bug("obj_free: " #x "(%s) != FALSE", rb_obj_info(vp))
4360+ CHECK (RVALUE_WB_UNPROTECTED );
4361+ CHECK (RVALUE_MARKED );
4362+ CHECK (RVALUE_MARKING );
4363+ CHECK (RVALUE_UNCOLLECTIBLE );
4364+ #undef CHECK
4365+ }
4366+ #else
4367+ #define debug_free_check (...) (void)0
4368+ #endif
4369+
43504370static inline void
43514371gc_pre_sweep_plane (rb_objspace_t * objspace , rb_heap_t * heap , struct heap_page * page , uintptr_t p , bits_t bitset , short slot_size , short slot_bits )
43524372{
@@ -4378,6 +4398,7 @@ gc_pre_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *p
43784398 }
43794399 break ;
43804400 case T_DATA : {
4401+ debug_free_check (objspace , vp );
43814402 void * data = RTYPEDDATA_P (vp ) ? RTYPEDDATA_GET_DATA (vp ) : DATA_PTR (vp );
43824403 if (!data ) {
43834404 goto free ;
@@ -4408,6 +4429,7 @@ gc_pre_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *p
44084429 break ;
44094430 }
44104431 case T_IMEMO : {
4432+ debug_free_check (objspace , vp );
44114433 if (rb_gc_obj_has_blacklisted_vm_weak_references (vp )) {
44124434 sweep_in_ruby_thread (objspace , page , vp , true);
44134435 break ;
@@ -4442,6 +4464,7 @@ gc_pre_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *p
44424464 case T_MATCH :
44434465 case T_REGEXP :
44444466 case T_FILE : {
4467+ debug_free_check (objspace , vp );
44454468 if (rb_gc_obj_has_blacklisted_vm_weak_references (vp )) {
44464469 sweep_in_ruby_thread (objspace , page , vp , true);
44474470 break ;
@@ -4452,6 +4475,7 @@ gc_pre_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *p
44524475 break ;
44534476 }
44544477 default : // ex: T_CLASS/T_MODULE/T_ICLASS
4478+ debug_free_check (objspace , vp );
44554479 if (!rb_gc_obj_needs_cleanup_p (vp )) {
44564480 heap_page_add_deferred_freeobj (objspace , page , vp );
44574481 psweep_debug (2 , "[sweep] freed: page(%p), obj(%p)\n" , (void * )page , (void * )vp );
@@ -4462,6 +4486,7 @@ gc_pre_sweep_plane(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *p
44624486 }
44634487 break ;
44644488 free : {
4489+ debug_free_check (objspace , vp );
44654490 if (rb_gc_obj_free_vm_weak_references (vp )) {
44664491 bool can_put_back_on_freelist = rb_gc_obj_free (objspace , vp );
44674492 if (can_put_back_on_freelist ) {
0 commit comments