This is needed because in some configurations the constructor for the
global placeholder is not called before the first allocation (i.e. when
other globals call the allocator in their constructor) and so we ended
up following a null pointer.
This change introduces a per small sizeclass free list. That can be
used to access the free objects for that sizeclass with minimal
calculations being required.
It changes to a partial bump ptr. We bump allocate a whole OS
page worth of objects at a go, so we don't switch as frequently
between bump and free list allocation.
The code for the fast paths has been restructured to minimise the
work required on the common case, and also it is all inlined for the
common case.
Allocating a zero sized object is moved off the fast path. Ask for 1
byte if you want to be fast.
Will detect corruption caused by either
* Use-after-free
* Double-free
Neither is comprehensive. Full temporal safety is not possible.
This just aids with debugging.
This introduces a new `address_t` type and two new casts: `pointer_cast`
and `address_cast` for casting between an `address_t` and a pointer.
These should make it easier to audit the codebase for casts between
pointers and integers. In particular, the remaining `reinterpret_cast`s
and `pointer_cast`s should be the only places where we could perform
invalid pointer arithmetic.
Also adds a `pointer_offset` helper that adds an offset (in bytes) to a
pointer, preserving its original type. This is a sufficiently common
pattern that it seemed worthwhile to centralise it.
This is a generalisation of `std::nullptr_t` that allows non-0 values of
pointer-sized-but-not-a-pointer thing. `DLList` now takes an
`InvalidPointer`, `nullptr_t`, or some other compatible class as a
sentinel value instead of a `uintptr_t`.
Introduce a wrapper that ensure various fields of meta data, represent
valid indexes into the the address space, and not beyond the current
slab/superslab.
The union in Metaslab provides no benefit in size, as the single byte
it effectively saves will be removed due to padding.
By removing the union, we get stronger properties over sizeclass, and
remove an out-of-bounds access.