Skip to main content

Module class

Module class 

Source
Expand description

Size classes.

§Why eight subdivisions per octave, not four

Two terms of the accounting contract pull against each other: finer classes cut rounding, coarser classes cut span slack (fewer classes means fewer partial spans sitting around). Both are real, so the choice is not taste.

§8.1 of the RFC settles it. Rounding is the only term that scales with the dataset; slack is O(classes × shards) and constant in the data. Spend the constant to shrink the term that scales. Hence eight subdivisions per octave — worst-case rounding ≈ 11.1 %, against the ~20 % that four subdivisions would give.

Below 128 bytes the classes step by 8, and the bound there is absolute rather than relative: at most 7 bytes wasted, but that is 29 % of a 24-byte class. The relative bound cannot be rescued at that end — 8 bytes is the granularity floor, since finer classes would not keep slots 8-byte aligned. Saying “the step is finer so it costs nothing” would have been wrong, and the class table’s own test said so before this comment was written.

§Why spans are one uniform size after all

The first draft sized spans per class, reasoning that a fixed span size makes slack proportional to the class count — which the decision above deliberately increases. Two things overturned it.

Geometry: dealloc finds a pointer’s span by masking, which needs uniform span geometry. Variable spans would need a lookup structure on the free path, paid on every deallocation, to save address space.

And the worry was misplaced. Spans hand out slots by bumping a cursor, so the untouched tail of a span is mapped but never resident — it costs address space, not memory. That is why the accounting splits slack into touched (span_free) and untouched (virgin): only the first is RSS. A large uniform span whose tail is never reached is close to free in the metric that matters.

Constants§

CLASSES
The class table: every size a slot may have, ascending.
MAX_NATIVE_ALIGN
Strongest alignment served by picking a suitable class rather than by over-allocating. Requests above this go to the GlobalAlloc shim’s over-aligned path.
MAX_SMALL
The largest allocation served by a size class. Above this, requests are mapped directly and returned with unmap.
MIN_ALIGN
Alignment every class satisfies natively, because every class is a multiple of it and spans are aligned far beyond it.
NCLASSES
Number of size classes.
SPAN_BYTES
Every span is this many bytes, whatever class it serves. Uniform geometry is what lets dealloc find a span by masking; see the module docs for why the variable-size draft lost. 64 KiB gives the largest class eight slots and the smallest four thousand.

Functions§

index_of
The class index serving size at align, or None when the request belongs on the direct-mapping path (too large, or too strictly aligned to serve from a class).
size_of
Slot size for a class index.
slot_of_offset
Divide a span offset by a class’s slot size via the reciprocal table. off must be below SPAN_BYTES.
slots_per_span
Slots that fit in a span of this class.