[optimize and clean up code based on profiling
John Meacham <john@repetae.net>**20100408001545
 Ignore-this: a345682ba45c5b963d467703b9208e60
] hunk ./src/data/rts/jhc_jgc.c 225
-        saved_gc = gc_stack_base = malloc(8*8192*sizeof(gc_stack_base[0]));
+        saved_gc = gc_stack_base = malloc((1UL << 18)*sizeof(gc_stack_base[0]));
hunk ./src/data/rts/slub.c 52
-/* this finds a bit that isn't set, sets it, and returns it */
-static int
-bitset_find_free(int *next_free,int n,bitarray_t ba[static n]) {
+/* This finds a bit that isn't set, sets it, then returns its index.  It
+ * assumes that a bit is available to be found, otherwise it goes into an
+ * infinite loop. */
+
+static unsigned
+bitset_find_free(unsigned *next_free,int n,bitarray_t ba[static n]) {
hunk ./src/data/rts/slub.c 59
-        int i = *next_free;
-        for(; i < n; i++) {
-                if(~ba[i]) goto found;
-        }
-        for(i = 0; i < *next_free; i++) {
-                if(~ba[i]) goto found;
-        }
-        return -1;
-found: ;
-       int o = __builtin_ffsl(~ba[i]);
-       assert(o);
-       ba[i] |= (1UL << (o - 1));
-       *next_free = i;
-       return (i*BITS_PER_UNIT + (o - 1));
+        unsigned i = *next_free;
+        do {
+                int o = __builtin_ffsl(~ba[i]);
+                if(__predict_true(o)) {
+                        ba[i] |= (1UL << (o - 1));
+                        *next_free = i;
+                        return (i*BITS_PER_UNIT + (o - 1));
+                }
+                i = (i + 1) % n;
+                assert(i != *next_free);
+        } while (1);
hunk ./src/data/rts/slub.c 78
-        if(__predict_false(arena->num_used >= page_threshold)) {
-                gc_perform_gc(gc);
-                // if we are stil using 80% of the heap after a gc, raise the threshold.
-                if(__predict_false((unsigned)arena->num_used * 10 >= page_threshold * 9)) {
-                        page_threshold *= 2;
-                }
-        }
-        struct s_page *pg;
hunk ./src/data/rts/slub.c 79
-                pg = SLIST_FIRST(&arena->free_pages);
+                struct s_page *pg = SLIST_FIRST(&arena->free_pages);
hunk ./src/data/rts/slub.c 81
+                arena->num_used++;
+                return pg;
hunk ./src/data/rts/slub.c 84
-                int next_free = arena->next_free;
-                int found = bitset_find_free(&next_free, BITARRAY_SIZE(ARENASIZE), arena->used);
+                if((arena->num_used >= page_threshold)) {
+                        gc_perform_gc(gc);
+                        // if we are still using 80% of the heap after a gc, raise the threshold.
+                        if(__predict_false((unsigned)arena->num_used * 10 >= page_threshold * 9)) {
+                                page_threshold *= 2;
+                        }
+                }
+                unsigned next_free = arena->next_free;
+                unsigned found = bitset_find_free(&next_free, BITARRAY_SIZE(ARENASIZE), arena->used);
hunk ./src/data/rts/slub.c 94
-                if(found == -1)
-                        return NULL;
-                int r;
-                J1S(r, gc_inheap, (uintptr_t)arena->base/PAGESIZE + found);
-                pg = (struct s_page *)(arena->base + PAGESIZE*found);
+                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);
+                pg->num_free = 0;
+                return pg;
hunk ./src/data/rts/slub.c 100
-        arena->num_used++;
-        //        printf("Allocing: %p %u\n", pg, arena->num_used);
-        return pg;
hunk ./src/data/rts/slub.c 132
-//                                BIT_UNSET(arena->used,((uintptr_t)pg - (uintptr_t)arena->base) / PAGESIZE);
hunk ./src/data/rts/slub.c 139
-                                                best = pg;
-                                                pg = tmp;
+                                                best = pg; pg = tmp;
hunk ./src/data/rts/slub.c 157
-clear_page_used_bits(struct s_cache *sc, struct s_page *pg)
+clear_page_used_bits(unsigned num_entries, struct s_page *pg)
hunk ./src/data/rts/slub.c 159
-        pg->num_free = sc->num_entries;
-        memset(pg->used,0,BITARRAY_SIZE_IN_BYTES(sc->num_entries));
-//      unsigned max = BITARRAY_SIZE(sc->num_entries);
-//      for(unsigned i = 0;i < max; i++)
-//              pg->used[i] = 0;
-        int excess = sc->num_entries % BITS_PER_UNIT;
-        if(excess)
-                pg->used[BITARRAY_SIZE(sc->num_entries) - 1] = ~((1UL << excess) - 1);
+        pg->num_free = num_entries;
+        memset(pg->used,0,BITARRAY_SIZE_IN_BYTES(num_entries) - sizeof(pg->used[0]));
+        int excess = num_entries % BITS_PER_UNIT;
+        pg->used[BITARRAY_SIZE(num_entries) - 1] = ~((1UL << excess) - 1);
hunk ./src/data/rts/slub.c 168
-        struct s_page *pg;
-        int found = 0;
-        assert(sc);
-        pg = SLIST_FIRST(&sc->pages);
+        struct s_page *pg = SLIST_FIRST(&sc->pages);
hunk ./src/data/rts/slub.c 175
-                clear_page_used_bits(sc,pg);
+                if(sc->num_entries != pg->num_free)
+                        clear_page_used_bits(sc->num_entries, pg);
hunk ./src/data/rts/slub.c 178
+                pg->num_free = sc->num_entries - 1;
+                return (uintptr_t *)pg + pg->pi.color;
hunk ./src/data/rts/slub.c 181
-                int next_free = pg->next_free;
-                found = bitset_find_free(&next_free,BITARRAY_SIZE(sc->num_entries),pg->used);
+                __builtin_prefetch(pg->used,1);
+                pg->num_free--;
+                unsigned next_free = pg->next_free;
+                unsigned found = bitset_find_free(&next_free,BITARRAY_SIZE(sc->num_entries),pg->used);
hunk ./src/data/rts/slub.c 186
-                assert(found != -1);
-        }
-        uintptr_t *pgp = (uintptr_t *)pg + pg->pi.color;
-        void *val = &pgp[found *pg->pi.size];
-        pg->num_free--;
-        if(__predict_false(0 == pg->num_free)) {
-                assert(pg == SLIST_FIRST(&sc->pages));
-                SLIST_REMOVE_HEAD(&sc->pages,link);
-                SLIST_INSERT_HEAD(&sc->full_pages,pg,link);
+                void *val = (uintptr_t *)pg + pg->pi.color + found*pg->pi.size;
+                if(__predict_false(0 == pg->num_free)) {
+                        assert(pg == SLIST_FIRST(&sc->pages));
+                        SLIST_REMOVE_HEAD(&sc->pages,link);
+                        SLIST_INSERT_HEAD(&sc->full_pages,pg,link);
+                }
+                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);
+                return val;
hunk ./src/data/rts/slub.c 196
-        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);
-        return val;
hunk ./src/data/rts/slub.c 244
-                                clear_page_used_bits(sc,pg);
+                                clear_page_used_bits(sc->num_entries,pg);