- 21 Apr, 2017 23 commits
-
-
Austin Clements authored
Currently SetGCPercent forces a GC in order to recompute GC pacing. Since we can now recompute pacing on the fly using gcSetTriggerRatio, change SetGCPercent (really runtime.setGCPercent) to go through gcSetTriggerRatio and not trigger a GC. Fixes #19076. Change-Id: Ib30d7ab1bb3b55219535b9f238108f3d45a1b522 Reviewed-on: https://go-review.googlesource.com/39835 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Austin Clements authored
The current SetGCPercent test is, shall we say, minimal. Expand it to check that the GC target is actually computed and updated correctly. For #19076. Change-Id: I6e9b2ee0ef369f22f72e43b58d89e9f1e1b73b1b Reviewed-on: https://go-review.googlesource.com/39834 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Austin Clements authored
This changes gcSetTriggerRatio so it can be called even during concurrent mark or sweep. In this case, it will adjust the pacing of the current phase, accounting for progress that has already been made. To make this work for concurrent sweep, this introduces a "basis" for the pagesSwept count, much like the basis we just introduced for heap_live. This lets gcSetTriggerRatio shift the basis to the current heap_live and pagesSwept and compute a slope from there to completion. This avoids creating a discontinuity where, if the ratio has increased, there has to be a flurry of sweep activity to catch up. Instead, this creates a continuous, piece-wise linear function as adjustments are made. For #19076. Change-Id: Ibcd76aeeb81ff4814b00be7cbd3530b73bbdbba9 Reviewed-on: https://go-review.googlesource.com/39833 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Austin Clements authored
Currently, proportional sweep maintains its own count of how many bytes have been allocated since the beginning of the sweep cycle so it can compute how many pages need to be swept for a given allocation. However, this requires a somewhat complex reimbursement scheme since proportional sweep must be done before a span is allocated, but we don't know how many bytes to charge until we've allocated a span. This means that the allocated byte count used by proportional sweep can go up and down, which has led to underflow bugs in the past (#18043) and is going to interfere with adjusting sweep pacing on-the-fly (for #19076). This approach also means we're maintaining a statistic that is very closely related to heap_live, but has a different 0 value. This is particularly confusing because the sweep ratio is computed based on heap_live, so you have to understand that these two statistics are very closely related. Replace all of this and compute the sweep debt directly from the current value of heap_live. To make this work, we simply save the value of heap_live when the sweep ratio is computed to use as a "basis" for later computing the sweep debt. This eliminates the need for reimbursement as well as the code for maintaining the sweeper's version of the live heap size. For #19076. Coincidentally fixes #18043, since this eliminates sweep reimbursement entirely. Change-Id: I1f931ddd6e90c901a3972c7506874c899251dc2a Reviewed-on: https://go-review.googlesource.com/39832 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Austin Clements authored
Currently, the computations that derive controls from the GC trigger are spread across several parts of the mark termination code. Consolidate computing the absolute trigger, the heap goal, and sweep pacing into a single function called at the end of mark termination. Unlike the code being consolidated, this has to be more careful about negative gcpercent. Many of the consolidated code paths simply didn't execute if GC was off. This is a step toward being able to change the GC trigger ratio in the middle of concurrent sweeping and marking. For this commit, we try to stick close to the original structure of the code that's being consolidated, so it doesn't yet support mid-cycle adjustments. For #19076. Change-Id: Ic5335be04b96ad20e70d53d67913a86bd6b31456 Reviewed-on: https://go-review.googlesource.com/39831 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Austin Clements authored
gcController.triggerRatio is the only field in gcController that persists across cycles. As global mutable state, the places where it written and read are spread out, making it difficult to see that updates and downstream calculations are done correctly. Improve this situation by doing two things: 1) Move triggerRatio to memstats so it lives with the other trigger-related fields and makes gcController entirely transient state. 2) Commit the new trigger ratio during mark termination when we compute other next-cycle controls, including the absolute trigger. This forces us to explicitly thread the new trigger ratio from gcController.endCycle to mark termination, so we're not just pulling it out of global state. Change-Id: I6669932f8039a8c0ef46a3f2a8c537db72e578aa Reviewed-on: https://go-review.googlesource.com/39830 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Austin Clements authored
heap_live is updated atomically without locking, so we should also use atomic loads to read it. Fix the reads of heap_live that happen outside of STW to be atomic. Change-Id: Idca9451c348168c2a792a9499af349833a3c333f Reviewed-on: https://go-review.googlesource.com/41371 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
-
Hiroshi Ioka authored
Change-Id: I0f8c695146b39cff72ca2374f861f3e9f72b0f77 Reviewed-on: https://go-review.googlesource.com/41314Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Austin Clements authored
The inliner's ishairy passes a budget and a reason down through the walk. Lift these into a visitor object and turn ishairy and its helpers into methods. This will make it easy to add more state. Change-Id: Ic6ae246e1affd67ed283c3205f9595ae33e22215 Reviewed-on: https://go-review.googlesource.com/41151 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
Josh Bleecher Snyder authored
Response to code review feedback on CL 40693. It is now only accessible by types.TypePkgLookup. Passes toolstash-check. Change-Id: I0c422c1a271f97467ae38de53af9dc33f4b31bdb Reviewed-on: https://go-review.googlesource.com/41304 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
-
Josh Bleecher Snyder authored
Response to code review feedback on CL 40693. Remove the final reference to it from package gc, and manually unexport. Passes toolstash-check. Change-Id: I7fc48edd43263d8f7c56b47aeb7573408463dc22 Reviewed-on: https://go-review.googlesource.com/41303 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
-
Josh Bleecher Snyder authored
Response to code review feedback on CL 40693. This CL was prepared by: (1) manually adding new implementations and the Ctxt var to package types (2) running eg with template: func before(s *types.Sym) *obj.LSym { return gc.Linksym(s) } func after(s *types.Sym) *obj.LSym { return s.Linksym() } (3) running gofmt -r: gofmt -r 'isblanksym(a) -> a.IsBlank()' (4) manually removing old implementations from package gc Passes toolstash-check. Change-Id: I39c35def7cae5bcbcc7c77253e5d2b066b981dea Reviewed-on: https://go-review.googlesource.com/41302 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
-
Josh Bleecher Snyder authored
Per code review feedback on CL 40693. Change-Id: I38c522022a3c2f3e61ea90181391edb5c178916e Reviewed-on: https://go-review.googlesource.com/41300 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Robert Griesemer <gri@golang.org>
-
David Lazar authored
Previously, helpers were identified by entry PC, but this breaks if the helper is inlined (as in notHelperCallingHelper). Instead, identify helpers by function name (with package path). Now TestTBHelper and TestTBHelperParallel pass with -l=4. To keep the code unified, this change makes it so that the runner is also identified by function name instead of entry PC. Change-Id: I1b1987fc49d114e69d075fab56aeeacd5294982b Reviewed-on: https://go-review.googlesource.com/41257 Run-TryBot: David Lazar <lazard@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Austin Clements <austin@google.com>
-
David Lazar authored
runtime.getcaller{pc,sp} expect their argument to be a pointer to the caller's first function argument. This assumption breaks when the caller is inlined. For example, with -l=4, calls to runtime.entersyscall (which calls getcallerpc) are inlined and that breaks multiple cgo tests. This change modifies the compiler to refuse to inline functions that call runtime.getcaller{pc,sp}. Alternatively, we could mark these functions //go:noinline but that limits optimization opportunities if the calls to getcaller{pc,sp} are eliminated as dead code. Previously TestCgoPprofPIE, TestCgoPprof, and TestCgoCallbackGC failed with -l=4. Now all of the runtime tests pass with -l=4. Change-Id: I258bca9025e20fc451e673a18f862b5da1e07ae7 Reviewed-on: https://go-review.googlesource.com/40998 Run-TryBot: David Lazar <lazard@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Austin Clements <austin@google.com>
-
Austin Clements authored
On 32-bit architectures (or if we fail to map a 64-bit-style arena), we try to map the heap arena just above the end of the process image. While we can accept any address, using lower addresses is preferable because lower addresses cause us to map less of the heap bitmap. However, if a program is linked against C code that has global constructors, those constructors may call brk/sbrk to allocate memory (e.g., many C malloc implementations do this for small allocations). The brk also starts just above the process image, so this may adjust the brk past the beginning of where we want to put the heap arena. In this case, the kernel will pick a different address for the arena and it will usually be very high (at least, as these things go in a 32-bit address space). Fix this by consulting the current value of the brk and using this in addition to the end of the process image to compute the initial arena placement. This is implemented only on Linux currently, since we have no evidence that it's an issue on any other OSes. Fixes #19831. Change-Id: Id64b45d08d8c91e4f50d92d0339146250b04f2f8 Reviewed-on: https://go-review.googlesource.com/39810 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
-
Josh Bleecher Snyder authored
This makes the cmd/compile/internal/ssa package compile much faster, and has no impact on the speed of the compiler. The chunk size was selected empirically, in that at chunk size 10, the object file was smaller than at chunk size 5 or 20. name old time/op new time/op delta SSA 7.33s ± 5% 5.64s ± 1% -23.10% (p=0.000 n=10+10) name old user-time/op new user-time/op delta SSA 9.70s ± 1% 8.04s ± 2% -17.17% (p=0.000 n=9+10) name old obj-bytes new obj-bytes delta SSA 9.82M ± 0% 8.28M ± 0% -15.67% (p=0.000 n=10+10) Change-Id: Iab472905da3f0e82f3db2c93d06e2759abc9dd44 Reviewed-on: https://go-review.googlesource.com/41296Reviewed-by: Keith Randall <khr@golang.org>
-
Josh Bleecher Snyder authored
They are left over from the days before we had BlockKindFirst and swapSuccessors. Change-Id: I9259d53ac2821ca4d5de5dd520ca4b78f52ecad4 Reviewed-on: https://go-review.googlesource.com/41206 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
xufei_Alex authored
Change-Id: I24c824edd8af6311a4eff44ef4bb28d73a91c68e Reviewed-on: https://go-review.googlesource.com/41295Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Mostyn Bramley-Moore authored
FreeBSD doesn't allow non-root users to enable the SetGID bit on files or directories in /tmp, however it does allow this in subdirectories, so create the test directory one level deeper. Followup to golang/go#19596. Change-Id: I30e71c6d6a156badc863e8068df10ef6ed817e26 Reviewed-on: https://go-review.googlesource.com/41216Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Damien Lespiau authored
Brad noticed a bullet list was rendered as preformatted text because of the indentation. One can use a unicode bullet as an ersatz for bullet lists. Fixes #20043 Change-Id: Iaed3582d14bd05920455669039a900d7155960d9 Reviewed-on: https://go-review.googlesource.com/41212Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Ian Lance Taylor authored
Change-Id: I377403fc0981d58aec5d84a1dd0d4e08532a575c Reviewed-on: https://go-review.googlesource.com/41291Reviewed-by: Dan Peterson <dpiddy@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Carlisia Campos authored
Adding the Go Time podcast under the `Stay informed` section of the help page on the website. Change-Id: Ifb1c6bb20cbf640a91572d47f14a432f58439261 Reviewed-on: https://go-review.googlesource.com/41146Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
- 20 Apr, 2017 17 commits
-
-
Keith Randall authored
At VARKILLs, zero a variable if it is ambiguously live. After the VARKILL anything this variable references might be collected. If it were to become live again later, the GC will see references to already-collected objects. We don't know a variable is ambiguously live until very late in compilation (after lowering, register allocation, ...), so it is hard to generate the code in an arch-independent way. We also have to be careful not to clobber any registers. Fortunately, this almost never happens so performance is ~irrelevant. There are only 2 instances where this triggers in the stdlib. Fixes #20029 Change-Id: Ia9585a91d7b823fad4a9d141d954464cc7af31f4 Reviewed-on: https://go-review.googlesource.com/41076 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
-
Keith Randall authored
Copied by hand. Update #17410 Update #19142 Fixes #19986 Change-Id: I21d16d254161c75466b31c670f3b2c8c463abd66 Reviewed-on: https://go-review.googlesource.com/41205 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Aliaksandr Valialkin authored
Make poolLocal size multiple of 128, so it aligns to CPU cache line on the most common architectures. This also has the following benefits: - It may help compiler substituting integer multiplication by bit shift inside indexLocal. - It shrinks poolLocal size from 176 bytes to 128 bytes on amd64, so now it fits two cache lines (or a single cache line on certain Intel CPUs - see https://software.intel.com/en-us/articles/optimizing-application-performance-on-intel-coret-microarchitecture-using-hardware-implemented-prefetchers). No measurable performance changes on linux/amd64 and linux/386. Change-Id: I11df0f064718a662e77a85d88b8a15a8919f25e9 Reviewed-on: https://go-review.googlesource.com/40918Reviewed-by: Dmitry Vyukov <dvyukov@google.com> Run-TryBot: Dmitry Vyukov <dvyukov@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Alberto Donizetti authored
Fixes #8438 Change-Id: Ib43cdcdc962a8d9e14faf984bc859a92ba1eb517 Reviewed-on: https://go-review.googlesource.com/40531Reviewed-by: Robert Griesemer <gri@golang.org>
-
Josh Bleecher Snyder authored
There were only two versions, 0 and 1, and the only user of version 1 was the assembler, to indicate that a symbol was static. Rename LSym.Version to Static, and add it to LSym.Attributes. Simplify call-sites. Passes toolstash-check. Change-Id: Iabd39918f5019cce78f381d13f0481ae09f3871f Reviewed-on: https://go-review.googlesource.com/41201 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
Robert Griesemer authored
Imported interfaces must be completed, whether they are named or not. The original code was collecting all types (including anonymous ones) in the importer's typList. That list was used in the end to complete interface types. When we introduced tracking of named types only, we lost anonymous interfaces. Use an independent list of interface types so the completion code is independent of which types are tracked. Added test and factored some of the existing tests. Fixes #20046. Change-Id: Icd1329032aec33f96890380dd5042de3bef8cdc7 Reviewed-on: https://go-review.googlesource.com/41198Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
David Lazar authored
TestBreakpoint expects to see "runtime.Breakpoint()" in the stack trace. If runtime.Breakpoint() is inlined, then the stack trace prints "runtime.Breakpoint(...)" since the runtime does not have information about arguments (or lack thereof) to inlined functions. This change makes the test independent of inlining by looking for the string "runtime.Breakpoint(". Now TestBreakpoint passes with -l=4. Change-Id: Ia044a8e8a4de2337cb2b393d6fa78c73a2f25926 Reviewed-on: https://go-review.googlesource.com/40997 Run-TryBot: David Lazar <lazard@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Austin Clements authored
TestBlockProfile matches samples against a regexp that accepts "," in profile PCs. I suspect this was just a syntax mistake. Remove "," from the character class. Change-Id: Idcfc20ed6900075abae08597ba71db559e89b37b Reviewed-on: https://go-review.googlesource.com/41111 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Peter Weinberger <pjw@google.com>
-
Austin Clements authored
TestBlockProfile currently requires exactly five PCs in each sample. With more aggressive inlining there may be fewer, so change this test to use the same pattern as TestMutexProfile, which accepts one or more PCs. With this change, this test passes when compiled with -l=4. Change-Id: I1421a6d56c96b77111bdc671d88723a222672fd6 Reviewed-on: https://go-review.googlesource.com/41110 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Lazar <lazard@golang.org>
-
Josh Bleecher Snyder authored
CL 40876 changed ExampleFrames so that the output was stable with and without mid-stack inlining. However, that change lost some of the pedagogical and copy/paste value of the example. It was unclear why both more and i were being tracked, and whether the 5 in i < 5 is related to len(pc), and if so, why and how. This CL rewrites the example with lots more comments, and such that the core structure more closely matches normal usage, and such that it is obvious which lines of code should be deleted when copying. As a bonus, it also now illustrates Frame.File. Change-Id: Iab73541dd096657ddf79c5795337e8b596d89740 Reviewed-on: https://go-review.googlesource.com/41136 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Austin Clements authored
The period recorded in CPU profiles is in nanoseconds, but was being computed incorrectly as hz * 1000. As a result, many absolute times displayed by pprof were incorrect. Fix this by computing the period correctly. Change-Id: I6fadd6d8ad3e57f31e8cc7a25a24fcaec510d8d4 Reviewed-on: https://go-review.googlesource.com/40995 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com> Reviewed-by: Russ Cox <rsc@golang.org>
-
Samuel Tan authored
Convert the parsed attribute name to lowercase before checking its value in the HTML parser state machine. This ensures that the type attribute in the script element is handled in a case-sensitive manner, just like all other attribute names. Fixes #19965 Change-Id: I806d8c62aada2c3b5b4328aff75f217ea60cb339 Reviewed-on: https://go-review.googlesource.com/40650 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
-
Matthew Dempsky authored
The arch backends no longer depend on gc.Node. Passes toolstash-check -all. Change-Id: Ic7e49ae0a3ed155a2761c25e17cc341b46333fb4 Reviewed-on: https://go-review.googlesource.com/41196 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Ilya Tocar authored
VEX encoded instructions don't have a REX byte, so for PC relative addressing we don't need to recalculate relocation offset. Fixes #19518 Change-Id: Icf5414962de4350d76fd220817498337f90614fc Reviewed-on: https://go-review.googlesource.com/38138 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Samuel Tan authored
Handle MIME types found in the type attribute of the script element in a case insensitive way, as per Section 5.1 of RFC 2045. Fixes #19968 Change-Id: Ie1416178c937dcf2c96bcec4191cebe7c3477af8 Reviewed-on: https://go-review.googlesource.com/40702Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Lynn Boger authored
This updates PPC64.rules to include rules to generate rotates for ADD, OR, XOR operators that combine two opposite shifts that sum to 32 or 64. To support this change opcodes for ROTL and ROTLW were added to be used like the rotldi and rotlwi extended mnemonics. This provides the following improvement in sha3: BenchmarkPermutationFunction-8 302.83 376.40 1.24x BenchmarkSha3_512_MTU-8 98.64 121.92 1.24x BenchmarkSha3_384_MTU-8 136.80 168.30 1.23x BenchmarkSha3_256_MTU-8 169.21 211.29 1.25x BenchmarkSha3_224_MTU-8 179.76 221.19 1.23x BenchmarkShake128_MTU-8 212.87 263.23 1.24x BenchmarkShake256_MTU-8 196.62 245.60 1.25x BenchmarkShake256_16x-8 163.57 194.37 1.19x BenchmarkShake256_1MiB-8 199.02 248.74 1.25x BenchmarkSha3_512_1MiB-8 106.55 133.13 1.25x Fixes #20030 Change-Id: I484c56f48395d32f53ff3ecb3ac6cb8191cfee44 Reviewed-on: https://go-review.googlesource.com/40992 Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com> Reviewed-by: Michael Munday <munday@ca.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Alberto Donizetti authored
Fixes #19207 Change-Id: I69b70492fd01599a13c1a3beb87f492de40a18b0 Reviewed-on: https://go-review.googlesource.com/37312Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-