Borrow checker with GC fallback?

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!

1 Like