aboutsummaryrefslogtreecommitdiff
path: root/test/escape_slice.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2015-05-15 12:19:07 -0400
committerDavid Chase <drchase@google.com>2015-05-18 15:34:39 +0000
commita21cf5b6a281df2c3506105cecfbeeda70afca1c (patch)
tree0f47567dddaaca8cbbf060a99eaa24c519fd5117 /test/escape_slice.go
parentf0dd002895b48595f6c14f2bf606775289f59d5f (diff)
downloadgo-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.go81
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},
+ }...)
+}