TCO for gc_mark_object

This commit is contained in:
Yuichi Nishiwaki 2015-07-20 14:24:58 +09:00
parent 7dc26dd674
commit e6c35764dd
1 changed files with 21 additions and 14 deletions

View File

@ -276,16 +276,23 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
{ {
union header *p; union header *p;
loop:
p = ((union header *)obj) - 1; p = ((union header *)obj) - 1;
if (gc_is_marked(p)) if (gc_is_marked(p))
return; return;
p->s.mark = PIC_GC_MARK; p->s.mark = PIC_GC_MARK;
#define LOOP(o) obj = (o); goto loop
switch (obj->tt) { switch (obj->tt) {
case PIC_TT_PAIR: { case PIC_TT_PAIR: {
gc_mark(pic, ((struct pic_pair *)obj)->car); struct pic_pair *pair = (struct pic_pair *)obj;
gc_mark(pic, ((struct pic_pair *)obj)->cdr); gc_mark(pic, pair->car);
if (pic_obj_p(pair->cdr)) {
LOOP(pic_obj_ptr(pair->cdr));
}
break; break;
} }
case PIC_TT_CXT: { case PIC_TT_CXT: {
@ -296,7 +303,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
gc_mark(pic, cxt->regs[i]); gc_mark(pic, cxt->regs[i]);
} }
if (cxt->up) { if (cxt->up) {
gc_mark_object(pic, (struct pic_object *)cxt->up); LOOP((struct pic_object *)cxt->up);
} }
break; break;
} }
@ -305,11 +312,11 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
if (pic_proc_irep_p(proc)) { if (pic_proc_irep_p(proc)) {
gc_mark_object(pic, (struct pic_object *)proc->u.i.irep); gc_mark_object(pic, (struct pic_object *)proc->u.i.irep);
if (proc->u.i.cxt) { if (proc->u.i.cxt) {
gc_mark_object(pic, (struct pic_object *)proc->u.i.cxt); LOOP((struct pic_object *)proc->u.i.cxt);
} }
} else { } else {
if (proc->u.f.env) { if (proc->u.f.env) {
gc_mark_object(pic, (struct pic_object *)proc->u.f.env); LOOP((struct pic_object *)proc->u.f.env);
} }
} }
break; break;
@ -322,7 +329,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
gc_mark_object(pic, (struct pic_object *)err->type); gc_mark_object(pic, (struct pic_object *)err->type);
gc_mark_object(pic, (struct pic_object *)err->msg); gc_mark_object(pic, (struct pic_object *)err->msg);
gc_mark(pic, err->irrs); gc_mark(pic, err->irrs);
gc_mark_object(pic, (struct pic_object *)err->stack); LOOP((struct pic_object *)err->stack);
break; break;
} }
case PIC_TT_STRING: { case PIC_TT_STRING: {
@ -341,7 +348,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
case PIC_TT_ID: { case PIC_TT_ID: {
struct pic_id *id = (struct pic_id *)obj; struct pic_id *id = (struct pic_id *)obj;
gc_mark(pic, id->var); gc_mark(pic, id->var);
gc_mark_object(pic, (struct pic_object *)id->env); LOOP((struct pic_object *)id->env);
break; break;
} }
case PIC_TT_ENV: { case PIC_TT_ENV: {
@ -349,22 +356,22 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
khash_t(env) *h = &env->map; khash_t(env) *h = &env->map;
khiter_t it; khiter_t it;
if (env->up) {
gc_mark_object(pic, (struct pic_object *)env->up);
}
for (it = kh_begin(h); it != kh_end(h); ++it) { for (it = kh_begin(h); it != kh_end(h); ++it) {
if (kh_exist(h, it)) { if (kh_exist(h, it)) {
gc_mark_object(pic, kh_key(h, it)); gc_mark_object(pic, kh_key(h, it));
gc_mark_object(pic, (struct pic_object *)kh_val(h, it)); gc_mark_object(pic, (struct pic_object *)kh_val(h, it));
} }
} }
if (env->up) {
LOOP((struct pic_object *)env->up);
}
break; break;
} }
case PIC_TT_LIB: { case PIC_TT_LIB: {
struct pic_lib *lib = (struct pic_lib *)obj; struct pic_lib *lib = (struct pic_lib *)obj;
gc_mark(pic, lib->name); gc_mark(pic, lib->name);
gc_mark_object(pic, (struct pic_object *)lib->env); gc_mark_object(pic, (struct pic_object *)lib->env);
gc_mark_object(pic, (struct pic_object *)lib->exports); LOOP((struct pic_object *)lib->exports);
break; break;
} }
case PIC_TT_IREP: { case PIC_TT_IREP: {
@ -382,10 +389,10 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
case PIC_TT_DATA: { case PIC_TT_DATA: {
struct pic_data *data = (struct pic_data *)obj; struct pic_data *data = (struct pic_data *)obj;
gc_mark_object(pic, (struct pic_object *)data->storage);
if (data->type->mark) { if (data->type->mark) {
data->type->mark(pic, data->data, gc_mark); data->type->mark(pic, data->data, gc_mark);
} }
LOOP((struct pic_object *)data->storage);
break; break;
} }
case PIC_TT_DICT: { case PIC_TT_DICT: {
@ -402,7 +409,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
case PIC_TT_RECORD: { case PIC_TT_RECORD: {
struct pic_record *rec = (struct pic_record *)obj; struct pic_record *rec = (struct pic_record *)obj;
gc_mark_object(pic, (struct pic_object *)rec->data); LOOP((struct pic_object *)rec->data);
break; break;
} }
case PIC_TT_SYMBOL: { case PIC_TT_SYMBOL: {
@ -425,7 +432,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
gc_mark_object(pic, (struct pic_object *)cp->in); gc_mark_object(pic, (struct pic_object *)cp->in);
} }
if (cp->out) { if (cp->out) {
gc_mark_object(pic, (struct pic_object *)cp->out); LOOP((struct pic_object *)cp->out);
} }
break; break;
} }