Implement arena regind computation using div_info_t.

This eliminates the need to generate an enormous switch statement in
arena_slab_regind.
This commit is contained in:
David Goldblatt 2017-12-20 17:21:56 -08:00 committed by David Goldblatt
parent 21f7c13d0b
commit d41b19f9c7

View File

@ -3,6 +3,7 @@
#include "jemalloc/internal/jemalloc_internal_includes.h" #include "jemalloc/internal/jemalloc_internal_includes.h"
#include "jemalloc/internal/assert.h" #include "jemalloc/internal/assert.h"
#include "jemalloc/internal/div.h"
#include "jemalloc/internal/extent_dss.h" #include "jemalloc/internal/extent_dss.h"
#include "jemalloc/internal/extent_mmap.h" #include "jemalloc/internal/extent_mmap.h"
#include "jemalloc/internal/mutex.h" #include "jemalloc/internal/mutex.h"
@ -39,6 +40,8 @@ const uint64_t h_steps[SMOOTHSTEP_NSTEPS] = {
#undef STEP #undef STEP
}; };
static div_info_t arena_binind_div_info[NBINS];
/******************************************************************************/ /******************************************************************************/
/* /*
* Function prototypes for static functions that are referenced prior to * Function prototypes for static functions that are referenced prior to
@ -247,24 +250,10 @@ arena_slab_regind(extent_t *slab, szind_t binind, const void *ptr) {
assert(((uintptr_t)ptr - (uintptr_t)extent_addr_get(slab)) % assert(((uintptr_t)ptr - (uintptr_t)extent_addr_get(slab)) %
(uintptr_t)bin_infos[binind].reg_size == 0); (uintptr_t)bin_infos[binind].reg_size == 0);
/* Avoid doing division with a variable divisor. */
diff = (size_t)((uintptr_t)ptr - (uintptr_t)extent_addr_get(slab)); diff = (size_t)((uintptr_t)ptr - (uintptr_t)extent_addr_get(slab));
switch (binind) {
#define REGIND_bin_yes(index, reg_size) \ /* Avoid doing division with a variable divisor. */
case index: \ regind = div_compute(&arena_binind_div_info[binind], diff);
regind = diff / (reg_size); \
assert(diff == regind * (reg_size)); \
break;
#define REGIND_bin_no(index, reg_size)
#define SC(index, lg_grp, lg_delta, ndelta, psz, bin, pgs, \
lg_delta_lookup) \
REGIND_bin_##bin(index, (1U<<lg_grp) + (ndelta<<lg_delta))
SIZE_CLASSES
#undef REGIND_bin_yes
#undef REGIND_bin_no
#undef SC
default: not_reached();
}
assert(regind < bin_infos[binind].nregs); assert(regind < bin_infos[binind].nregs);
@ -1929,6 +1918,16 @@ void
arena_boot(void) { arena_boot(void) {
arena_dirty_decay_ms_default_set(opt_dirty_decay_ms); arena_dirty_decay_ms_default_set(opt_dirty_decay_ms);
arena_muzzy_decay_ms_default_set(opt_muzzy_decay_ms); arena_muzzy_decay_ms_default_set(opt_muzzy_decay_ms);
#define REGIND_bin_yes(index, reg_size) \
div_init(&arena_binind_div_info[(index)], (reg_size));
#define REGIND_bin_no(index, reg_size)
#define SC(index, lg_grp, lg_delta, ndelta, psz, bin, pgs, \
lg_delta_lookup) \
REGIND_bin_##bin(index, (1U<<lg_grp) + (ndelta << lg_delta))
SIZE_CLASSES
#undef REGIND_bin_yes
#undef REGIND_bin_no
#undef SC
} }
void void