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: unnecessarily moving variables into heap when using goroutine #33216

Closed
choleraehyq opened this issue Jul 22, 2019 · 3 comments
Closed
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. Performance
Milestone

Comments

@choleraehyq
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version go1.13beta1 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/cholerae/Library/Caches/go-build"
GOENV="/Users/cholerae/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/cholerae/Documents/gopath"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/cholerae/Documents/gopath/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/cholerae/Documents/gopath/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/lg/ld5t5rss459241qtzmqfp0h80000gn/T/go-build208988386=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

https://play.golang.org/p/VeUzT10cew9

What did you expect to see?

Variable c can be allocated on stack because lifetime of the new goroutine is shorter than the main goroutine.

What did you see instead?

➜  test go tool compile -m -m escape.go
escape.go:8:6: cannot inline main: unhandled op GO
escape.go:12:5: can inline main.func1 as: func(*int64, *sync.WaitGroup) { atomic.AddInt64(c, 1); wg.Done() }
escape.go:14:10: inlining call to sync.(*WaitGroup).Done method(*sync.WaitGroup) func() { sync.wg.Add(int(-1)) }
escape.go:9:6: moved to heap: c
escape.go:10:6: moved to heap: wg
escape.go:12:10: leaking param: c
escape.go:12:20: leaking param: wg
escape.go:12:5: func literal escapes to heap
@randall77
Copy link
Contributor

This would be hard. In order to correctly analyze the lifetime, we'd require the compiler to understand the semantics of sync.WaitGroup.
In addition, this would allow for pointers from one goroutine stack to another, something we currently don't allow. It would complicate the garbage collector significantly.
I'm not convinced it is worth it. Starting a goroutine has a fair amount of overhead (e.g. allocating a stack). One more allocation won't make a huge difference.

@katiehockman katiehockman added this to the Unplanned milestone Jul 29, 2019
@katiehockman katiehockman added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Jul 29, 2019
@mdempsky
Copy link
Member

mdempsky commented Sep 24, 2019

Beyond goroutine lifetime concerns, the runtime would also need to be extended to handle cross-stack pointers to stack objects. E.g., we wouldn't be able to optimize based on assumptions that pointers to stack objects only happen from that same stack. This includes concerns about being able to resize/move stacks.

At that point, would there still be value in using stack objects(*) instead of heap objects?

(* By "stack objects" here, I mean objects that are stack allocated, but whose lifetime are handled by GC tracing. Obviously stack-allocation of variables whose lifetimes are statically resolved via liveness analysis still have value.)

@randall77
Copy link
Contributor

I'm going to close this issue. We aren't going down the road of inter-stack pointers without a much stronger justification.

@golang golang locked and limited conversation to collaborators Oct 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. Performance
Projects
None yet
Development

No branches or pull requests

5 participants