diff options
author | Peter Zhu <[email protected]> | 2025-01-22 14:51:44 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2025-01-23 10:24:35 -0500 |
commit | 7ed08c4fd31c53d4c4e3713c390daff8064d2a52 (patch) | |
tree | d24638c6a155602edffac3503e58740bc7fcf80e | |
parent | abde86afe819350174b60a8bc8f9e72807ac81b1 (diff) |
Fix memory leak in rb_gc_vm_weak_table_foreach
When deleting from the generic ivar table, we need to free the gen_ivtbl
otherwise we will have a memory leak.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/12615
-rw-r--r-- | common.mk | 1 | ||||
-rw-r--r-- | gc.c | 13 |
2 files changed, 14 insertions, 0 deletions
@@ -7555,6 +7555,7 @@ gc.$(OBJEXT): {$(VPATH)}thread.h gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h gc.$(OBJEXT): {$(VPATH)}thread_native.h gc.$(OBJEXT): {$(VPATH)}util.h +gc.$(OBJEXT): {$(VPATH)}variable.h gc.$(OBJEXT): {$(VPATH)}vm.h gc.$(OBJEXT): {$(VPATH)}vm_callinfo.h gc.$(OBJEXT): {$(VPATH)}vm_core.h @@ -121,6 +121,7 @@ #include "ruby_assert.h" #include "ruby_atomic.h" #include "symbol.h" +#include "variable.h" #include "vm_core.h" #include "vm_sync.h" #include "vm_callinfo.h" @@ -3384,11 +3385,23 @@ vm_weak_table_foreach_update_value(st_data_t *key, st_data_t *value, st_data_t d return iter_data->update_callback((VALUE *)value, iter_data->data); } +static void +free_gen_ivtbl(VALUE obj, struct gen_ivtbl *ivtbl) +{ + if (UNLIKELY(rb_shape_obj_too_complex(obj))) { + st_free_table(ivtbl->as.complex.table); + } + + xfree(ivtbl); +} + static int vm_weak_table_gen_ivar_foreach(st_data_t key, st_data_t value, st_data_t data, int error) { int retval = vm_weak_table_foreach_key(key, value, data, error); if (retval == ST_DELETE) { + free_gen_ivtbl((VALUE)key, (struct gen_ivtbl *)value); + FL_UNSET((VALUE)key, FL_EXIVAR); } return retval; |