From 26a0fe0a1bdf92c017e75a9fdf48cc54a8deca68 Mon Sep 17 00:00:00 2001 From: yoyo Date: Sun, 1 Sep 2024 18:06:18 +0900 Subject: [PATCH] add gc to function param --- dat.h | 1 + eval.c | 12 ++--- fn.h | 25 +++++----- gc.c | 140 ++++++++++++++++++++++++++++++------------------------- main.c | 7 +-- obj.c | 34 +++++++------- parser.c | 18 +++---- str.c | 2 +- 8 files changed, 126 insertions(+), 113 deletions(-) diff --git a/dat.h b/dat.h index d2920bf..3510c8d 100644 --- a/dat.h +++ b/dat.h @@ -79,6 +79,7 @@ typedef struct }; }GC; +extern GC *gc; extern Object Nil; extern Object True; extern Object False; diff --git a/eval.c b/eval.c index fceea69..afdd18a 100644 --- a/eval.c +++ b/eval.c @@ -40,9 +40,9 @@ enter(Object *env, Object *vars, Object *args) error("Cna't apply function argment dose not match"); Object *id = vars->car; Object *val = args->car; - map = newacons(id, val, map); + map = newacons(gc, id, val, map); } - return newenv(&Nil, map, env); + return newenv(gc, &Nil, map, env); } Object* @@ -56,7 +56,7 @@ fnlambda(Object *env, Object *l) } Object *params = l->car; Object *body = l->cdr; - return newfn(env, params, body); + return newfn(gc, env, params, body); } Object* @@ -79,7 +79,7 @@ fndefine(Object *env, Object *list) Object *obj = find(env, list->car); if(obj) return obj->cdr = val; - return env->vars = newacons(list->car, val, env->vars); + return env->vars = newacons(gc, list->car, val, env->vars); } Object* @@ -91,7 +91,7 @@ fnplus(Object *env, Object *list) error("+ take only number"); sum += p->car->num; } - return newint(sum); + return newint(gc, sum); } static Object* @@ -103,7 +103,7 @@ evallist(Object *env, Object *list) error("type is not list"); Object *car = eval(env, list->car); Object *cdr = evallist(env, list->cdr); - return newcons(car, cdr); + return newcons(gc, car, cdr); } static Object* diff --git a/fn.h b/fn.h index b5c9263..76746cf 100644 --- a/fn.h +++ b/fn.h @@ -7,21 +7,20 @@ Object* eval(Object *env, Object *expr); /* new */ -Object* newint(long); -Object* newcons(Object*,Object*); -Object* newenv(Object*name, Object *vars, Object *up); -Object* newacons(Object*, Object*, Object*); -Object* newsymbol(char*, int); -Object* newstr(int); -Object* newfn(Object *env, Object *params, Object *body); +Object* newint(GC *,long); +Object* newcons(GC *,Object*,Object*); +Object* newenv(GC *,Object*name, Object *vars, Object *up); +Object* newacons(GC *,Object*, Object*, Object*); +Object* newsymbol(GC *,char*, int); +Object* newstr(GC *,int); +Object* newfn(GC *,Object *env, Object *params, Object *body); /* gc.c */ -void gcstatus(void); -Object* newobj(enum OType); -void* gcalloc(int); -void* gcralloc(void*, int); -void gcinit(void *top, int cap); -void gcrun(void); +Object* newobj(GC *,enum OType); +void* gcalloc(GC *,int); +void* gcralloc(GC *, void*, int); +GC* newgc(void *top, int cap); +void gcrun(GC *); /* str.c */ void strputc(Object*, int); diff --git a/gc.c b/gc.c index cb12e9c..3ba83f7 100644 --- a/gc.c +++ b/gc.c @@ -12,52 +12,58 @@ enum OFFSET = sizeof(int), }; -GC gc = {0}; +int running = 0; void -gcfree(void *src) +gccompact(int cap, GC *gc) +{ + GC *ngc = newgc((void*)gc->top, gc->cap * 2); +} + +void +gcfree(GC *gc, void *src) { int *p = (int*)src - 1; int sz = *p; memset(p, 0, sz); - gc.using -= sz; + gc->using -= sz; } void -freeobj(Object *p) +freeobj(GC *gc, Object *p) { - gc.using -= sizeof(Object); + gc->using -= sizeof(Object); p->next = 0; switch(p->type){ default: break; case OSTRING: case OIDENT: - gcfree(p->beg); + gcfree(gc, p->beg); break; } memset(p, 0, sizeof(Object)); - if(gc.freed == 0) - gc.freed = p; + if(gc->freed == 0) + gc->freed = p; else{ - p->next = gc.freed; - gc.freed = p; + p->next = gc->freed; + gc->freed = p; } } void* -gcalloc(int sz) +gcalloc(GC *gc, int sz) { sz += OFFSET; if(sz % OFFSET) sz = sz + OFFSET - (sz % OFFSET); - for(u64 i = gc.sb; i < gc.se;){ + for(u64 i = gc->sb; i < gc->se;){ u64 j = i; for(;j - i < sz; j += OFFSET){ if(*(int*)(j) != 0) break; } if(j - i == sz){ - gc.using += sz; + gc->using += sz; *(int*)i = sz; i += OFFSET; return (void*)i; @@ -68,44 +74,44 @@ gcalloc(int sz) } void* -gcralloc(void *src, int sz) +gcralloc(GC *gc, void *src, int sz) { - void *dst = gcalloc(sz); + void *dst = gcalloc(gc, sz); int osz = ((int*)src)[-1]; memcpy(dst, src, osz); - gcfree(src); + gcfree(gc, src); return dst; } void -mark(Object *obj) +mark(GC *gc, Object *obj) { if(obj == 0 || obj->flag&USING) return; obj->flag = USING; switch(obj->type){ case OCELL: - mark(obj->car); - mark(obj->cdr); + mark(gc, obj->car); + mark(gc, obj->cdr); break; case OENV: - mark(obj->name); - mark(obj->vars); - mark(obj->up); + mark(gc, obj->name); + mark(gc, obj->vars); + mark(gc, obj->up); break; case OFUNC: - mark(obj->params); - mark(obj->body); - mark(obj->env); + mark(gc, obj->params); + mark(gc, obj->body); + mark(gc, obj->env); break; } } void -gcsweep(void) +gcsweep(GC *gc) { Object *last = 0; - for(Object *p = gc.objs; p;){ + for(Object *p = gc->objs; p;){ if(p->flag&USING){ p->flag = 0; last = p; @@ -113,87 +119,93 @@ gcsweep(void) }else{ Object *tmp = p; if(last == 0){ - gc.objs = p->next; + gc->objs = p->next; }else{ last->next = p->next; } p = p->next; - freeobj(tmp); + freeobj(gc, tmp); } } } int -isobj(u64 p) +isobj(GC *gc, u64 p) { - if(gc.ob <= p && p < gc.oe){ - p -= gc.ob; + if(gc->ob <= p && p < gc->oe){ + p -= gc->ob; return (p % sizeof(Object)) == 0; } return 0; } void -gcmark(void) +gcmark(GC *gc) { void *_ = 0; u64 bot = (u64)&_; - for(; bot < gc.top; bot += sizeof(bot)){ + for(; bot < gc->top; bot += sizeof(bot)){ u64 val = (u64)*(void**)bot; - if(isobj(val)) - mark((Object*)val); + if(isobj(gc, val)) + mark(gc, (Object*)val); } } void -gcrun(void) +gcrun(GC *gc) { - printf("before=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using); + running = 1; + printf("before=> cap:%d using:%d remain:%d\n", gc->cap, gc->using, gc->cap-gc->using); jmp_buf reg; setjmp(reg); - gcmark(); - gcsweep(); - printf("after=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using); + gcmark(gc); + gcsweep(gc); + printf("after=> cap:%d using:%d remain:%d\n", gc->cap, gc->using, gc->cap-gc->using); + running = 0; } Object* -newobj(enum OType type) +newobj(GC *gc, enum OType type) { - if(gc.op + sizeof(Object) >= gc.oe){ + if(gc->op + sizeof(Object) >= gc->oe){ panic("Not impl yet newobj raise"); } - gcrun(); - gc.using += sizeof(Object); + gcrun(gc); + gc->using += sizeof(Object); Object *r = 0; - if(gc.freed){ - r = gc.freed; - gc.freed = gc.freed->next; + if(gc->freed){ + r = gc->freed; + gc->freed = gc->freed->next; }else{ - r = (Object*)gc.op; - gc.op += sizeof(Object); + r = (Object*)gc->op; + gc->op += sizeof(Object); } r->type = type; - if(gc.objs == 0) - gc.objs = r; + if(gc->objs == 0) + gc->objs = r; else{ - r->next = gc.objs; - gc.objs = r; + r->next = gc->objs; + gc->objs = r; } return r; } -void -gcinit(void *top, int cap) +GC* +newgc(void *top, int cap) { - gc.top = (u64)top; - if((gc.memory = malloc(cap)) == 0) + GC *gc = calloc(1, sizeof(GC)); + if(gc == 0) + panic("can't alloc %d byte\n", sizeof(GC)); + gc->top = (u64)top; + if((gc->memory = malloc(cap)) == 0) panic("can't alloc %d byte\n", cap); - gc.cap = cap; - gc.using = 0; + gc->cap = cap; + gc->using = 0; - gc.op = gc.ob = (u64)gc.memory; - gc.oe = gc.op + (float)cap * 0.64; + gc->op = gc->ob = (u64)gc->memory; + gc->oe = gc->op + (float)cap * 0.64; - gc.sb = (u64)gc.memory + (float)cap * 0.64; - gc.se = (u64)gc.memory + cap; + gc->sb = (u64)gc->memory + (float)cap * 0.64; + gc->se = (u64)gc->memory + cap; + return gc; } diff --git a/main.c b/main.c index 05f7f28..4024332 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,7 @@ #include jmp_buf err; +GC *gc; static void SExprint(Object *obj) @@ -58,10 +59,10 @@ printexpr(Object *obj) static void loop(void) { - Object *root = newenv(&Nil, &Nil, &Nil); + Object *root = newenv(gc, &Nil, &Nil, &Nil); if(setjmp(err) == 1){ skipline(); - gcrun(); + gcrun(gc); } while(1){ Object *res = nextexpr(); @@ -73,6 +74,6 @@ loop(void) int main(int argc, char *argv[]) { - gcinit(&argc, 4000); + gc = newgc(&argc, 4000); loop(); } diff --git a/obj.c b/obj.c index ee24769..12c4e05 100644 --- a/obj.c +++ b/obj.c @@ -4,26 +4,26 @@ #include Object* -newint(long val) +newint(GC *gc, long val) { - Object *obj = newobj(OINT); + Object *obj = newobj(gc, OINT); obj->num = val; return obj; } Object* -newcons(Object *car, Object *cdr) +newcons(GC *gc, Object *car, Object *cdr) { - Object *obj = newobj(OCELL); + Object *obj = newobj(gc, OCELL); obj->car = car; obj->cdr = cdr; return obj; } Object* -newenv(Object* name, Object *vars, Object *up) +newenv(GC *gc, Object* name, Object *vars, Object *up) { - Object *obj = newobj(OENV); + Object *obj = newobj(gc, OENV); obj->name = name; obj->up = up; obj->vars = vars; @@ -31,16 +31,16 @@ newenv(Object* name, Object *vars, Object *up) } Object* -newacons(Object *x, Object *y, Object *z) +newacons(GC *gc, Object *x, Object *y, Object *z) { - Object *cons = newcons(x, y); - return newcons(cons, z); + Object *cons = newcons(gc, x, y); + return newcons(gc, cons, z); } Object* -newfn(Object *env, Object *params, Object *body) +newfn(GC *gc, Object *env, Object *params, Object *body) { - Object *fn = newobj(OFUNC); + Object *fn = newobj(gc, OFUNC); fn->params = params; fn->body = body; fn->env = env; @@ -48,7 +48,7 @@ newfn(Object *env, Object *params, Object *body) } Object* -newsymbol(char *str, int len) +newsymbol(GC *gc, char *str, int len) { static Object *syms[] = { &Nil, &True, &False, &Minus, &Plus, @@ -59,18 +59,18 @@ newsymbol(char *str, int len) if(strlen(c->sym)==len && memcmp(c->sym, str, len) == 0) return c; } - Object *obj = newobj(OIDENT); - obj->beg = gcalloc(len + 1); + Object *obj = newobj(gc, OIDENT); + obj->beg = gcalloc(gc, len + 1); obj->end = obj->ptr = obj->beg + len; memcpy(obj->beg, str, len+1); return obj; } Object* -newstr(int len) +newstr(GC *gc, int len) { - Object *obj = newobj(OSTRING); - obj->ptr = obj->beg = gcalloc(len + 1); + Object *obj = newobj(gc, OSTRING); + obj->ptr = obj->beg = gcalloc(gc, len + 1); obj->end = obj->beg + len; return obj; } diff --git a/parser.c b/parser.c index 8c347f3..32b6a1c 100644 --- a/parser.c +++ b/parser.c @@ -62,7 +62,7 @@ symbol(char c) buf[len++] = get(); } buf[len] = 0; - return newsymbol(buf, len); + return newsymbol(gc, buf, len); } static long @@ -79,14 +79,14 @@ quote(void) { Object *car = &Quote; Object *ccdr = list(); - Object *cdr = newcons(ccdr, &Nil); - return newcons(car, cdr); + Object *cdr = newcons(gc, ccdr, &Nil); + return newcons(gc, car, cdr); } static Object* string(void) { - Object *str = newstr(16); + Object *str = newstr(gc, 16); while(lookup() != '\"'){ strputc(str, get()); } @@ -98,11 +98,11 @@ static Object* atom(char c) { if(isdigit(c)) - return newint(number()); + return newint(gc, number()); get(); if(c == '-'){ if(isdigit(lookup())) - return newint(-number()); + return newint(gc, -number()); else return symbol('-'); } @@ -126,20 +126,20 @@ lparlist(void) get(); car = quote(); cdr = lparlist(); - return newcons(car, cdr); + return newcons(gc, car, cdr); case '.': get(); return list(); case '(': car = list(); cdr = lparlist(); - return newcons(car, cdr); + return newcons(gc, car, cdr); case ')': return &Nil; } car = atom(c); cdr = lparlist(); - return newcons(car ,cdr); + return newcons(gc, car ,cdr); } static Object* diff --git a/str.c b/str.c index adcb595..4dea718 100644 --- a/str.c +++ b/str.c @@ -6,7 +6,7 @@ void strraise(Object *s, int ns) { int pos = s->ptr - s->beg; - char *ptr = gcralloc(s->beg, ns + 1); + char *ptr = gcralloc(gc, s->beg, ns + 1); s->beg = ptr; s->ptr = s->beg + pos; s->end = s->beg + ns;