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: escape analysis oddity #7213

Open
davecheney opened this Issue Jan 27, 2014 · 9 comments

Comments

Projects
None yet
8 participants
@davecheney
Contributor

davecheney commented Jan 27, 2014

What steps will reproduce the problem?

package q

import "io"

type Thing struct {
        r io.Reader
}

func (t *Thing) Read() error {
        _, err := t.r.Read(nil)
        return err
}

func Use() error {
        var t Thing
        return t.Read()
}

% go build -gcflags -m leak.go
# command-line-arguments
./leak.go:9: leaking param: t
./leak.go:15: moved to heap: t
./leak.go:16: t escapes to heap

What is the expected output? What do you see instead?

Why does t leak on like 9, what is it about referencing t.r that causes t to leak onto
the heap.

Please use labels and text to provide additional information.

This question arose from an investigation if json.NewDecoder could be stack allocated.
@minux

This comment has been minimized.

Member

minux commented Jan 27, 2014

Comment 1:

because the compile doesn't know if the Reader leaks r or not.
@dvyukov

This comment has been minimized.

Member

dvyukov commented Jan 27, 2014

Comment 2:

Minux, How can Read implementation leak r in this case? Can you provide an example where
it's necessary to allocate Thing on heap?
@minux

This comment has been minimized.

Member

minux commented Jan 27, 2014

Comment 3:

OK. for the current interface implementation the interface value r couldn't be leaked,
but the actual value in r could be leaked.
So yes, Thing should be able to allocate on the stack.
so the conclusion is that for interface values contained in structs, if it's not leaked
thru. other means, just calling interface method will never leak the interface?
this seems easy enough to implement in the compiler.
@dvyukov

This comment has been minimized.

Member

dvyukov commented Jan 27, 2014

Comment 4:

looks correct to me
@davecheney

This comment has been minimized.

Contributor

davecheney commented Jan 31, 2014

Comment 5:

Status changed to Accepted.

@lukescott

This comment has been minimized.

lukescott commented May 1, 2014

Comment 6:

I think this is because of the interface{}. The compiler doesn't know what io.Reader is:
It could be a pointer or a value. Either way r is tied to Thing, and it has to fit on
the stack as well, whether that be a pointer or a value. At compile time the compiler
doesn't know which.
For some reason this seems to make a difference (not sure why):
func (t Thing) Read() error {
        _, err := t.r.Read(nil)
        return err
}
# command-line-arguments
./test.go:9: leaking param: t
I observed something similar with issue #7661. I am still unsure why bytes.Buffer is
always heap allocated.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@rsc rsc removed release-none labels Apr 10, 2015

@rsc rsc changed the title from cmd/gc: escape analysis oddity to cmd/compile: escape analysis oddity Jun 8, 2015

@freeformz

This comment has been minimized.

Contributor

freeformz commented Jul 20, 2016

FWIW: This is the output under go1.7rc2

$ go build -gcflags '-m -l' leak.go
# command-line-arguments
./leak.go:9: leaking param content: t
./leak.go:16: Use t does not escape

While t is detected as leaking, it does not escape.

@odeke-em

This comment has been minimized.

Member

odeke-em commented Jan 14, 2017

/cc @davecheney @minux @dvyukov to the update from @freeformz's comment here #7213 (comment)

@cespare

This comment has been minimized.

Contributor

cespare commented Apr 5, 2017

Yeah, seems like this minimal repro is no longer a repro, yet the &json.Decoder literal from json.NewDecoder still escapes (even though json.NewDecoder is inlined).

(Go 1.8.)

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