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: generic method values at package scope pin their receiver value #54343
Comments
Maybe it could rewrite to something like
So it will not be a "package-scoped closure"? |
So the natural time to do the rewrite would be during IR construction, which currently happens before initialization ordering. That rewrite would unfortunately affect when But along those lines, I think rewriting to this would work without affecting initialization ordering:
And then that could get further rewritten into:
Thanks for the suggestion. |
Change https://go.dev/cl/422198 mentions this issue: |
The Go 1.18 frontend handles package-scope generic method values by spilling the receiver value to a global temporary variable, which pins it into memory. This issue isn't present in unified IR, which uses OMETHVALUE when the receiver type is statically known. Updates #54343. Change-Id: I2c4ffeb125a3cf338f949a93b0baac75fff6cd31 Reviewed-on: https://go-review.googlesource.com/c/go/+/422198 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
The Go 1.18 frontend handles package-scope generic method values by spilling the receiver value to a global temporary variable, which pins it into memory. This issue isn't present in unified IR, which uses OMETHVALUE when the receiver type is statically known. Updates golang#54343. Change-Id: I2c4ffeb125a3cf338f949a93b0baac75fff6cd31 Reviewed-on: https://go-review.googlesource.com/c/go/+/422198 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
The Go 1.18 frontend handles package-scope generic method values by spilling the receiver value to a global temporary variable, which pins it into memory. This issue isn't present in unified IR, which uses OMETHVALUE when the receiver type is statically known. Updates golang#54343. Change-Id: I2c4ffeb125a3cf338f949a93b0baac75fff6cd31 Reviewed-on: https://go-review.googlesource.com/c/go/+/422198 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
https://go-review.googlesource.com/c/go/+/423074 tested a non-generic version of the test, and it still flaked on arm with "never GC'd": https://storage.googleapis.com/go-build-log/019cddda/linux-arm-aws_8b1e8c2b.log |
Change https://go.dev/cl/423115 mentions this issue: |
I structured the test for issue54343.go after issue46725.go, where I was careful to use `[4]int`, which is a type large enough to avoid the tiny object allocator (which interferes with finalizer semantics). But in that test, I didn't note the importance of that type, so I mistakenly used just `int` in issue54343.go. This CL switches issue54343.go to use `[4]int` too, and then adds comments to both pointing out the significance of this type. Updates #54343. Change-Id: I699b3e64b844ff6d8438bbcb4d1935615a6d8cc4 Reviewed-on: https://go-review.googlesource.com/c/go/+/423115 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: David Chase <drchase@google.com>
This will be fixed in 1.20 with GOEXPERIMENT=unified, and there's a regress test. |
https://go.dev/play/p/EO98OQn3OIr
If the generic method value
x.M
appears at package scope, thenx
is spilled into a global variable and never gets garbage collected, even if the method value itself is garbage collected.This happens because for generic method values, stencil.go desugar the method value into a function literal that captures the receiver value after evaluating it. However, the compiler backend (particularly escape analysis) doesn't currently handle package-scope function literals with closure variables. This causes a problem for generic method values that appear in package-scope initialization expressions.
The solution currently taken by stencil.go (and that I've duplicated in unified IR's shaped-based stenciling) is to spill the receiver value to a global variable instead. However, this is suboptimal because it prevents garbage collection.
Strictly speaking, this isn't a correctness issue, because runtime.SetFinalizer warns that variables allocated during package initialization may never be finalized. But it's something that we can do better about.
/cc @golang/compiler
The text was updated successfully, but these errors were encountered: