New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/compile: open-coded defers keep pointer arguments alive past the deferred call #44623
Comments
Yes, we now keep all open-defer arg slots live throughout the whole function. This is to deal with all the unusual cases where a function may never exit (at all or when it reaches certain points in the function). This makes it very hard to use liveness analysis to determine if a defer arg is no longer alive. At these points where the function can't exit, it looks like the defer args shouldn't be live, but of course the function may panic at almost any point, so they actually must be kept live. Keith and I decided we didn't want to make the compiler more complex, just to adjust the liveness properties of variables that people shouldn't really be depending on. But I will ponder a bit and see if there is any relatively easy approach that we are still missing. |
In order to not scan the arguments, we'd have to make the pointer bitmap dependent on more than just the PC. It would also have to depend on the bitmask of defers. Could we zero the (pointer-containing) argument slots in the frame just before we call the deferred function? It could be tricky to do the zeroing while assembling the arguments, but may be possible. |
We already zero out all defer arg slots that have pointers in them at the beginning of the function. Those will still be zero if the defer was not actually activated. So, I don't think you have to depend on the defer bitmask, right? |
Right, but I don't think that's the issue here. The issue is if the defer is activated, and then at the end of the function we run it, it returns, some other defer is then run, and at that point we do a GC scan of the stack. Are the arguments for the defer that already completed still alive? |
It looks like open-coded defers are keeping their arguments alive past the deferred call:
Failing test case using open-coded defer: https://play.golang.org/p/9SEiOeaLmCS
Passing test case using heap-allocated defer: https://play.golang.org/p/BWEQuC5EowK
In these tests, there are two deferred function calls. The first call needs
p
kept alive, but the second does not. We should be able to collectp
(and run its finalizer) as soon as the first deferred function call returns. The heap-allocated defer does this, but the open-coded one does not./cc @danscales
The text was updated successfully, but these errors were encountered: