Skip to main content

Crate inillucent_alloc

Crate inillucent_alloc 

Source
Expand description

A size-classed free list over the system allocator.

Invariant: it recycles rather than accumulating. A bump arena that never frees is the shortest thing to write and the wrong thing to ship: thirty rounds of the gate’s plan would grow it without bound, and what it measured would be page faults rather than allocation. This keeps one intrusive list per size class, capped, and hands a block back to the system allocator when the class is full.

§Why the engine has one at all

Because allocation is where a compile goes. A trivial compile was measured at 25 heap allocations, with the Windows C runtime heap at 59% of the time, and a size-classed free list at 17% overall on the same plan - which is why Phase 3’s Part E names it the cheapest first move rather than one of the several structural changes beside it. The same shape is visible outside compilation: CREATE INDEX over a hundred thousand rows builds two allocations per row just to hold the key and the rowid, and the gate’s schema.index spends more time in its scan than SQLite spends on the whole statement.

What it removes is exactly what was in question: the size lookup, the locking and the per-call bookkeeping the system allocator does. It does not try to be a better allocator in general - above LARGEST and for any alignment the system’s own guarantee does not cover, the request is forwarded unchanged.

§Why it never allocates

An allocator that allocates re-enters itself, and a re-entrant allocator is a deadlock or a stack overflow waiting for the right allocation pattern. So the free lists are intrusive: a freed block holds the pointer to the next free block of its class in its own first eight bytes, and the heads live in a fixed-size array of Cells in thread-local storage. Nothing here calls Vec, Box, or anything that could.

§Why it is a crate of its own

Because every other production crate in this workspace carries #![forbid(unsafe_code)], and an allocator cannot. Putting it here keeps that true everywhere it is true today and confines the unsafe to one file that has nothing else in it - no dependencies, first-party or otherwise, so there is nothing it could re-enter itself through.

§Why it is per thread

Because a shared list needs a lock, and the lock is most of what this exists to remove. A block allocated on one thread and freed on another goes onto the freeing thread’s list, which is safe - the block is memory of a known class, and the class is derived from the layout the caller hands back - and at worst moves a block between threads. The per-class cap bounds what that can cost.

Structs§

Pooled
A size-classed free list over the system allocator.

Constants§

LARGEST
The largest allocation the free list handles itself.