The nix system allocator passed Linux's MAP_ANONYMOUS (0x20) on every
platform. On macOS and the BSDs MAP_ANON is 0x1000, so mmap got a file
mapping of fd -1, failed, and malloc always returned nil. It now uses
the C constants, as builtin/closure does. Trimming a segment on Linux
called mremap, which glibc declares only with _GNU_SOURCE, so clang and
gcc 14 rejected the generated C and V retried with V 0.5.2; it now
unmaps the tail with munmap on every system, as it did on macOS.
On Linux the port also diverged from upstream dlmalloc. left_bits was
written (x << 1) | (~(x << 1)) + 1, and since V gives | and + the same
precedence it was 0 for every input, so tmalloc_large never moved on to
a larger tree bin and the small-bin path disabled in #13120 read an
uninitialized bin. insert_large_chunk had the same trap in its child
index, putting every chunk under child[1], and tested the child slot's
address instead of its contents, so a second size in a tree bin
dereferenced nil. tmalloc_small started from the whole size of the
first chunk instead of its remainder, the disabled small-bin path gave
its remainder the request size, sys_alloc set a prepended segment's
size instead of growing it, add_segment compared a fencepost's contents
with the segment end instead of its address, and realloc did not free
the block it moved away from. With these fixed the small-bin path
matches upstream again and is enabled. The unused Chunk.prev() now
subtracts prev_foot.
The test checks left_bits, Chunk.prev and the tree descent directly,
and runs an allocate/write/realloc/free stress with pattern, overlap,
alignment and chunk header checks, over mmap and over an arena that
hands out regions above, below and away from the previous ones, so
every sys_alloc path runs on every platform.
The checker ignores errors in library bodies that no program code
calls, so these stayed hidden until a program reached them. A probe
that reports every library body error, run on every vlib module for
macOS, Linux, Windows and FreeBSD, found five.
v.mir: #30531 rewrote `typ.elem_type > 0` to `typ.elem_type_text() >
0`, which does not exist on ssa.Type, so mir.lower_from_ssa and
Module.type_size/type_align did not compile. Restore the comparison.
dlmalloc: `left_bits(1 << idx)` passed an int to a u32 parameter, so
every program calling dlmalloc.malloc failed to compile. Shift a u32
one instead.
sokol.sapp: the X11 drop list parser compared a char with rune
literals, so sapp's internal Linux test did not compile. Read the
characters as u8.
fasthttp: accept_loop stores its &Server parameter in each IocpConn,
which the checker rejects unless Server is @[heap], as it already is on
Linux and BSD. Mark the Windows Server @[heap] too, so a program that
calls Server.run directly compiles on Windows.
builtin.overflow: the __builtin_*_overflow declarations used the V1
`any` type, so the gcc/clang branches did not type-check. Declare them
as C variadic functions; the generated C is unchanged.
Add internal tests for v.mir and dlmalloc, which had none, so `v test`
type-checks every body of both modules from now on.