Allocate pic_blocks in picrin's gc pool; reference count may cause problems
This commit is contained in:
parent
4ddf7fb163
commit
50879dd7b6
|
@ -57,18 +57,11 @@ typedef struct {
|
|||
struct pic_env *up;
|
||||
} pic_callinfo;
|
||||
|
||||
typedef struct pic_block {
|
||||
struct pic_block *prev;
|
||||
int depth;
|
||||
struct pic_proc *in, *out;
|
||||
unsigned refcnt;
|
||||
} pic_block;
|
||||
|
||||
typedef struct {
|
||||
int argc;
|
||||
char **argv, **envp;
|
||||
|
||||
pic_block *blk;
|
||||
struct pic_block *blk;
|
||||
|
||||
pic_value *sp;
|
||||
pic_value *stbase, *stend;
|
||||
|
|
|
@ -9,11 +9,18 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct pic_block {
|
||||
PIC_OBJECT_HEADER
|
||||
struct pic_block *prev;
|
||||
int depth;
|
||||
struct pic_proc *in, *out;
|
||||
};
|
||||
|
||||
struct pic_cont {
|
||||
PIC_OBJECT_HEADER
|
||||
jmp_buf jmp;
|
||||
|
||||
pic_block *blk;
|
||||
struct pic_block *blk;
|
||||
|
||||
char *stk_pos, *stk_ptr;
|
||||
ptrdiff_t stk_len;
|
||||
|
@ -36,34 +43,6 @@ struct pic_cont {
|
|||
pic_value results;
|
||||
};
|
||||
|
||||
#define PIC_BLK_INCREF(pic,blk) do { \
|
||||
(blk)->refcnt++; \
|
||||
} while (0)
|
||||
|
||||
#define PIC_BLK_DECREF(pic,blk) do { \
|
||||
pic_block *_a = (blk), *_b; \
|
||||
while (_a) { \
|
||||
if (! --_a->refcnt) { \
|
||||
_b = _a->prev; \
|
||||
pic_free((pic), _a); \
|
||||
_a = _b; \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIC_BLK_EXIT(pic) do { \
|
||||
pic_block *_a; \
|
||||
while (pic->blk) { \
|
||||
if (pic->blk->out) \
|
||||
pic_apply0(pic, pic->blk->out); \
|
||||
_a = pic->blk->prev; \
|
||||
PIC_BLK_DECREF(pic, pic->blk); \
|
||||
pic->blk = _a; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
pic_value pic_values0(pic_state *);
|
||||
pic_value pic_values1(pic_state *, pic_value);
|
||||
pic_value pic_values2(pic_state *, pic_value, pic_value);
|
||||
|
|
|
@ -115,7 +115,8 @@ enum pic_tt {
|
|||
PIC_TT_VAR,
|
||||
PIC_TT_IREP,
|
||||
PIC_TT_DATA,
|
||||
PIC_TT_DICT
|
||||
PIC_TT_DICT,
|
||||
PIC_TT_BLK,
|
||||
};
|
||||
|
||||
#define PIC_OBJECT_HEADER \
|
||||
|
@ -268,6 +269,8 @@ pic_type_repr(enum pic_tt tt)
|
|||
return "data";
|
||||
case PIC_TT_DICT:
|
||||
return "dict";
|
||||
case PIC_TT_BLK:
|
||||
return "block";
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -831,6 +831,7 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos)
|
|||
case PIC_TT_IREP:
|
||||
case PIC_TT_DATA:
|
||||
case PIC_TT_DICT:
|
||||
case PIC_TT_BLK:
|
||||
pic_errorf(pic, "invalid expression given: ~s", obj);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
|
14
src/cont.c
14
src/cont.c
|
@ -119,7 +119,6 @@ save_cont(pic_state *pic, struct pic_cont **c)
|
|||
cont = *c = (struct pic_cont *)pic_obj_alloc(pic, sizeof(struct pic_cont), PIC_TT_CONT);
|
||||
|
||||
cont->blk = pic->blk;
|
||||
PIC_BLK_INCREF(pic, cont->blk);
|
||||
|
||||
cont->stk_len = native_stack_length(pic, &pos);
|
||||
cont->stk_pos = pos;
|
||||
|
@ -167,7 +166,7 @@ restore_cont(pic_state *pic, struct pic_cont *cont)
|
|||
void pic_vm_tear_off(pic_state *);
|
||||
char v;
|
||||
struct pic_cont *tmp = cont;
|
||||
pic_block *blk;
|
||||
struct pic_block *blk;
|
||||
|
||||
pic_vm_tear_off(pic); /* tear off */
|
||||
|
||||
|
@ -180,8 +179,6 @@ restore_cont(pic_state *pic, struct pic_cont *cont)
|
|||
|
||||
blk = pic->blk;
|
||||
pic->blk = cont->blk;
|
||||
PIC_BLK_INCREF(pic, pic->blk);
|
||||
PIC_BLK_DECREF(pic, blk);
|
||||
|
||||
pic->stbase = (pic_value *)pic_realloc(pic, pic->stbase, sizeof(pic_value) * cont->st_len);
|
||||
memcpy(pic->stbase, cont->st_ptr, sizeof(pic_value) * cont->st_len);
|
||||
|
@ -211,7 +208,7 @@ restore_cont(pic_state *pic, struct pic_cont *cont)
|
|||
}
|
||||
|
||||
static void
|
||||
walk_to_block(pic_state *pic, pic_block *here, pic_block *there)
|
||||
walk_to_block(pic_state *pic, struct pic_block *here, struct pic_block *there)
|
||||
{
|
||||
if (here == there)
|
||||
return;
|
||||
|
@ -229,7 +226,7 @@ walk_to_block(pic_state *pic, pic_block *here, pic_block *there)
|
|||
static pic_value
|
||||
pic_dynamic_wind(pic_state *pic, struct pic_proc *in, struct pic_proc *thunk, struct pic_proc *out)
|
||||
{
|
||||
pic_block *here;
|
||||
struct pic_block *here;
|
||||
pic_value val;
|
||||
|
||||
if (in != NULL) {
|
||||
|
@ -237,17 +234,14 @@ pic_dynamic_wind(pic_state *pic, struct pic_proc *in, struct pic_proc *thunk, st
|
|||
}
|
||||
|
||||
here = pic->blk;
|
||||
pic->blk = (pic_block *)pic_alloc(pic, sizeof(pic_block));
|
||||
pic->blk = (struct pic_block *)pic_obj_alloc(pic, sizeof(struct pic_block), PIC_TT_BLK);
|
||||
pic->blk->prev = here;
|
||||
pic->blk->depth = here->depth + 1;
|
||||
pic->blk->in = in;
|
||||
pic->blk->out = out;
|
||||
pic->blk->refcnt = 1;
|
||||
PIC_BLK_INCREF(pic, here);
|
||||
|
||||
val = pic_apply0(pic, thunk);
|
||||
|
||||
PIC_BLK_DECREF(pic, pic->blk);
|
||||
pic->blk = here;
|
||||
|
||||
if (out != NULL) {
|
||||
|
|
36
src/gc.c
36
src/gc.c
|
@ -322,18 +322,6 @@ gc_free(pic_state *pic, union header *bp)
|
|||
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, 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 bool
|
||||
gc_is_marked(union header *p)
|
||||
{
|
||||
|
@ -418,7 +406,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
int i;
|
||||
|
||||
/* block */
|
||||
gc_mark_block(pic, cont->blk);
|
||||
gc_mark_object(pic, (struct pic_object *)cont->blk);
|
||||
|
||||
/* stack */
|
||||
for (stack = cont->st_ptr; stack != cont->st_ptr + cont->sp_offset; ++stack) {
|
||||
|
@ -506,6 +494,20 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TT_BLK: {
|
||||
struct pic_block *blk = (struct pic_block *)obj;
|
||||
|
||||
if (blk->prev) {
|
||||
gc_mark_object(pic, (struct pic_object *)blk->prev);
|
||||
}
|
||||
if (blk->in) {
|
||||
gc_mark_object(pic, (struct pic_object *)blk->in);
|
||||
}
|
||||
if (blk->out) {
|
||||
gc_mark_object(pic, (struct pic_object *)blk->out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TT_NIL:
|
||||
case PIC_TT_BOOL:
|
||||
case PIC_TT_FLOAT:
|
||||
|
@ -539,7 +541,9 @@ gc_mark_phase(pic_state *pic)
|
|||
xh_iter it;
|
||||
|
||||
/* block */
|
||||
gc_mark_block(pic, pic->blk);
|
||||
if (pic->blk) {
|
||||
gc_mark_object(pic, (struct pic_object *)pic->blk);
|
||||
}
|
||||
|
||||
/* stack */
|
||||
for (stack = pic->stbase; stack != pic->sp; ++stack) {
|
||||
|
@ -622,7 +626,6 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
pic_free(pic, cont->ci_ptr);
|
||||
pic_free(pic, cont->arena);
|
||||
pic_free(pic, cont->try_jmps);
|
||||
PIC_BLK_DECREF(pic, cont->blk);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_SENV: {
|
||||
|
@ -659,6 +662,9 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
|||
xh_destroy(&dict->hash);
|
||||
break;
|
||||
}
|
||||
case PIC_TT_BLK: {
|
||||
break;
|
||||
}
|
||||
case PIC_TT_NIL:
|
||||
case PIC_TT_BOOL:
|
||||
case PIC_TT_FLOAT:
|
||||
|
|
|
@ -416,6 +416,7 @@ macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv)
|
|||
case PIC_TT_IREP:
|
||||
case PIC_TT_DATA:
|
||||
case PIC_TT_DICT:
|
||||
case PIC_TT_BLK:
|
||||
pic_errorf(pic, "unexpected value type: ~s", expr);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
|
23
src/state.c
23
src/state.c
|
@ -23,18 +23,14 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
|
||||
pic = (pic_state *)malloc(sizeof(pic_state));
|
||||
|
||||
/* root block */
|
||||
pic->blk = NULL;
|
||||
|
||||
/* command line */
|
||||
pic->argc = argc;
|
||||
pic->argv = argv;
|
||||
pic->envp = envp;
|
||||
|
||||
/* root block */
|
||||
pic->blk = (pic_block *)malloc(sizeof(pic_block));
|
||||
pic->blk->prev = NULL;
|
||||
pic->blk->depth = 0;
|
||||
pic->blk->in = pic->blk->out = NULL;
|
||||
pic->blk->refcnt = 1;
|
||||
|
||||
/* prepare VM stack */
|
||||
pic->stbase = pic->sp = (pic_value *)calloc(PIC_STACK_SIZE, sizeof(pic_value));
|
||||
pic->stend = pic->stbase + PIC_STACK_SIZE;
|
||||
|
@ -135,6 +131,12 @@ pic_open(int argc, char *argv[], char **envp)
|
|||
register_renamed_symbol(pic, rEXPORT, "export");
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
|
||||
/* root block */
|
||||
pic->blk = (struct pic_block *)pic_obj_alloc(pic, sizeof(struct pic_block), PIC_TT_BLK);
|
||||
pic->blk->prev = NULL;
|
||||
pic->blk->depth = 0;
|
||||
pic->blk->in = pic->blk->out = NULL;
|
||||
|
||||
pic_init_core(pic);
|
||||
|
||||
/* set library */
|
||||
|
@ -150,7 +152,12 @@ pic_close(pic_state *pic)
|
|||
xh_iter it;
|
||||
|
||||
/* invoke exit handlers */
|
||||
PIC_BLK_EXIT(pic);
|
||||
while (pic->blk) {
|
||||
if (pic->blk->out) {
|
||||
pic_apply0(pic, pic->blk->out);
|
||||
}
|
||||
pic->blk = pic->blk->prev;
|
||||
}
|
||||
|
||||
/* clear out root objects */
|
||||
pic->sp = pic->stbase;
|
||||
|
|
|
@ -47,7 +47,7 @@ pic_system_exit(pic_state *pic)
|
|||
}
|
||||
}
|
||||
|
||||
PIC_BLK_EXIT(pic);
|
||||
pic_close(pic);
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue