The hardened_malloc now uses 4 independent arenas by default outside mobile and supports an extended set of slab size classes:
github.com/GrapheneOS/har
It supports slabs with 1 slot now to better support large sizes too. These changes drastically improve performance.
Conversation
Mandatory size classes end with 16KiB because it's the final size in the 2048 spacing class (10240, 12288, 14336, 16384) right before size class spacing matches the 4096 byte page size. There are 4 sizes per spacing (x5, x6, x7, x8) as a balance between different kinds of waste.
1
2
It'd be possible to use a different size class scheme with 8 sizes per spacing [x9, x10, x11, x12, x13, x14, x15, x16] to reach a different balance by having 2x as many size classes (more waste from partial / empty slabs) with finer granularity (a lot less waste from rounding).
1
2
However, it's really not worth it, especially since the earliest size classes (which are by far the most used) can't have fine granularity due to ABI alignment requirements. Doubling # of size classes would also double virtual memory that needs to be reserved for the slab region.
1
2
Another impact of the size classes is determining the # of reallocations needed to grow sequential data structures naively without a growth factor like 2x. 4 sizes per spacing means 4 actual reallocs for 2x growth. It's why I allowed using the size classes for large allocations.
