[add run-time code needed for regions
John Meacham <john@repetae.net>**20090704015859
 Ignore-this: b4ce88b1fb6609b6eeda4a0c340158f2
] hunk ./data/rts/jhc_rts_alloc.c 9
+#define _JHC_GC_CONTEXT 0
hunk ./data/rts/jhc_rts_alloc.c 147
+#elif _JHC_GC == _JHC_GC_REGION
+
+#undef _JHC_GC_CONTEXT
+#define _JHC_GC_CONTEXT 1
+
+
+typedef unsigned jhc_gc_context_t;
+
+#include <sys/queue.h>
+
+static inline void jhc_malloc_init(void) { return; }
+static inline void jhc_alloc_print_stats(void) { return; }
+
+// Region chunk size
+#define JHC_MEM_CHUNK_SIZE (1 << 12)
+
+
+struct region {
+        SLIST_HEAD(,region_page) pages;
+        unsigned offset;
+};
+
+struct region_page {
+        SLIST_ENTRY(region_page) next;
+        uintptr_t data[];
+};
+
+
+#define JHC_REGION_STACK_SIZE  1024
+static struct region region_stack[JHC_REGION_STACK_SIZE];
+
+SLIST_HEAD(,region_page) free_pages;
+
+
+static struct region_page *
+new_region_page(unsigned current_region) {
+        if(SLIST_EMPTY(&free_pages)) {
+
+                unsigned cr = current_region;
+                while(cr < JHC_REGION_STACK_SIZE && !SLIST_EMPTY(&region_stack[cr].pages)) {
+                        struct region_page *next = SLIST_FIRST(&region_stack[cr].pages);
+                        SLIST_FIRST(&region_stack[cr].pages) = NULL;
+                        while(next) {
+                                struct region_page *nnext = SLIST_NEXT(next,next);
+                                SLIST_INSERT_HEAD(&free_pages, next, next);
+                                next = nnext;
+                        }
+                        cr++;
+                }
+                if(cr == current_region) {
+                        return malloc(JHC_MEM_CHUNK_SIZE);
+                }
+        }
+        struct region_page *r = SLIST_FIRST(&free_pages);
+        SLIST_REMOVE_HEAD(&free_pages,next);
+        return r;
+}
+
+static struct region *
+new_region(unsigned current_region) {
+        struct region *r = &region_stack[current_region];
+        if(SLIST_EMPTY(&r->pages)) {
+                r->offset = JHC_MEM_CHUNK_SIZE;
+                return r;
+        } else {
+                // if the region already has some pages allocated, then
+                // we reuse one of them and return the rest to the free list.
+                struct region_page *next = SLIST_NEXT(SLIST_FIRST(&r->pages),next);
+                if(next) {
+                        SLIST_NEXT(SLIST_FIRST(&r->pages), next) = NULL;
+                        while(next) {
+                                struct region_page *nnext = SLIST_NEXT(next,next);
+                                SLIST_INSERT_HEAD(&free_pages, next, next);
+                                next = nnext;
+                        }
+                }
+                r->offset = sizeof(struct region_page);
+                return r;
+        }
+}
+
+
+
+static inline void * A_MALLOC
+jhc_malloc_region(unsigned current_region, struct region *r, size_t n) {
+        n = ALIGN(sizeof(void *),n);
+        struct region_page *rp;
+        if (n > (JHC_MEM_CHUNK_SIZE - r->offset)) {
+                rp = new_region_page(current_region);
+                SLIST_INSERT_HEAD(&r->pages, rp, next);
+                r->offset = sizeof(struct region_page);
+        } else {
+                rp = SLIST_FIRST(&r->pages);
+        }
+
+
+        void *ret = (void *)rp + r->offset;
+        r->offset += n;
+        return ret;
+}
+
+
+
hunk ./data/rts/jhc_rts_header.h 25
-#define _JHC_GC_NONE  0
-#define _JHC_JGC      1
-#define _JHC_GC_BOEHM 2
+#define _JHC_GC_NONE   0
+#define _JHC_JGC       1
+#define _JHC_GC_BOEHM  2
+#define _JHC_GC_REGION 3