add memory map

This commit is contained in:
yoyo 2024-09-01 17:17:08 +09:00
parent cb8a52600d
commit 4ed169adc4
7 changed files with 166 additions and 122 deletions

28
dat.h
View File

@ -1,3 +1,6 @@
#include <stdint.h>
typedef uintptr_t u64;
typedef struct Object Object;
typedef Object* (*Bltinfn)(Object *env, Object *args);
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 True;
extern Object False;

4
fn.h
View File

@ -18,8 +18,8 @@ Object* newfn(Object *env, Object *params, Object *body);
/* gc.c */
void gcstatus(void);
Object* newobj(enum OType);
void* xalloc(int);
void* xralloc(void*, int);
void* gcalloc(int);
void* gcralloc(void*, int);
void gcinit(void *top, int cap);
void gcrun(void);

233
gc.c
View File

@ -1,45 +1,86 @@
#include "dat.h"
#include "fn.h"
#include <stdlib.h>
#include <stdint.h>
#include <setjmp.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
enum
{
USING = 1 << 1,
};
typedef struct
{
int total;
int using;
uintptr_t top;
uintptr_t beg;
uintptr_t end;
Object objs;
Object freed;
}GC;
OFFSET = sizeof(int),
};
GC gc = {0};
static void
pushobj(Object *list, Object *obj)
void
gcfree(void *src)
{
Object *l = list;
Object *c = l->next;
while(c){
l = c;
c=c->next;
}
l->next = obj;
int *p = (int*)src - 1;
int sz = *p;
memset(p, 0, sz);
gc.using -= sz;
}
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)
{
if(obj == 0 || obj->flag & USING)
if(obj == 0 || obj->flag&USING)
return;
obj->flag = USING;
switch(obj->type){
@ -60,57 +101,45 @@ mark(Object *obj)
}
}
static int
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
void
gcsweep(void)
{
Object *l = &gc.objs;
Object *c = l->next;
while(c){
if(c->flag&USING){
c->flag = 0;
l = c;
c = c->next;
continue;
Object *last = 0;
for(Object *p = gc.objs; p;){
if(p->flag&USING){
p->flag = 0;
last = p;
p = p->next;
}else{
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)
{
void *_ = 0;
uintptr_t bot = (uintptr_t)&_;
u64 bot = (u64)&_;
for(; bot < gc.top; bot += sizeof(bot)){
uintptr_t val = (uintptr_t)*(void**)bot;
u64 val = (u64)*(void**)bot;
if(isobj(val))
mark((Object*)val);
}
@ -119,64 +148,52 @@ gcmark(void)
void
gcrun(void)
{
printf("before=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using);
jmp_buf reg;
setjmp(reg);
gcmark();
gcsweep();
gcstatus();
}
void
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;
printf("after=> cap:%d using:%d remain:%d\n", gc.cap, gc.using, gc.cap-gc.using);
}
Object*
newobj(enum OType type)
{
if(gc.op + sizeof(Object) >= gc.oe){
panic("Not impl yet newobj raise");
}
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);
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
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.top = (uintptr_t)top;
gc.beg = (uintptr_t)xalloc(cap);
gc.end = gc.beg + cap;
Object *p = &gc.freed;
for(uintptr_t i = gc.beg; i < gc.end; i+=sizeof(Object)){
p = p->next = (Object*)i;
}
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;
}

3
main.c
View File

@ -64,7 +64,6 @@ loop(void)
gcrun();
}
while(1){
gcstatus();
Object *res = nextexpr();
res = eval(root, res);
printexpr(res);
@ -74,6 +73,6 @@ loop(void)
int
main(int argc, char *argv[])
{
gcinit(&argc, 3000);
gcinit(&argc, 4000);
loop();
}

View File

@ -10,7 +10,7 @@ OFILES=\
parser.o
AS=$(CC) -c
CFLAGS=-c -g -O2
CFLAGS=-c -g -O0
all: $(NAME)

4
obj.c
View File

@ -60,7 +60,7 @@ newsymbol(char *str, int len)
return c;
}
Object *obj = newobj(OIDENT);
obj->beg = xalloc(len + 1);
obj->beg = gcalloc(len + 1);
obj->end = obj->ptr = obj->beg + len;
memcpy(obj->beg, str, len+1);
return obj;
@ -70,7 +70,7 @@ Object*
newstr(int len)
{
Object *obj = newobj(OSTRING);
obj->ptr = obj->beg = xalloc(len + 1);
obj->ptr = obj->beg = gcalloc(len + 1);
obj->end = obj->beg + len;
return obj;
}

10
str.c
View File

@ -2,11 +2,11 @@
#include "fn.h"
#include <string.h>
static void
raise(Object *s, int ns)
void
strraise(Object *s, int ns)
{
int pos = s->ptr - s->beg;
char *ptr = xralloc(s->beg, ns + 1);
char *ptr = gcralloc(s->beg, ns + 1);
s->beg = ptr;
s->ptr = s->beg + pos;
s->end = s->beg + ns;
@ -16,7 +16,7 @@ void
strputc(Object *s, int c)
{
if(s->ptr >= s->end)
raise(s, (s->end - s->beg) * 2);
strraise(s, (s->end - s->beg) * 2);
*s->ptr++ = c;
*s->ptr = 0;
}
@ -26,7 +26,7 @@ strputs(Object *s, char *ptr)
{
int l = strlen(ptr);
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);
s->ptr += l;
s->ptr[0] = 0;