summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-03-03 14:19:55 -0500
committerPeter Zhu <peter@peterzhu.ca>2023-03-07 08:28:03 -0500
commitc78138abd3ccbc80b259430a78dfb6c0f65c6f5c (patch)
tree0abf9ec5db2047c4920e858f58a73a62b7ec3884 /gc.c
parent638f68b2fe16e7c765ab9bf7a927b95ff187b3d3 (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.c88
1 files changed, 42 insertions, 46 deletions
diff --git a/gc.c b/gc.c
index 43cbd0f92c..bbb85a21b6 100644
--- a/gc.c
+++ b/gc.c
@@ -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) {