manage ireps by gc
This commit is contained in:
parent
2d8980b2d0
commit
d478affabd
|
@ -21,7 +21,7 @@ pic_get_backtrace(pic_state *pic)
|
|||
trace = pic_str_cat(pic, trace, pic_lit_value(pic, " at "));
|
||||
trace = pic_str_cat(pic, trace, pic_lit_value(pic, "(anonymous lambda)"));
|
||||
|
||||
if (pic_func_p(pic, proc)) {
|
||||
if (pic_proc_func_p(pic, proc)) {
|
||||
trace = pic_str_cat(pic, trace, pic_lit_value(pic, " (native function)\n"));
|
||||
} else {
|
||||
trace = pic_str_cat(pic, trace, pic_lit_value(pic, " (unknown location)\n")); /* TODO */
|
||||
|
|
|
@ -643,9 +643,7 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
|
|||
struct irep *irep;
|
||||
|
||||
/* create irep */
|
||||
irep = pic_malloc(pic, sizeof(struct irep));
|
||||
irep->list.next = irep->list.prev = 0;
|
||||
irep->refc = 1;
|
||||
irep = (struct irep *)pic_obj_alloc(pic, sizeof(struct irep), PIC_TYPE_IREP);
|
||||
irep->varg = pic_sym_p(pic, cxt->rest);
|
||||
irep->argc = pic_vec_len(pic, cxt->args) + 1;
|
||||
irep->localc = pic_vec_len(pic, cxt->locals);
|
||||
|
@ -661,13 +659,6 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
|
|||
irep->nnums = cxt->flen;
|
||||
irep->npool = cxt->plen;
|
||||
|
||||
if (irep->npool > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1072,7 +1063,6 @@ static pic_value
|
|||
pic_compile(pic_state *pic, pic_value obj)
|
||||
{
|
||||
struct irep *irep;
|
||||
pic_value proc;
|
||||
size_t ai = pic_enter(pic);
|
||||
|
||||
#if 0
|
||||
|
@ -1106,11 +1096,7 @@ pic_compile(pic_state *pic, pic_value obj)
|
|||
/* codegen */
|
||||
irep = pic_codegen(pic, obj);
|
||||
|
||||
proc = pic_make_proc_irep(pic, irep, NULL);
|
||||
|
||||
pic_irep_decref(pic, irep);
|
||||
|
||||
return proc;
|
||||
return pic_make_proc_irep(pic, irep, NULL);
|
||||
}
|
||||
|
||||
pic_value
|
||||
|
|
|
@ -448,8 +448,10 @@ typename(pic_state *pic, pic_value obj)
|
|||
return "identifier";
|
||||
case PIC_TYPE_CXT:
|
||||
return "context";
|
||||
case PIC_TYPE_FUNC:
|
||||
case PIC_TYPE_IREP:
|
||||
return "irep";
|
||||
case PIC_TYPE_PROC_FUNC:
|
||||
case PIC_TYPE_PROC_IREP:
|
||||
return "procedure";
|
||||
case PIC_TYPE_ENV:
|
||||
return "environment";
|
||||
|
|
37
lib/gc.c
37
lib/gc.c
|
@ -33,6 +33,7 @@ struct object {
|
|||
struct port port;
|
||||
struct error err;
|
||||
struct checkpoint cp;
|
||||
struct irep irep;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -342,16 +343,27 @@ gc_mark_object(pic_state *pic, struct object *obj)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_FUNC: {
|
||||
case PIC_TYPE_PROC_FUNC: {
|
||||
int i;
|
||||
for (i = 0; i < obj->u.proc.u.f.localc; ++i) {
|
||||
gc_mark(pic, obj->u.proc.locals[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_IREP: {
|
||||
case PIC_TYPE_PROC_IREP: {
|
||||
if (obj->u.proc.u.i.cxt) {
|
||||
LOOP(obj->u.proc.u.i.cxt);
|
||||
gc_mark_object(pic, (struct object *)obj->u.proc.u.i.cxt);
|
||||
}
|
||||
LOOP(obj->u.proc.u.i.irep);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_IREP: {
|
||||
size_t i;
|
||||
for (i = 0; i < obj->u.irep.npool; ++i) {
|
||||
gc_mark_object(pic, obj->u.irep.pool[i]);
|
||||
}
|
||||
for (i = 0; i < obj->u.irep.nirep; ++i) {
|
||||
gc_mark_object(pic, (struct object *)obj->u.irep.irep[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -451,7 +463,6 @@ gc_mark_phase(pic_state *pic)
|
|||
{
|
||||
pic_value *stack;
|
||||
struct callinfo *ci;
|
||||
struct list_head *list;
|
||||
int it;
|
||||
size_t j;
|
||||
|
||||
|
@ -479,14 +490,6 @@ gc_mark_phase(pic_state *pic)
|
|||
gc_mark_object(pic, (struct object *)pic->arena[j]);
|
||||
}
|
||||
|
||||
/* ireps */
|
||||
for (list = pic->ireps.next; list != &pic->ireps; list = list->next) {
|
||||
struct irep *irep = (struct irep *)list;
|
||||
for (j = 0; j < irep->npool; ++j) {
|
||||
gc_mark_object(pic, irep->pool[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/* global variables */
|
||||
gc_mark(pic, pic->globals);
|
||||
|
||||
|
@ -580,7 +583,12 @@ gc_finalize_object(pic_state *pic, struct object *obj)
|
|||
break;
|
||||
}
|
||||
case PIC_TYPE_IREP: {
|
||||
pic_irep_decref(pic, obj->u.proc.u.i.irep);
|
||||
struct irep *irep = &obj->u.irep;
|
||||
pic_free(pic, irep->code);
|
||||
pic_free(pic, irep->ints);
|
||||
pic_free(pic, irep->nums);
|
||||
pic_free(pic, irep->pool);
|
||||
pic_free(pic, irep->irep);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_PORT: {
|
||||
|
@ -594,7 +602,8 @@ gc_finalize_object(pic_state *pic, struct object *obj)
|
|||
case PIC_TYPE_ID:
|
||||
case PIC_TYPE_RECORD:
|
||||
case PIC_TYPE_CP:
|
||||
case PIC_TYPE_FUNC:
|
||||
case PIC_TYPE_PROC_FUNC:
|
||||
case PIC_TYPE_PROC_IREP:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -10,34 +10,35 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
enum {
|
||||
PIC_TYPE_INVALID = 1,
|
||||
PIC_TYPE_FLOAT = 2,
|
||||
PIC_TYPE_INT = 3,
|
||||
PIC_TYPE_CHAR = 4,
|
||||
PIC_TYPE_EOF = 5,
|
||||
PIC_TYPE_UNDEF = 6,
|
||||
PIC_TYPE_TRUE = 8,
|
||||
PIC_TYPE_NIL = 7,
|
||||
PIC_TYPE_FALSE = 9,
|
||||
PIC_IVAL_END = 10,
|
||||
PIC_TYPE_INVALID = 1,
|
||||
PIC_TYPE_FLOAT = 2,
|
||||
PIC_TYPE_INT = 3,
|
||||
PIC_TYPE_CHAR = 4,
|
||||
PIC_TYPE_EOF = 5,
|
||||
PIC_TYPE_UNDEF = 6,
|
||||
PIC_TYPE_TRUE = 8,
|
||||
PIC_TYPE_NIL = 7,
|
||||
PIC_TYPE_FALSE = 9,
|
||||
PIC_IVAL_END = 10,
|
||||
/* -------------------- */
|
||||
PIC_TYPE_STRING = 16,
|
||||
PIC_TYPE_VECTOR = 17,
|
||||
PIC_TYPE_BLOB = 18,
|
||||
PIC_TYPE_PORT = 20,
|
||||
PIC_TYPE_ERROR = 21,
|
||||
PIC_TYPE_ID = 22,
|
||||
PIC_TYPE_ENV = 23,
|
||||
PIC_TYPE_DATA = 24,
|
||||
PIC_TYPE_DICT = 25,
|
||||
PIC_TYPE_WEAK = 26,
|
||||
PIC_TYPE_RECORD = 27,
|
||||
PIC_TYPE_SYMBOL = 28,
|
||||
PIC_TYPE_PAIR = 29,
|
||||
PIC_TYPE_CXT = 30,
|
||||
PIC_TYPE_CP = 31,
|
||||
PIC_TYPE_FUNC = 32,
|
||||
PIC_TYPE_IREP = 33
|
||||
PIC_TYPE_STRING = 16,
|
||||
PIC_TYPE_VECTOR = 17,
|
||||
PIC_TYPE_BLOB = 18,
|
||||
PIC_TYPE_PORT = 20,
|
||||
PIC_TYPE_ERROR = 21,
|
||||
PIC_TYPE_ID = 22,
|
||||
PIC_TYPE_ENV = 23,
|
||||
PIC_TYPE_DATA = 24,
|
||||
PIC_TYPE_DICT = 25,
|
||||
PIC_TYPE_WEAK = 26,
|
||||
PIC_TYPE_RECORD = 27,
|
||||
PIC_TYPE_SYMBOL = 28,
|
||||
PIC_TYPE_PAIR = 29,
|
||||
PIC_TYPE_CXT = 30,
|
||||
PIC_TYPE_CP = 31,
|
||||
PIC_TYPE_PROC_FUNC = 32,
|
||||
PIC_TYPE_PROC_IREP = 33,
|
||||
PIC_TYPE_IREP = 34
|
||||
};
|
||||
|
||||
#if !PIC_NAN_BOXING
|
||||
|
@ -221,7 +222,8 @@ DEFPRED(pic_rec_p, PIC_TYPE_RECORD)
|
|||
DEFPRED(pic_sym_p, PIC_TYPE_SYMBOL)
|
||||
DEFPRED(pic_pair_p, PIC_TYPE_PAIR)
|
||||
DEFPRED(pic_cp_p, PIC_TYPE_CP)
|
||||
DEFPRED(pic_func_p, PIC_TYPE_FUNC)
|
||||
DEFPRED(pic_proc_func_p, PIC_TYPE_PROC_FUNC)
|
||||
DEFPRED(pic_proc_irep_p, PIC_TYPE_PROC_IREP)
|
||||
DEFPRED(pic_irep_p, PIC_TYPE_IREP)
|
||||
|
||||
PIC_STATIC_INLINE bool
|
||||
|
@ -233,7 +235,7 @@ pic_bool_p(pic_state *pic, pic_value obj)
|
|||
PIC_STATIC_INLINE bool
|
||||
pic_proc_p(pic_state *pic, pic_value o)
|
||||
{
|
||||
return pic_func_p(pic, o) || pic_irep_p(pic, o);
|
||||
return pic_proc_func_p(pic, o) || pic_proc_irep_p(pic, o);
|
||||
}
|
||||
|
||||
PIC_STATIC_INLINE bool
|
||||
|
|
19
lib/object.h
19
lib/object.h
|
@ -90,6 +90,24 @@ struct data {
|
|||
void *data;
|
||||
};
|
||||
|
||||
struct code {
|
||||
int insn;
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct irep {
|
||||
OBJECT_HEADER
|
||||
int argc, localc, capturec;
|
||||
bool varg;
|
||||
struct code *code;
|
||||
struct irep **irep;
|
||||
int *ints;
|
||||
double *nums;
|
||||
struct object **pool;
|
||||
size_t ncode, nirep, nints, nnums, npool;
|
||||
};
|
||||
|
||||
struct context {
|
||||
OBJECT_HEADER
|
||||
pic_value *regs;
|
||||
|
@ -260,6 +278,7 @@ DEFPTR(pic_port_ptr, struct port)
|
|||
DEFPTR(pic_error_ptr, struct error)
|
||||
DEFPTR(pic_rec_ptr, struct record)
|
||||
DEFPTR(pic_cp_ptr, struct checkpoint)
|
||||
DEFPTR(pic_irep_ptr, struct irep)
|
||||
|
||||
struct object *pic_obj_alloc(pic_state *, size_t, int type);
|
||||
|
||||
|
|
42
lib/proc.c
42
lib/proc.c
|
@ -268,8 +268,6 @@ pic_closure_ref(pic_state *pic, int n)
|
|||
{
|
||||
pic_value self = GET_PROC(pic);
|
||||
|
||||
assert(pic_func_p(pic, self));
|
||||
|
||||
if (n < 0 || pic_proc_ptr(pic, self)->u.f.localc <= n) {
|
||||
pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n));
|
||||
}
|
||||
|
@ -281,8 +279,6 @@ pic_closure_set(pic_state *pic, int n, pic_value v)
|
|||
{
|
||||
pic_value self = GET_PROC(pic);
|
||||
|
||||
assert(pic_func_p(pic, self));
|
||||
|
||||
if (n < 0 || pic_proc_ptr(pic, self)->u.f.localc <= n) {
|
||||
pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n));
|
||||
}
|
||||
|
@ -542,7 +538,7 @@ pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv)
|
|||
ci->fp = pic->sp - c.a;
|
||||
ci->irep = NULL;
|
||||
ci->cxt = NULL;
|
||||
if (proc->tt == PIC_TYPE_FUNC) {
|
||||
if (proc->tt == PIC_TYPE_PROC_FUNC) {
|
||||
|
||||
/* invoke! */
|
||||
v = proc->u.f.func(pic);
|
||||
|
@ -821,44 +817,13 @@ pic_vcall(pic_state *pic, pic_value proc, int n, va_list ap)
|
|||
return pic_apply(pic, proc, n, args);
|
||||
}
|
||||
|
||||
void
|
||||
pic_irep_incref(pic_state *PIC_UNUSED(pic), struct irep *irep)
|
||||
{
|
||||
irep->refc++;
|
||||
}
|
||||
|
||||
void
|
||||
pic_irep_decref(pic_state *pic, struct irep *irep)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (--irep->refc == 0) {
|
||||
pic_free(pic, irep->code);
|
||||
pic_free(pic, irep->ints);
|
||||
pic_free(pic, irep->nums);
|
||||
pic_free(pic, irep->pool);
|
||||
|
||||
/* unchain before decref children ireps */
|
||||
if (irep->list.prev) { /* && irep->list.next */
|
||||
irep->list.prev->next = irep->list.next;
|
||||
irep->list.next->prev = irep->list.prev;
|
||||
}
|
||||
|
||||
for (i = 0; i < irep->nirep; ++i) {
|
||||
pic_irep_decref(pic, irep->irep[i]);
|
||||
}
|
||||
pic_free(pic, irep->irep);
|
||||
pic_free(pic, irep);
|
||||
}
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_make_proc(pic_state *pic, pic_func_t func, int n, pic_value *env)
|
||||
{
|
||||
struct proc *proc;
|
||||
int i;
|
||||
|
||||
proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals) + sizeof(pic_value) * n, PIC_TYPE_FUNC);
|
||||
proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals) + sizeof(pic_value) * n, PIC_TYPE_PROC_FUNC);
|
||||
proc->u.f.func = func;
|
||||
proc->u.f.localc = n;
|
||||
for (i = 0; i < n; ++i) {
|
||||
|
@ -872,10 +837,9 @@ pic_make_proc_irep(pic_state *pic, struct irep *irep, struct context *cxt)
|
|||
{
|
||||
struct proc *proc;
|
||||
|
||||
proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals), PIC_TYPE_IREP);
|
||||
proc = (struct proc *)pic_obj_alloc(pic, offsetof(struct proc, locals), PIC_TYPE_PROC_IREP);
|
||||
proc->u.i.irep = irep;
|
||||
proc->u.i.cxt = cxt;
|
||||
pic_irep_incref(pic, irep);
|
||||
return obj_value(pic, proc);
|
||||
}
|
||||
|
||||
|
|
|
@ -231,10 +231,6 @@ pic_open(pic_allocf allocf, void *userdata)
|
|||
kh_init(ltable, &pic->ltable);
|
||||
pic->lib = NULL;
|
||||
|
||||
/* ireps */
|
||||
pic->ireps.next = &pic->ireps;
|
||||
pic->ireps.prev = &pic->ireps;
|
||||
|
||||
/* raised error object */
|
||||
pic->panicf = NULL;
|
||||
pic->err = pic_invalid_value(pic);
|
||||
|
|
|
@ -56,7 +56,6 @@ struct pic_state {
|
|||
pic_value globals; /* weak */
|
||||
pic_value macros; /* weak */
|
||||
khash_t(ltable) ltable;
|
||||
struct list_head ireps;
|
||||
|
||||
bool gc_enable;
|
||||
struct heap *heap;
|
||||
|
|
26
lib/vm.h
26
lib/vm.h
|
@ -52,32 +52,6 @@ enum {
|
|||
OP_STOP
|
||||
};
|
||||
|
||||
struct code {
|
||||
int insn;
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct list_head {
|
||||
struct list_head *prev, *next;
|
||||
};
|
||||
|
||||
struct irep {
|
||||
struct list_head list;
|
||||
unsigned refc;
|
||||
int argc, localc, capturec;
|
||||
bool varg;
|
||||
struct code *code;
|
||||
struct irep **irep;
|
||||
int *ints;
|
||||
double *nums;
|
||||
struct object **pool;
|
||||
size_t ncode, nirep, nints, nnums, npool;
|
||||
};
|
||||
|
||||
void pic_irep_incref(pic_state *, struct irep *);
|
||||
void pic_irep_decref(pic_state *, struct irep *);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue