add compact function
This commit is contained in:
parent
26a0fe0a1b
commit
c1c9614744
2
dat.h
2
dat.h
@ -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
1
fn.h
@ -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);
|
||||||
|
|||||||
136
gc.c
136
gc.c
@ -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,16 +245,19 @@ 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*
|
||||||
@ -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
8
main.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user