add memory map
This commit is contained in:
parent
cb8a52600d
commit
4ed169adc4
28
dat.h
28
dat.h
@ -1,3 +1,6 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uintptr_t u64;
|
||||||
typedef struct Object Object;
|
typedef struct Object Object;
|
||||||
typedef Object* (*Bltinfn)(Object *env, Object *args);
|
typedef Object* (*Bltinfn)(Object *env, Object *args);
|
||||||
typedef struct Object Object;
|
typedef struct Object Object;
|
||||||
@ -51,6 +54,31 @@ struct Object
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*0 ~ 64 : for object
|
||||||
|
*64 ~ 100 : for string
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *memory;
|
||||||
|
u64 cap;
|
||||||
|
u64 using;
|
||||||
|
u64 top;
|
||||||
|
/* objects */
|
||||||
|
struct{
|
||||||
|
Object *objs;
|
||||||
|
u64 ob;
|
||||||
|
u64 oe;
|
||||||
|
u64 op;
|
||||||
|
Object *freed;
|
||||||
|
};
|
||||||
|
/* string */
|
||||||
|
struct{
|
||||||
|
u64 sb;
|
||||||
|
u64 se;
|
||||||
|
};
|
||||||
|
}GC;
|
||||||
|
|
||||||
extern Object Nil;
|
extern Object Nil;
|
||||||
extern Object True;
|
extern Object True;
|
||||||
extern Object False;
|
extern Object False;
|
||||||
|
|||||||
4
fn.h
4
fn.h
@ -18,8 +18,8 @@ Object* newfn(Object *env, Object *params, Object *body);
|
|||||||
/* gc.c */
|
/* gc.c */
|
||||||
void gcstatus(void);
|
void gcstatus(void);
|
||||||
Object* newobj(enum OType);
|
Object* newobj(enum OType);
|
||||||
void* xalloc(int);
|
void* gcalloc(int);
|
||||||
void* xralloc(void*, int);
|
void* gcralloc(void*, int);
|
||||||
void gcinit(void *top, int cap);
|
void gcinit(void *top, int cap);
|
||||||
void gcrun(void);
|
void gcrun(void);
|
||||||
|
|
||||||
|
|||||||
237
gc.c
237
gc.c
@ -1,45 +1,86 @@
|
|||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
USING = 1 << 1,
|
USING = 1 << 1,
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
OFFSET = sizeof(int),
|
||||||
{
|
};
|
||||||
int total;
|
|
||||||
int using;
|
|
||||||
uintptr_t top;
|
|
||||||
uintptr_t beg;
|
|
||||||
uintptr_t end;
|
|
||||||
Object objs;
|
|
||||||
Object freed;
|
|
||||||
}GC;
|
|
||||||
|
|
||||||
GC gc = {0};
|
GC gc = {0};
|
||||||
|
|
||||||
static void
|
void
|
||||||
pushobj(Object *list, Object *obj)
|
gcfree(void *src)
|
||||||
{
|
{
|
||||||
Object *l = list;
|
int *p = (int*)src - 1;
|
||||||
Object *c = l->next;
|
int sz = *p;
|
||||||
while(c){
|
memset(p, 0, sz);
|
||||||
l = c;
|
gc.using -= sz;
|
||||||
c=c->next;
|
|
||||||
}
|
|
||||||
l->next = obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
|
freeobj(Object *p)
|
||||||
|
{
|
||||||
|
gc.using -= sizeof(Object);
|
||||||
|
p->next = 0;
|
||||||
|
switch(p->type){
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case OSTRING:
|
||||||
|
case OIDENT:
|
||||||
|
gcfree(p->beg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memset(p, 0, sizeof(Object));
|
||||||
|
if(gc.freed == 0)
|
||||||
|
gc.freed = p;
|
||||||
|
else{
|
||||||
|
p->next = gc.freed;
|
||||||
|
gc.freed = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
gcalloc(int sz)
|
||||||
|
{
|
||||||
|
sz += OFFSET;
|
||||||
|
if(sz % OFFSET) sz = sz + OFFSET - (sz % OFFSET);
|
||||||
|
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;
|
||||||
|
*(int*)i = sz;
|
||||||
|
i += OFFSET;
|
||||||
|
return (void*)i;
|
||||||
|
}
|
||||||
|
i = j + *(int*)(j);
|
||||||
|
}
|
||||||
|
panic("gccalloc : Not impl yet raise");
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
gcralloc(void *src, int sz)
|
||||||
|
{
|
||||||
|
void *dst = gcalloc(sz);
|
||||||
|
int osz = ((int*)src)[-1];
|
||||||
|
memcpy(dst, src, osz);
|
||||||
|
gcfree(src);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
mark(Object *obj)
|
mark(Object *obj)
|
||||||
{
|
{
|
||||||
if(obj == 0 || obj->flag & USING)
|
if(obj == 0 || obj->flag&USING)
|
||||||
return;
|
return;
|
||||||
obj->flag = USING;
|
obj->flag = USING;
|
||||||
switch(obj->type){
|
switch(obj->type){
|
||||||
@ -60,57 +101,45 @@ mark(Object *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
void
|
||||||
isobj(uintptr_t val)
|
|
||||||
{
|
|
||||||
if(val < gc.beg || val >= gc.end)
|
|
||||||
return 0;
|
|
||||||
val -= gc.beg;
|
|
||||||
uintptr_t mod = val % sizeof(Object);
|
|
||||||
return mod == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
freeobj(Object *obj)
|
|
||||||
{
|
|
||||||
switch(obj->type){
|
|
||||||
case OSTRING:
|
|
||||||
case OIDENT:
|
|
||||||
printf("freed => '%s'\n", obj->beg);
|
|
||||||
free(obj->beg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memset(obj, 0, sizeof(*obj));
|
|
||||||
pushobj(&gc.freed, obj);
|
|
||||||
gc.using -= sizeof(Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gcsweep(void)
|
gcsweep(void)
|
||||||
{
|
{
|
||||||
Object *l = &gc.objs;
|
Object *last = 0;
|
||||||
Object *c = l->next;
|
for(Object *p = gc.objs; p;){
|
||||||
while(c){
|
if(p->flag&USING){
|
||||||
if(c->flag&USING){
|
p->flag = 0;
|
||||||
c->flag = 0;
|
last = p;
|
||||||
l = c;
|
p = p->next;
|
||||||
c = c->next;
|
}else{
|
||||||
continue;
|
Object *tmp = p;
|
||||||
|
if(last == 0){
|
||||||
|
gc.objs = p->next;
|
||||||
|
}else{
|
||||||
|
last->next = p->next;
|
||||||
|
}
|
||||||
|
p = p->next;
|
||||||
|
freeobj(tmp);
|
||||||
}
|
}
|
||||||
Object *t = c;
|
|
||||||
l->next = c->next;
|
|
||||||
c = c->next;
|
|
||||||
freeobj(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int
|
||||||
|
isobj(u64 p)
|
||||||
|
{
|
||||||
|
if(gc.ob <= p && p < gc.oe){
|
||||||
|
p -= gc.ob;
|
||||||
|
return (p % sizeof(Object)) == 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
gcmark(void)
|
gcmark(void)
|
||||||
{
|
{
|
||||||
void *_ = 0;
|
void *_ = 0;
|
||||||
uintptr_t bot = (uintptr_t)&_;
|
u64 bot = (u64)&_;
|
||||||
for(; bot < gc.top; bot += sizeof(bot)){
|
for(; bot < gc.top; bot += sizeof(bot)){
|
||||||
uintptr_t val = (uintptr_t)*(void**)bot;
|
u64 val = (u64)*(void**)bot;
|
||||||
if(isobj(val))
|
if(isobj(val))
|
||||||
mark((Object*)val);
|
mark((Object*)val);
|
||||||
}
|
}
|
||||||
@ -119,64 +148,52 @@ gcmark(void)
|
|||||||
void
|
void
|
||||||
gcrun(void)
|
gcrun(void)
|
||||||
{
|
{
|
||||||
|
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();
|
gcmark();
|
||||||
gcsweep();
|
gcsweep();
|
||||||
gcstatus();
|
printf("after=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Object*
|
||||||
gcstatus(void)
|
|
||||||
{
|
|
||||||
printf("curren=> total:%d using:%d remain:%d\n", gc.total, gc.using, gc.total-gc.using);
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
xalloc(int sz)
|
|
||||||
{
|
|
||||||
int *res = calloc(1, sz);
|
|
||||||
if(res == 0)
|
|
||||||
panic("Can't allocated %d byte", sz);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
xralloc(void *src, int sz)
|
|
||||||
{
|
|
||||||
int *p = realloc(src, sz);
|
|
||||||
if(p == 0)
|
|
||||||
panic("Can't allocated %d byte", sz);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object*
|
|
||||||
newobj(enum OType type)
|
newobj(enum OType type)
|
||||||
{
|
{
|
||||||
|
if(gc.op + sizeof(Object) >= gc.oe){
|
||||||
|
panic("Not impl yet newobj raise");
|
||||||
|
}
|
||||||
gcrun();
|
gcrun();
|
||||||
Object *obj = 0;
|
|
||||||
if(gc.freed.next){
|
|
||||||
obj = gc.freed.next;
|
|
||||||
gc.freed.next = obj->next;
|
|
||||||
obj->next = 0;
|
|
||||||
}else
|
|
||||||
panic("not impl yet");
|
|
||||||
obj->type = type;
|
|
||||||
pushobj(&gc.objs, obj);
|
|
||||||
gc.using += sizeof(Object);
|
gc.using += sizeof(Object);
|
||||||
return obj;
|
Object *r = 0;
|
||||||
|
if(gc.freed){
|
||||||
|
r = gc.freed;
|
||||||
|
gc.freed = gc.freed->next;
|
||||||
|
}else{
|
||||||
|
r = (Object*)gc.op;
|
||||||
|
gc.op += sizeof(Object);
|
||||||
|
}
|
||||||
|
r->type = type;
|
||||||
|
if(gc.objs == 0)
|
||||||
|
gc.objs = r;
|
||||||
|
else{
|
||||||
|
r->next = gc.objs;
|
||||||
|
gc.objs = r;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gcinit(void *top, int cap)
|
gcinit(void *top, int cap)
|
||||||
{
|
{
|
||||||
gc.total = cap;
|
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.using = 0;
|
||||||
gc.top = (uintptr_t)top;
|
|
||||||
gc.beg = (uintptr_t)xalloc(cap);
|
gc.op = gc.ob = (u64)gc.memory;
|
||||||
gc.end = gc.beg + cap;
|
gc.oe = gc.op + (float)cap * 0.64;
|
||||||
Object *p = &gc.freed;
|
|
||||||
for(uintptr_t i = gc.beg; i < gc.end; i+=sizeof(Object)){
|
gc.sb = (u64)gc.memory + (float)cap * 0.64;
|
||||||
p = p->next = (Object*)i;
|
gc.se = (u64)gc.memory + cap;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
3
main.c
3
main.c
@ -64,7 +64,6 @@ loop(void)
|
|||||||
gcrun();
|
gcrun();
|
||||||
}
|
}
|
||||||
while(1){
|
while(1){
|
||||||
gcstatus();
|
|
||||||
Object *res = nextexpr();
|
Object *res = nextexpr();
|
||||||
res = eval(root, res);
|
res = eval(root, res);
|
||||||
printexpr(res);
|
printexpr(res);
|
||||||
@ -74,6 +73,6 @@ loop(void)
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
gcinit(&argc, 3000);
|
gcinit(&argc, 4000);
|
||||||
loop();
|
loop();
|
||||||
}
|
}
|
||||||
|
|||||||
2
makefile
2
makefile
@ -10,7 +10,7 @@ OFILES=\
|
|||||||
parser.o
|
parser.o
|
||||||
|
|
||||||
AS=$(CC) -c
|
AS=$(CC) -c
|
||||||
CFLAGS=-c -g -O2
|
CFLAGS=-c -g -O0
|
||||||
|
|
||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
|
|||||||
4
obj.c
4
obj.c
@ -60,7 +60,7 @@ newsymbol(char *str, int len)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
Object *obj = newobj(OIDENT);
|
Object *obj = newobj(OIDENT);
|
||||||
obj->beg = xalloc(len + 1);
|
obj->beg = gcalloc(len + 1);
|
||||||
obj->end = obj->ptr = obj->beg + len;
|
obj->end = obj->ptr = obj->beg + len;
|
||||||
memcpy(obj->beg, str, len+1);
|
memcpy(obj->beg, str, len+1);
|
||||||
return obj;
|
return obj;
|
||||||
@ -70,7 +70,7 @@ Object*
|
|||||||
newstr(int len)
|
newstr(int len)
|
||||||
{
|
{
|
||||||
Object *obj = newobj(OSTRING);
|
Object *obj = newobj(OSTRING);
|
||||||
obj->ptr = obj->beg = xalloc(len + 1);
|
obj->ptr = obj->beg = gcalloc(len + 1);
|
||||||
obj->end = obj->beg + len;
|
obj->end = obj->beg + len;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|||||||
10
str.c
10
str.c
@ -2,11 +2,11 @@
|
|||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static void
|
void
|
||||||
raise(Object *s, int ns)
|
strraise(Object *s, int ns)
|
||||||
{
|
{
|
||||||
int pos = s->ptr - s->beg;
|
int pos = s->ptr - s->beg;
|
||||||
char *ptr = xralloc(s->beg, ns + 1);
|
char *ptr = gcralloc(s->beg, ns + 1);
|
||||||
s->beg = ptr;
|
s->beg = ptr;
|
||||||
s->ptr = s->beg + pos;
|
s->ptr = s->beg + pos;
|
||||||
s->end = s->beg + ns;
|
s->end = s->beg + ns;
|
||||||
@ -16,7 +16,7 @@ void
|
|||||||
strputc(Object *s, int c)
|
strputc(Object *s, int c)
|
||||||
{
|
{
|
||||||
if(s->ptr >= s->end)
|
if(s->ptr >= s->end)
|
||||||
raise(s, (s->end - s->beg) * 2);
|
strraise(s, (s->end - s->beg) * 2);
|
||||||
*s->ptr++ = c;
|
*s->ptr++ = c;
|
||||||
*s->ptr = 0;
|
*s->ptr = 0;
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ strputs(Object *s, char *ptr)
|
|||||||
{
|
{
|
||||||
int l = strlen(ptr);
|
int l = strlen(ptr);
|
||||||
if(s->ptr + l >= s->end)
|
if(s->ptr + l >= s->end)
|
||||||
raise(s, s->end - s->beg + l);
|
strraise(s, s->end - s->beg + l);
|
||||||
memcpy(s->ptr, ptr, l);
|
memcpy(s->ptr, ptr, l);
|
||||||
s->ptr += l;
|
s->ptr += l;
|
||||||
s->ptr[0] = 0;
|
s->ptr[0] = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user