Relatively simple question: are object references guaranteed to “live” (i.e. retain the object they point to) for the entirety of the lexical scope in which they reside, or is the compiler free to “forget” them in the middle of a function body, after their last use?
Are you asking about language internals, or Ref
? Also, an example to make this concrete would be useful.
More so along the lines of language internals. As an example:
mutable struct Foo
...
end
function baz()
bar = Foo(...)
bar_ptr = ptr_from_objref(bar)
# 'safe' use of bar
func(bar)
# activities that may allocate memory
# but which do not cause bar to escape
...
# 'unsafe' use of bar
func(unsafe_load(bar_ptr))
end
My question is, what are the guarantees (if any) about the aliveness of bar
(and thus the validity of the memory bar
points to) at the ‘unsafe’ use site? I could personally imagine two scenarios:
- The object reference bound to
bar
is held on some GC-reachable stack frame for the duration of any call tobaz
, making it perfectly safe to access that object through a non-retaining pointer within the function’s scope. - The object reference bound to
bar
may not exist in any GC-reachable location (e.g. it gets popped off the stack) after the last point in the function where it is used, making it unsafe to access that object through a non-retaining pointer after said last usage point.
AFAIK the documentation that exists on this is here.
Short summary is neither. It may or may not be live before or after the last use of the variable. Only very few use will guarantee the liveness of the variable, including cconvert
return value during a ccall
and GC.@preserve
.
3 Likes
Okay, that clarifies things a bit. My best interpretation of the docs lines up with @yuyichao’s answer.