replace mock allocator with simple k&r malloc

This commit is contained in:
Yuichi Nishiwaki 2013-10-13 15:14:15 +09:00
parent 38858e7a11
commit e3600a65c9
4 changed files with 95 additions and 7 deletions

View File

@ -17,11 +17,15 @@ struct pic_proc {
} u; } u;
}; };
#define PIC_HEAP_SIZE 1024
typedef struct { typedef struct {
pic_value *sp; pic_value *sp;
pic_value *stbase, *stend; pic_value *stbase, *stend;
struct pic_env *global_env; struct pic_env *global_env;
struct heap_page *heap;
} pic_state; } pic_state;
void *pic_alloc(pic_state *, size_t); void *pic_alloc(pic_state *, size_t);

16
include/picrin/gc.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef GC_H__
#define GC_H__
struct header {
struct header *ptr;
size_t size;
};
struct heap_page {
struct header *base, *freep;
size_t heap_size;
};
void init_heap_page(struct heap_page *);
#endif

View File

@ -1,12 +1,80 @@
#include <stdlib.h> #include <stdlib.h>
#include "picrin.h" #include "picrin.h"
#include "picrin/gc.h"
void
init_heap_page(struct heap_page *heap)
{
struct header *base, *freep;
void *p;
p = (struct header *)malloc(PIC_HEAP_SIZE);
heap->base = base = (struct header *)
(((unsigned long)p + sizeof(struct header) -1) & ~(sizeof(struct header) - 1));
base->ptr = base + 1;
base->size = 0;
heap->freep = freep = base->ptr;
freep->ptr = base;
freep->size = ((char *)p + PIC_HEAP_SIZE - (char *)freep) / sizeof(struct header);
}
void * void *
pic_alloc(pic_state *pic, size_t size) pic_alloc(pic_state *pic, size_t size)
{ {
/* mock */ struct header *freep, *p, *prevp;
return malloc(size); size_t nunits;
nunits = (size + sizeof(struct header) - 1) / sizeof(struct header) + 1;
freep = pic->heap->freep;
prevp = freep;
for (p = prevp->ptr; ; prevp = p, p = p->ptr) {
if (p->size >= nunits)
break;
if (p == freep)
return 0;
}
if (p->size == nunits) {
prevp->ptr = p->ptr;
}
else {
p->size -= nunits;
p += p->size;
p->size = nunits;
}
pic->heap->freep = prevp;
return (void *)(p + 1);
}
void
pic_free(pic_state *pic, void *ptr)
{
struct header *bp, *p;
bp = (struct header *)ptr - 1;
for (p = pic->heap->freep; !(p < bp && bp < p->ptr); p = p->ptr) {
if (p >= p->ptr && (bp > p || bp < p->ptr))
break;
}
if (bp + bp->size == p->ptr) {
bp->size += p->ptr->size;
bp->ptr = p->ptr->ptr;
}
else {
bp->ptr = p->ptr;
}
if (p + p->size == bp) {
p->size += bp->size;
p->ptr = bp->ptr;
} else {
p->ptr = bp;
}
pic->heap->freep = p;
} }
struct pic_object * struct pic_object *
@ -20,8 +88,3 @@ pic_gc_alloc(pic_state *pic, size_t size, enum pic_tt tt)
return obj; return obj;
} }
void
pic_free(pic_state *pic, void *ptr)
{
free(ptr);
}

View File

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "picrin.h" #include "picrin.h"
#include "picrin/gc.h"
static struct pic_env * static struct pic_env *
pic_new_empty_env() pic_new_empty_env()
@ -25,6 +26,10 @@ pic_open()
pic->stbase = pic->sp = (pic_value *)malloc(sizeof(pic_value) * 1024); pic->stbase = pic->sp = (pic_value *)malloc(sizeof(pic_value) * 1024);
pic->stend = pic->stbase + 1024; pic->stend = pic->stbase + 1024;
/* memory heap */
pic->heap = (struct heap_page *)malloc(sizeof(struct heap_page));
init_heap_page(pic->heap);
pic->global_env = pic_new_empty_env(); pic->global_env = pic_new_empty_env();
return pic; return pic;