aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorHParker <HParker@github.com>2023-09-29 14:06:26 -0700
committerPeter Zhu <peter@peterzhu.ca>2023-10-01 10:55:19 -0400
commitc74dc8b4af4ef1b32f65587f083fbeba4ca186fa (patch)
treeaccaa8ec5d5b0aadb8ee0368530229450c6e8df2 /gc.c
parentbe09c8370b8f332620592b1837e040ded583489f (diff)
downloadruby-c74dc8b4af4ef1b32f65587f083fbeba4ca186fa.tar.gz
Use reference counting to avoid memory leak in kwargs
Tracks other callinfo that references the same kwargs and frees them when all references are cleared. [bug #19906] Co-authored-by: Peter Zhu <peter@peterzhu.ca>
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/gc.c b/gc.c
index 2993e56a36..273207c4b7 100644
--- a/gc.c
+++ b/gc.c
@@ -3681,8 +3681,15 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
RB_DEBUG_COUNTER_INC(obj_imemo_parser_strterm);
break;
case imemo_callinfo:
- RB_DEBUG_COUNTER_INC(obj_imemo_callinfo);
- break;
+ {
+ const struct rb_callinfo * ci = ((const struct rb_callinfo *)obj);
+ if (ci->kwarg) {
+ ((struct rb_callinfo_kwarg *)ci->kwarg)->references--;
+ if (ci->kwarg->references == 0) xfree((void *)ci->kwarg);
+ }
+ RB_DEBUG_COUNTER_INC(obj_imemo_callinfo);
+ break;
+ }
case imemo_callcache:
RB_DEBUG_COUNTER_INC(obj_imemo_callcache);
break;