9b0cbf0850
Make promotion of sampled small objects to large objects mandatory, so that profiling metadata can always be stored in the chunk map, rather than requiring one pointer per small region in each small-region page run. In practice the non-prof-promote code was only useful when using jemalloc to track all objects and report them as leaks at program exit. However, Valgrind is at least as good a tool for this particular use case. Furthermore, the non-prof-promote code is getting in the way of some optimizations that will make heap profiling much cheaper for the predominant use case (sampling a small representative proportion of all allocations).
122 lines
3.2 KiB
Bash
Executable File
122 lines
3.2 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# The following limits are chosen such that they cover all supported platforms.
|
|
|
|
# Range of quanta.
|
|
lg_qmin=3
|
|
lg_qmax=4
|
|
|
|
# The range of tiny size classes is [2^lg_tmin..2^(lg_q-1)].
|
|
lg_tmin=3
|
|
|
|
# Range of page sizes.
|
|
lg_pmin=12
|
|
lg_pmax=16
|
|
|
|
pow2() {
|
|
e=$1
|
|
pow2_result=1
|
|
while [ ${e} -gt 0 ] ; do
|
|
pow2_result=$((${pow2_result} + ${pow2_result}))
|
|
e=$((${e} - 1))
|
|
done
|
|
}
|
|
|
|
cat <<EOF
|
|
/* This file was automatically generated by size_classes.sh. */
|
|
/******************************************************************************/
|
|
#ifdef JEMALLOC_H_TYPES
|
|
|
|
EOF
|
|
|
|
lg_q=${lg_qmin}
|
|
while [ ${lg_q} -le ${lg_qmax} ] ; do
|
|
lg_t=${lg_tmin}
|
|
while [ ${lg_t} -le ${lg_q} ] ; do
|
|
lg_p=${lg_pmin}
|
|
while [ ${lg_p} -le ${lg_pmax} ] ; do
|
|
echo "#if (LG_TINY_MIN == ${lg_t} && LG_QUANTUM == ${lg_q} && LG_PAGE == ${lg_p})"
|
|
echo "#define SIZE_CLASSES_DEFINED"
|
|
pow2 ${lg_q}; q=${pow2_result}
|
|
pow2 ${lg_t}; t=${pow2_result}
|
|
pow2 ${lg_p}; p=${pow2_result}
|
|
bin=0
|
|
psz=0
|
|
sz=${t}
|
|
delta=$((${sz} - ${psz}))
|
|
echo "/* SIZE_CLASS(bin, delta, sz) */"
|
|
echo "#define SIZE_CLASSES \\"
|
|
|
|
# Tiny size classes.
|
|
while [ ${sz} -lt ${q} ] ; do
|
|
echo " SIZE_CLASS(${bin}, ${delta}, ${sz}) \\"
|
|
bin=$((${bin} + 1))
|
|
psz=${sz}
|
|
sz=$((${sz} + ${sz}))
|
|
delta=$((${sz} - ${psz}))
|
|
done
|
|
# Quantum-multiple size classes. For each doubling of sz, as many as 4
|
|
# size classes exist. Their spacing is the greater of:
|
|
# - q
|
|
# - sz/4, where sz is a power of 2
|
|
while [ ${sz} -lt ${p} ] ; do
|
|
if [ ${sz} -ge $((${q} * 4)) ] ; then
|
|
i=$((${sz} / 4))
|
|
else
|
|
i=${q}
|
|
fi
|
|
next_2pow=$((${sz} * 2))
|
|
while [ ${sz} -lt $next_2pow ] ; do
|
|
echo " SIZE_CLASS(${bin}, ${delta}, ${sz}) \\"
|
|
bin=$((${bin} + 1))
|
|
psz=${sz}
|
|
sz=$((${sz} + ${i}))
|
|
delta=$((${sz} - ${psz}))
|
|
done
|
|
done
|
|
echo
|
|
echo "#define NBINS ${bin}"
|
|
echo "#define SMALL_MAXCLASS ${psz}"
|
|
echo "#endif"
|
|
echo
|
|
lg_p=$((${lg_p} + 1))
|
|
done
|
|
lg_t=$((${lg_t} + 1))
|
|
done
|
|
lg_q=$((${lg_q} + 1))
|
|
done
|
|
|
|
cat <<EOF
|
|
#ifndef SIZE_CLASSES_DEFINED
|
|
# error "No size class definitions match configuration"
|
|
#endif
|
|
#undef SIZE_CLASSES_DEFINED
|
|
/*
|
|
* The small_size2bin lookup table uses uint8_t to encode each bin index, so we
|
|
* cannot support more than 256 small size classes. Further constrain NBINS to
|
|
* 255 since all small size classes, plus a "not small" size class must be
|
|
* stored in 8 bits of arena_chunk_map_t's bits field.
|
|
*/
|
|
#if (NBINS > 255)
|
|
# error "Too many small size classes"
|
|
#endif
|
|
|
|
#endif /* JEMALLOC_H_TYPES */
|
|
/******************************************************************************/
|
|
#ifdef JEMALLOC_H_STRUCTS
|
|
|
|
|
|
#endif /* JEMALLOC_H_STRUCTS */
|
|
/******************************************************************************/
|
|
#ifdef JEMALLOC_H_EXTERNS
|
|
|
|
|
|
#endif /* JEMALLOC_H_EXTERNS */
|
|
/******************************************************************************/
|
|
#ifdef JEMALLOC_H_INLINES
|
|
|
|
|
|
#endif /* JEMALLOC_H_INLINES */
|
|
/******************************************************************************/
|
|
EOF
|