add compact function

This commit is contained in:
yoyo 2024-09-01 22:16:39 +09:00
parent 26a0fe0a1b
commit c1c9614744
4 changed files with 124 additions and 25 deletions

2
dat.h
View File

@ -24,6 +24,7 @@ struct Object
enum OType type; /* type */ enum OType type; /* type */
int flag; /* flag */ int flag; /* flag */
Object *next; /* for gc */ Object *next; /* for gc */
Object *forward;
union{ union{
/* int */ /* int */
long num; long num;
@ -60,6 +61,7 @@ struct Object
*/ */
typedef struct typedef struct
{ {
int running;
void *memory; void *memory;
u64 cap; u64 cap;
u64 using; u64 using;

1
fn.h
View File

@ -21,6 +21,7 @@ void* gcalloc(GC *,int);
void* gcralloc(GC *, void*, int); void* gcralloc(GC *, void*, int);
GC* newgc(void *top, int cap); GC* newgc(void *top, int cap);
void gcrun(GC *); void gcrun(GC *);
void gccompact(int cap, GC *src);
/* str.c */ /* str.c */
void strputc(Object*, int); void strputc(Object*, int);

138
gc.c
View File

@ -8,16 +8,119 @@
enum enum
{ {
USING = 1 << 1, USING = 1 << 1,
FORWARD = 1 << 2,
OFFSET = sizeof(int), OFFSET = sizeof(int),
}; };
int running = 0; int
isobj(GC *gc, u64 p)
{
if(gc->ob <= p && p < gc->oe){
p -= gc->ob;
return (p % sizeof(Object)) == 0;
}
return 0;
}
Object*
cloneobj(GC *dst, GC *src, Object *obj)
{
if(obj == 0)
return 0;
if(obj->type==OBLTIN||obj->type==OSYMBOL)
return obj;
if(obj->flag&FORWARD)
return obj->forward;
Object *p = newobj(dst, obj->type);
obj->flag |= FORWARD;
obj->forward = p;
switch(obj->type){
case OINT:
p->num = obj->num;
break;
case OSTRING:
case OIDENT:
int len = obj->ptr - obj->beg;
p->beg = gcalloc(dst, len + 1);
p->end = p->ptr = p->beg + len;
memcpy(p->beg, obj->beg, len + 1);
break;
case OCELL:
p->car = cloneobj(dst, src, obj->car);
p->cdr = cloneobj(dst, src, obj->cdr);
break;
case OENV:
p->name = cloneobj(dst, src, obj->name);
p->vars = cloneobj(dst, src, obj->vars);
p->up = cloneobj(dst, src, obj->up);
break;
case OFUNC:
p->params = cloneobj(dst, src, obj->params);
p->body = cloneobj(dst, src, obj->body);
p->env = cloneobj(dst, src, obj->env);
break;
}
return p;
}
Object*
forwardobj(Object *p)
{
if(p == 0)
return 0;
if(p->flag&FORWARD)
return p->forward;
switch(p->type){
case OBLTIN:
case OSYMBOL:
break;
case OCELL:
p->car = forwardobj(p->car);
p->cdr = forwardobj(p->cdr);
break;
case OENV:
p->name = forwardobj(p->name);
p->vars = forwardobj(p->vars);
p->up = forwardobj(p->up);
break;
case OFUNC:
p->params = forwardobj(p->params);
p->body = forwardobj(p->body);
p->env = forwardobj(p->env);
break;
}
return p;
}
void void
gccompact(int cap, GC *gc) compact(u64 bot, GC *dst, GC *src)
{ {
GC *ngc = newgc((void*)gc->top, gc->cap * 2); for(Object *p=src->objs; p; p=p->next){
cloneobj(dst, src, p);
}
for(; bot < src->top; bot += sizeof(bot)){
u64 val = (u64)*(void**)bot;
if(isobj(src, val)){
Object *obj = (Object*)val;
if(obj->flag&FORWARD)
*(void**)bot = forwardobj(obj);
}
}
}
void
gccompact(int cap, GC *src)
{
void *_ = 0;
u64 bot = (u64)&_;
GC *dst = newgc((void*)src->top, cap);
dst->running = 1;
compact(bot, dst, src);
dst->running = 0;
free(src->memory);
*src = *dst;
free(dst);
} }
void void
@ -113,7 +216,7 @@ gcsweep(GC *gc)
Object *last = 0; Object *last = 0;
for(Object *p = gc->objs; p;){ for(Object *p = gc->objs; p;){
if(p->flag&USING){ if(p->flag&USING){
p->flag = 0; p->flag &= ~(USING);
last = p; last = p;
p = p->next; p = p->next;
}else{ }else{
@ -129,16 +232,6 @@ gcsweep(GC *gc)
} }
} }
int
isobj(GC *gc, u64 p)
{
if(gc->ob <= p && p < gc->oe){
p -= gc->ob;
return (p % sizeof(Object)) == 0;
}
return 0;
}
void void
gcmark(GC *gc) gcmark(GC *gc)
{ {
@ -152,23 +245,26 @@ gcmark(GC *gc)
} }
void void
gcrun(GC *gc) gcrun(GC *src)
{ {
running = 1; if(src->running)
return;
src->running = 1;
printf("before=> cap:%d using:%d remain:%d\n", gc->cap, gc->using, gc->cap-gc->using); printf("before=> cap:%d using:%d remain:%d\n", gc->cap, gc->using, gc->cap-gc->using);
jmp_buf reg; jmp_buf reg;
setjmp(reg); setjmp(reg);
gcmark(gc); gcmark(src);
gcsweep(gc); gcsweep(src);
gccompact(src->cap + 500, src);
printf("after=> cap:%d using:%d remain:%d\n", gc->cap, gc->using, gc->cap-gc->using); printf("after=> cap:%d using:%d remain:%d\n", gc->cap, gc->using, gc->cap-gc->using);
running = 0; src->running = 0;
} }
Object* Object*
newobj(GC *gc, 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"); panic("Not impl yet newobj raise");
} }
gcrun(gc); gcrun(gc);
gc->using += sizeof(Object); gc->using += sizeof(Object);
@ -197,7 +293,7 @@ newgc(void *top, int cap)
if(gc == 0) if(gc == 0)
panic("can't alloc %d byte\n", sizeof(GC)); panic("can't alloc %d byte\n", sizeof(GC));
gc->top = (u64)top; gc->top = (u64)top;
if((gc->memory = malloc(cap)) == 0) if((gc->memory = calloc(1, cap)) == 0)
panic("can't alloc %d byte\n", cap); panic("can't alloc %d byte\n", cap);
gc->cap = cap; gc->cap = cap;
gc->using = 0; gc->using = 0;

8
main.c
View File

@ -57,16 +57,15 @@ printexpr(Object *obj)
} }
static void static void
loop(void) loop(Object *env)
{ {
Object *root = newenv(gc, &Nil, &Nil, &Nil);
if(setjmp(err) == 1){ if(setjmp(err) == 1){
skipline(); skipline();
gcrun(gc); gcrun(gc);
} }
while(1){ while(1){
Object *res = nextexpr(); Object *res = nextexpr();
res = eval(root, res); res = eval(env, res);
printexpr(res); printexpr(res);
} }
} }
@ -75,5 +74,6 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
gc = newgc(&argc, 4000); gc = newgc(&argc, 4000);
loop(); Object *env = newenv(gc, &Nil, &Nil, &Nil);
loop(env);
} }