replace the system allocator in executables

This adds support for replacing the system allocator with jemalloc by
overriding the weak symbols on Linux (including Android). It is disabled
by default with #![no_std] and can be toggled via a compiler switch. It
will be possible to extend this to other platforms in the future.

This results in a performance improvement for memory allocation in C
along with reduced fragmentation. For example, the time spent on LLVM
passes in the Rust compiler on Linux is cut by 10% and peak memory usage
is reduced by 15%.

Closes #18896
It's necessary for Rust's jemalloc to satisfy the needs of third party code calling into jemalloc. That was the primary argument against the last pull request...