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