diff options
author | Jason Evans <jasone@canonware.com> | 2016-04-08 21:16:19 (GMT) |
---|---|---|
committer | Jason Evans <jasone@canonware.com> | 2016-05-16 19:21:27 (GMT) |
commit | 3aea827f5e7d07ce156476bba8a843640969de51 (patch) | |
tree | b850eeab9f8b8d2d7fa5876cc91b3d9a74b6476c | |
parent | 7bb00ae9d656b3d3ea9a01777cf1a13ab97f2430 (diff) | |
download | jemalloc-3aea827f5e7d07ce156476bba8a843640969de51.zip jemalloc-3aea827f5e7d07ce156476bba8a843640969de51.tar.gz jemalloc-3aea827f5e7d07ce156476bba8a843640969de51.tar.bz2 |
Simplify run quantization.
-rw-r--r-- | include/jemalloc/internal/arena.h | 2 | ||||
-rwxr-xr-x | include/jemalloc/internal/size_classes.sh | 16 | ||||
-rw-r--r-- | src/arena.c | 179 | ||||
-rw-r--r-- | src/jemalloc.c | 3 |
4 files changed, 31 insertions, 169 deletions
diff --git a/include/jemalloc/internal/arena.h b/include/jemalloc/internal/arena.h index bb65c7a..11863fc 100644 --- a/include/jemalloc/internal/arena.h +++ b/include/jemalloc/internal/arena.h @@ -569,7 +569,7 @@ unsigned arena_nthreads_get(arena_t *arena, bool internal); void arena_nthreads_inc(arena_t *arena, bool internal); void arena_nthreads_dec(arena_t *arena, bool internal); arena_t *arena_new(tsdn_t *tsdn, unsigned ind); -bool arena_boot(void); +void arena_boot(void); void arena_prefork0(tsdn_t *tsdn, arena_t *arena); void arena_prefork1(tsdn_t *tsdn, arena_t *arena); void arena_prefork2(tsdn_t *tsdn, arena_t *arena); diff --git a/include/jemalloc/internal/size_classes.sh b/include/jemalloc/internal/size_classes.sh index d1b1db1..440953a 100755 --- a/include/jemalloc/internal/size_classes.sh +++ b/include/jemalloc/internal/size_classes.sh @@ -158,7 +158,6 @@ size_classes() { lg_tiny_maxclass='"NA"' nbins=0 npsizes=0 - slab_maxpgs=0 # Tiny size classes. ndelta=0 @@ -175,9 +174,6 @@ size_classes() { fi if [ ${bin} != "no" ] ; then nbins=$((${index} + 1)) - if [ ${pgs} -gt ${slab_maxpgs} ] ; then - slab_maxpgs=${pgs} - fi fi ntbins=$((${ntbins} + 1)) lg_tiny_maxclass=${lg_grp} # Final written value is correct. @@ -200,9 +196,6 @@ size_classes() { if [ ${psz} = "yes" ] ; then npsizes=$((${npsizes} + 1)) fi - if [ ${pgs} -gt ${slab_maxpgs} ] ; then - slab_maxpgs=${pgs} - fi fi while [ ${ndelta} -lt ${g} ] ; do size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax} @@ -211,9 +204,6 @@ size_classes() { if [ ${psz} = "yes" ] ; then npsizes=$((${npsizes} + 1)) fi - if [ ${pgs} -gt ${slab_maxpgs} ] ; then - slab_maxpgs=${pgs} - fi done # All remaining groups. @@ -240,9 +230,6 @@ size_classes() { nbins=$((${index} + 1)) # Final written value is correct: small_maxclass="((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))" - if [ ${pgs} -gt ${slab_maxpgs} ] ; then - slab_maxpgs=${pgs} - fi if [ ${lg_g} -gt 0 ] ; then lg_large_minclass=$((${lg_grp} + 1)) else @@ -269,7 +256,6 @@ size_classes() { # - lg_tiny_maxclass # - lookup_maxclass # - small_maxclass - # - slab_maxpgs # - lg_large_minclass # - huge_maxclass } @@ -303,7 +289,6 @@ cat <<EOF * LG_TINY_MAXCLASS: Lg of maximum tiny size class. * LOOKUP_MAXCLASS: Maximum size class included in lookup table. * SMALL_MAXCLASS: Maximum small size class. - * SLAB_MAXPGS: Maximum pages in small size class run. * LG_LARGE_MINCLASS: Lg of minimum large size class. * HUGE_MAXCLASS: Maximum (huge) size class. */ @@ -329,7 +314,6 @@ for lg_z in ${lg_zarr} ; do echo "#define LG_TINY_MAXCLASS ${lg_tiny_maxclass}" echo "#define LOOKUP_MAXCLASS ${lookup_maxclass}" echo "#define SMALL_MAXCLASS ${small_maxclass}" - echo "#define SLAB_MAXPGS ${slab_maxpgs}" echo "#define LG_LARGE_MINCLASS ${lg_large_minclass}" echo "#define HUGE_MAXCLASS ${huge_maxclass}" echo "#endif" diff --git a/src/arena.c b/src/arena.c index a0fd2ce..06a6985 100644 --- a/src/arena.c +++ b/src/arena.c @@ -34,9 +34,6 @@ size_t map_bias; size_t map_misc_offset; size_t arena_maxrun; /* Max run size for arenas. */ size_t large_maxclass; /* Max large size class. */ -static bool *small_run_tab; /* Valid small run page multiples. */ -static size_t *run_quantize_floor_tab; /* run_quantize_floor() memoization. */ -static size_t *run_quantize_ceil_tab; /* run_quantize_ceil() memoization. */ unsigned nlclasses; /* Number of large size classes. */ unsigned nhclasses; /* Number of huge size classes. */ @@ -86,84 +83,6 @@ arena_run_addr_comp(const arena_chunk_map_misc_t *a, ph_gen(static UNUSED, arena_run_heap_, arena_run_heap_t, arena_chunk_map_misc_t, ph_link, arena_run_addr_comp) -static size_t -run_quantize_floor_compute(size_t size) -{ - size_t qsize; - - assert(size != 0); - assert(size == PAGE_CEILING(size)); - - /* Don't change sizes that are valid small run sizes. */ - if (size <= (ZU(SLAB_MAXPGS) << LG_PAGE) && small_run_tab[size >> - LG_PAGE]) - return (size); - - /* - * Round down to the nearest run size that can actually be requested - * during normal large allocation. Add large_pad so that cache index - * randomization can offset the allocation from the page boundary. - */ - qsize = index2size(size2index(size - large_pad + 1) - 1) + large_pad; - if (qsize <= SMALL_MAXCLASS + large_pad) - return (run_quantize_floor_compute(size - large_pad)); - assert(qsize <= size); - return (qsize); -} - -static size_t -run_quantize_ceil_compute_hard(size_t size) -{ - size_t large_run_size_next; - - assert(size != 0); - assert(size == PAGE_CEILING(size)); - - /* - * Return the next quantized size greater than the input size. - * Quantized sizes comprise the union of run sizes that back small - * region runs, and run sizes that back large regions with no explicit - * alignment constraints. - */ - - if (size > SMALL_MAXCLASS) { - large_run_size_next = PAGE_CEILING(index2size(size2index(size - - large_pad) + 1) + large_pad); - } else - large_run_size_next = SIZE_T_MAX; - if ((size >> LG_PAGE) >= ZU(SLAB_MAXPGS)) - return (large_run_size_next); - - while (true) { - size += PAGE; - assert(size <= (ZU(SLAB_MAXPGS) << LG_PAGE)); - if (small_run_tab[size >> LG_PAGE]) { - if (large_run_size_next < size) - return (large_run_size_next); - return (size); - } - } -} - -static size_t -run_quantize_ceil_compute(size_t size) -{ - size_t qsize = run_quantize_floor_compute(size); - - if (qsize < size) { - /* - * Skip a quantization that may have an adequately large run, - * because under-sized runs may be mixed in. This only happens - * when an unusual size is requested, i.e. for aligned - * allocation, and is just one of several places where linear - * search would potentially find sufficiently aligned available - * memory somewhere lower. - */ - qsize = run_quantize_ceil_compute_hard(qsize); - } - return (qsize); -} - #ifdef JEMALLOC_JET #undef run_quantize_floor #define run_quantize_floor JEMALLOC_N(n_run_quantize_floor) @@ -172,13 +91,27 @@ static size_t run_quantize_floor(size_t size) { size_t ret; + pszind_t pind; assert(size > 0); assert(size <= HUGE_MAXCLASS); assert((size & PAGE_MASK) == 0); - ret = run_quantize_floor_tab[(size >> LG_PAGE) - 1]; - assert(ret == run_quantize_floor_compute(size)); + assert(size != 0); + assert(size == PAGE_CEILING(size)); + + pind = psz2ind(size - large_pad + 1); + if (pind == 0) { + /* + * Avoid underflow. This short-circuit would also do the right + * thing for all sizes in the range for which there are + * PAGE-spaced size classes, but it's simplest to just handle + * the one case that would cause erroneous results. + */ + return (size); + } + ret = pind2sz(pind - 1) + large_pad; + assert(ret <= size); return (ret); } #ifdef JEMALLOC_JET @@ -200,8 +133,18 @@ run_quantize_ceil(size_t size) assert(size <= HUGE_MAXCLASS); assert((size & PAGE_MASK) == 0); - ret = run_quantize_ceil_tab[(size >> LG_PAGE) - 1]; - assert(ret == run_quantize_ceil_compute(size)); + ret = run_quantize_floor(size); + if (ret < size) { + /* + * Skip a quantization that may have an adequately large run, + * because under-sized runs may be mixed in. This only happens + * when an unusual size is requested, i.e. for aligned + * allocation, and is just one of several places where linear + * search would potentially find sufficiently aligned available + * memory somewhere lower. + */ + ret = pind2sz(psz2ind(ret - large_pad + 1)) + large_pad; + } return (ret); } #ifdef JEMALLOC_JET @@ -3483,64 +3426,7 @@ arena_new(tsdn_t *tsdn, unsigned ind) return (arena); } -static bool -small_run_size_init(void) -{ - - assert(SLAB_MAXPGS != 0); - - small_run_tab = (bool *)base_alloc(NULL, sizeof(bool) * SLAB_MAXPGS); - if (small_run_tab == NULL) - return (true); - -#define TAB_INIT_bin_yes(index, size) { \ - const arena_bin_info_t *bin_info = \ - &arena_bin_info[index]; \ - small_run_tab[bin_info->run_size >> LG_PAGE] = true; \ - } -#define TAB_INIT_bin_no(index, size) -#define SC(index, lg_grp, lg_delta, ndelta, psz, bin, run_size, \ - lg_delta_lookup) \ - TAB_INIT_bin_##bin(index, (ZU(1)<<lg_grp) + (ZU(ndelta)<<lg_delta)) - SIZE_CLASSES -#undef TAB_INIT_bin_yes -#undef TAB_INIT_bin_no -#undef SC - - return (false); -} - -static bool -run_quantize_init(void) -{ - size_t run_quantize_max; - unsigned i; - - run_quantize_max = chunksize + large_pad; - - run_quantize_floor_tab = (size_t *)base_alloc(NULL, sizeof(size_t) * - (run_quantize_max >> LG_PAGE)); - if (run_quantize_floor_tab == NULL) - return (true); - - run_quantize_ceil_tab = (size_t *)base_alloc(NULL, sizeof(size_t) * - (run_quantize_max >> LG_PAGE)); - if (run_quantize_ceil_tab == NULL) - return (true); - - for (i = 1; i <= run_quantize_max >> LG_PAGE; i++) { - size_t run_size = i << LG_PAGE; - - run_quantize_floor_tab[i-1] = - run_quantize_floor_compute(run_size); - run_quantize_ceil_tab[i-1] = - run_quantize_ceil_compute(run_size); - } - - return (false); -} - -bool +void arena_boot(void) { unsigned i; @@ -3586,13 +3472,6 @@ arena_boot(void) assert(large_maxclass > 0); nlclasses = size2index(large_maxclass) - size2index(SMALL_MAXCLASS); nhclasses = NSIZES - nlclasses - NBINS; - - if (small_run_size_init()) - return (true); - if (run_quantize_init()) - return (true); - - return (false); } void diff --git a/src/jemalloc.c b/src/jemalloc.c index 849e941..929f3b8 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -1234,8 +1234,7 @@ malloc_init_hard_a0_locked() return (true); if (config_prof) prof_boot1(); - if (arena_boot()) - return (true); + arena_boot(); if (config_tcache && tcache_boot(TSDN_NULL)) return (true); if (malloc_mutex_init(&arenas_lock, "arenas", WITNESS_RANK_ARENAS)) |