Fix a false positive. The loops in the pagemap accessor are too
complicated for the static analyser to check, so it doesn't spot that a
non-null return is impossible.
Change the result of `operator=` on `Mod` to return `Mod&`. In this
example:
```c++
Mod<4, int> a;
int b = (a = 8);
```
The value of `b` will now be 0, not 8, and will equal the value of `a`.
Hopefully this is less confusing to users of this class.
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`.
We don't follow the pointers passed into the pagemap directly, but
instead use them to calculate indexs into the pagemap. Use uintptr_t
means it is easier to perform address arithmetic, and not have casts
back to void* everywhere.
Rather than unconditionally storing a pointer to the pagemap and
initialising this with a global, we now provide a choice of three
compile-time options for how the pagemap should be accessed.
If you're creating a new allocator and the pagemap comes from a library
that exports the pagemap accessor function but not the pagemap symbol,
you need to be able to replace this.
- Don't run an expensive functionality test in debug builds.
- Don't run the different cache configurations (they're probably going
away soon because they help only in synthetic benchmarks).
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.