[switch terminology from pages and arenas to blocks and megablocks to agree with ghc and reduce confusion. introduce megablocks as an allocation unit.
John Meacham <john@repetae.net>**20100408023038
 Ignore-this: 4fd1c467469e1142cdb552e5c07ed615
] hunk ./src/data/rts/jhc_jgc.c 34
-        int r; J1T(r,gc_inheap,(uintptr_t)s / PAGESIZE);
+        int r; J1T(r,gc_inheap,(uintptr_t)s / MEGABLOCK_SIZE);
hunk ./src/data/rts/jhc_jgc.c 161
-                struct s_page *pg = S_PAGE(e);
+                struct s_block *pg = S_BLOCK(e);
hunk ./src/data/rts/jhc_jgc.c 181
-        s_cleanup_pages(arena);
+        s_cleanup_blocks(arena);
hunk ./src/data/rts/jhc_jgc.c 192
-                        (unsigned)arena->num_used,
-                        page_threshold,
+                        (unsigned)arena->block_used,
+                        block_threshold,
hunk ./src/data/rts/jhc_jgc.c 233
-                printf("  base: %p\n", arena->base);
-                printf("  next_free: %i\n", arena->next_free);
-                printf("  num_used: %i\n", arena->num_used);
+                printf("  block_used: %i\n", arena->block_used);
+                printf("  block_threshold: %i\n", arena->block_threshold);
hunk ./src/data/rts/jhc_jgc.h 1
-
hunk ./src/data/rts/jhc_jgc.h 9
-#define JGC_STATUS 1
+#ifndef JGC_STATUS
+#define JGC_STATUS 0
+#endif
hunk ./src/data/rts/jhc_jgc.h 37
-#define ALIGN(a,n) ((n) - 1 + ((a) - ((n) - 1) % (a)))
-
-
-// round all allocations up to this many blocks.
-// the underlying malloc implementation has some
-// minimum size and this allows memory blocks to
-// be reused more often.
hunk ./src/data/rts/jhc_jgc.h 39
-#define GC_ALIGNMENT (sizeof(void *))
hunk ./src/data/rts/jhc_jgc.h 42
-
hunk ./src/data/rts/jhc_jgc.h 43
-
hunk ./src/data/rts/jhc_jgc.h 44
-static void *gc_alloc_tag(gc_t gc,struct s_cache **sc, unsigned count, unsigned nptrs, int tag);
+static void *gc_alloc(gc_t gc,struct s_cache **sc, unsigned count, unsigned nptrs);
hunk ./src/data/rts/jhc_jgc.h 53
-
hunk ./src/data/rts/jhc_jgc.h 59
-
-
hunk ./src/data/rts/slub.c 8
-#define PAGESIZE  4096
-#define ARENASIZE 65536
+#define BLOCK_SIZE     (1UL << 12)
+#define MEGABLOCK_SIZE (1UL << 20)
hunk ./src/data/rts/slub.c 11
-#define S_PAGE(val) (struct s_page *)((uintptr_t)(val) & ~ (PAGESIZE - 1))
+#define S_BLOCK(val) (struct s_block *)((uintptr_t)(val) & ~ (BLOCK_SIZE - 1))
hunk ./src/data/rts/slub.c 13
-static Pvoid_t  gc_inheap; // whether the page is a heap page
-
-typedef uint16_t page_num_t;
+static Pvoid_t  gc_inheap; // whether the megablock is in the heap
hunk ./src/data/rts/slub.c 16
-        void *base;
+        struct s_megablock *current_megablock;
+        SLIST_HEAD(,s_block) free_blocks;
+        unsigned block_used;
+        unsigned block_threshold;
hunk ./src/data/rts/slub.c 21
-        page_num_t next_free,num_used;
-        SLIST_HEAD(,s_page) free_pages;
-        bitarray_t used[BITARRAY_SIZE(ARENASIZE)];
+        SLIST_HEAD(,s_megablock) megablocks;
+};
+
+struct s_megablock {
+        void *base;
+        unsigned next_free;
+        SLIST_ENTRY(s_megablock) next;
hunk ./src/data/rts/slub.c 31
-struct s_page_info {
+
+struct s_block_info {
hunk ./src/data/rts/slub.c 38
-struct s_page {
-        SLIST_ENTRY(s_page) link;
-        struct s_page_info pi;
+struct s_block {
+        SLIST_ENTRY(s_block) link;
+        struct s_block_info pi;
hunk ./src/data/rts/slub.c 48
-        SLIST_HEAD(,s_page) pages;
-        SLIST_HEAD(,s_page) full_pages;
-        struct s_page_info pi;
+        SLIST_HEAD(,s_block) blocks;
+        SLIST_HEAD(,s_block) full_blocks;
+        struct s_block_info pi;
hunk ./src/data/rts/slub.c 77
-/* page allocator */
+struct s_megablock *
+s_new_megablock(struct s_arena *arena)
+{
+        struct s_megablock *mb = malloc(sizeof(*mb));
+        int ret = posix_memalign(&mb->base,MEGABLOCK_SIZE,MEGABLOCK_SIZE);
+        if(ret != 0) {
+                fprintf(stderr,"Unable to allocate memory with posix_memalign for megablock\n");
+                abort();
+        }
+        int r; J1S(r, gc_inheap, (uintptr_t)mb->base/MEGABLOCK_SIZE);
+        mb->next_free = 0;
+        return mb;
+}
hunk ./src/data/rts/slub.c 91
-static unsigned page_threshold = 8;
+/* block allocator */
hunk ./src/data/rts/slub.c 93
-static struct s_page *
-get_free_page(gc_t gc, struct s_arena *arena) {
-        if(__predict_true(SLIST_FIRST(&arena->free_pages))) {
-                struct s_page *pg = SLIST_FIRST(&arena->free_pages);
-                SLIST_REMOVE_HEAD(&arena->free_pages,link);
-                arena->num_used++;
+static unsigned block_threshold = 8;
+
+static struct s_block *
+get_free_block(gc_t gc, struct s_arena *arena) {
+        arena->block_used++;
+        if(__predict_true(SLIST_FIRST(&arena->free_blocks))) {
+                struct s_block *pg = SLIST_FIRST(&arena->free_blocks);
+                SLIST_REMOVE_HEAD(&arena->free_blocks,link);
hunk ./src/data/rts/slub.c 103
-                if((arena->num_used >= page_threshold)) {
+                if((arena->block_used >= arena->block_threshold)) {
hunk ./src/data/rts/slub.c 106
-                        if(__predict_false((unsigned)arena->num_used * 10 >= page_threshold * 9)) {
-                                page_threshold *= 2;
+                        if(__predict_false((unsigned)arena->block_used * 10 >= arena->block_threshold * 9)) {
+                                arena->block_threshold *= 2;
hunk ./src/data/rts/slub.c 110
-                unsigned next_free = arena->next_free;
-                unsigned found = bitset_find_free(&next_free, BITARRAY_SIZE(ARENASIZE), arena->used);
-                arena->next_free = next_free;
-                int r; J1S(r, gc_inheap, (uintptr_t)arena->base/PAGESIZE + found);
-                arena->num_used++;
-                struct s_page *pg = (struct s_page *)(arena->base + PAGESIZE*found);
+                if(__predict_false(!arena->current_megablock))
+                        arena->current_megablock = s_new_megablock(arena);
+                struct s_megablock *mb = arena->current_megablock;
+                struct s_block *pg = mb->base + BLOCK_SIZE*mb->next_free;
+                mb->next_free++;
+                if(mb->next_free == MEGABLOCK_SIZE / BLOCK_SIZE) {
+                        SLIST_INSERT_HEAD(&arena->megablocks,mb, next);
+                        arena->current_megablock = NULL;
+                }
hunk ./src/data/rts/slub.c 121
+
hunk ./src/data/rts/slub.c 126
-s_cleanup_pages(struct s_arena *arena) {
+s_cleanup_blocks(struct s_arena *arena) {
hunk ./src/data/rts/slub.c 130
-                // 'best' keeps track of the page with the fewest free spots
+                // 'best' keeps track of the block with the fewest free spots
hunk ./src/data/rts/slub.c 134
-                // we had to scan every page anyway, but over many passes
+                // we had to scan every block anyway, but over many passes
hunk ./src/data/rts/slub.c 138
-                struct s_page *best = NULL;
+                struct s_block *best = NULL;
hunk ./src/data/rts/slub.c 140
-                struct s_page *pg = SLIST_FIRST(&sc->pages);
-                struct s_page *fpg = SLIST_FIRST(&sc->full_pages);
-                SLIST_INIT(&sc->pages);
-                SLIST_INIT(&sc->full_pages);
+                struct s_block *pg = SLIST_FIRST(&sc->blocks);
+                struct s_block *fpg = SLIST_FIRST(&sc->full_blocks);
+                SLIST_INIT(&sc->blocks);
+                SLIST_INIT(&sc->full_blocks);
hunk ./src/data/rts/slub.c 149
-                        struct s_page *npg = SLIST_NEXT(pg,link);
+                        struct s_block *npg = SLIST_NEXT(pg,link);
hunk ./src/data/rts/slub.c 151
-                                SLIST_INSERT_HEAD(&sc->full_pages,pg,link);
+                                SLIST_INSERT_HEAD(&sc->full_blocks,pg,link);
hunk ./src/data/rts/slub.c 153
-                                arena->num_used--;
-                                SLIST_INSERT_HEAD(&arena->free_pages,pg,link);
+                                arena->block_used--;
+                                SLIST_INSERT_HEAD(&arena->free_blocks,pg,link);
hunk ./src/data/rts/slub.c 161
-                                                struct s_page *tmp = best;
+                                                struct s_block *tmp = best;
hunk ./src/data/rts/slub.c 165
-                                        SLIST_INSERT_HEAD(&sc->pages,pg,link);
+                                        SLIST_INSERT_HEAD(&sc->blocks,pg,link);
hunk ./src/data/rts/slub.c 175
-                        SLIST_INSERT_HEAD(&sc->pages,best,link);
+                        SLIST_INSERT_HEAD(&sc->blocks,best,link);
hunk ./src/data/rts/slub.c 180
-clear_page_used_bits(unsigned num_entries, struct s_page *pg)
+clear_block_used_bits(unsigned num_entries, struct s_block *pg)
hunk ./src/data/rts/slub.c 191
-        struct s_page *pg = SLIST_FIRST(&sc->pages);
+        struct s_block *pg = SLIST_FIRST(&sc->blocks);
hunk ./src/data/rts/slub.c 193
-                pg = get_free_page(gc, sc->arena);
+                pg = get_free_block(gc, sc->arena);
hunk ./src/data/rts/slub.c 197
-                SLIST_INSERT_HEAD(&sc->pages,pg,link);
+                SLIST_INSERT_HEAD(&sc->blocks,pg,link);
hunk ./src/data/rts/slub.c 199
-                        clear_page_used_bits(sc->num_entries, pg);
+                        clear_block_used_bits(sc->num_entries, pg);
hunk ./src/data/rts/slub.c 211
-                        assert(pg == SLIST_FIRST(&sc->pages));
-                        SLIST_REMOVE_HEAD(&sc->pages,link);
-                        SLIST_INSERT_HEAD(&sc->full_pages,pg,link);
+                        assert(pg == SLIST_FIRST(&sc->blocks));
+                        SLIST_REMOVE_HEAD(&sc->blocks,link);
+                        SLIST_INSERT_HEAD(&sc->full_blocks,pg,link);
hunk ./src/data/rts/slub.c 215
-                assert(S_PAGE(val) == pg);
-                //printf("s_alloc: val: %p s_page: %p size: %i color: %i found: %i num_free: %i\n", val, pg, pg->pi.size, pg->pi.color, found, pg->num_free);
+                assert(s_block(val) == pg);
+                //printf("s_alloc: val: %p s_block: %p size: %i color: %i found: %i num_free: %i\n", val, pg, pg->pi.size, pg->pi.color, found, pg->num_free);
hunk ./src/data/rts/slub.c 227
-        struct s_page *pg = S_PAGE(val);
+        struct s_block *pg = s_block(val);
hunk ./src/data/rts/slub.c 229
-//        printf("s_free:  val: %p s_page: %p size: %i color: %i num_free: %i offset: %i bit: %i\n", val, pg, pg->pi.size, pg->pi.color, pg->num_free, offset, offset/pg->pi.size);
+//        printf("s_free:  val: %p s_block: %p size: %i color: %i num_free: %i offset: %i bit: %i\n", val, pg, pg->pi.size, pg->pi.color, pg->num_free, offset, offset/pg->pi.size);
hunk ./src/data/rts/slub.c 244
-        size_t excess = PAGESIZE - sizeof(struct s_page);
+        size_t excess = BLOCK_SIZE - sizeof(struct s_block);
hunk ./src/data/rts/slub.c 247
-        sc->pi.color = (sizeof(struct s_page) + BITARRAY_SIZE_IN_BYTES(sc->num_entries) + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
-        SLIST_INIT(&sc->pages);
-        SLIST_INIT(&sc->full_pages);
+        sc->pi.color = (sizeof(struct s_block) + BITARRAY_SIZE_IN_BYTES(sc->num_entries) + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
+        SLIST_INIT(&sc->blocks);
+        SLIST_INIT(&sc->full_blocks);
hunk ./src/data/rts/slub.c 262
-                struct s_page *pg = SLIST_FIRST(&sc->pages);
-                struct s_page *fpg = SLIST_FIRST(&sc->full_pages);
+                struct s_block *pg = SLIST_FIRST(&sc->blocks);
+                struct s_block *fpg = SLIST_FIRST(&sc->full_blocks);
hunk ./src/data/rts/slub.c 266
-                                clear_page_used_bits(sc->num_entries,pg);
+                                clear_block_used_bits(sc->num_entries,pg);
hunk ./src/data/rts/slub.c 282
-        struct s_page *pg = S_PAGE(val);
+        struct s_block *pg = S_BLOCK(val);
hunk ./src/data/rts/slub.c 313
-        SLIST_INIT(&arena->free_pages);
-        int ret = posix_memalign(&arena->base,PAGESIZE,ARENASIZE*PAGESIZE);
-        if(ret != 0) {
-                fprintf(stderr,"Unable to allocate memory with posix_memalign\n");
-                exit(1);
-        }
-        arena->next_free = 0;
-        arena->num_used = 0;
-        memset(arena->used,0,sizeof(arena->used));
+        SLIST_INIT(&arena->free_blocks);
+        SLIST_INIT(&arena->megablocks);
+        arena->block_used = 0;
+        arena->block_threshold = 8;
+        arena->current_megablock = NULL;
hunk ./src/data/rts/slub.c 326
-        printf("  header: %lu bytes\n", sizeof(struct s_page) + BITARRAY_SIZE_IN_BYTES(sc->num_entries));
+        printf("  header: %lu bytes\n", sizeof(struct s_block) + BITARRAY_SIZE_IN_BYTES(sc->num_entries));
hunk ./src/data/rts/slub.c 331
-        printf("%20s %9s %9s\n", "page", "num_free", "next_free");
-        struct s_page *pg;
-        SLIST_FOREACH(pg,&sc->pages,link) {
-            printf("%20p %9i %9i\n", pg, pg->num_free, pg->next_free);
+        printf("%20s %9s %9s %s\n", "block", "num_free", "next_free", "status");
+        struct s_block *pg;
+        SLIST_FOREACH(pg,&sc->blocks,link) {
+            printf("%20p %9i %9i %c\n", pg, pg->num_free, pg->next_free, 'P');
hunk ./src/data/rts/slub.c 336
-        printf("  full_pages:\n");
-        SLIST_FOREACH(pg,&sc->full_pages,link) {
-            printf("%20p %9i %9i\n", pg, pg->num_free, pg->next_free);
+        printf("  full_blocks:\n");
+        SLIST_FOREACH(pg,&sc->full_blocks,link) {
+            printf("%20p %9i %9i %c\n", pg, pg->num_free, pg->next_free, 'F');