`malloc` + `free` are unknown function calls, they can't be inlined, don't understand the semantics of your language, the strategy behind them is quite generic, etc.
A GC that's integrated with a programming language can do much much better (different heaps for short and long lived allocations, for example).
One can do even better by supporting custom "pluggable" allocators, and not just a single global allocator like Rust does at present. Some of these allocators could even implement GC-like logic internally.
A GC that's integrated with a programming language can do much much better (different heaps for short and long lived allocations, for example).