in src/mem/sizeclasstable.h [204:268]
constexpr SizeClassTable() : fast_(), slow_(), DIV_MULT_SHIFT()
{
size_t max_capacity = 0;
for (sizeclass_compress_t sizeclass = 0;
sizeclass < NUM_SMALL_SIZECLASSES;
sizeclass++)
{
auto& meta = fast_small(sizeclass);
size_t rsize =
bits::from_exp_mant<INTERMEDIATE_BITS, MIN_ALLOC_BITS>(sizeclass);
meta.size = rsize;
size_t slab_bits = bits::max(
bits::next_pow2_bits_const(MIN_OBJECT_COUNT * rsize), MIN_CHUNK_BITS);
meta.slab_mask = bits::one_at_bit(slab_bits) - 1;
auto& meta_slow = slow(sizeclass_t::from_small_class(sizeclass));
meta_slow.capacity =
static_cast<uint16_t>((meta.slab_mask + 1) / rsize);
meta_slow.waking =
#ifdef SNMALLOC_CHECK_CLIENT
static_cast<uint16_t>(meta_slow.capacity / 4);
#else
static_cast<uint16_t>(bits::min((meta_slow.capacity / 4), 32));
#endif
if (meta_slow.capacity > max_capacity)
{
max_capacity = meta_slow.capacity;
}
}
// Get maximum precision to calculate largest division range.
DIV_MULT_SHIFT = bits::BITS - bits::next_pow2_bits_const(max_capacity);
for (sizeclass_compress_t sizeclass = 0;
sizeclass < NUM_SMALL_SIZECLASSES;
sizeclass++)
{
// Calculate reciprocal division constant.
auto& meta = fast_small(sizeclass);
meta.div_mult =
((bits::one_at_bit(DIV_MULT_SHIFT) - 1) / meta.size) + 1;
size_t zero = 0;
meta.mod_zero_mult = (~zero / meta.size) + 1;
}
for (size_t sizeclass = 0; sizeclass < bits::BITS; sizeclass++)
{
auto lsc = sizeclass_t::from_large_class(sizeclass);
auto& meta = fast(lsc);
meta.size = sizeclass == 0 ? 0 : bits::one_at_bit(lsc.as_large());
meta.slab_mask = meta.size - 1;
// The slab_mask will do all the necessary work, so
// perform identity multiplication for the test.
meta.mod_zero_mult = 1;
// The slab_mask will do all the necessary work for division
// so collapse the calculated offset.
meta.div_mult = 0;
}
}