On platforms that do not support aligned mmap/VirtualAlloc,
we need to produce heavily aligned blocks to guarantee we can meet
all possible alignment requests.
This commit grabs a block much larger than requested, and then produces
"offcuts" before and after the block of smaller/same "large_classes". This
enables one mmap/virtual alloc request to services many other requests
for aligned memory.
The PAL API previously allowed for returning more memory than asked for.
This was when the PAL performed the alignment work, now this is done in
large alloc, so removing from the PAL.
HEADER_GLOBAL was using non-standard attributes to achieve what C++17
now permits with a keyword. Use the standard formulation.
Update the README to note that gcc is still not recommended, but because
of its poor codegen for 128-bit atomic compare and exchange, rather than
because it doesn't support the attribute used for HEADER_GLOBAL.
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.
The PAL can now advertise that it supports aligned allocation. If it
does not, then the memory provider will do the alignment for it.
This change still leaves the PAL responsible for systematic testing, but
it should now be much easier to lift that out.
Replace them with some very simple constexpr things. This is what the
code used to look like, but it appears that I fundamentally
misunderstood why it didn't work. This version should be a lot more
maintainable.
- Rename MemoryProviderState to PAL to reflect what is now is.
- Hide calls to the PAL's low memory functions behind something that
returns a default value if they're not implemented.
This does not deallocate memory until the OS tells us that we are short
on memory, then tries to decommit all of the cached chunks (except for
the first page, used for the linked lists).
Nowhere near enough testing to commit to master yet!