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

Open
choleraehyq opened this issue Jul 22, 2019 · 1 comment

Comments

@choleraehyq
Copy link
Contributor

commented Jul 22, 2019

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

This comment has been minimized.

Copy link
Contributor

commented Jul 22, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.