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

Closed
davecheney opened this issue Jan 27, 2014 · 10 comments
Closed

cmd/compile: escape analysis oddity #7213

davecheney opened this issue Jan 27, 2014 · 10 comments

Comments

@davecheney
Copy link
Contributor

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
Copy link
Member

minux commented Jan 27, 2014

Comment 1:

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

@dvyukov
Copy link
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
Copy link
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
Copy link
Member

dvyukov commented Jan 27, 2014

Comment 4:

looks correct to me

@davecheney
Copy link
Contributor Author

Comment 5:

Status changed to Accepted.

@lukescott
Copy link

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 changed the title cmd/gc: escape analysis oddity cmd/compile: escape analysis oddity Jun 8, 2015
@freeformz
Copy link

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
Copy link
Member

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

@cespare
Copy link
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.)

@mdempsky
Copy link
Member

The original minimized repro case has been fixed (since Go 1.7, evidently), so I'm going to close this as fixed.

@golang golang locked and limited conversation to collaborators Aug 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants