add reference count GC for pic_block objects
This commit is contained in:
parent
c22f566c06
commit
984588b1b6
|
@ -22,6 +22,7 @@ struct pic_block {
|
||||||
struct pic_block *prev;
|
struct pic_block *prev;
|
||||||
int depth;
|
int depth;
|
||||||
struct pic_proc *in, *out;
|
struct pic_proc *in, *out;
|
||||||
|
unsigned refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -22,4 +22,21 @@ struct pic_cont {
|
||||||
pic_value result;
|
pic_value result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PIC_BLK_INCREF(pic,blk) do { \
|
||||||
|
(blk)->refcnt++; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define PIC_BLK_DECREF(pic,blk) do { \
|
||||||
|
struct pic_block *_a = (blk), *_b; \
|
||||||
|
while (_a) { \
|
||||||
|
if (! --_a->refcnt) { \
|
||||||
|
_b = _a->prev; \
|
||||||
|
pic_free((pic), _a); \
|
||||||
|
_a = _b; \
|
||||||
|
} else { \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,7 @@ save_cont(pic_state *pic)
|
||||||
cont = (struct pic_cont *)pic_obj_alloc(pic, sizeof(struct pic_cont), PIC_TT_CONT);
|
cont = (struct pic_cont *)pic_obj_alloc(pic, sizeof(struct pic_cont), PIC_TT_CONT);
|
||||||
|
|
||||||
cont->blk = pic->blk;
|
cont->blk = pic->blk;
|
||||||
|
PIC_BLK_INCREF(pic, cont->blk);
|
||||||
|
|
||||||
cont->stk_len = native_stack_length(pic, &pos);
|
cont->stk_len = native_stack_length(pic, &pos);
|
||||||
cont->stk_pos = pos;
|
cont->stk_pos = pos;
|
||||||
|
@ -77,6 +78,8 @@ restore_cont(pic_state *pic, struct pic_cont *cont)
|
||||||
if (&v > cont->stk_pos + cont->stk_len) native_stack_extend(pic, cont);
|
if (&v > cont->stk_pos + cont->stk_len) native_stack_extend(pic, cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PIC_BLK_DECREF(pic, pic->blk);
|
||||||
|
PIC_BLK_INCREF(pic, cont->blk);
|
||||||
pic->blk = cont->blk;
|
pic->blk = cont->blk;
|
||||||
|
|
||||||
pic->sp = cont->sp;
|
pic->sp = cont->sp;
|
||||||
|
@ -122,7 +125,7 @@ cont_call(pic_state *pic)
|
||||||
cont = (struct pic_cont *)pic_ptr(proc->env->values[0]);
|
cont = (struct pic_cont *)pic_ptr(proc->env->values[0]);
|
||||||
cont->result = v;
|
cont->result = v;
|
||||||
|
|
||||||
/* execute winded handlers */
|
/* execute guard handlers */
|
||||||
walk_to_block(pic, pic->blk, cont->blk);
|
walk_to_block(pic, pic->blk, cont->blk);
|
||||||
|
|
||||||
restore_cont(pic, cont);
|
restore_cont(pic, cont);
|
||||||
|
@ -196,9 +199,12 @@ pic_cont_dynamic_wind(pic_state *pic)
|
||||||
pic->blk->depth = here->depth + 1;
|
pic->blk->depth = here->depth + 1;
|
||||||
pic->blk->in = in;
|
pic->blk->in = in;
|
||||||
pic->blk->out = out;
|
pic->blk->out = out;
|
||||||
|
pic->blk->refcnt = 1;
|
||||||
|
PIC_BLK_INCREF(pic, here);
|
||||||
|
|
||||||
v = pic_apply_argv(pic, thunk, 0);
|
v = pic_apply_argv(pic, thunk, 0);
|
||||||
|
|
||||||
|
PIC_BLK_DECREF(pic, pic->blk);
|
||||||
pic->blk = here;
|
pic->blk = here;
|
||||||
}
|
}
|
||||||
/* exit */
|
/* exit */
|
||||||
|
|
20
src/gc.c
20
src/gc.c
|
@ -142,6 +142,19 @@ gc_alloc(pic_state *pic, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gc_mark(pic_state *, pic_value);
|
static void gc_mark(pic_state *, pic_value);
|
||||||
|
static void gc_mark_object(pic_state *pic, struct pic_object *obj);
|
||||||
|
|
||||||
|
static void
|
||||||
|
gc_mark_block(pic_state *pic, struct pic_block *blk)
|
||||||
|
{
|
||||||
|
while (blk) {
|
||||||
|
if (blk->in)
|
||||||
|
gc_mark_object(pic, (struct pic_object *)blk->in);
|
||||||
|
if (blk->out)
|
||||||
|
gc_mark_object(pic, (struct pic_object *)blk->out);
|
||||||
|
blk = blk->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_mark_object(pic_state *pic, struct pic_object *obj)
|
gc_mark_object(pic_state *pic, struct pic_object *obj)
|
||||||
|
@ -198,6 +211,9 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* block */
|
||||||
|
gc_mark_block(pic, cont->blk);
|
||||||
|
|
||||||
/* stack */
|
/* stack */
|
||||||
for (stack = cont->st_ptr; stack != cont->sp; ++stack) {
|
for (stack = cont->st_ptr; stack != cont->sp; ++stack) {
|
||||||
gc_mark(pic, *stack);
|
gc_mark(pic, *stack);
|
||||||
|
@ -249,6 +265,9 @@ gc_mark_phase(pic_state *pic)
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* block */
|
||||||
|
gc_mark_block(pic, pic->blk);
|
||||||
|
|
||||||
/* stack */
|
/* stack */
|
||||||
for (stack = pic->stbase; stack != pic->sp; ++stack) {
|
for (stack = pic->stbase; stack != pic->sp; ++stack) {
|
||||||
gc_mark(pic, *stack);
|
gc_mark(pic, *stack);
|
||||||
|
@ -336,6 +355,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
||||||
pic_free(pic, cont->stk_ptr);
|
pic_free(pic, cont->stk_ptr);
|
||||||
pic_free(pic, cont->st_ptr);
|
pic_free(pic, cont->st_ptr);
|
||||||
pic_free(pic, cont->ci_ptr);
|
pic_free(pic, cont->ci_ptr);
|
||||||
|
PIC_BLK_DECREF(pic, cont->blk);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIC_TT_NIL:
|
case PIC_TT_NIL:
|
||||||
|
|
|
@ -27,6 +27,7 @@ pic_open(int argc, char *argv[], char **envp)
|
||||||
pic->blk->prev = NULL;
|
pic->blk->prev = NULL;
|
||||||
pic->blk->depth = 0;
|
pic->blk->depth = 0;
|
||||||
pic->blk->in = pic->blk->out = NULL;
|
pic->blk->in = pic->blk->out = NULL;
|
||||||
|
pic->blk->refcnt = 1;
|
||||||
|
|
||||||
/* prepare VM stack */
|
/* prepare VM stack */
|
||||||
pic->stbase = pic->sp = (pic_value *)malloc(sizeof(pic_value) * PIC_STACK_SIZE);
|
pic->stbase = pic->sp = (pic_value *)malloc(sizeof(pic_value) * PIC_STACK_SIZE);
|
||||||
|
|
Loading…
Reference in New Issue