From 619a014adf4af34d1506efeb5b1d64b17e8358eb Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 12 Apr 2017 13:18:06 +0900 Subject: [PATCH] calculate object size from type --- lib/blob.c | 2 +- lib/data.c | 2 +- lib/dict.c | 2 +- lib/error.c | 2 +- lib/ext/load.c | 2 +- lib/gc.c | 49 ++++++++++++++++++++++++++++++++++++------------- lib/object.h | 2 +- lib/pair.c | 2 +- lib/port.c | 2 +- lib/proc.c | 8 ++++---- lib/record.c | 2 +- lib/string.c | 2 +- lib/symbol.c | 2 +- lib/vector.c | 2 +- lib/weak.c | 2 +- 15 files changed, 53 insertions(+), 30 deletions(-) diff --git a/lib/blob.c b/lib/blob.c index 22a9c7ed..1462e1a3 100644 --- a/lib/blob.c +++ b/lib/blob.c @@ -10,7 +10,7 @@ pic_blob_value(pic_state *pic, const unsigned char *buf, int len) { struct blob *bv; - bv = (struct blob *)pic_obj_alloc(pic, sizeof(struct blob), PIC_TYPE_BLOB); + bv = (struct blob *)pic_obj_alloc(pic, PIC_TYPE_BLOB); bv->data = pic_malloc(pic, len); bv->len = len; if (buf) { diff --git a/lib/data.c b/lib/data.c index 571a41aa..122a46ea 100644 --- a/lib/data.c +++ b/lib/data.c @@ -25,7 +25,7 @@ pic_data_value(pic_state *pic, void *userdata, const pic_data_type *type) { struct data *data; - data = (struct data *)pic_obj_alloc(pic, sizeof(struct data), PIC_TYPE_DATA); + data = (struct data *)pic_obj_alloc(pic, PIC_TYPE_DATA); data->type = type; data->data = userdata; diff --git a/lib/dict.c b/lib/dict.c index eb7a6710..54a01ac6 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -12,7 +12,7 @@ pic_make_dict(pic_state *pic) { struct dict *dict; - dict = (struct dict *)pic_obj_alloc(pic, sizeof(struct dict), PIC_TYPE_DICT); + dict = (struct dict *)pic_obj_alloc(pic, PIC_TYPE_DICT); kh_init(dict, &dict->hash); return obj_value(pic, dict); } diff --git a/lib/error.c b/lib/error.c index 23c2f000..3e1331a4 100644 --- a/lib/error.c +++ b/lib/error.c @@ -85,7 +85,7 @@ pic_make_error(pic_state *pic, const char *type, const char *msg, pic_value irrs struct error *e; pic_value ty = pic_intern_cstr(pic, type); - e = (struct error *)pic_obj_alloc(pic, sizeof(struct error), PIC_TYPE_ERROR); + e = (struct error *)pic_obj_alloc(pic, PIC_TYPE_ERROR); e->type = sym_ptr(pic, ty); e->msg = str_ptr(pic, pic_cstr_value(pic, msg)); e->irrs = irrs; diff --git a/lib/ext/load.c b/lib/ext/load.c index 9b6a033b..6cfd5df2 100644 --- a/lib/ext/load.c +++ b/lib/ext/load.c @@ -416,7 +416,7 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) struct irep *irep; /* create irep */ - irep = (struct irep *)pic_obj_alloc(pic, sizeof(struct irep), PIC_TYPE_IREP); + irep = (struct irep *)pic_obj_alloc(pic, PIC_TYPE_IREP); irep->varg = pic_sym_p(pic, cxt->rest); irep->argc = pic_vec_len(pic, cxt->args) + 1; irep->localc = pic_vec_len(pic, cxt->locals); diff --git a/lib/gc.c b/lib/gc.c index e36b9834..20a4f9d5 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -439,15 +439,37 @@ gc_finalize_object(pic_state *pic, struct object *obj) } } -static void * -heap_alloc(pic_state *pic, size_t size) +static size_t +type2size(int type) +{ + switch (type) { + case PIC_TYPE_VECTOR: return sizeof(struct vector); + case PIC_TYPE_BLOB: return sizeof(struct blob); + case PIC_TYPE_STRING: return sizeof(struct string); + case PIC_TYPE_DATA: return sizeof(struct data); + case PIC_TYPE_DICT: return sizeof(struct dict); + case PIC_TYPE_SYMBOL: return sizeof(struct symbol); + case PIC_TYPE_WEAK: return sizeof(struct weak); + case PIC_TYPE_IREP: return sizeof(struct irep); + case PIC_TYPE_PORT: return sizeof(struct port); + case PIC_TYPE_PAIR: return sizeof(struct pair); + case PIC_TYPE_FRAME: return sizeof(struct frame); + case PIC_TYPE_ERROR: return sizeof(struct error); + case PIC_TYPE_RECORD: return sizeof(struct record); + case PIC_TYPE_PROC_FUNC: return sizeof(struct proc); + case PIC_TYPE_PROC_IREP: return sizeof(struct proc); + default: PIC_UNREACHABLE(); + } +} + +static struct object * +obj_alloc(pic_state *pic, int type) { union header *p, *prevp; + struct object *obj; size_t nunits; - assert(size > 0); - - nunits = (size + sizeof(union header) - 1) / sizeof(union header) + 1; + nunits = (type2size(type) + sizeof(union header) - 1) / sizeof(union header) + 1; prevp = pic->heap->freep; for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) { @@ -468,7 +490,9 @@ heap_alloc(pic_state *pic, size_t size) } pic->heap->freep = prevp; - return (void *)(p + 1); + obj = (struct object *)(p + 1); + obj->u.basic.tt = type; + return obj; } static void @@ -623,7 +647,7 @@ pic_gc(pic_state *pic) } struct object * -pic_obj_alloc_unsafe(pic_state *pic, size_t size, int type) +pic_obj_alloc_unsafe(pic_state *pic, int type) { struct object *obj; @@ -631,28 +655,27 @@ pic_obj_alloc_unsafe(pic_state *pic, size_t size, int type) pic_gc(pic); #endif - obj = (struct object *)heap_alloc(pic, size); + obj = obj_alloc(pic, type); if (obj == NULL) { pic_gc(pic); - obj = (struct object *)heap_alloc(pic, size); + obj = obj_alloc(pic, type); if (obj == NULL) { heap_morecore(pic); - obj = (struct object *)heap_alloc(pic, size); + obj = obj_alloc(pic, type); if (obj == NULL) pic_panic(pic, "GC memory exhausted"); } } - obj->u.basic.tt = type; return obj; } struct object * -pic_obj_alloc(pic_state *pic, size_t size, int type) +pic_obj_alloc(pic_state *pic, int type) { struct object *obj; - obj = pic_obj_alloc_unsafe(pic, size, type); + obj = pic_obj_alloc_unsafe(pic, type); gc_protect(pic, obj); return obj; diff --git a/lib/object.h b/lib/object.h index 2aae3d00..096da7e8 100644 --- a/lib/object.h +++ b/lib/object.h @@ -242,7 +242,7 @@ DEFPTR(irep, struct irep) #undef pic_data_p #undef pic_port_p -struct object *pic_obj_alloc(pic_state *, size_t, int type); +struct object *pic_obj_alloc(pic_state *, int type); pic_value pic_make_proc_func(pic_state *, pic_func_t, int, pic_value *); pic_value pic_make_proc_irep(pic_state *, struct irep *, struct frame *); diff --git a/lib/pair.c b/lib/pair.c index a1380e99..39c8643e 100644 --- a/lib/pair.c +++ b/lib/pair.c @@ -10,7 +10,7 @@ pic_cons(pic_state *pic, pic_value car, pic_value cdr) { struct pair *pair; - pair = (struct pair *)pic_obj_alloc(pic, sizeof(struct pair), PIC_TYPE_PAIR); + pair = (struct pair *)pic_obj_alloc(pic, PIC_TYPE_PAIR); pair->car = car; pair->cdr = cdr; diff --git a/lib/port.c b/lib/port.c index dbb52d51..997cb814 100644 --- a/lib/port.c +++ b/lib/port.c @@ -15,7 +15,7 @@ pic_funopen(pic_state *pic, void *cookie, const pic_port_type *type) { struct port *port; - port = (struct port *)pic_obj_alloc(pic, sizeof(struct port), PIC_TYPE_PORT); + port = (struct port *)pic_obj_alloc(pic, PIC_TYPE_PORT); port->file.cnt = 0; port->file.base = NULL; port->file.flag = type->read ? FILE_READ : FILE_WRITE; diff --git a/lib/proc.c b/lib/proc.c index 8751c8a9..913a6421 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -39,7 +39,7 @@ pic_make_proc_func(pic_state *pic, pic_func_t func, int n, pic_value *env) if (n > 0) { int i; - fp = (struct frame *)pic_obj_alloc(pic, sizeof(struct frame), PIC_TYPE_FRAME); + fp = (struct frame *)pic_obj_alloc(pic, PIC_TYPE_FRAME); fp->storage = pic_malloc(pic, sizeof(pic_value) * n); fp->regc = n; fp->regs = fp->storage; @@ -49,7 +49,7 @@ pic_make_proc_func(pic_state *pic, pic_func_t func, int n, pic_value *env) } } - proc = (struct proc *)pic_obj_alloc(pic, sizeof(struct proc), PIC_TYPE_PROC_FUNC); + proc = (struct proc *)pic_obj_alloc(pic, PIC_TYPE_PROC_FUNC); proc->u.func = func; proc->fp = fp; return obj_value(pic, proc); @@ -60,7 +60,7 @@ pic_make_proc_irep(pic_state *pic, struct irep *irep, struct frame *fp) { struct proc *proc; - proc = (struct proc *)pic_obj_alloc(pic, sizeof(struct proc), PIC_TYPE_PROC_IREP); + proc = (struct proc *)pic_obj_alloc(pic, PIC_TYPE_PROC_IREP); proc->u.irep = irep; proc->fp = fp; return obj_value(pic, proc); @@ -351,7 +351,7 @@ vm_push_cxt(pic_state *pic) { struct callinfo *ci = pic->ci; - ci->cxt = (struct frame *)pic_obj_alloc(pic, sizeof(struct frame), PIC_TYPE_FRAME); + ci->cxt = (struct frame *)pic_obj_alloc(pic, PIC_TYPE_FRAME); ci->cxt->storage = pic_malloc(pic, sizeof(pic_value) * ci->regc); ci->cxt->up = ci->up; ci->cxt->regc = ci->regc; diff --git a/lib/record.c b/lib/record.c index d98707fc..09fb2e1f 100644 --- a/lib/record.c +++ b/lib/record.c @@ -10,7 +10,7 @@ pic_make_record(pic_state *pic, pic_value type, pic_value datum) { struct record *rec; - rec = (struct record *)pic_obj_alloc(pic, sizeof(struct record), PIC_TYPE_RECORD); + rec = (struct record *)pic_obj_alloc(pic, PIC_TYPE_RECORD); rec->type = sym_ptr(pic, type); rec->datum = datum; diff --git a/lib/string.c b/lib/string.c index b7933340..f5ae1549 100644 --- a/lib/string.c +++ b/lib/string.c @@ -117,7 +117,7 @@ make_str(pic_state *pic, struct rope *rope) { struct string *str; - str = (struct string *)pic_obj_alloc(pic, sizeof(struct string), PIC_TYPE_STRING); + str = (struct string *)pic_obj_alloc(pic, PIC_TYPE_STRING); str->rope = rope; /* delegate ownership */ return obj_value(pic, str); diff --git a/lib/symbol.c b/lib/symbol.c index 0f99660e..35ad7ada 100644 --- a/lib/symbol.c +++ b/lib/symbol.c @@ -29,7 +29,7 @@ pic_intern(pic_state *pic, pic_value str) kh_val(h, it) = NULL; /* dummy */ - sym = (struct symbol *)pic_obj_alloc(pic, sizeof(struct symbol), PIC_TYPE_SYMBOL); + sym = (struct symbol *)pic_obj_alloc(pic, PIC_TYPE_SYMBOL); sym->str = str_ptr(pic, str); kh_val(h, it) = sym; diff --git a/lib/vector.c b/lib/vector.c index 2925f884..b5ecc23a 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -11,7 +11,7 @@ pic_make_vec(pic_state *pic, int len, pic_value *argv) struct vector *vec; int i; - vec = (struct vector *)pic_obj_alloc(pic, sizeof(struct vector), PIC_TYPE_VECTOR); + vec = (struct vector *)pic_obj_alloc(pic, PIC_TYPE_VECTOR); vec->len = len; vec->data = (pic_value *)pic_malloc(pic, sizeof(pic_value) * len); if (argv == NULL) { diff --git a/lib/weak.c b/lib/weak.c index a1a4a606..275b8eaa 100644 --- a/lib/weak.c +++ b/lib/weak.c @@ -41,7 +41,7 @@ pic_make_weak(pic_state *pic) { struct weak *weak; - weak = (struct weak *)pic_obj_alloc(pic, sizeof(struct weak), PIC_TYPE_WEAK); + weak = (struct weak *)pic_obj_alloc(pic, PIC_TYPE_WEAK); weak->prev = NULL; kh_init(weak, &weak->hash); return pic_lambda(pic, weak_call, 1, obj_value(pic, weak));