diff options
author | Peter Zhu <[email protected]> | 2023-03-03 14:19:55 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2023-03-07 08:28:03 -0500 |
commit | c78138abd3ccbc80b259430a78dfb6c0f65c6f5c (patch) | |
tree | 0abf9ec5db2047c4920e858f58a73a62b7ec3884 /gc.c | |
parent | 638f68b2fe16e7c765ab9bf7a927b95ff187b3d3 (diff) |
Add function rb_data_free
This commit adds a function rb_data_free used by obj_free and
rb_objspace_call_finalizer to free T_DATA objects. This change also
means that RUBY_TYPED_FREE_IMMEDIATELY objects can be freed immediately
in rb_objspace_call_finalizer rather than being created into a zombie.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7438
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 88 |
1 files changed, 42 insertions, 46 deletions
@@ -3452,6 +3452,45 @@ obj_free_object_id(rb_objspace_t *objspace, VALUE obj) } } +static bool +rb_data_free(rb_objspace_t *objspace, VALUE obj) +{ + if (DATA_PTR(obj)) { + int free_immediately = false; + void (*dfree)(void *); + void *data = DATA_PTR(obj); + + if (RTYPEDDATA_P(obj)) { + free_immediately = (RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0; + dfree = RANY(obj)->as.typeddata.type->function.dfree; + } + else { + dfree = RANY(obj)->as.data.dfree; + } + + if (dfree) { + if (dfree == RUBY_DEFAULT_FREE) { + xfree(data); + RB_DEBUG_COUNTER_INC(obj_data_xfree); + } + else if (free_immediately) { + (*dfree)(data); + RB_DEBUG_COUNTER_INC(obj_data_imm_free); + } + else { + RB_DEBUG_COUNTER_INC(obj_data_zombie); + make_zombie(objspace, obj, dfree, data); + return false; + } + } + else { + RB_DEBUG_COUNTER_INC(obj_data_empty); + } + } + + return true; +} + static int obj_free(rb_objspace_t *objspace, VALUE obj) { @@ -3608,42 +3647,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj) } break; case T_DATA: - if (DATA_PTR(obj)) { - int free_immediately = FALSE; - void (*dfree)(void *); - void *data = DATA_PTR(obj); - - if (RTYPEDDATA_P(obj)) { - free_immediately = (RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0; - dfree = RANY(obj)->as.typeddata.type->function.dfree; - if (0 && free_immediately == 0) { - /* to expose non-free-immediate T_DATA */ - fprintf(stderr, "not immediate -> %s\n", RANY(obj)->as.typeddata.type->wrap_struct_name); - } - } - else { - dfree = RANY(obj)->as.data.dfree; - } - - if (dfree) { - if (dfree == RUBY_DEFAULT_FREE) { - xfree(data); - RB_DEBUG_COUNTER_INC(obj_data_xfree); - } - else if (free_immediately) { - (*dfree)(data); - RB_DEBUG_COUNTER_INC(obj_data_imm_free); - } - else { - make_zombie(objspace, obj, dfree, data); - RB_DEBUG_COUNTER_INC(obj_data_zombie); - return FALSE; - } - } - else { - RB_DEBUG_COUNTER_INC(obj_data_empty); - } - } + if (!rb_data_free(objspace, obj)) return false; break; case T_MATCH: if (RANY(obj)->as.match.rmatch) { @@ -4582,16 +4586,8 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace) if (rb_obj_is_mutex(vp)) break; if (rb_obj_is_fiber(vp)) break; if (rb_obj_is_main_ractor(vp)) break; - if (RTYPEDDATA_P(vp)) { - RDATA(p)->dfree = RANY(p)->as.typeddata.type->function.dfree; - } - RANY(p)->as.free.flags = 0; - if (RANY(p)->as.data.dfree == RUBY_DEFAULT_FREE) { - xfree(DATA_PTR(p)); - } - else if (RANY(p)->as.data.dfree) { - make_zombie(objspace, vp, RANY(p)->as.data.dfree, RANY(p)->as.data.data); - } + + rb_data_free(objspace, vp); break; case T_FILE: if (RANY(p)->as.file.fptr) { |