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

Escape analysis #231

Closed
mkevac opened this issue Nov 21, 2014 · 6 comments
Closed

Escape analysis #231

mkevac opened this issue Nov 21, 2014 · 6 comments
Labels

Comments

@mkevac
Copy link

mkevac commented Nov 21, 2014

When building go program with flag -gcflags=-m, e.g. go install -v -gcflags=-m, compiler will print info about variables\arguments that escape and are allocated on heap. These variables increase pressure on garbage collector, so one should change code for these variables to be allocated on stack.

Giving information about escaped variables in vim would be very useful.

@fatih
Copy link
Owner

fatih commented Nov 22, 2014

What is your use case? How would you like to see it? Can you show me an example output of this command? I wonder if it's really useful to integrate this.

@fatih fatih added feature and removed feature labels Nov 22, 2014
@alexaandru
Copy link
Contributor

This features may be quite handy. Here's a sample output:

$ go build -gcflags=-m
# github.com/alexaandru/csvsplit
./csvsplit.go:27: inlining call to bufio.NewScanner
./csvsplit.go:29: inlining call to Text
./csvsplit.go:33: inlining call to Text
./csvsplit.go:37: inlining call to Err
./csvsplit.go:19: &(*opts).source escapes to heap
./csvsplit.go:18: leaking param: opts
./csvsplit.go:20: &(*opts).repeatRows escapes to heap
./csvsplit.go:18: leaking param: opts
./csvsplit.go:21: &(*opts).limit escapes to heap
./csvsplit.go:18: leaking param: opts
./utils.go:34: determineFilePrefix leaking param opts content to result ~r1
./utils.go:25: leaking param: fname
./utils.go:29: createFile ... argument does not escape
./utils.go:42: leaking param: buf
./utils.go:42: bufWrite line does not escape
./utils.go:44: bufWrite ... argument does not escape
./utils.go:48: leaking param: buf
./utils.go:48: leaking param: buf
./utils.go:48: bufWriteln line does not escape
./csvsplit.go:50: leaking closure reference curBuf
./csvsplit.go:49: leaking closure reference curFile
./csvsplit.go:56: leaking closure reference prefix
./csvsplit.go:49: leaking closure reference curFile
./csvsplit.go:50: leaking closure reference curBuf
./csvsplit.go:50: leaking closure reference curBuf
./csvsplit.go:47: func literal escapes to heap
./csvsplit.go:45: moved to heap: lineno
./csvsplit.go:48: &lineno escapes to heap
./csvsplit.go:42: moved to heap: opts
./csvsplit.go:48: &opts escapes to heap
./csvsplit.go:43: moved to heap: curFile
./csvsplit.go:49: &curFile escapes to heap
./csvsplit.go:44: moved to heap: curBuf
./csvsplit.go:50: &curBuf escapes to heap
./csvsplit.go:45: moved to heap: prefix
./csvsplit.go:56: &prefix escapes to heap
./csvsplit.go:47: <S> row does not escape
./csvsplit.go:51: func·001 ... argument does not escape
./csvsplit.go:56: func·001 ... argument does not escape
./csvsplit.go:25: leaking param: what
./csvsplit.go:27: make([]byte, 4096) escapes to heap
./csvsplit.go:25: leaking param: opts
./csvsplit.go:27: &bufio.Scanner literal escapes to heap
./csvsplit.go:25: leaking param: what
./csvsplit.go:27: make([]byte, 4096) escapes to heap
./csvsplit.go:25: leaking param: opts
./csvsplit.go:27: &bufio.Scanner literal escapes to heap
./csvsplit.go:25: leaking param: what
./csvsplit.go:27: make([]byte, 4096) escapes to heap
./csvsplit.go:25: leaking param: what
./csvsplit.go:27: make([]byte, 4096) escapes to heap
./csvsplit.go:38: scan ... argument does not escape
./utils.go:16: leaking param: fname
./utils.go:20: openFile ... argument does not escape
./csvsplit.go:72: new(options) escapes to heap
./csvsplit.go:72: new(options) escapes to heap
./csvsplit.go:72: new(options) escapes to heap
./csvsplit.go:80: main ... argument does not escape

That could go nicely into the quickfix window and we could jump to the appropriate files:lines from it :)

@fatih
Copy link
Owner

fatih commented Nov 22, 2014

Hm, if the std output of go build is the same, all we need is allowing to pass arguments to :GoBuild command. I don't have much time for the time being, however let this be for future reference.

@alexaandru
Copy link
Contributor

That actually makes sense :) Not to mention there are other interesting flags, "-s" being my favourite :) as it complains about redundant type definitions.

Given the code:

package main

type dummy struct {
    whatever int
}

var dummies = []dummy{
    dummy{1},
    dummy{2},
    dummy{3},
}

var smarties = []dummy{
    {1},
    {2},
    {3},
}

func main() {}

running go build -gcflags=-s dummy.go will produce:

# command-line-arguments
.//home/alex/dummy.go:8: redundant type: dummy
.//home/alex/dummy.go:9: redundant type: dummy
.//home/alex/dummy.go:10: redundant type: dummy

@fatih
Copy link
Owner

fatih commented Nov 24, 2014

This is merged via @alexaandru PR #237.

@fatih fatih closed this as completed Nov 24, 2014
@mkevac
Copy link
Author

mkevac commented Nov 24, 2014

Escape analysis gives about 1-4 lines per each variable and function argument. Giving them all to the user is not going to help. I was thinking about highlighting escaped variables only, for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants