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.
This commit is contained in:
Peter Zhu 2025-01-22 14:51:44 -05:00
parent abde86afe8
commit 7ed08c4fd3
Notes: git 2025-01-23 15:24:52 +00:00
2 changed files with 14 additions and 0 deletions

View File

@ -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

13
gc.c
View File

@ -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;