Skip to content
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

Open
mdempsky opened this issue Feb 25, 2021 · 4 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@mdempsky
Copy link
Member

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 collect p (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

@mdempsky mdempsky added the NeedsFix The path to resolution is known, but the work has not been done. label Feb 25, 2021
@danscales danscales self-assigned this Mar 10, 2021
@danscales
Copy link
Contributor

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.

@randall77
Copy link
Contributor

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.

@danscales
Copy link
Contributor

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?

@randall77
Copy link
Contributor

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.

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?

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
@seankhliao seankhliao added this to the Unplanned milestone Aug 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Projects
Status: Triage Backlog
Development

No branches or pull requests

5 participants