I don’t think we do?
We do SROA, i.e. scalar-replacement-of-aggregates, and the scalar replacement lives in registers and maybe spills to the stack.
Afaiu we never do stack-alloc, where we know that the lifetime is bounded by the stackframe and we allocate a fully formed object on the stack (please correct me if if I’m wrong or this changed!).
Afaiu we don’t do eager deterministic de-alloc, i.e. the compiler never generates a matching free
to the malloc
/ ijl_gc_pool_alloc
.
An example is the following:
julia> @noinline g(r) = (r[] += 1);
julia> f(i)=begin r = Ref(i); g(r); r[] end
In a perfect world, g
would have inferred effects that imply that r
doesn’t leak. But we requested the function @noinline
, so we cannot use scalar replacement.
So f
could place the Ref
on the stack instead of the heap; but it would still require an object header.
Or f
could allocate the Ref
on the heap, using jl_gc_pool_alloc
and then free it upon return from g
. But we don’t do that. (we are already paying the price of expensive allocations for non-compacting GC; might as well reap the benefits of opportunistic early free)
Related Feature request: unsafe_free!