[bugfix] memory leak of pic_checkpoint

This commit is contained in:
Yuichi Nishiwaki 2015-06-22 17:06:13 +09:00
parent c8581b849f
commit e730a314f4
5 changed files with 27 additions and 28 deletions

View File

@ -31,7 +31,7 @@ pic_dynamic_wind(pic_state *pic, struct pic_proc *in, struct pic_proc *thunk, st
} }
here = pic->cp; here = pic->cp;
pic->cp = pic_malloc(pic, sizeof(pic_checkpoint)); pic->cp = (pic_checkpoint *)pic_obj_alloc(pic, sizeof(pic_checkpoint), PIC_TT_CP);
pic->cp->prev = here; pic->cp->prev = here;
pic->cp->depth = here->depth + 1; pic->cp->depth = here->depth + 1;
pic->cp->in = in; pic->cp->in = in;

View File

@ -329,20 +329,6 @@ gc_unmark(union header *p)
p->s.mark = PIC_GC_UNMARK; p->s.mark = PIC_GC_UNMARK;
} }
static void
gc_mark_checkpoint(pic_state *pic, pic_checkpoint *cp)
{
if (cp->prev) {
gc_mark_object(pic, (struct pic_object *)cp->prev);
}
if (cp->in) {
gc_mark_object(pic, (struct pic_object *)cp->in);
}
if (cp->out) {
gc_mark_object(pic, (struct pic_object *)cp->out);
}
}
static void static void
gc_mark_object(pic_state *pic, struct pic_object *obj) gc_mark_object(pic_state *pic, struct pic_object *obj)
{ {
@ -495,6 +481,20 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
pic->regs = reg; pic->regs = reg;
break; break;
} }
case PIC_TT_CP: {
struct pic_checkpoint *cp = (struct pic_checkpoint *)obj;
if (cp->prev) {
gc_mark_object(pic, (struct pic_object *)cp->prev);
}
if (cp->in) {
gc_mark_object(pic, (struct pic_object *)cp->in);
}
if (cp->out) {
gc_mark_object(pic, (struct pic_object *)cp->out);
}
break;
}
case PIC_TT_NIL: case PIC_TT_NIL:
case PIC_TT_BOOL: case PIC_TT_BOOL:
#if PIC_ENABLE_FLOAT #if PIC_ENABLE_FLOAT
@ -565,7 +565,7 @@ gc_mark_phase(pic_state *pic)
/* checkpoint */ /* checkpoint */
if (pic->cp) { if (pic->cp) {
gc_mark_checkpoint(pic, pic->cp); gc_mark_object(pic, (struct pic_object *)pic->cp);
} }
/* stack */ /* stack */
@ -722,6 +722,9 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
xh_destroy(&reg->hash); xh_destroy(&reg->hash);
break; break;
} }
case PIC_TT_CP: {
break;
}
case PIC_TT_NIL: case PIC_TT_NIL:
case PIC_TT_BOOL: case PIC_TT_BOOL:
#if PIC_ENABLE_FLOAT #if PIC_ENABLE_FLOAT

View File

@ -53,6 +53,7 @@ typedef struct pic_jmpbuf {
} pic_jmpbuf; } pic_jmpbuf;
typedef struct pic_checkpoint { typedef struct pic_checkpoint {
PIC_OBJECT_HEADER
struct pic_proc *in; struct pic_proc *in;
struct pic_proc *out; struct pic_proc *out;
int depth; int depth;

View File

@ -158,14 +158,15 @@ enum pic_tt {
PIC_TT_PORT, PIC_TT_PORT,
PIC_TT_ERROR, PIC_TT_ERROR,
PIC_TT_ID, PIC_TT_ID,
PIC_TT_CXT,
PIC_TT_ENV, PIC_TT_ENV,
PIC_TT_LIB, PIC_TT_LIB,
PIC_TT_IREP,
PIC_TT_DATA, PIC_TT_DATA,
PIC_TT_DICT, PIC_TT_DICT,
PIC_TT_REG, PIC_TT_REG,
PIC_TT_RECORD PIC_TT_RECORD,
PIC_TT_CXT,
PIC_TT_IREP,
PIC_TT_CP
}; };
#define PIC_OBJECT_HEADER \ #define PIC_OBJECT_HEADER \
@ -336,6 +337,8 @@ pic_type_repr(enum pic_tt tt)
return "reg"; return "reg";
case PIC_TT_RECORD: case PIC_TT_RECORD:
return "record"; return "record";
case PIC_TT_CP:
return "checkpoint";
} }
PIC_UNREACHABLE(); PIC_UNREACHABLE();
} }

View File

@ -355,7 +355,7 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf)
pic->attrs = pic_make_reg(pic); pic->attrs = pic_make_reg(pic);
/* root block */ /* root block */
pic->cp = pic_malloc(pic, sizeof(pic_checkpoint)); pic->cp = (pic_checkpoint *)pic_obj_alloc(pic, sizeof(pic_checkpoint), PIC_TT_CP);
pic->cp->prev = NULL; pic->cp->prev = NULL;
pic->cp->depth = 0; pic->cp->depth = 0;
pic->cp->in = pic->cp->out = NULL; pic->cp->in = pic->cp->out = NULL;
@ -401,14 +401,6 @@ pic_close(pic_state *pic)
xh_entry *it; xh_entry *it;
pic_allocf allocf = pic->allocf; pic_allocf allocf = pic->allocf;
/* invoke exit handlers */
while (pic->cp) {
if (pic->cp->out) {
pic_apply0(pic, pic->cp->out);
}
pic->cp = pic->cp->prev;
}
/* free symbol names */ /* free symbol names */
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) {
allocf(xh_key(it, char *), 0); allocf(xh_key(it, char *), 0);