unify struct pic_object and union object

This commit is contained in:
Yuichi Nishiwaki 2015-08-05 10:59:52 +09:00
parent ceafb6b600
commit 50dce97bac
2 changed files with 112 additions and 109 deletions

View File

@ -16,8 +16,9 @@ struct heap_page {
struct heap_page *next;
};
union object {
struct pic_object obj;
struct pic_object {
union {
struct pic_basic basic;
struct pic_symbol sym;
struct pic_string str;
struct pic_blob blob;
@ -37,6 +38,7 @@ union object {
struct pic_lib lib;
struct pic_box box;
struct pic_checkpoint cp;
} u;
};
struct pic_heap {
@ -260,7 +262,7 @@ heap_morecore(pic_state *pic)
/* MARK */
static void gc_mark_object(pic_state *, union object *);
static void gc_mark_object(pic_state *, struct pic_object *);
static void
gc_mark(pic_state *pic, pic_value v)
@ -268,49 +270,49 @@ gc_mark(pic_state *pic, pic_value v)
if (! pic_obj_p(v))
return;
gc_mark_object(pic, (union object *)pic_obj_ptr(v));
gc_mark_object(pic, pic_obj_ptr(v));
}
static void
gc_mark_object(pic_state *pic, union object *obj)
gc_mark_object(pic_state *pic, struct pic_object *obj)
{
loop:
if (obj->obj.gc_mark == PIC_GC_MARK)
if (obj->u.basic.gc_mark == PIC_GC_MARK)
return;
obj->obj.gc_mark = PIC_GC_MARK;
obj->u.basic.gc_mark = PIC_GC_MARK;
#define LOOP(o) obj = (union object *)(o); goto loop
#define LOOP(o) obj = (struct pic_object *)(o); goto loop
switch (obj->obj.tt) {
switch (obj->u.basic.tt) {
case PIC_TT_PAIR: {
gc_mark(pic, obj->pair.car);
if (pic_obj_p(obj->pair.cdr)) {
LOOP(pic_obj_ptr(obj->pair.cdr));
gc_mark(pic, obj->u.pair.car);
if (pic_obj_p(obj->u.pair.cdr)) {
LOOP(pic_obj_ptr(obj->u.pair.cdr));
}
break;
}
case PIC_TT_CXT: {
int i;
for (i = 0; i < obj->cxt.regc; ++i) {
gc_mark(pic, obj->cxt.regs[i]);
for (i = 0; i < obj->u.cxt.regc; ++i) {
gc_mark(pic, obj->u.cxt.regs[i]);
}
if (obj->cxt.up) {
LOOP(obj->cxt.up);
if (obj->u.cxt.up) {
LOOP(obj->u.cxt.up);
}
break;
}
case PIC_TT_PROC: {
if (pic_proc_irep_p(&obj->proc)) {
gc_mark_object(pic, (union object *)obj->proc.u.i.irep);
if (obj->proc.u.i.cxt) {
LOOP(obj->proc.u.i.cxt);
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);
}
} else {
if (obj->proc.u.f.env) {
LOOP(obj->proc.u.f.env);
if (obj->u.proc.u.f.env) {
LOOP(obj->u.proc.u.f.env);
}
}
break;
@ -319,10 +321,10 @@ gc_mark_object(pic_state *pic, union object *obj)
break;
}
case PIC_TT_ERROR: {
gc_mark_object(pic, (union object *)obj->err.type);
gc_mark_object(pic, (union object *)obj->err.msg);
gc_mark(pic, obj->err.irrs);
LOOP(obj->err.stack);
gc_mark_object(pic, (struct pic_object *)obj->u.err.type);
gc_mark_object(pic, (struct pic_object *)obj->u.err.msg);
gc_mark(pic, obj->u.err.irrs);
LOOP(obj->u.err.stack);
break;
}
case PIC_TT_STRING: {
@ -330,8 +332,8 @@ gc_mark_object(pic_state *pic, union object *obj)
}
case PIC_TT_VECTOR: {
size_t i;
for (i = 0; i < obj->vec.len; ++i) {
gc_mark(pic, obj->vec.data[i]);
for (i = 0; i < obj->u.vec.len; ++i) {
gc_mark(pic, obj->u.vec.data[i]);
}
break;
}
@ -339,61 +341,61 @@ gc_mark_object(pic_state *pic, union object *obj)
break;
}
case PIC_TT_ID: {
gc_mark(pic, obj->id.var);
LOOP(obj->id.env);
gc_mark(pic, obj->u.id.var);
LOOP(obj->u.id.env);
break;
}
case PIC_TT_ENV: {
khash_t(env) *h = &obj->env.map;
khash_t(env) *h = &obj->u.env.map;
khiter_t it;
for (it = kh_begin(h); it != kh_end(h); ++it) {
if (kh_exist(h, it)) {
gc_mark_object(pic, kh_key(h, it));
gc_mark_object(pic, (union object *)kh_val(h, it));
gc_mark_object(pic, (struct pic_object *)kh_val(h, it));
}
}
if (obj->env.up) {
LOOP(obj->env.up);
if (obj->u.env.up) {
LOOP(obj->u.env.up);
}
break;
}
case PIC_TT_LIB: {
gc_mark(pic, obj->lib.name);
gc_mark_object(pic, (union object *)obj->lib.env);
LOOP(obj->lib.exports);
gc_mark(pic, obj->u.lib.name);
gc_mark_object(pic, (struct pic_object *)obj->u.lib.env);
LOOP(obj->u.lib.exports);
break;
}
case PIC_TT_IREP: {
size_t i;
for (i = 0; i < obj->irep.ilen; ++i) {
gc_mark_object(pic, (union object *)obj->irep.irep[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->irep.plen; ++i) {
gc_mark(pic, obj->irep.pool[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->data.type->mark) {
obj->data.type->mark(pic, obj->data.data, gc_mark);
if (obj->u.data.type->mark) {
obj->u.data.type->mark(pic, obj->u.data.data, gc_mark);
}
LOOP(obj->data.storage);
LOOP(obj->u.data.storage);
break;
}
case PIC_TT_DICT: {
pic_sym *sym;
khiter_t it;
pic_dict_for_each (sym, &obj->dict, it) {
gc_mark_object(pic, (union object *)sym);
gc_mark(pic, pic_dict_ref(pic, &obj->dict, sym));
pic_dict_for_each (sym, &obj->u.dict, it) {
gc_mark_object(pic, (struct pic_object *)sym);
gc_mark(pic, pic_dict_ref(pic, &obj->u.dict, sym));
}
break;
}
case PIC_TT_RECORD: {
LOOP(obj->rec.data);
LOOP(obj->u.rec.data);
break;
}
case PIC_TT_SYMBOL: {
@ -407,20 +409,20 @@ gc_mark_object(pic_state *pic, union object *obj)
break;
}
case PIC_TT_BOX: {
if (pic_obj_p(obj->box.value)) {
LOOP(pic_obj_ptr(obj->box.value));
if (pic_obj_p(obj->u.box.value)) {
LOOP(pic_obj_ptr(obj->u.box.value));
}
break;
}
case PIC_TT_CP: {
if (obj->cp.prev) {
gc_mark_object(pic, (union object *)obj->cp.prev);
if (obj->u.cp.prev) {
gc_mark_object(pic, (struct pic_object *)obj->u.cp.prev);
}
if (obj->cp.in) {
gc_mark_object(pic, (union object *)obj->cp.in);
if (obj->u.cp.in) {
gc_mark_object(pic, (struct pic_object *)obj->u.cp.in);
}
if (obj->cp.out) {
LOOP((struct pic_object *)obj->cp.out);
if (obj->u.cp.out) {
LOOP((struct pic_object *)obj->u.cp.out);
}
break;
}
@ -436,7 +438,7 @@ gc_mark_object(pic_state *pic, union object *obj)
}
}
#define M(x) gc_mark_object(pic, (union object *)pic->x)
#define M(x) gc_mark_object(pic, (struct pic_object *)pic->x)
#define P(x) gc_mark(pic, pic->x)
static void
@ -451,7 +453,7 @@ gc_mark_phase(pic_state *pic)
/* checkpoint */
if (pic->cp) {
gc_mark_object(pic, (union object *)pic->cp);
gc_mark_object(pic, (struct pic_object *)pic->cp);
}
/* stack */
@ -462,18 +464,18 @@ gc_mark_phase(pic_state *pic)
/* callinfo */
for (ci = pic->ci; ci != pic->cibase; --ci) {
if (ci->cxt) {
gc_mark_object(pic, (union object *)ci->cxt);
gc_mark_object(pic, (struct pic_object *)ci->cxt);
}
}
/* exception handlers */
for (xhandler = pic->xpbase; xhandler != pic->xp; ++xhandler) {
gc_mark_object(pic, (union object *)*xhandler);
gc_mark_object(pic, (struct pic_object *)*xhandler);
}
/* arena */
for (j = 0; j < pic->arena_idx; ++j) {
gc_mark_object(pic, (union object *)pic->arena[j]);
gc_mark_object(pic, (struct pic_object *)pic->arena[j]);
}
/* mark reserved symbols */
@ -497,17 +499,17 @@ gc_mark_phase(pic_state *pic)
/* global variables */
if (pic->globals) {
gc_mark_object(pic, (union object *)pic->globals);
gc_mark_object(pic, (struct pic_object *)pic->globals);
}
/* macro objects */
if (pic->macros) {
gc_mark_object(pic, (union object *)pic->macros);
gc_mark_object(pic, (struct pic_object *)pic->macros);
}
/* attribute table */
if (pic->attrs) {
gc_mark_object(pic, (union object *)pic->attrs);
gc_mark_object(pic, (struct pic_object *)pic->attrs);
}
/* error object */
@ -540,8 +542,8 @@ gc_mark_phase(pic_state *pic)
continue;
key = kh_key(h, it);
val = kh_val(h, it);
if (key->gc_mark == PIC_GC_MARK) {
if (pic_obj_p(val) && pic_obj_ptr(val)->gc_mark == PIC_GC_UNMARK) {
if (key->u.basic.gc_mark == PIC_GC_MARK) {
if (pic_obj_p(val) && pic_obj_ptr(val)->u.basic.gc_mark == PIC_GC_UNMARK) {
gc_mark(pic, val);
++j;
}
@ -555,47 +557,47 @@ gc_mark_phase(pic_state *pic)
/* SWEEP */
static void
gc_finalize_object(pic_state *pic, union object *obj)
gc_finalize_object(pic_state *pic, struct pic_object *obj)
{
switch (obj->obj.tt) {
switch (obj->u.basic.tt) {
case PIC_TT_VECTOR: {
pic_free(pic, obj->vec.data);
pic_free(pic, obj->u.vec.data);
break;
}
case PIC_TT_BLOB: {
pic_free(pic, obj->blob.data);
pic_free(pic, obj->u.blob.data);
break;
}
case PIC_TT_STRING: {
pic_rope_decref(pic, obj->str.rope);
pic_rope_decref(pic, obj->u.str.rope);
break;
}
case PIC_TT_ENV: {
kh_destroy(env, &obj->env.map);
kh_destroy(env, &obj->u.env.map);
break;
}
case PIC_TT_IREP: {
pic_free(pic, obj->irep.code);
pic_free(pic, obj->irep.irep);
pic_free(pic, obj->irep.pool);
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->data.type->dtor) {
obj->data.type->dtor(pic, obj->data.data);
if (obj->u.data.type->dtor) {
obj->u.data.type->dtor(pic, obj->u.data.data);
}
break;
}
case PIC_TT_DICT: {
kh_destroy(dict, &obj->dict.hash);
kh_destroy(dict, &obj->u.dict.hash);
break;
}
case PIC_TT_SYMBOL: {
pic_free(pic, (void *)obj->sym.cstr);
pic_free(pic, (void *)obj->u.sym.cstr);
break;
}
case PIC_TT_REG: {
kh_destroy(reg, &obj->reg.hash);
kh_destroy(reg, &obj->u.reg.hash);
break;
}
@ -627,7 +629,7 @@ static size_t
gc_sweep_page(pic_state *pic, struct heap_page *page)
{
union header *bp, *p, *head = NULL, *tail = NULL;
union object *obj;
struct pic_object *obj;
size_t alive = 0;
for (bp = page->basep; ; bp = bp->s.ptr) {
@ -636,9 +638,9 @@ gc_sweep_page(pic_state *pic, struct heap_page *page)
if (p < page->basep || page->endp <= p) {
goto escape;
}
obj = (union object *)(p + 1);
if (obj->obj.gc_mark == PIC_GC_MARK) {
obj->obj.gc_mark = PIC_GC_UNMARK;
obj = (struct pic_object *)(p + 1);
if (obj->u.basic.gc_mark == PIC_GC_MARK) {
obj->u.basic.gc_mark = PIC_GC_UNMARK;
alive += p->s.size;
} else {
if (head == NULL) {
@ -658,7 +660,7 @@ gc_sweep_page(pic_state *pic, struct heap_page *page)
while (head != NULL) {
p = head;
head = head->s.ptr;
gc_finalize_object(pic, (union object *)(p + 1));
gc_finalize_object(pic, (struct pic_object *)(p + 1));
heap_free(pic, p + 1);
}
@ -683,7 +685,7 @@ gc_sweep_phase(pic_state *pic)
if (! kh_exist(h, it))
continue;
obj = kh_key(h, it);
if (obj->gc_mark == PIC_GC_UNMARK) {
if (obj->u.basic.gc_mark == PIC_GC_UNMARK) {
kh_del(reg, h, it);
}
}
@ -743,8 +745,8 @@ pic_obj_alloc_unsafe(pic_state *pic, size_t size, enum pic_tt tt)
pic_panic(pic, "GC memory exhausted");
}
}
obj->gc_mark = PIC_GC_UNMARK;
obj->tt = tt;
obj->u.basic.gc_mark = PIC_GC_UNMARK;
obj->u.basic.tt = tt;
return obj;
}

View File

@ -166,10 +166,11 @@ enum pic_tt {
enum pic_tt tt; \
char gc_mark;
struct pic_object {
struct pic_basic {
PIC_OBJECT_HEADER
};
struct pic_object;
struct pic_symbol;
struct pic_pair;
struct pic_string;
@ -255,7 +256,7 @@ pic_type(pic_value v)
case PIC_VTYPE_EOF:
return PIC_TT_EOF;
case PIC_VTYPE_HEAP:
return ((struct pic_object *)pic_ptr(v))->tt;
return ((struct pic_basic *)pic_ptr(v))->tt;
}
PIC_UNREACHABLE();