diff --git a/include/config.h b/include/config.h index 28bebc91..5b72b9be 100644 --- a/include/config.h +++ b/include/config.h @@ -12,7 +12,7 @@ /* initial memory size (to be dynamically extended if necessary) */ #define PIC_ARENA_SIZE 100 -#define PIC_HEAP_SIZE (20000 * 8) +#define PIC_HEAP_PAGE_SIZE (8192 * 8) #define PIC_STACK_SIZE 1024 #define PIC_RESCUE_SIZE 30 #define PIC_IREP_SIZE 256 diff --git a/src/gc.c b/src/gc.c index b88a03e4..fa8ca17d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -16,28 +16,42 @@ void init_heap_page(struct heap_page *heap) { - int nu; - - nu = (PIC_HEAP_SIZE + sizeof(union header) - 1) / sizeof(union header) + 1; - - heap->base.s.ptr = (union header *)calloc(nu, sizeof(union header)); + heap->base.s.ptr = heap->freep = &heap->base; heap->base.s.size = 0; /* not 1, since it must never be fused into other headers */ heap->base.s.mark = PIC_GC_UNMARK; - heap->freep = heap->base.s.ptr; - heap->freep->s.size = nu - 1; - heap->freep->s.ptr = heap->freep + heap->freep->s.size; - heap->freep->s.mark = PIC_GC_UNMARK; - - heap->freep->s.ptr->s.size = 0; - heap->freep->s.ptr->s.ptr = &heap->base; - heap->freep->s.ptr->s.mark = PIC_GC_UNMARK; - #if GC_DEBUG printf("freep = %p\n", heap->freep); #endif } +static void gc_free(pic_state *, union header *); + +static void * +add_heap_page(pic_state *pic) +{ + int nu; + union header *p, *ep; + +#if DEBUG + puts("heap page added"); +#endif + + nu = (PIC_HEAP_PAGE_SIZE + sizeof(union header) - 1) / sizeof(union header) + 1; + p = (union header *)calloc(nu, sizeof(union header)); + p->s.size = nu - 1; + p->s.mark = PIC_GC_UNMARK; + gc_free(pic, p); + + ep = p + p->s.size; /* end of page */ + ep->s.size = 0; + ep->s.mark = PIC_GC_UNMARK; + ep->s.ptr = p->s.ptr; + p->s.ptr = ep; + + return pic->heap->freep; +} + void * pic_alloc(pic_state *pic, size_t size) { @@ -125,7 +139,8 @@ gc_alloc(pic_state *pic, size_t size) if (p->s.size >= nunits) break; if (p == freep) { - return 0; + if ((p = add_heap_page(pic)) == NULL) + return NULL; } } if (p->s.size == nunits) {