diff options
author | David Chase <drchase@google.com> | 2015-05-15 12:19:07 -0400 |
---|---|---|
committer | David Chase <drchase@google.com> | 2015-05-18 15:34:39 +0000 |
commit | a21cf5b6a281df2c3506105cecfbeeda70afca1c (patch) | |
tree | 0f47567dddaaca8cbbf060a99eaa24c519fd5117 /test/escape_slice.go | |
parent | f0dd002895b48595f6c14f2bf606775289f59d5f (diff) | |
download | go-a21cf5b6a281df2c3506105cecfbeeda70afca1c.tar.gz go-a21cf5b6a281df2c3506105cecfbeeda70afca1c.zip |
cmd/internal/gc: extend escape analysis to pointers in slices
Modified esc.go to allow slice literals (before append)
to be non-escaping. Modified tests to account for changes
in escape behavior and to also test the two cases that
were previously not tested.
Also minor cleanups to debug-printing within esc.go
Allocation stats for running compiler
( cd src/html/template;
for i in {1..5} ; do
go tool 6g -memprofile=testzz.${i}.prof -memprofilerate=1 *.go ;
go tool pprof -alloc_objects -text testzz.${i}.prof ;
done ; )
before about 86k allocations
after about 83k allocations
Fixes #8972
Change-Id: Ib61dd70dc74adb40d6f6fdda6eaa4bf7d83481de
Reviewed-on: https://go-review.googlesource.com/10118
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'test/escape_slice.go')
-rw-r--r-- | test/escape_slice.go | 81 |
1 files changed, 78 insertions, 3 deletions
diff --git a/test/escape_slice.go b/test/escape_slice.go index 9315e27682..0b6599719d 100644 --- a/test/escape_slice.go +++ b/test/escape_slice.go @@ -8,6 +8,11 @@ package escape +import ( + "os" + "strings" +) + var sink interface{} func slice0() { @@ -71,9 +76,8 @@ func slice7() *int { } func slice8() { - // BAD: i should not escape here - i := 0 // ERROR "moved to heap: i" - s := []*int{&i} // ERROR "&i escapes to heap" "literal does not escape" + i := 0 + s := []*int{&i} // ERROR "&i does not escape" "literal does not escape" _ = s } @@ -88,3 +92,74 @@ func slice10() []*int { s := []*int{&i} // ERROR "&i escapes to heap" "literal escapes to heap" return s } + +func envForDir(dir string) []string { // ERROR "dir does not escape" + env := os.Environ() + return mergeEnvLists([]string{"PWD=" + dir}, env) // ERROR ".PWD=. \+ dir escapes to heap" "\[\]string literal does not escape" +} + +func mergeEnvLists(in, out []string) []string { // ERROR "leaking param content: in" "leaking param content: out" "leaking param: out to result ~r2 level=0" +NextVar: + for _, inkv := range in { + k := strings.SplitAfterN(inkv, "=", 2)[0] + for i, outkv := range out { + if strings.HasPrefix(outkv, k) { + out[i] = inkv + continue NextVar + } + } + out = append(out, inkv) + } + return out +} + +const ( + IPv4len = 4 + IPv6len = 16 +) + +var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff} + +func IPv4(a, b, c, d byte) IP { + p := make(IP, IPv6len) // ERROR "make\(IP, IPv6len\) escapes to heap" + copy(p, v4InV6Prefix) + p[12] = a + p[13] = b + p[14] = c + p[15] = d + return p +} + +type IP []byte + +type IPAddr struct { + IP IP + Zone string // IPv6 scoped addressing zone +} + +type resolveIPAddrTest struct { + network string + litAddrOrName string + addr *IPAddr + err error +} + +var resolveIPAddrTests = []resolveIPAddrTest{ + {"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, + {"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, + {"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, +} + +func setupTestData() { + resolveIPAddrTests = append(resolveIPAddrTests, + []resolveIPAddrTest{ // ERROR "\[\]resolveIPAddrTest literal does not escape" + {"ip", + "localhost", + &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap" + nil}, + {"ip4", + "localhost", + &IPAddr{IP: IPv4(127, 0, 0, 1)}, // ERROR "&IPAddr literal escapes to heap" + nil}, + }...) +} |