From de790bdc2785ee36730563982afc45480f6c0f42 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 8 Nov 2013 20:39:50 +0900 Subject: allow irep to be GCed --- src/gc.c | 10 ++++++++++ src/proc.c | 6 +++++- src/state.c | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index 866d5bdc8..a1ff4d32b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -640,6 +640,16 @@ obj_free(mrb_state *mrb, struct RBasic *obj) mrb_gc_free_str(mrb, (struct RString*)obj); break; + case MRB_TT_PROC: + { + struct RProc *p = (struct RProc*)obj; + + if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { + mrb_irep_decref(mrb, p->body.irep); + } + } + break; + case MRB_TT_RANGE: mrb_free(mrb, ((struct RRange*)obj)->edges); break; diff --git a/src/proc.c b/src/proc.c index a7e4192aa..cfb677f0a 100644 --- a/src/proc.c +++ b/src/proc.c @@ -22,6 +22,7 @@ mrb_proc_new(mrb_state *mrb, mrb_irep *irep) p->target_class = (mrb->c->ci) ? mrb->c->ci->target_class : 0; p->body.irep = irep; p->env = 0; + mrb_irep_incref(mrb, irep); return p; } @@ -80,6 +81,9 @@ mrb_proc_copy(struct RProc *a, struct RProc *b) { a->flags = b->flags; a->body = b->body; + if (!MRB_PROC_CFUNC_P(a)) { + a->body.irep->refcnt++; + }; a->target_class = b->target_class; a->env = b->env; } @@ -181,7 +185,7 @@ void mrb_init_proc(mrb_state *mrb) { struct RProc *m; - mrb_irep *call_irep = (mrb_irep *)mrb_alloca(mrb, sizeof(mrb_irep)); + mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); static const mrb_irep mrb_irep_zero = { 0 }; if (call_irep == NULL) diff --git a/src/state.c b/src/state.c index 6e6394c9c..0012bc189 100644 --- a/src/state.c +++ b/src/state.c @@ -106,6 +106,21 @@ mrb_open(void) void mrb_free_symtbl(mrb_state *mrb); void mrb_free_heap(mrb_state *mrb); +void +mrb_irep_incref(mrb_state *mrb, mrb_irep *irep) +{ + irep->refcnt++; +} + +void +mrb_irep_decref(mrb_state *mrb, mrb_irep *irep) +{ + irep->refcnt--; + if (irep->refcnt == 0) { + mrb_irep_free(mrb, irep); + } +} + void mrb_irep_free(mrb_state *mrb, mrb_irep *irep) { @@ -119,6 +134,9 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) } mrb_free(mrb, irep->pool); mrb_free(mrb, irep->syms); + for (i=0; irlen; i++) { + mrb_irep_decref(mrb, irep->reps[i]); + } mrb_free(mrb, irep->reps); mrb_free(mrb, (void *)irep->filename); mrb_free(mrb, irep->lines); @@ -163,6 +181,7 @@ mrb_add_irep(mrb_state *mrb) irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); *irep = mrb_irep_zero; + irep->refcnt = 1; return irep; } -- cgit v1.2.3