unify struct object and struct basic
This commit is contained in:
parent
f69bc42187
commit
86e4eac543
127
lib/gc.c
127
lib/gc.c
|
@ -7,24 +7,6 @@
|
|||
#include "object.h"
|
||||
#include "state.h"
|
||||
|
||||
struct object {
|
||||
union {
|
||||
struct basic basic;
|
||||
struct symbol sym;
|
||||
struct string str;
|
||||
struct blob blob;
|
||||
struct pair pair;
|
||||
struct vector vec;
|
||||
struct dict dict;
|
||||
struct attr attr;
|
||||
struct data data;
|
||||
struct record rec;
|
||||
struct proc proc;
|
||||
struct frame frame;
|
||||
struct irep irep;
|
||||
} u;
|
||||
};
|
||||
|
||||
#if PIC_USE_LIBC
|
||||
void *
|
||||
pic_default_allocf(void *PIC_UNUSED(userdata), void *ptr, size_t size)
|
||||
|
@ -107,9 +89,9 @@ pic_alloca(pic_state *pic, size_t n)
|
|||
|
||||
/* GC */
|
||||
|
||||
#define is_alive(obj) ((obj)->u.basic.tt & GC_MARK)
|
||||
#define mark(obj) ((obj)->u.basic.tt |= GC_MARK)
|
||||
#define unmark(obj) ((obj)->u.basic.tt &= ~GC_MARK)
|
||||
#define is_alive(obj) ((obj)->tt & GC_MARK)
|
||||
#define mark(obj) ((obj)->tt |= GC_MARK)
|
||||
#define unmark(obj) ((obj)->tt &= ~GC_MARK)
|
||||
|
||||
static void gc_mark_object(pic_state *, struct object *);
|
||||
|
||||
|
@ -136,75 +118,83 @@ gc_mark_object(pic_state *pic, struct object *obj)
|
|||
|
||||
switch (obj_type(obj)) {
|
||||
case PIC_TYPE_PAIR: {
|
||||
gc_mark(pic, obj->u.pair.car);
|
||||
if (pic_obj_p(pic, obj->u.pair.cdr)) {
|
||||
LOOP(pic_ptr(pic, obj->u.pair.cdr));
|
||||
struct pair *pair = (struct pair *) obj;
|
||||
gc_mark(pic, pair->car);
|
||||
if (pic_obj_p(pic, pair->cdr)) {
|
||||
LOOP(pic_ptr(pic, pair->cdr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_FRAME: {
|
||||
struct frame *frame = (struct frame *) obj;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < obj->u.frame.regc; ++i) {
|
||||
gc_mark(pic, obj->u.frame.regs[i]);
|
||||
for (i = 0; i < frame->regc; ++i) {
|
||||
gc_mark(pic, frame->regs[i]);
|
||||
}
|
||||
if (obj->u.frame.up) {
|
||||
LOOP(obj->u.frame.up);
|
||||
if (frame->up) {
|
||||
LOOP(frame->up);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_PROC_FUNC: {
|
||||
if (obj->u.proc.env) {
|
||||
LOOP(obj->u.proc.env);
|
||||
struct proc *proc = (struct proc *) obj;
|
||||
if (proc->env) {
|
||||
LOOP(proc->env);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_PROC_IREP: {
|
||||
if (obj->u.proc.env) {
|
||||
gc_mark_object(pic, (struct object *)obj->u.proc.env);
|
||||
struct proc *proc = (struct proc *) obj;
|
||||
if (proc->env) {
|
||||
gc_mark_object(pic, (struct object *) proc->env);
|
||||
}
|
||||
LOOP(obj->u.proc.u.irep);
|
||||
LOOP(proc->u.irep);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_IREP: {
|
||||
struct irep *irep = (struct irep *) obj;
|
||||
size_t i;
|
||||
for (i = 0; i < obj->u.irep.objc; ++i) {
|
||||
gc_mark(pic, obj->u.irep.obj[i]);
|
||||
for (i = 0; i < irep->objc; ++i) {
|
||||
gc_mark(pic, irep->obj[i]);
|
||||
}
|
||||
for (i = 0; i < obj->u.irep.irepc; ++i) {
|
||||
gc_mark_object(pic, (struct object *)obj->u.irep.irep[i]);
|
||||
for (i = 0; i < irep->irepc; ++i) {
|
||||
gc_mark_object(pic, (struct object *) irep->irep[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_VECTOR: {
|
||||
struct vector *vec = (struct vector *) obj;
|
||||
int i;
|
||||
for (i = 0; i < obj->u.vec.len; ++i) {
|
||||
gc_mark(pic, obj->u.vec.data[i]);
|
||||
for (i = 0; i < vec->len; ++i) {
|
||||
gc_mark(pic, vec->data[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_DICT: {
|
||||
pic_value key, val;
|
||||
int it = 0;
|
||||
|
||||
while (pic_dict_next(pic, obj_value(pic, &obj->u.dict), &it, &key, &val)) {
|
||||
gc_mark(pic, key);
|
||||
gc_mark(pic, val);
|
||||
struct dict *dict = (struct dict *) obj;
|
||||
khash_t(dict) *h = &dict->hash;
|
||||
int it;
|
||||
for (it = 0; it != kh_end(h); ++it) {
|
||||
if (kh_exist(h, it)) {
|
||||
gc_mark_object(pic, (struct object *) kh_key(h, it));
|
||||
gc_mark(pic, kh_val(h, it));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_RECORD: {
|
||||
gc_mark(pic, obj->u.rec.datum);
|
||||
LOOP(obj->u.rec.type);
|
||||
struct record *rec = (struct record *) obj;
|
||||
gc_mark(pic, rec->datum);
|
||||
LOOP(rec->type);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_SYMBOL: {
|
||||
LOOP(obj->u.sym.str);
|
||||
struct symbol *sym = (struct symbol *) obj;
|
||||
LOOP(sym->str);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_ATTR: {
|
||||
struct attr *attr = (struct attr *)obj;
|
||||
|
||||
struct attr *attr = (struct attr *) obj;
|
||||
attr->prev = pic->gc_attrs;
|
||||
pic->gc_attrs = attr;
|
||||
break;
|
||||
|
@ -225,25 +215,30 @@ gc_finalize_object(pic_state *pic, struct object *obj)
|
|||
{
|
||||
switch (obj_type(obj)) {
|
||||
case PIC_TYPE_VECTOR: {
|
||||
pic_free(pic, obj->u.vec.data);
|
||||
struct vector *vec = (struct vector *) obj;
|
||||
pic_free(pic, vec->data);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_BLOB: {
|
||||
pic_free(pic, obj->u.blob.data);
|
||||
struct blob *blob = (struct blob *) obj;
|
||||
pic_free(pic, blob->data);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_STRING: {
|
||||
pic_rope_decref(pic, obj->u.str.rope);
|
||||
struct string *str = (struct string *) obj;
|
||||
pic_rope_decref(pic, str->rope);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_DATA: {
|
||||
if (obj->u.data.type->dtor) {
|
||||
obj->u.data.type->dtor(pic, obj->u.data.data);
|
||||
struct data *data = (struct data *) obj;
|
||||
if (data->type->dtor) {
|
||||
data->type->dtor(pic, data->data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_DICT: {
|
||||
kh_destroy(dict, &obj->u.dict.hash);
|
||||
struct dict *dict = (struct dict *) obj;
|
||||
kh_destroy(dict, &dict->hash);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_SYMBOL: {
|
||||
|
@ -251,11 +246,12 @@ gc_finalize_object(pic_state *pic, struct object *obj)
|
|||
break;
|
||||
}
|
||||
case PIC_TYPE_ATTR: {
|
||||
kh_destroy(attr, &obj->u.attr.hash);
|
||||
struct attr *attr = (struct attr *) obj;
|
||||
kh_destroy(attr, &attr->hash);
|
||||
break;
|
||||
}
|
||||
case PIC_TYPE_IREP: {
|
||||
struct irep *irep = &obj->u.irep;
|
||||
struct irep *irep = (struct irep *) obj;
|
||||
if ((irep->flags & IREP_CODE_STATIC) == 0) {
|
||||
pic_free(pic, (code_t *) irep->code);
|
||||
}
|
||||
|
@ -264,7 +260,8 @@ gc_finalize_object(pic_state *pic, struct object *obj)
|
|||
break;
|
||||
}
|
||||
case PIC_TYPE_FRAME: {
|
||||
pic_free(pic, obj->u.frame.regs);
|
||||
struct frame *frame = (struct frame *) obj;
|
||||
pic_free(pic, frame->regs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -367,14 +364,14 @@ pic_gc(pic_state *pic)
|
|||
|
||||
/* reclaim dead objects */
|
||||
|
||||
for (prev = (struct object *) &pic->gc_head, obj = prev->u.basic.next; obj != (struct object *) &pic->gc_head; prev = obj, obj = next) {
|
||||
next = obj->u.basic.next;
|
||||
for (prev = &pic->gc_head, obj = prev->next; obj != &pic->gc_head; prev = obj, obj = next) {
|
||||
next = obj->next;
|
||||
if (is_alive(obj)) {
|
||||
unmark(obj);
|
||||
} else {
|
||||
gc_finalize_object(pic, obj);
|
||||
pic_free(pic, obj);
|
||||
prev->u.basic.next = next;
|
||||
prev->next = next;
|
||||
obj = prev;
|
||||
}
|
||||
}
|
||||
|
@ -413,8 +410,8 @@ pic_obj_alloc_unsafe(pic_state *pic, int type)
|
|||
}
|
||||
|
||||
obj = pic_malloc(pic, size);
|
||||
obj->u.basic.tt = type;
|
||||
obj->u.basic.next = pic->gc_head.next;
|
||||
obj->tt = type;
|
||||
obj->next = pic->gc_head.next;
|
||||
pic->gc_head.next = obj;
|
||||
|
||||
pic->gc_count += size;
|
||||
|
|
|
@ -18,9 +18,7 @@ extern "C" {
|
|||
#define TYPE_MASK 0x7f
|
||||
#define GC_MARK 0x80
|
||||
|
||||
struct object; /* defined in gc.c */
|
||||
|
||||
struct basic {
|
||||
struct object {
|
||||
OBJECT_HEADER
|
||||
};
|
||||
|
||||
|
@ -158,7 +156,7 @@ struct proc {
|
|||
PIC_STATIC_INLINE int
|
||||
obj_type(void *ptr)
|
||||
{
|
||||
return ((struct basic *) ptr)->tt & TYPE_MASK;
|
||||
return ((struct object *) ptr)->tt & TYPE_MASK;
|
||||
}
|
||||
|
||||
PIC_STATIC_INLINE pic_value
|
||||
|
|
|
@ -45,7 +45,7 @@ struct pic_state {
|
|||
size_t arena_size;
|
||||
|
||||
bool gc_enable;
|
||||
struct basic gc_head;
|
||||
struct object gc_head;
|
||||
struct attr *gc_attrs;
|
||||
size_t gc_count;
|
||||
|
||||
|
|
Loading…
Reference in New Issue