summaryrefslogtreecommitdiffhomepage
path: root/src/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc.c')
-rw-r--r--src/gc.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/gc.c b/src/gc.c
index ccd925da8..e8dce1fdf 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -470,6 +470,31 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
}
}
+static size_t
+mark_irep_pool_size(mrb_state *mrb, mrb_irep *irep)
+{
+ size_t size = irep->plen;
+ size_t i;
+
+ for (i=0; i<irep->rlen; i++) {
+ size += mark_irep_pool_size(mrb, irep->reps[i]);
+ }
+ return size;
+}
+
+static void
+mark_irep_pool(mrb_state *mrb, mrb_irep *irep)
+{
+ size_t i;
+
+ for (i=0; i<irep->plen; i++) {
+ mrb_gc_mark_value(mrb, irep->pool[i]);
+ }
+ for (i=0; i<irep->rlen; i++) {
+ mark_irep_pool(mrb, irep->reps[i]);
+ }
+}
+
static void
gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{
@@ -504,6 +529,9 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
mrb_gc_mark(mrb, (struct RBasic*)p->env);
mrb_gc_mark(mrb, (struct RBasic*)p->target_class);
+ if (!MRB_PROC_CFUNC_P(p)) {
+ mark_irep_pool(mrb, p->body.irep);
+ }
}
break;
@@ -771,6 +799,10 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_PROC:
+ if (!MRB_PROC_CFUNC_P((struct RProc*)obj)) {
+ children += mark_irep_pool_size(mrb, ((struct RProc*)obj)->body.irep);
+ }
+ /* fall through */
case MRB_TT_RANGE:
children+=2;
break;