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: method values cause receiver to escape to the heap #27557

Open
deepilla opened this Issue Sep 7, 2018 · 1 comment

Comments

Projects
None yet
3 participants
@deepilla

deepilla commented Sep 7, 2018

What did you do?

In this minimal code example, functions f1 and f2 both take an argument t and call its foo method. t1 calls the method directly; t2 uses a method value.

package escape

type T struct{}

func (pt *T) foo() {}

func f1(t T) {
    t.foo()
}

func f2(t T) {
    f := t.foo
    f()
}

See this golang-nuts thread for background.

What did you expect to see?

The value t allocated on the stack in both functions.

What did you see instead?

In function f2, t escapes to the heap.

$ go build -gcflags="-l -m=2"

./escape.go:5:7: (*T).foo pt does not escape
./escape.go:8:3: f1 t does not escape
./escape.go:12:8: t escapes to heap
./escape.go:12:8:       from t.foo (call part) at ./escape.go:12:8
./escape.go:11:9: moved to heap: t
./escape.go:12:8: f2 t.foo does not escape

I understand that method values involve making a copy of the receiver (a pointer in this case). But if the compiler can figure out that t doesn't escape from f1, why can't it do the same for f2?

Does this issue reproduce with the latest release (go1.11)?

Yes.

System details

go version go1.11 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/deepilla/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/deepilla/Projects/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
GOROOT/bin/go version: go version go1.11 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.11
uname -sr: Linux 4.18.7-arch1-1-ARCH
LSB Version:	1.4
Distributor ID:	Arch
Description:	Arch Linux
Release:	rolling
Codename:	n/a
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.28.
@cherrymui

This comment has been minimized.

Contributor

cherrymui commented Sep 7, 2018

We probably can treat the method expression the same way as closures, which will probably solve this.

@andybons andybons added this to the Unplanned milestone Sep 7, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment