unify struct pic_object and union object
This commit is contained in:
parent
ceafb6b600
commit
50dce97bac
178
extlib/benz/gc.c
178
extlib/benz/gc.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue