manage ireps using reference count
This commit is contained in:
parent
6488e315d3
commit
64788af4b9
|
@ -694,7 +694,8 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
|
|||
struct pic_irep *irep;
|
||||
|
||||
/* create irep */
|
||||
irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
|
||||
irep = pic_malloc(pic, sizeof(struct pic_irep));
|
||||
irep->refc = 1;
|
||||
irep->varg = cxt->rest != NULL;
|
||||
irep->argc = (int)cxt->args->len + 1;
|
||||
irep->localc = (int)cxt->locals->len;
|
||||
|
@ -705,6 +706,11 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
|
|||
irep->pool = pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->plen);
|
||||
irep->plen = cxt->plen;
|
||||
|
||||
irep->list.next = pic->ireps.next;
|
||||
irep->list.prev = &pic->ireps;
|
||||
irep->list.next->prev = &irep->list;
|
||||
irep->list.prev->next = &irep->list;
|
||||
|
||||
return irep;
|
||||
}
|
||||
|
||||
|
@ -1086,6 +1092,7 @@ struct pic_proc *
|
|||
pic_compile(pic_state *pic, pic_value obj, struct pic_env *env)
|
||||
{
|
||||
struct pic_irep *irep;
|
||||
struct pic_proc *proc;
|
||||
size_t ai = pic_gc_arena_preserve(pic);
|
||||
|
||||
#if DEBUG
|
||||
|
@ -1143,7 +1150,9 @@ pic_compile(pic_state *pic, pic_value obj, struct pic_env *env)
|
|||
puts("");
|
||||
#endif
|
||||
|
||||
SAVE(pic, ai, pic_obj_value(irep));
|
||||
proc = pic_make_proc_irep(pic, irep, NULL);
|
||||
|
||||
return pic_make_proc_irep(pic, irep, NULL);
|
||||
pic_irep_decref(pic, irep);
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ struct pic_object {
|
|||
struct pic_env env;
|
||||
struct pic_proc proc;
|
||||
struct pic_context cxt;
|
||||
struct pic_irep irep;
|
||||
struct pic_port port;
|
||||
struct pic_error err;
|
||||
struct pic_lib lib;
|
||||
|
@ -300,7 +299,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
}
|
||||
case PIC_TT_PROC: {
|
||||
if (pic_proc_irep_p(&obj->u.proc)) {
|
||||
gc_mark_object(pic, (struct pic_object *)obj->u.proc.u.i.irep);
|
||||
if (obj->u.proc.u.i.cxt) {
|
||||
LOOP(obj->u.proc.u.i.cxt);
|
||||
}
|
||||
|
@ -360,17 +358,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
LOOP(obj->u.lib.exports);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_IREP: {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < obj->u.irep.ilen; ++i) {
|
||||
gc_mark_object(pic, (struct pic_object *)obj->u.irep.irep[i]);
|
||||
}
|
||||
for (i = 0; i < obj->u.irep.plen; ++i) {
|
||||
gc_mark(pic, obj->u.irep.pool[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TT_DATA: {
|
||||
if (obj->u.data.type->mark) {
|
||||
obj->u.data.type->mark(pic, obj->u.data.data, gc_mark);
|
||||
|
@ -441,6 +428,7 @@ gc_mark_phase(pic_state *pic)
|
|||
pic_value *stack;
|
||||
pic_callinfo *ci;
|
||||
struct pic_proc **xhandler;
|
||||
struct pic_list *list;
|
||||
size_t j;
|
||||
|
||||
assert(pic->heap->regs == NULL);
|
||||
|
@ -472,6 +460,14 @@ gc_mark_phase(pic_state *pic)
|
|||
gc_mark_object(pic, (struct pic_object *)pic->arena[j]);
|
||||
}
|
||||
|
||||
/* ireps */
|
||||
for (list = pic->ireps.next; list != &pic->ireps; list = list->next) {
|
||||
struct pic_irep *irep = (struct pic_irep *)list;
|
||||
for (j = 0; j < irep->plen; ++j) {
|
||||
gc_mark(pic, irep->pool[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/* mark reserved symbols */
|
||||
M(sQUOTE); M(sQUASIQUOTE); M(sUNQUOTE); M(sUNQUOTE_SPLICING);
|
||||
M(sSYNTAX_QUOTE); M(sSYNTAX_QUASIQUOTE); M(sSYNTAX_UNQUOTE); M(sSYNTAX_UNQUOTE_SPLICING);
|
||||
|
@ -564,12 +560,6 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
kh_destroy(env, &obj->u.env.map);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_IREP: {
|
||||
pic_free(pic, obj->u.irep.code);
|
||||
pic_free(pic, obj->u.irep.irep);
|
||||
pic_free(pic, obj->u.irep.pool);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_DATA: {
|
||||
if (obj->u.data.type->dtor) {
|
||||
obj->u.data.type->dtor(pic, obj->u.data.data);
|
||||
|
@ -588,10 +578,15 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
kh_destroy(reg, &obj->u.reg.hash);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_PROC: {
|
||||
if (pic_proc_irep_p(&obj->u.proc)) {
|
||||
pic_irep_decref(pic, obj->u.proc.u.i.irep);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PIC_TT_PAIR:
|
||||
case PIC_TT_CXT:
|
||||
case PIC_TT_PROC:
|
||||
case PIC_TT_PORT:
|
||||
case PIC_TT_ERROR:
|
||||
case PIC_TT_ID:
|
||||
|
|
|
@ -121,6 +121,7 @@ struct pic_state {
|
|||
struct pic_reg *globals;
|
||||
struct pic_reg *macros;
|
||||
pic_value libs;
|
||||
struct pic_list ireps; /* chain */
|
||||
|
||||
pic_reader reader;
|
||||
xFILE files[XOPEN_MAX];
|
||||
|
|
|
@ -20,16 +20,25 @@ typedef struct {
|
|||
} u;
|
||||
} pic_code;
|
||||
|
||||
struct pic_list {
|
||||
struct pic_list *prev, *next;
|
||||
};
|
||||
|
||||
struct pic_irep {
|
||||
PIC_OBJECT_HEADER
|
||||
struct pic_list list;
|
||||
int refc;
|
||||
pic_code *code;
|
||||
int argc, localc, capturec;
|
||||
bool varg;
|
||||
struct pic_irep **irep;
|
||||
size_t ilen;
|
||||
pic_value *pool;
|
||||
size_t ilen, plen;
|
||||
size_t plen;
|
||||
};
|
||||
|
||||
void pic_irep_incref(pic_state *, struct pic_irep *);
|
||||
void pic_irep_decref(pic_state *, struct pic_irep *);
|
||||
|
||||
pic_sym *pic_resolve(pic_state *, pic_value, struct pic_env *);
|
||||
pic_value pic_expand(pic_state *, pic_value, struct pic_env *);
|
||||
pic_value pic_analyze(pic_state *, pic_value);
|
||||
|
|
|
@ -158,7 +158,6 @@ enum pic_tt {
|
|||
PIC_TT_RECORD,
|
||||
PIC_TT_BOX,
|
||||
PIC_TT_CXT,
|
||||
PIC_TT_IREP,
|
||||
PIC_TT_CP
|
||||
};
|
||||
|
||||
|
@ -305,8 +304,6 @@ pic_type_repr(enum pic_tt tt)
|
|||
return "env";
|
||||
case PIC_TT_LIB:
|
||||
return "lib";
|
||||
case PIC_TT_IREP:
|
||||
return "irep";
|
||||
case PIC_TT_DATA:
|
||||
return "data";
|
||||
case PIC_TT_DICT:
|
||||
|
|
|
@ -4,6 +4,33 @@
|
|||
|
||||
#include "picrin.h"
|
||||
|
||||
void
|
||||
pic_irep_incref(pic_state PIC_UNUSED(*pic), struct pic_irep *irep)
|
||||
{
|
||||
irep->refc++;
|
||||
}
|
||||
|
||||
void
|
||||
pic_irep_decref(pic_state *pic, struct pic_irep *irep)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (--irep->refc == 0) {
|
||||
pic_free(pic, irep->code);
|
||||
pic_free(pic, irep->pool);
|
||||
|
||||
/* unchain before decref children ireps */
|
||||
irep->list.prev->next = irep->list.next;
|
||||
irep->list.next->prev = irep->list.prev;
|
||||
|
||||
for (i = 0; i < irep->ilen; ++i) {
|
||||
pic_irep_decref(pic, irep->irep[i]);
|
||||
}
|
||||
pic_free(pic, irep->irep);
|
||||
pic_free(pic, irep);
|
||||
}
|
||||
}
|
||||
|
||||
struct pic_proc *
|
||||
pic_make_proc(pic_state *pic, pic_func_t func)
|
||||
{
|
||||
|
@ -25,6 +52,7 @@ pic_make_proc_irep(pic_state *pic, struct pic_irep *irep, struct pic_context *cx
|
|||
proc->tag = PIC_PROC_TAG_IREP;
|
||||
proc->u.i.irep = irep;
|
||||
proc->u.i.cxt = cxt;
|
||||
pic_irep_incref(pic, irep);
|
||||
return proc;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,6 +316,10 @@ pic_open(pic_allocf allocf, void *userdata)
|
|||
pic->libs = pic_nil_value();
|
||||
pic->lib = NULL;
|
||||
|
||||
/* ireps */
|
||||
pic->ireps.next = &pic->ireps;
|
||||
pic->ireps.prev = &pic->ireps;
|
||||
|
||||
/* raised error object */
|
||||
pic->err = pic_invalid_value();
|
||||
|
||||
|
@ -478,6 +482,18 @@ pic_close(pic_state *pic)
|
|||
/* free all heap objects */
|
||||
pic_gc_run(pic);
|
||||
|
||||
#if 0
|
||||
{
|
||||
/* FIXME */
|
||||
int i = 0;
|
||||
struct pic_list *list;
|
||||
for (list = pic->ireps.next; list != &pic->ireps; list = list->next) {
|
||||
i++;
|
||||
}
|
||||
printf("%d\n", i);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* flush all xfiles */
|
||||
xfflush(pic, NULL);
|
||||
|
||||
|
|
Loading…
Reference in New Issue