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

Comments

@choleraehyq
Copy link
Contributor

@choleraehyq choleraehyq 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

@randall77 randall77 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
@mdempsky

This comment has been minimized.

Copy link
Member

@mdempsky 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

This comment has been minimized.

Copy link
Contributor

@randall77 randall77 commented Oct 7, 2019

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

@randall77 randall77 closed this Oct 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.