diff options
author | Keith Randall <khr@golang.org> | 2016-04-23 22:59:01 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2016-04-24 18:15:41 +0000 |
commit | 934c3599648ae841668ec753881134347fc28c29 (patch) | |
tree | df3cd69d7126192c1d5b6cf09b790645207d56dd /test/writebarrier.go | |
parent | c4c182140adedf300800778127840e3b8b9f7423 (diff) | |
download | go-934c3599648ae841668ec753881134347fc28c29.tar.gz go-934c3599648ae841668ec753881134347fc28c29.zip |
cmd/compile: reorder how slicelit initializes a slice
func f(x, y, z *int) {
a := []*int{x,y,z}
...
}
We used to use:
var tmp [3]*int
a := tmp[:]
a[0] = x
a[1] = y
a[2] = z
Now we do:
var tmp [3]*int
tmp[0] = x
tmp[1] = y
tmp[2] = z
a := tmp[:]
Doesn't sound like a big deal, but the compiler has trouble
eliminating write barriers when using the former method because it
doesn't know that the slice points to the stack. In the latter
method, the compiler knows the array is on the stack and as a result
doesn't emit any write barriers.
This turns out to be extremely common when building ... args, like
for calls fmt.Printf.
Makes go binaries ~1% smaller.
Doesn't have a measurable effect on the go1 fmt benchmarks,
unfortunately.
Fixes #14263
Update #6853
Change-Id: I9074a2788ec9e561a75f3b71c119b69f304d6ba2
Reviewed-on: https://go-review.googlesource.com/22395
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'test/writebarrier.go')
-rw-r--r-- | test/writebarrier.go | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/test/writebarrier.go b/test/writebarrier.go index 44e42f0883..2ff0ee9584 100644 --- a/test/writebarrier.go +++ b/test/writebarrier.go @@ -182,3 +182,17 @@ func f18(p *T18, x *[]int) { p.s = p.s[8:9] // ERROR "write barrier" *x = (*x)[3:5] // ERROR "write barrier" } + +func f19(x, y *int, i int) int { + // Constructing a temporary slice on the stack should not + // require any write barriers. See issue 14263. + a := []*int{x, y} // no barrier + return *a[i] +} + +func f20(x, y *int, i int) []*int { + // ... but if that temporary slice escapes, then the + // write barriers are necessary. + a := []*int{x, y} // ERROR "write barrier" + return a +} |