Skip to content

Commit 7ed08c4

Browse files
committed
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.
1 parent abde86a commit 7ed08c4

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

common.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7555,6 +7555,7 @@ gc.$(OBJEXT): {$(VPATH)}thread.h
75557555
gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
75567556
gc.$(OBJEXT): {$(VPATH)}thread_native.h
75577557
gc.$(OBJEXT): {$(VPATH)}util.h
7558+
gc.$(OBJEXT): {$(VPATH)}variable.h
75587559
gc.$(OBJEXT): {$(VPATH)}vm.h
75597560
gc.$(OBJEXT): {$(VPATH)}vm_callinfo.h
75607561
gc.$(OBJEXT): {$(VPATH)}vm_core.h

gc.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
#include "ruby_assert.h"
122122
#include "ruby_atomic.h"
123123
#include "symbol.h"
124+
#include "variable.h"
124125
#include "vm_core.h"
125126
#include "vm_sync.h"
126127
#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
33843385
return iter_data->update_callback((VALUE *)value, iter_data->data);
33853386
}
33863387

3388+
static void
3389+
free_gen_ivtbl(VALUE obj, struct gen_ivtbl *ivtbl)
3390+
{
3391+
if (UNLIKELY(rb_shape_obj_too_complex(obj))) {
3392+
st_free_table(ivtbl->as.complex.table);
3393+
}
3394+
3395+
xfree(ivtbl);
3396+
}
3397+
33873398
static int
33883399
vm_weak_table_gen_ivar_foreach(st_data_t key, st_data_t value, st_data_t data, int error)
33893400
{
33903401
int retval = vm_weak_table_foreach_key(key, value, data, error);
33913402
if (retval == ST_DELETE) {
3403+
free_gen_ivtbl((VALUE)key, (struct gen_ivtbl *)value);
3404+
33923405
FL_UNSET((VALUE)key, FL_EXIVAR);
33933406
}
33943407
return retval;

0 commit comments

Comments
 (0)