- 07 Nov, 2019 28 commits
-
-
Cherry Zhang authored
For async preemption, we will be using REGTMP as a temporary register in injected call on MIPS, which will clobber it. So any code that uses REGTMP is not safe for async preemption. In the assembler backend, we expand a Prog to multiple machine instructions and use REGTMP as a temporary register if necessary. These need to be marked unsafe. In fact, most of the multi-instruction Progs use REGTMP, so we mark all of them, except ones that are whitelisted. Change-Id: Ic00ae5589683c2c9525abdaee076d884df6b0d1e Reviewed-on: https://go-review.googlesource.com/c/go/+/203718 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Cherry Zhang authored
This CL adds support of call injection and async preemption on ARM64. There seems no way to return from the injected call without clobbering *any* register. So we have to clobber one, which is chosen to be REGTMP. Previous CLs have marked code sequences that use REGTMP async-nonpreemtible. Change-Id: Ieca4e3ba5557adf3d0f5d923bce5f1769b58e30b Reviewed-on: https://go-review.googlesource.com/c/go/+/203461 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Cherry Zhang authored
For async preemption, we will be using REGTMP as a temporary register in injected call on ARM64, which will clobber it. So any code that uses REGTMP is not safe for async preemption. In the assembler backend, we expand a Prog to multiple machine instructions and use REGTMP as a temporary register if necessary. These need to be marked unsafe. In fact, most of the multi-instruction Progs use REGTMP, so we mark all of them, except ones that are whitelisted. Change-Id: I6e97805a13950e3b693fb606d77834940ac3722e Reviewed-on: https://go-review.googlesource.com/c/go/+/203460 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Michael Anthony Knyszek authored
This change adds a "locked" parameter to scavenge() and scavengeone() which allows these methods to be run with the heap lock acquired, and synchronously with respect to others which acquire the heap lock. This mode is necessary for both heap-growth scavenging (multiple asynchronous scavengers here could be problematic) and debug.FreeOSMemory. Updates #35112. Change-Id: I24eea8e40f971760999c980981893676b4c9b666 Reviewed-on: https://go-review.googlesource.com/c/go/+/195699Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Keith Randall <khr@golang.org>
-
Michael Anthony Knyszek authored
This change makes it so that the new page allocator returns the number of pages that are scavenged in a new allocation so that mheap can update memstats appropriately. The accounting could be embedded into pageAlloc, but that would make the new allocator more difficult to test. Updates #35112. Change-Id: I0f94f563d7af2458e6d534f589d2e7dd6af26d12 Reviewed-on: https://go-review.googlesource.com/c/go/+/195698Reviewed-by: Austin Clements <austin@google.com>
-
Michael Anthony Knyszek authored
This change adds a scavenger for the new page allocator along with tests. The scavenger walks over the heap backwards once per GC, looking for memory to scavenge. It walks across the heap without any lock held, searching optimistically. If it finds what appears to be a scavenging candidate it acquires the heap lock and attempts to verify it. Upon verification it then scavenges. Notably, unlike the old scavenger, it doesn't show any preference for huge pages and instead follows a more strict last-page-first policy. Updates #35112. Change-Id: I0621ef73c999a471843eab2d1307ae5679dd18d6 Reviewed-on: https://go-review.googlesource.com/c/go/+/195697Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Michael Anthony Knyszek authored
This change adds a new bitmap-based allocator to the runtime with tests. It does not yet integrate the page allocator into the runtime and thus this change is almost purely additive. Updates #35112. Change-Id: Ic3d024c28abee8be8797d3918116a80f901cc2bf Reviewed-on: https://go-review.googlesource.com/c/go/+/190622 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Ian Lance Taylor authored
Fixes #35356 Change-Id: I67b9e57b88d00ed98cbc3aa0aeb26b5f2d75a3f7 Reviewed-on: https://go-review.googlesource.com/c/go/+/205720 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-
Bryan C. Mills authored
This fixes a test failure introduced in CL 190620. Updates #35112 Change-Id: I568ae85a456ccd8103563b0ce2e42b7348776a5c Reviewed-on: https://go-review.googlesource.com/c/go/+/205877 Run-TryBot: Bryan C. Mills <bcmills@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
-
Michael Anthony Knyszek authored
This change ensures js-wasm returns page-aligned memory. While today its lack of alignment doesn't cause problems, this is an invariant of sysAlloc which is documented in HACKING.md but isn't upheld by js-wasm. Any code that calls sysAlloc directly for small structures expects a certain alignment (e.g. debuglog, tracebufs) but this is not maintained by js-wasm's sysAlloc. Where sysReserve comes into play is that sysAlloc is implemented in terms of sysReserve on js-wasm. Also, the documentation of sysReserve says that the returned memory is "OS-aligned" which on most platforms means page-aligned, but the "OS-alignment" on js-wasm is effectively 1, which doesn't seem right either. The expected impact of this change is increased memory use on wasm, since there's no way to decommit memory, and any small structures allocated with sysAlloc won't be packed quite as tightly. However, any memory increase should be minimal. Most calls to sysReserve and sysAlloc already aligned their request to physPageSize before calling it; there are only a few circumstances where this is not true, and they involve allocating an amount of memory returned by unsafe.Sizeof where it's actually quite important that we get the alignment right. Updates #35112. Change-Id: I9ca171e507ff3bd186326ccf611b35b9ebea1bfe Reviewed-on: https://go-review.googlesource.com/c/go/+/205277 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Richard Musiol <neelance@gmail.com>
-
Michael Anthony Knyszek authored
This change adds the concept of summaries and of summarizing a set of pallocBits, a core concept in the new page allocator. These summaries are really just three integers packed into a uint64. This change also adds tests and a benchmark for generating these summaries. Updates #35112. Change-Id: I69686316086c820c792b7a54235859c2105e5fee Reviewed-on: https://go-review.googlesource.com/c/go/+/190621 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-
Michael Anthony Knyszek authored
This change adds a per-chunk bitmap for page allocation called pallocBits with algorithms for allocating and freeing pages out of the bitmap. This change also adds tests for pallocBits, but does not yet integrate it into the runtime. Updates #35112. Change-Id: I479006ed9f1609c80eedfff0580d5426b064b0ff Reviewed-on: https://go-review.googlesource.com/c/go/+/190620 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Brian Kessler authored
Commit 44343c77 (CL 173557) added rules for handling divisibility checks for powers of 2 for signed integers, x%c ==0. This change adds the complementary indivisibility rules, x%c != 0. Fixes #34166 Change-Id: I87379e30af7aff633371acca82db2397da9b2c07 Reviewed-on: https://go-review.googlesource.com/c/go/+/194219 Run-TryBot: Brian Kessler <brian.m.kessler@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Michael Anthony Knyszek authored
This change is the first of a series of changes which replace the current page allocator (which is based on the contents of mgclarge.go and some of mheap.go) with one based on free/used bitmaps. It adds in the key constants for the page allocator as well as a comment describing the implementation. Updates #35112. Change-Id: I839d3a07f46842ad379701d27aa691885afdba63 Reviewed-on: https://go-review.googlesource.com/c/go/+/190619 Run-TryBot: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-
Jay Conrod authored
zip.Create is now used to filter and translate zip files from VCS tools. zip.Unzip is now used instead of Unzip. Fixes #35290 Change-Id: I4aa41b2e96bf147c09db43d1d189b8393cafb06f Reviewed-on: https://go-review.googlesource.com/c/go/+/204917 Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
-
Michael Anthony Knyszek authored
This changes makes it so that sysReserve, which creates a PROT_NONE mapping, maps that memory as NORESERVE. Before this change, relatively large PROT_NONE mappings could cause fork to fail with ENOMEM, reported as "not enough space". Presumably this refers to swap space, since adding this flag causes the failures to go away. This helps unblock page allocator work, since it allows us to make large PROT_NONE mappings on solaris safely. Updates #35112. Change-Id: Ic3cba310c626e93d5db0f27269e2569bb7bc393e Reviewed-on: https://go-review.googlesource.com/c/go/+/205759 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-
Jay Conrod authored
This CL adds a new test package which downloads specific versions of ~1000 modules in direct mode and verifies that modules have the same sums and the zip files have the same SHA-256 hashes. This test takes a long time to run and depends heavily on external data that may disappear. It must be enabled manually with -zipsum. Fixes #35290 Change-Id: Ic6959e685096e8b09cea291f19d5bd0255432284 Reviewed-on: https://go-review.googlesource.com/c/go/+/204838Reviewed-by: Bryan C. Mills <bcmills@google.com>
-
Bryan C. Mills authored
This reverts CL 200577. Reason for revert: broke linux-arm64-packet and solaris-amd64-oraclerel builders Fixes #35424 Updates #33747 Change-Id: I2575fd84d37995d458183caae54704f15d8b8426 Reviewed-on: https://go-review.googlesource.com/c/go/+/205817 Run-TryBot: Bryan C. Mills <bcmills@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Russ Cox authored
This makes it a little less likely the portable FMA will be broken without realizing it. Change-Id: I7f7f4509b35160a9709f8b8a0e494c09ea6e410a Reviewed-on: https://go-review.googlesource.com/c/go/+/205337 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
Russ Cox authored
This API was added for #25819, where it was discussed as math.FMA. The commit adding it used math.Fma, presumably for consistency with the rest of the unusual names in package math (Sincos, Acosh, Erfcinv, Float32bits, etc). I believe that using an idiomatic Go name is more important here than consistency with these other names, most of which are historical baggage from C's standard library. Early additions like Float32frombits happened before "uppercase for export" (so they were originally like "float32frombits") and they were not properly reconsidered when we uppercased the symbols to export them. That's a mistake we live with. The names of functions we have added since then, and even a few that were legacy, are more properly Go-cased, such as IsNaN, IsInf, and RoundToEven, rather than Isnan, Isinf, and Roundtoeven. And also constants like MaxFloat32. For new API, we should keep using proper Go-cased symbols instead of minimally-upper-cased-C symbols. So math.FMA, not math.Fma. This API has not yet been released, so this change does not break the compatibility promise. This CL also modifies cmd/compile, since the compiler knows the name of the function. I could have stopped at changing the string constants, but it seemed to make more sense to use a consistent casing everywhere. Change-Id: I0f6f3407f41e99bfa8239467345c33945088896e Reviewed-on: https://go-review.googlesource.com/c/go/+/205317 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Cuong Manh Le authored
This CL was verified by running: go test -gcflags=all=-d=checkptr=2 internal/syscall/windows internal/syscall/windows.TestRunAtLowIntegrity uses code in question. Updates #34972 Change-Id: I434530058e2d41f132e9bf154e8c64c03894e9c4 Reviewed-on: https://go-review.googlesource.com/c/go/+/204117 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Rob Pike authored
No need to check as pieces further down do so anyway: % go doc '&&.%$^' doc: symbol && is not a type in package fmt installed in "fmt" exit status 1 % Removing this check allows 'go doc sort.interface' or 'go doc types.type' to discover sort.Interface and go/types.Type. Easily Fixes #34656. Change-Id: I84352e83dd7f91a232f45a44d1a52f019a1a9a06 Reviewed-on: https://go-review.googlesource.com/c/go/+/205778Reviewed-by: Caleb Spare <cespare@gmail.com> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
-
Brian Kessler authored
Allow the inputs a and b to be zero or negative to GCD with the following definitions. If x or y are not nil, GCD sets their value such that z = a*x + b*y. Regardless of the signs of a and b, z is always >= 0. If a == b == 0, GCD sets z = x = y = 0. If a == 0 and b != 0, GCD sets z = |b|, x = 0, y = sign(b) * 1. If a != 0 and b == 0, GCD sets z = |a|, x = sign(a) * 1, y = 0. Fixes #28878 Change-Id: Ia83fce66912a96545c95cd8df0549bfd852652f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/164972 Run-TryBot: Brian Kessler <brian.m.kessler@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
-
Carlo Alberto Ferraris authored
When we have already assigned the semaphore ticket to a specific waiter, we want to get the waiter running as fast as possible since no other G waiting on the semaphore can acquire it optimistically. The net effect is that, when a sync.Mutex is contented, the code in the critical section guarded by the Mutex gets a priority boost. Fixes #33747 Change-Id: I9967f0f763c25504010651bdd7f944ee0189cd45 Reviewed-on: https://go-review.googlesource.com/c/go/+/200577Reviewed-by: Rhys Hiltner <rhys@justin.tv> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Ian Lance Taylor authored
Fixes #15191 Change-Id: I86214ede619400acd44f21138b5ddf6cef4649a3 Reviewed-on: https://go-review.googlesource.com/c/go/+/205698 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Michael Anthony Knyszek authored
On iOS, the address space is not 48 bits as one might believe, since it's arm64 hardware. In fact, all pointers are truncated to 33 bits, and the OS only gives applications access to the range [1<<32, 2<<32). While today this has no effect on the Go runtime, future changes which care about address space size need this to be correct. Updates #35112. Change-Id: Id518a2298080f7e3d31cf7d909506a37748cc49a Reviewed-on: https://go-review.googlesource.com/c/go/+/205758 Run-TryBot: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@golang.org>
-
Benjamin Peterson authored
Change-Id: I857d39486cbddbbee0c00fd45eb77f21488f4806 GitHub-Last-Rev: 1b500183cfebadffb4c183e56850bfb794a11703 GitHub-Pull-Request: golang/go#35399 Reviewed-on: https://go-review.googlesource.com/c/go/+/205602Reviewed-by: Jonathan Amsterdam <jba@google.com>
-
Michael Anthony Knyszek authored
This change removes a hack which was added to deal with Darwin 10.10's weird ignorance of mapping hints which would cause race mode to fail since it requires the heap to live within a certain address range. We no longer support 10.10, and this is potentially causing problems related to the page allocator, so drop this code. Updates #26475. Updates #35112. Change-Id: I0e1c6f8c924afe715a2aceb659a969d7c7b6f749 Reviewed-on: https://go-review.googlesource.com/c/go/+/205757 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-
- 06 Nov, 2019 12 commits
-
-
Ian Lance Taylor authored
The test deliberately constructs an invalid pointer, so don't check it. Fixes #35379 Change-Id: Ifeff3484740786b0470de3a4d2d4103d91e06f5d Reviewed-on: https://go-review.googlesource.com/c/go/+/205717Reviewed-by: Matthew Dempsky <mdempsky@google.com>
-
Vitaly Zdanevich authored
Change-Id: I7f5947cef3ec43746f60abca556dda29a705caf7 GitHub-Last-Rev: b9aefd06abdaee854671451711579dd5bd33bd26 GitHub-Pull-Request: golang/go#35404 Reviewed-on: https://go-review.googlesource.com/c/go/+/205610Reviewed-by: Rob Pike <r@golang.org>
-
Kevin Burke authored
Change-Id: Ib29da1ad77c9a243a623d25113c6f8dd0261f42a Reviewed-on: https://go-review.googlesource.com/c/go/+/205601Reviewed-by: Ian Lance Taylor <iant@golang.org>
-
Bryan C. Mills authored
This change is based on the previous discussion in CL 202442. Fixes #34634 Change-Id: I1319aa26d5cfcd034bc576555787b3ca79968c38 Reviewed-on: https://go-review.googlesource.com/c/go/+/205637 Run-TryBot: Bryan C. Mills <bcmills@google.com> Reviewed-by: Jay Conrod <jayconrod@google.com>
-
Bryan C. Mills authored
This change employs the same strategy as in CL 203017 to detect when vendoring is in use, and if so treats the vendor directory as a (non-module, prefixless) root. The integration test also verifies that the 'std' and 'cmd' modules are included and their vendored dependencies are visible (as they are with 'go list') even when outside of those modules. Fixes #35224 Change-Id: I18cd01218e9eb97c1fc6e2401c1907536b0b95f7 Reviewed-on: https://go-review.googlesource.com/c/go/+/205577 Run-TryBot: Bryan C. Mills <bcmills@google.com> Reviewed-by: Jay Conrod <jayconrod@google.com>
-
Joel Sing authored
Factor out the direct CALL identification code from objabi.IsDirectJump and use this in two places that have separately maintained lists of reloc types. Provide an objabi.IsDirectCallOrJump function that implements the original behaviour of objabi.IsDirectJump. Change-Id: I48131bae92b2938fd7822110d53df0b4ffb35766 Reviewed-on: https://go-review.googlesource.com/c/go/+/196577 Run-TryBot: Joel Sing <joel@sing.id.au> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-
Robert Griesemer authored
Don't print to stdout in non-verbose (-v) test mode. Exception: Timing output (2 lines) of TestStdLib. If we want to disable that as well we should use another flag to differenciate between -verbose output and measurement results. Leaving alone for now. Fixes #35223. Change-Id: Ie8160760e8db1138f9031888d654eaeab202128c Reviewed-on: https://go-review.googlesource.com/c/go/+/204039Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-
Meng Zhuo authored
This CL adds basic encode test for mips64x and most of the instructions are cross checked with 'gas' Update #35008 Change-Id: I18bb524897aa745bfe23db43fcbb44c3b009463c Reviewed-on: https://go-review.googlesource.com/c/go/+/204297Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-
Ian Lance Taylor authored
Otherwise, we can get into a deadlock: sysmon takes the scheduler lock and calls timeSleepUntil which takes each P's timer lock. Simultaneously, some P calls runtimer (holding the P's own timer lock) which wakes up the scavenger, calling goready, calling wakep, calling startm, getting the scheduler lock. Now the sysmon thread is holding the scheduler lock and trying to get a P's timer lock, while some other thread running on that P is holding the P's timer lock and trying to get the scheduler lock. So change sysmon to call timeSleepUntil without holding the scheduler lock, and change timeSleepUntil to use allpLock, which is only held for limited periods of time and should never compete with timer locks. This hopefully Fixes #35375 At least it should fix the linux-arm64-packet builder problems, which occurred more reliably as that system has GOMAXPROCS == 96, giving a lot more scope for this deadlock. Change-Id: I7a7917daf7a4882e0b27ca416e4f6300cfaaa774 Reviewed-on: https://go-review.googlesource.com/c/go/+/205558 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
-
Bryan C. Mills authored
Updates #31870 Updates #33326 Fixes #34822 Change-Id: I1337f171133c20800eacc6b0955ede5a394ea7eb Reviewed-on: https://go-review.googlesource.com/c/go/+/204878 Run-TryBot: Bryan C. Mills <bcmills@google.com> Reviewed-by: Jay Conrod <jayconrod@google.com>
-
Elias Naur authored
The -Wl,-headerpad, -Wl,-no_pie, -Wl,-pagezero_size flags are incompatible with the bitcode-related flags used for iOS. We already omitted the flags on darwin/arm and darwin/arm64; this change omits the flags on all platforms != macOS so that building for the iOS simulator works. Updates #32963 Change-Id: Ic9af0daf01608f5ae0f70858e3045e399de7e95b Reviewed-on: https://go-review.googlesource.com/c/go/+/205340 Run-TryBot: Elias Naur <mail@eliasnaur.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
-
Austin Clements authored
WaitForSigusr1 registers a callback to be called on SIGUSR1 directly from the runtime signal handler. Currently, this callback has a write barrier in it, which can crash with a nil P if the GC is active and the signal arrives on an M that doesn't have a P. Fix this by recording the ID of the M that receives the signal instead of the M itself, since that's all we needed anyway. To make sure there are no other problems, this also lifts the callback into a package function and marks it "go:nowritebarrierrec". Fixes #35248. Updates #35276, since in principle a write barrier at exactly the wrong time while entering the scheduler could cause issues, though I suspect that bug is unrelated. Change-Id: I47b4bc73782efbb613785a93e381d8aaf6850826 Reviewed-on: https://go-review.googlesource.com/c/go/+/204620 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
-