- 17 Aug, 2016 16 commits
-
-
Cherry Zhang authored
- Use machine instructions for uint64<->float conversions - Do not enforce alignment on Zero/Move ARM64 supports unaligned load/stores, but only aligned offset or small offset can be encoded into instructions. - Do combined loads Change-Id: Iffca7dd0f13070b17b784861ce5a30af584680eb Reviewed-on: https://go-review.googlesource.com/27086Reviewed-by: David Chase <drchase@google.com>
-
Alberto Donizetti authored
name old time/op new time/op delta FloatAdd/10-4 116ns ± 1% 82ns ± 0% -28.74% (p=0.008 n=5+5) FloatAdd/100-4 124ns ± 0% 86ns ± 1% -30.34% (p=0.016 n=4+5) FloatAdd/1000-4 192ns ± 1% 123ns ± 0% -35.94% (p=0.008 n=5+5) FloatAdd/10000-4 826ns ± 0% 438ns ± 0% -46.99% (p=0.000 n=4+5) FloatAdd/100000-4 6.82µs ± 1% 3.36µs ± 0% -50.74% (p=0.008 n=5+5) FloatSub/10-4 108ns ± 1% 77ns ± 1% -29.06% (p=0.008 n=5+5) FloatSub/100-4 115ns ± 0% 79ns ± 0% -31.48% (p=0.029 n=4+4) FloatSub/1000-4 168ns ± 0% 99ns ± 0% -41.09% (p=0.029 n=4+4) FloatSub/10000-4 690ns ± 2% 288ns ± 1% -58.24% (p=0.008 n=5+5) FloatSub/100000-4 5.37µs ± 1% 2.10µs ± 1% -60.89% (p=0.008 n=5+5) name old alloc/op new alloc/op delta FloatAdd/10-4 48.0B ± 0% 0.0B ±NaN% -100.00% (p=0.008 n=5+5) FloatAdd/100-4 64.0B ± 0% 0.0B ±NaN% -100.00% (p=0.008 n=5+5) FloatAdd/1000-4 176B ± 0% 0B ±NaN% -100.00% (p=0.008 n=5+5) FloatAdd/10000-4 1.41kB ± 0% 0.00kB ±NaN% -100.00% (p=0.008 n=5+5) FloatAdd/100000-4 13.6kB ± 0% 0.0kB ±NaN% -100.00% (p=0.008 n=5+5) FloatSub/10-4 48.0B ± 0% 0.0B ±NaN% -100.00% (p=0.008 n=5+5) FloatSub/100-4 64.0B ± 0% 0.0B ±NaN% -100.00% (p=0.008 n=5+5) FloatSub/1000-4 176B ± 0% 0B ±NaN% -100.00% (p=0.008 n=5+5) FloatSub/10000-4 1.41kB ± 0% 0.00kB ±NaN% -100.00% (p=0.008 n=5+5) FloatSub/100000-4 13.6kB ± 0% 0.0kB ±NaN% -100.00% (p=0.008 n=5+5) Fixes #14868 Change-Id: Ia2b8b1a8ef0868288ecb25f812b17bd03ff40d1c Reviewed-on: https://go-review.googlesource.com/23568Reviewed-by: Robert Griesemer <gri@golang.org>
-
Robert Griesemer authored
Timings is a simple data structure that collects times of labeled Start/Stop events describing timed phases, which later can be written to a file. Adjacent phases with common label prefix are automatically collected in a group together with the accumulated phase time. Timing data can be appended to a file in benchmark data format using the new -bench flag: $ go build -gcflags="-bench=/dev/stdout" -o /dev/null go/types commit: devel +8847c6b Mon Aug 15 17:51:53 2016 -0700 goos: darwin goarch: amd64 BenchmarkCompile:go/types:fe:init 1 663292 ns/op 0.07 % BenchmarkCompile:go/types:fe:loadsys 1 1337371 ns/op 0.14 % BenchmarkCompile:go/types:fe:parse 1 47008869 ns/op 4.91 % 10824 lines 230254 lines/s BenchmarkCompile:go/types:fe:typecheck:top1 1 2843343 ns/op 0.30 % BenchmarkCompile:go/types:fe:typecheck:top2 1 447457 ns/op 0.05 % BenchmarkCompile:go/types:fe:typecheck:func 1 15119595 ns/op 1.58 % 427 funcs 28241 funcs/s BenchmarkCompile:go/types:fe:capturevars 1 56314 ns/op 0.01 % BenchmarkCompile:go/types:fe:inlining 1 9805767 ns/op 1.02 % BenchmarkCompile:go/types:fe:escapes 1 53598646 ns/op 5.60 % BenchmarkCompile:go/types:fe:xclosures 1 199302 ns/op 0.02 % BenchmarkCompile:go/types:fe:subtotal 1 131079956 ns/op 13.70 % BenchmarkCompile:go/types:be:compilefuncs 1 692009428 ns/op 72.33 % 427 funcs 617 funcs/s BenchmarkCompile:go/types:be:externaldcls 1 54591 ns/op 0.01 % BenchmarkCompile:go/types:be:dumpobj 1 133478173 ns/op 13.95 % BenchmarkCompile:go/types:be:subtotal 1 825542192 ns/op 86.29 % BenchmarkCompile:go/types:unaccounted 1 106101 ns/op 0.01 % BenchmarkCompile:go/types:total 1 956728249 ns/op 100.00 % For #16169. Change-Id: I93265fe0cb08e47cd413608d0824c5dd35ba7899 Reviewed-on: https://go-review.googlesource.com/24462Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
Tom Wilkie authored
.local addresses are used by things like Kubernetes and Weave DNS; Go should not avoid resolving them. This is a partial revert of https://golang.org/cl/21328 which was too strict of an interpretation of RFC 6762. Fixes #16739 Change-Id: I349415b4eab5d61240dd18217bd95dc7d2105cd5 Reviewed-on: https://go-review.googlesource.com/27250Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Matthew Dempsky authored
The Width{int,ptr,reg} assignments are no longer necessary since golang.org/cl/21623. The other arch's betypeinit functions were cleaned up, but apparently this one was missed. Change-Id: I1c7f074d7864a561659c1f98aef604f57f285fd0 Reviewed-on: https://go-review.googlesource.com/27272 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Michael Munday <munday@ca.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Matthew Dempsky authored
Updates #15419. Change-Id: If7c80adcb38b5731e337b2ae2d9d76fcf8513d8e Reviewed-on: https://go-review.googlesource.com/27271Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Dan Peterson authored
BIND libresolv allows values from 0 to 15. For invalid values and negative numbers, 0 is used. For numbers greater than 15, 15 is used. Fixes #15419 Change-Id: I1009bc119c3e87919bcb55a80a35532e9fc3ba52 Reviewed-on: https://go-review.googlesource.com/24901Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Cherry Zhang authored
Test nil check removal for access of PAUTOHEAP. Change-Id: Id739a9cda7cd3ff173bdcccfedcad93ee90711ef Reviewed-on: https://go-review.googlesource.com/27232 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Florian Uekermann authored
The Source provided by math/rand relies on an array of cooked pseudo-random 63bit integers for seeding. The origin of these numbers is undocumented. Add a standalone program in math/rand folder that generates the 63bit integer array as well as a 64bit version supporting extension of the Source to 64bit pseudo-random number generation while maintaining the current sequence in the lower 63bit. The code is largely based on the initial implementation of the random number generator in the go repository by Ken Thompson (revision 399). Change-Id: Ib4192aea8127595027116a0f5a7be53f11dc110b Reviewed-on: https://go-review.googlesource.com/22230Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Austin Clements authored
sysUnused (e.g., madvise MADV_FREE) is only sensible to call on physical page boundaries, so scavengelist rounds in the bounds of the region being released to the nearest physical page boundaries. However, if the region is smaller than a physical page and neither the start nor end fall on a boundary, then rounding the start up to a page boundary and the end down to a page boundary will result in end < start. Currently, we only give up on the region if start == end, so if we encounter end < start, we'll call madvise with a negative length and the madvise will fail. Issue #16644 gives a concrete example of this: start = 0x1285ac000 end = 0x1285ae000 (1 8K page) This leads to the rounded values start = 0x1285b0000 end = 0x1285a0000 which leads to len = -65536. Fix this by giving up on the region if end <= start, not just if end == start. Fixes #16644. Change-Id: I8300db492dbadc82ac1ad878318b36bcb7c39524 Reviewed-on: https://go-review.googlesource.com/27230Reviewed-by: Keith Randall <khr@golang.org>
-
Yasuhiro Matsumoto authored
fixes #16493 Change-Id: I86bec2f9bd7965449c43e94733791f7cb18c5c4c Reviewed-on: https://go-review.googlesource.com/25165Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
-
Dan Peterson authored
Callers pass strings sliced as necessary instead of giving an offset. Fixes #16350 Change-Id: I7ba896f6ff09e0fd0094ca6c5af5d9a81622f15e Reviewed-on: https://go-review.googlesource.com/27206 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Joe Tsai authored
Change-Id: Ib8855f8125970fc7ffb271635c28d31d310fcb5b Reviewed-on: https://go-review.googlesource.com/27192 Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Josh Bleecher Snyder authored
Instead of making a runtime call, compare types and values. Change-Id: Id302083d5a6a5f18e04f36f304f3d290c46976ad Reviewed-on: https://go-review.googlesource.com/26660 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Josh Bleecher Snyder authored
When T is a scalar, there are no runtime calls required, which makes this a clear win. encoding/binary: WriteInts-8 958ns ± 3% 864ns ± 2% -9.80% (p=0.000 n=15+15) This also considerably shrinks a core fmt routine: Before: "".(*pp).printArg t=1 size=3952 args=0x20 locals=0xf0 After: "".(*pp).printArg t=1 size=2624 args=0x20 locals=0x98 Unfortunately, I find it very hard to get stable numbers out of the fmt benchmarks due to thermal scaling. Change-Id: I1278006b030253bf8e48dc7631d18985cdaa143d Reviewed-on: https://go-review.googlesource.com/26659 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
-
Robert Griesemer authored
This removes some scaffolding introduced pre-1.7, introduced to fix an export format bug, and to minimize conflicts with older formats. The currently deployed and recognized format is "v1", so don't worry about other versions. This is a step towards a better scheme for internal export format versioning. For #16244. Change-Id: Ic7cf99dd2a24ad5484cc54aed44fa09332c2cf72 Reviewed-on: https://go-review.googlesource.com/27205Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Robert Griesemer <gri@golang.org>
-
- 16 Aug, 2016 24 commits
-
-
Robert Griesemer authored
Removes the encoding of this bit which was ignored but left behind for 1.7 to minimize pre-1.7 export format changes. See the issue for more details. Fixes #15772. Change-Id: I46cd7a66ad4c6003b78c64295cf3bda503ebf2dd Reviewed-on: https://go-review.googlesource.com/27201 Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
Jess Frazelle authored
Fixes #16156 Change-Id: I6989db4fd392583a2d490339cefc525b07c11b90 Reviewed-on: https://go-review.googlesource.com/24380Reviewed-by: Andrew Gerrand <adg@golang.org> Run-TryBot: Andrew Gerrand <adg@golang.org>
-
Josh Bleecher Snyder authored
s390x took up the last available chunk of int16 opcodes. There are RISC-V and sparc64 ports in progress out of tree, and there will likely be other architectures. Reduce the opcode space to allow more architectures to fit without increasing to int32. This is the smallest power of two that accomodates all existing architectures. All else being equal, smaller is better--smaller numbers are easier to generate immediates for and easier on the eyes when debugging. Change-Id: I4d0824b28913892fbd0579d3f90bea34e44c8946 Reviewed-on: https://go-review.googlesource.com/24223 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
-
Robert Griesemer authored
Fixes #15323. Change-Id: I50e996e6fde6b24327cb45dd84da31deef4dcc56 Reviewed-on: https://go-review.googlesource.com/27171 Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Keith Randall authored
We should check whether there is a concurrent writer at the start of every mapiternext, not just in mapaccessK (which is only called during certain map growth situations). Tests turned off by default because they are inherently flaky. Fixes #16278 Change-Id: I8b72cab1b8c59d1923bec6fa3eabc932e4e91542 Reviewed-on: https://go-review.googlesource.com/24749Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
-
Keith Randall authored
ssaMain is no longer needed. Change-Id: I0b77f0bcd482329d73018bd80a6e068e622e191b Reviewed-on: https://go-review.googlesource.com/27190Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Keith Randall authored
Only need to zero-extend to 32 bits and we get the top 32 bits zeroed for free. Only the WQ change actually generates different code. The assembler did this optimization for us in the other two cases. But we might as well do it during SSA so -S output more closely matches the actual generated instructions. Change-Id: I3e4ac50dc4da124014d4e31c86e9fc539d94f7fd Reviewed-on: https://go-review.googlesource.com/23711 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
-
Josh Bleecher Snyder authored
This CL adds a safety mechanism for changing the number of opcodes available per architecture. A subsequent CL will actually make the change. Change-Id: I6332ed5514f2f153c54d11b7da0cc8a6be1c8066 Reviewed-on: https://go-review.googlesource.com/24222 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Brad Fitzpatrick authored
Updates #16737 Change-Id: Ia51fc9b06df43b7c6f7136e90b40362263c20081 Reviewed-on: https://go-review.googlesource.com/27126Reviewed-by: Chris Broadfoot <cbro@golang.org>
-
Tamir Duberstein authored
Also includes a minor golint cleanup in the tests. Change-Id: I8c0fc81479e635e7cca18d5c48c28b654afa59d8 Reviewed-on: https://go-review.googlesource.com/25380Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Jaana Burcu Dogan authored
Fixes #16719. Change-Id: I20550628814e3454f17d6f8ae8b66cce17f09859 Reviewed-on: https://go-review.googlesource.com/27118Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Keith Randall authored
Fixes #16306 Change-Id: If8e2f411fe9a5a5c198f10765fee7261ba8feaf2 Reviewed-on: https://go-review.googlesource.com/24836 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
-
Josh Bleecher Snyder authored
This only triggers a few places in the stdlib, but it helps a lot when it does. Before: runtime.mapassign1 t=1 size=2400 args=0x20 locals=0xe0 After: runtime.mapassign1 t=1 size=2352 args=0x20 locals=0xd8 name old time/op new time/op delta MapPop100-8 19.8µs ±11% 18.4µs ± 9% -7.16% (p=0.000 n=20+19) MapPop1000-8 367µs ±17% 335µs ±11% -8.63% (p=0.000 n=19+19) MapPop10000-8 7.29ms ±15% 6.86ms ±12% -5.84% (p=0.020 n=20+20) Change-Id: I9faf32f95a6ba6a6d5d0818eab32cc271e01d10a Reviewed-on: https://go-review.googlesource.com/26666 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
Cherry Zhang authored
The frontend rewriting lowers them to runtime calls on 386. It matches explicitly uint32, but missed uint. Fixes #16738. Change-Id: Iece7a45edf74615baca052a53273c208f057636d Reviewed-on: https://go-review.googlesource.com/27085 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Keith Randall authored
Might as well tell the runtime how large the map is going to be. This avoids grow work and allocations while the map is being built. Will wait for 1.8. Fixes #15880 Fixes #16279 Change-Id: I377e3e5ec1e2e76ea2a50cc00810adda20ad0e79 Reviewed-on: https://go-review.googlesource.com/23558 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
-
Josh Bleecher Snyder authored
Update #16415 Change-Id: I83e0966931ada2f1ed02304685bb45effdd71268 Reviewed-on: https://go-review.googlesource.com/26665 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Josh Bleecher Snyder authored
This CL teaches SSA to recognize code of the form // b is a boolean value, i is an int of some flavor if b { i = 1 } else { i = 0 } and use b's underlying 0/1 representation for i instead of generating jumps. Unfortunately, it does not work on the obvious code: func bool2int(b bool) int { if b { return 1 } return 0 } This is left for future work. Note that the existing phiopt optimizations also don't work for: func neg(b bool) bool { if b { return false } return true } In the meantime, runtime authors and the like can use: func bool2int(b bool) int { var i int if b { i = 1 } else { i = 0 } return i } This compiles to: "".bool2int t=1 size=16 args=0x10 locals=0x0 0x0000 00000 (x.go:25) TEXT "".bool2int(SB), $0-16 0x0000 00000 (x.go:25) FUNCDATA $0, gclocals·23e8278e2b69a3a75fa59b23c49ed6ad(SB) 0x0000 00000 (x.go:25) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 0x0000 00000 (x.go:32) MOVBLZX "".b+8(FP), AX 0x0005 00005 (x.go:32) MOVBQZX AL, AX 0x0008 00008 (x.go:32) MOVQ AX, "".~r1+16(FP) 0x000d 00013 (x.go:32) RET The extraneous MOVBQZX is #15300. This optimization also helps range and slice. The compiler must protect against pointers pointing to the end of a slice/string. It does this by increasing a pointer by either 0 or 1 * elemsize, based on a condition. This CL optimizes away a jump in that code. This CL triggers 382 times while compiling the standard library. Updating code to utilize this optimization is left for future CLs. Updates #6011 Change-Id: Ia7c1185f8aa223c543f91a3cd6d4a2a09c691c70 Reviewed-on: https://go-review.googlesource.com/22711 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Robert Griesemer authored
For #16369. Change-Id: I4c9f5a66b95558adcc1bcface164b9b2b4382d2f Reviewed-on: https://go-review.googlesource.com/24979Reviewed-by: Alan Donovan <adonovan@google.com>
-
David Crawshaw authored
Fixes #16722 Change-Id: I50a0e69d3e79d13bc1860cd983267c3db087a4b8 Reviewed-on: https://go-review.googlesource.com/27119Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Keith Randall authored
Don't fold constant factors into a multiply beyond the capacity of a MULQ instruction (32 bits). Fixes #16733 Change-Id: Idc213c6cb06f7c94008a8cf9e60a9e77d085fd89 Reviewed-on: https://go-review.googlesource.com/27160 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Josh Bleecher Snyder authored
We already inlined _, ok = e.(T) _, ok = i.(E) _, ok = e.(E) The only ok-only variants not inlined are now _, ok = i.(I) _, ok = e.(I) These call getitab, so are non-trivial. Change-Id: Ie45fd8933ee179a679b92ce925079b94cff0ee12 Reviewed-on: https://go-review.googlesource.com/26658 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Michael Pratt authored
Now that assembler opcodes have their own type, they can have a true stringer, rather than explicit calls to Aconv, which makes for nicer format strings. Change-Id: Ic77f5f8ac38b4e519dcaa08c93e7b732226f7bfe Reviewed-on: https://go-review.googlesource.com/25045 Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
-
Josh Bleecher Snyder authored
Pick up a bunch of changes and fixes. Change-Id: If4101f7185d433a4c89096bc786ee5de8eeabac0 Reviewed-on: https://go-review.googlesource.com/27123 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Josh Bleecher Snyder authored
No functional changes, makes vet happy. Updates #11041 Change-Id: I59f3aba46d19b86d605508978652d76a1fe7ac7b Reviewed-on: https://go-review.googlesource.com/27125 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-