Compare commits

...

33 Commits

Author SHA1 Message Date
Chris Broadfoot
f75aafdf56 [release-branch.go1.7] go1.7.1
Change-Id: Id877244fba01ae84255ad2d1f6334d096d5d6f71
Reviewed-on: https://go-review.googlesource.com/28694
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 19:11:54 +00:00
Chris Broadfoot
b261730e56 [release-branch.go1.7] doc: document go1.7.1
Change-Id: I6bdbf0cafa0f70bdb7c435e45885f5d8f9e05dad
Reviewed-on: https://go-review.googlesource.com/28693
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/28692
2016-09-07 19:10:12 +00:00
Austin Clements
40712a9625 [release-branch.go1.7] runtime: fix check for vacuous page boundary rounding again
The previous fix for this, commit 336dad2a, had everything right in
the commit message, but reversed the test in the code. Fix the test in
the code.

This reversal effectively disabled the scavenger on large page systems
*except* in the rare cases where this code was originally wrong, which
is why it didn't obviously show up in testing.

Fixes #16644. Again. :(

Change-Id: I27cce4aea13de217197db4b628f17860f27ce83e
Reviewed-on: https://go-review.googlesource.com/27402
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/28631
Run-TryBot: Chris Broadfoot <cbro@golang.org>
2016-09-07 18:48:36 +00:00
Keith Randall
24f46bd34f [release-branch.go1.7] cmd/compile: compare size in dead store elimination
This CL is a manual backpatch of CL 27320 into the 1.7.1 release branch.

The manual backpatch is required because OpZero changed from having a
size as its AuxInt to having a size+align as its AuxInt (that was to support
the ARM SSA backend).  Otherwise the CLs should be identical.

Please review carefully!

Change-Id: I569b759c06d1971c9c62dc5dd589abc7ef7c844a
Reviewed-on: https://go-review.googlesource.com/28670
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-09-07 18:48:24 +00:00
Brad Fitzpatrick
c24b5d43a6 [release-branch.go1.7] syscall: use MNT_NOWAIT in TestGetfsstat
Fixes test failure when VMWare's shared folder filesystem is present.

MNT_NOWAIT is what the mount(8) command does.

Fixes #16937

Change-Id: Id436185f544b7069db46c8716d6a0bf580b31da0
Reviewed-on: https://go-review.googlesource.com/28550
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-on: https://go-review.googlesource.com/28650
Run-TryBot: Chris Broadfoot <cbro@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 18:15:52 +00:00
Brad Fitzpatrick
dc3612e0d1 [release-branch.go1.7] net/http: fix unwanted HTTP/2 conn Transport crash after IdleConnTimeout
Go 1.7 crashed after Transport.IdleConnTimeout if an HTTP/2 connection
was established but but its caller no longer wanted it. (Assuming the
connection cache was enabled, which it is by default)

Fixes #16208

Change-Id: I9628757f7669e344f416927c77f00ed3864839e3
Reviewed-on: https://go-review.googlesource.com/27450
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/28637
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:49:20 +00:00
Brad Fitzpatrick
6f12826a86 [release-branch.go1.7] net/http: make Transport.CancelRequest doc recommend Request.WithContext
The old deprecation docs were referencing another deprecated field.

Fixes #16752

Change-Id: I44a690048e00ddc790a80214ecb7f5bb0a5b7b34
Reviewed-on: https://go-review.googlesource.com/27510
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-on: https://go-review.googlesource.com/28638
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:47:55 +00:00
Hiroshi Ioka
3129c67db7 [release-branch.go1.7] path/filepath: handle ".." in normalizing a path on Windows
Current code assumes there are not ".." in the Clean(path).
That's not true. Clean doesn't handle leading "..", so we need to stop
normalization if we see "..".

Fixes #16793

Change-Id: I0a7901bedac17f1210b134d593ebd9f5e8483775
Reviewed-on: https://go-review.googlesource.com/27410
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/28641
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:47:27 +00:00
Matthew Dempsky
bb8706890b [release-branch.go1.7] net: restore per-query timeout logic
The handling of "options timeout:n" is supposed to be per individual
DNS server exchange, not per Lookup call.

Fixes #16865.

Change-Id: I2304579b9169c1515292f142cb372af9d37ff7c1
Reviewed-on: https://go-review.googlesource.com/28057
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/28640
2016-09-07 17:47:00 +00:00
Egon Elbre
287be1e42d [release-branch.go1.7] website: recreate 16px and 32px favicon
Recreated original favicon with svg. Note, the rasterizations are hand
tweaked for crispness and straight export will not give the same results.

Fixes #6938

Change-Id: I9bf7b59028711361c29365b145932d90af419b69
Reviewed-on: https://go-review.googlesource.com/26850
Reviewed-by: Chris Broadfoot <cbro@golang.org>
Reviewed-on: https://go-review.googlesource.com/28639
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:46:59 +00:00
Tom Wilkie
308bdd0256 [release-branch.go1.7] net: don't avoid resolving .local addresses
.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/27250
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/28632
2016-09-07 17:46:47 +00:00
David Crawshaw
9b4e323e88 [release-branch.go1.7] reflect: clear tflag on new types
Fixes #16722

Change-Id: I50a0e69d3e79d13bc1860cd983267c3db087a4b8
Reviewed-on: https://go-review.googlesource.com/27119
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/28630
2016-09-07 17:46:45 +00:00
Michael Munday
a5add8c726 [release-branch.go1.7] hash/crc32: fix optimized s390x implementation
The code wasn't checking to see if the data was still >= 64 bytes
long after aligning it.

Aligning the data is an optimization and we don't actually need
to do it. In fact for smaller sizes it slows things down due to
the overhead of calling the generic function. Therefore for now
I have simply removed the alignment stage. I have also added a
check into the assembly to deliberately trigger a segmentation
fault if the data is too short.

Fixes #16779.

Change-Id: Ic01636d775efc5ec97689f050991cee04ce8fe73
Reviewed-on: https://go-review.googlesource.com/27409
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/28635
2016-09-07 17:46:02 +00:00
Brad Fitzpatrick
e464c08bef [release-branch.go1.7] io: fix infinite loop bug in MultiReader
If an io.Reader returned (non-zero, EOF), MultiReader would yield
bytes forever.

This bug has existed before Go 1 (!!), introduced in the original
MultiReader implementation in https://golang.org/cl/1764043 and also
survived basically the only update to this code since then
(https://golang.org/cl/17873, git rev ccdca832c), which was added in
Go 1.7.

This just bit me when writing a test for some unrelated code.

Fixes #16795

Change-Id: I36e6a701269793935d19a47ac12f67b07179fbff
Reviewed-on: https://go-review.googlesource.com/27397
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-on: https://go-review.googlesource.com/28633
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:45:58 +00:00
Joe Tsai
c0f5de1ad2 [release-branch.go1.7] compress/flate: make huffmanBitWriter errors persistent
For persistent error handling, the methods of huffmanBitWriter have to be
consistent about how they check errors. It must either consistently
check error *before* every operation OR immediately *after* every
operation. Since most of the current logic uses the previous approach,
we apply the same style of error checking to writeBits and all calls
to Write such that they only operate if w.err is already nil going
into them.

The error handling approach is brittle and easily broken by future commits to
the code. In the near future, we should switch the logic to use panic at the
lowest levels and a recover at the edge of the public API to ensure
that errors are always persistent.

Fixes #16749

Change-Id: Ie1d83e4ed8842f6911a31e23311cd3cbf38abe8c
Reviewed-on: https://go-review.googlesource.com/27200
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/28634
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:45:45 +00:00
Brad Fitzpatrick
1861ac159e [release-branch.go1.7] net/http: update bundled http2 for Transport double STREAM_ENDED error
Updates bundled http2 to x/net/http2 git rev 7394c11 for:

http2: fix protocol violation regression when writing certain request bodies
https://golang.org/cl/27406

Fixes #16788

Change-Id: I0efcd36e2b4b34a1df79f763d35bf7a3a1858506
Reviewed-on: https://go-review.googlesource.com/27451
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
Reviewed-on: https://go-review.googlesource.com/28636
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-07 17:45:41 +00:00
Brad Fitzpatrick
759c2c48ea [release-branch.go1.7] doc/go1.7.html: fix name of tls.Config.NextProtos
Updates #16737

Change-Id: Ia51fc9b06df43b7c6f7136e90b40362263c20081
Reviewed-on: https://go-review.googlesource.com/27126
Reviewed-by: Chris Broadfoot <cbro@golang.org>
Reviewed-on: https://go-review.googlesource.com/27234
2016-08-17 17:35:08 +00:00
Chris Broadfoot
09fa0b8e95 [release-branch.go1.7] doc: add 1.7 to golang.org/project
Change-Id: Ib17f6643efd49e2bca188c4faa505f79832d18b1
Reviewed-on: https://go-review.googlesource.com/27110
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/27112
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2016-08-16 01:17:11 +00:00
Chris Broadfoot
0d81858868 go1.7
Change-Id: Id86f2615772ce087c2ac1a9039ffc27c33298773
Reviewed-on: https://go-review.googlesource.com/27075
Run-TryBot: Chris Broadfoot <cbro@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-08-15 22:43:38 +00:00
Chris Broadfoot
681a667ced [release-branch.go1.7] doc: document go1.7
Change-Id: Ieae5831b35768a625bf735a38f3d938f23f0b77b
Reviewed-on: https://go-review.googlesource.com/27057
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/27070
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2016-08-15 20:16:48 +00:00
Chris Broadfoot
806a84d3f1 [release-branch.go1.7] doc: update version tag in source install instructions
Change-Id: Id83e0371b7232b01be83640ef1e47f9026cf2a23
Reviewed-on: https://go-review.googlesource.com/27055
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/27056
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2016-08-15 19:52:58 +00:00
Chris Broadfoot
87d4bd1997 [release-branch.go1.6] doc/go1.7.html: remove DRAFT
Fixes #15820.

Change-Id: Ia5d5237754e77774a3a6049765eea163911f41c9
Reviewed-on: https://go-review.googlesource.com/25592
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-on: https://go-review.googlesource.com/27054
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2016-08-15 18:53:48 +00:00
Chris Broadfoot
1e933ed7c0 go1.7rc6
Change-Id: Ie76b5af0ecc4c64c523110b44483c06e7031237c
Reviewed-on: https://go-review.googlesource.com/25582
Reviewed-by: Chris Broadfoot <cbro@golang.org>
2016-08-08 18:42:30 +00:00
Chris Broadfoot
78d024a588 all: merge master into release-branch.go1.7
7a62274 net/http: make Transport use new connection if over HTTP/2 concurrency limit
219ca60 doc: fix required OS X version inconsistency for binary downloads
26015b9 runtime: make stack 16-byte aligned for external code in _rt0_amd64_linux_lib
9fde86b runtime, syscall: fix kernel gettimeofday ABI change on iOS 10
3a03e87 os: check for waitid returning ENOSYS
1031675 net/http: update bundled http2 for flow control window adjustment fix
da070be syscall: fix Gettimeofday on macOS Sierra
f135c32 runtime: initialize hash algs before typemap

Change-Id: Ie176f3db1e253d75ae8e56b16d3fd9900b37dde3
2016-08-08 11:30:51 -07:00
Brad Fitzpatrick
7a62274065 net/http: make Transport use new connection if over HTTP/2 concurrency limit
The Go HTTP/1 client will make as many new TCP connections as the user requests.

The HTTP/2 client tried to have that behavior, but the policy of
whether a connection is re-usable didn't take into account the extra 1
stream counting against SETTINGS_MAX_CONCURRENT_STREAMS so in practice
users were getting errors.

For example, if the server's advertised max concurrent streams is 100
and 200 concurrrent Go HTTP requests ask for a connection at once, all
200 will think they can reuse that TCP connection, but then 100 will
fail later when the number of concurrent streams exceeds 100.

Instead, recognize the "no cached connections" error value in the
shouldRetryRequest method, so those 100 will retry a new connection.

This is the conservative fix for Go 1.7 so users don't get errors, and
to match the HTTP/1 behavior. Issues #13957 and #13774 are the more
involved bugs for Go 1.8.

Updates #16582
Updates #13957

Change-Id: I1f15a7ce60c07a4baebca87675836d6fe03993e8
Reviewed-on: https://go-review.googlesource.com/25580
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Chris Broadfoot <cbro@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
2016-08-08 17:53:51 +00:00
Brad Fitzpatrick
219ca602ab doc: fix required OS X version inconsistency for binary downloads
Updates #16625

Change-Id: Icac6705828bd9b29379596ba64b34d922b9002c3
Reviewed-on: https://go-review.googlesource.com/25548
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-08-06 19:30:57 +00:00
Shenghou Ma
26015b9563 runtime: make stack 16-byte aligned for external code in _rt0_amd64_linux_lib
Fixes #16618.

Change-Id: Iffada12e8672bbdbcf2e787782c497e2c45701b1
Reviewed-on: https://go-review.googlesource.com/25550
Run-TryBot: Minux Ma <minux@golang.org>
Reviewed-by: Arjan Van De Ven <arjan.van.de.ven@intel.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-08-05 23:56:07 +00:00
Shenghou Ma
9fde86b012 runtime, syscall: fix kernel gettimeofday ABI change on iOS 10
Fixes #16570 on iOS.

Thanks Daniel Burhans for reporting the bug and testing the fix.

Change-Id: I43ae7b78c8f85a131ed3d93ea59da9f32a02cd8f
Reviewed-on: https://go-review.googlesource.com/25481
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-08-05 20:47:34 +00:00
Ian Lance Taylor
3a03e877cc os: check for waitid returning ENOSYS
Reportedly waitid is not available for Ubuntu on Windows.

Fixes #16610.

Change-Id: Ia724f45a85c6d3467b847da06d8c65d280781dcd
Reviewed-on: https://go-review.googlesource.com/25507
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-08-05 19:48:42 +00:00
Brad Fitzpatrick
10316757ce net/http: update bundled http2 for flow control window adjustment fix
Updates bundled http2 to x/net/http2 git rev 075e191 for:

   http2: adjust flow control on open streams when processing SETTINGS
   https://golang.org/cl/25508

Fixes #16612

Change-Id: Ib0513201bff44ab747a574ae6894479325c105d2
Reviewed-on: https://go-review.googlesource.com/25543
Run-TryBot: Chris Broadfoot <cbro@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Chris Broadfoot <cbro@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-08-05 17:08:52 +00:00
Brad Fitzpatrick
da070bed19 syscall: fix Gettimeofday on macOS Sierra
Fixes #16606

Change-Id: I57465061b90e901293cd8b6ef756d6aa84ebd4a3
Reviewed-on: https://go-review.googlesource.com/25495
Reviewed-by: Quentin Smith <quentin@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Quentin Smith <quentin@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-08-04 21:42:44 +00:00
Chris Broadfoot
09fc3cc5df go1.7rc5
Change-Id: I5571a5fa679065060950c554f7b28e42268b3e74
Reviewed-on: https://go-review.googlesource.com/25417
Run-TryBot: Chris Broadfoot <cbro@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-08-02 23:34:48 +00:00
Chris Broadfoot
17a48e0a00 all: merge master into release-branch.go1.7
Change-Id: I77d1665af543dc71f30b2afa48eac411de11afc7
2016-08-02 14:44:26 -07:00
39 changed files with 998 additions and 179 deletions

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.7.1

View File

@@ -34,6 +34,7 @@ We encourage all Go users to subscribe to
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
<ul>
<li><a href="/doc/go1.7">Go 1.7</a> <small>(August 2016)</small></li>
<li><a href="/doc/go1.6">Go 1.6</a> <small>(February 2016)</small></li>
<li><a href="/doc/go1.5">Go 1.5</a> <small>(August 2015)</small></li>
<li><a href="/doc/go1.4">Go 1.4</a> <small>(December 2014)</small></li>

View File

@@ -30,6 +30,25 @@ to fix critical security problems in both Go 1.4 and Go 1.5 as they arise.
See the <a href="/security">security policy</a> for more details.
</p>
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
<p>
Go 1.7 is a major release of Go.
Read the <a href="/doc/go1.7">Go 1.7 Release Notes</a> for more information.
</p>
<h3 id="go1.7.minor">Minor revisions</h3>
<p>
go1.7.1 (released 2016/09/07) includes fixes to the compiler, runtime,
documentation, and the <code>compress/flate</code>, <code>hash/crc32</code>,
<code>io</code> <code>net</code>, <code>net/http</code>,
<code>path/filepath</code>, <code>reflect</code>, and <code>syscall</code>
packages.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.1">Go
1.7.1 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.6">go1.6 (released 2016/02/17)</h2>
<p>

View File

@@ -1,5 +1,5 @@
<!--{
"Title": "Go 1.7 Release Notes DRAFT",
"Title": "Go 1.7 Release Notes",
"Path": "/doc/go1.7",
"Template": true
}-->
@@ -25,15 +25,6 @@ Do not send CLs removing the interior tags from such phrases.
ul li { margin: 0.5em 0; }
</style>
<p>
<!-- TODO: REMOVE THIS COMMENT -->
<!-- TODO: Also remove "DRAFT" in the "Title" at the top of this file. -->
<i>NOTE: This is a DRAFT of the Go 1.7 release notes, prepared for the Go 1.7 beta.
Go 1.7 has NOT yet been released.
By our regular schedule, it is expected some time in August 2016.
</i>
</p>
<h2 id="introduction">Introduction to Go 1.7</h2>
<p>
@@ -919,7 +910,7 @@ For example, the address on which a request received is
<p>
The server's <a href="/pkg/net/http/#Server.Serve"><code>Serve</code></a> method
now only enables HTTP/2 support if the <code>Server.TLSConfig</code> field is <code>nil</code>
or includes <code>"h2"</code> in its <code>TLSConfig.NextProto</code>.
or includes <code>"h2"</code> in its <code>TLSConfig.NextProtos</code>.
</p>
<p>

238
doc/gopher/favicon.svg Normal file
View File

@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 32 32.000001"
id="svg4416"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="favicon.svg"
inkscape:export-filename="../../favicon.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4418" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="15.839192"
inkscape:cx="17.966652"
inkscape:cy="9.2991824"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:snap-bbox="true"
inkscape:snap-bbox-edge-midpoints="false"
inkscape:bbox-nodes="true"
showguides="false"
inkscape:window-width="1920"
inkscape:window-height="1018"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-global="false">
<inkscape:grid
type="xygrid"
id="grid5148" />
</sodipodi:namedview>
<metadata
id="metadata4421">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="icon"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1020.3622)">
<ellipse
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#384e54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="ellipse4216"
cx="-907.35657"
cy="479.90009"
rx="3.5793996"
ry="3.8207953"
transform="matrix(-0.49169095,-0.87076978,-0.87076978,0.49169095,0,0)"
inkscape:transform-center-x="0.67794294"
inkscape:transform-center-y="-2.3634048" />
<ellipse
inkscape:transform-center-y="-2.3633882"
inkscape:transform-center-x="-0.67793718"
transform="matrix(0.49169095,-0.87076978,0.87076978,0.49169095,0,0)"
ry="3.8207953"
rx="3.5793996"
cy="507.8461"
cx="-891.57654"
id="ellipse4463"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#384e54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#384e54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 16.091693,1021.3642 c -1.105749,0.01 -2.210341,0.049 -3.31609,0.09 C 6.8422558,1021.6738 2,1026.3942 2,1032.3622 c 0,2.9786 0,13 0,20 l 28,0 c 0,-8 0,-16 0,-20 0,-5.9683 -4.667345,-10.4912 -10.59023,-10.908 -1.10575,-0.078 -2.212328,-0.099 -3.318077,-0.09 z"
id="path4465"
sodipodi:nodetypes="ccsccscc" />
<path
inkscape:transform-center-y="-1.3604657"
inkscape:transform-center-x="-0.98424303"
sodipodi:nodetypes="sssssss"
inkscape:connector-curvature="0"
id="path4469"
d="m 4.6078867,1025.0462 c 0.459564,0.2595 1.818262,1.2013 1.980983,1.648 0.183401,0.5035 0.159385,1.0657 -0.114614,1.551 -0.346627,0.6138 -1.005341,0.9487 -1.696421,0.9365 -0.339886,-0.01 -1.720283,-0.6372 -2.042561,-0.8192 -0.97754,-0.5519 -1.350795,-1.7418 -0.833686,-2.6576 0.517109,-0.9158 1.728749,-1.2107 2.706299,-0.6587 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#76e1fe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.32850246;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4473"
width="3.0866659"
height="3.5313663"
x="14.406213"
y="1035.6842"
ry="0.62426329" />
<path
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#76e1fe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 16,1023.3622 c -9,0 -12,3.7153 -12,9 l 0,20 24,0 c -0.04889,-7.3562 0,-18 0,-20 0,-5.2848 -3,-9 -12,-9 z"
id="path4471"
sodipodi:nodetypes="zsccsz" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#76e1fe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 27.074073,1025.0462 c -0.45957,0.2595 -1.818257,1.2013 -1.980979,1.648 -0.183401,0.5035 -0.159384,1.0657 0.114614,1.551 0.346627,0.6138 1.005335,0.9487 1.696415,0.9365 0.33988,-0.01 1.72029,-0.6372 2.04256,-0.8192 0.97754,-0.5519 1.35079,-1.7418 0.83369,-2.6576 -0.51711,-0.9158 -1.72876,-1.2107 -2.7063,-0.6587 z"
id="path4481"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssss"
inkscape:transform-center-x="0.98424094"
inkscape:transform-center-y="-1.3604657" />
<circle
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle4477"
cx="21.175734"
cy="1030.3542"
r="4.6537542"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<circle
r="4.8316345"
cy="1030.3542"
cx="10.339486"
id="circle4483"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename=".\rect4485.png"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.32941176;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect4246"
width="3.6673687"
height="4.1063409"
x="14.115863"
y="1035.9174"
ry="0.72590536" />
<rect
ry="0.72590536"
y="1035.2253"
x="14.115863"
height="4.1063409"
width="3.6673687"
id="rect4485"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#fffcfb;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.32941176;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 19.999735,1036.5289 c 0,0.838 -0.871228,1.2682 -2.144766,1.1659 -0.02366,0 -0.04795,-0.6004 -0.254147,-0.5832 -0.503669,0.042 -1.095902,-0.02 -1.685964,-0.02 -0.612939,0 -1.206342,0.1826 -1.68549,0.017 -0.110233,-0.038 -0.178298,0.5838 -0.261532,0.5816 -1.243685,-0.033 -2.078803,-0.3383 -2.078803,-1.1618 0,-1.2118 1.815635,-2.1941 4.055351,-2.1941 2.239704,0 4.055351,0.9823 4.055351,2.1941 z"
id="path4487"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssss"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
sodipodi:nodetypes="sssssssss"
inkscape:connector-curvature="0"
id="path4489"
d="m 19.977414,1035.7004 c 0,0.5685 -0.433659,0.8554 -1.138091,1.0001 -0.291933,0.06 -0.630371,0.096 -1.003719,0.1166 -0.56405,0.032 -1.207782,0.031 -1.89122,0.031 -0.672834,0 -1.307182,0 -1.864904,-0.029 -0.306268,-0.017 -0.589429,-0.043 -0.843164,-0.084 -0.813833,-0.1318 -1.324962,-0.417 -1.324962,-1.0344 0,-1.1601 1.805642,-2.1006 4.03303,-2.1006 2.227377,0 4.03303,0.9405 4.03303,2.1006 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c38c74;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<ellipse
cy="1033.8501"
cx="15.944382"
id="ellipse4491"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#23201f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
rx="2.0801733"
ry="1.343747"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<circle
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#171311;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle4493"
cx="12.414201"
cy="1030.3542"
r="1.9630634"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<circle
r="1.9630634"
cy="1030.3542"
cx="23.110121"
id="circle4495"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#171311;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:export-filename=".\rect4485.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4497"
d="m 5.0055377,1027.2727 c -1.170435,-1.0835 -2.026973,-0.7721 -2.044172,-0.7463"
style="display:inline;fill:none;fill-rule:evenodd;stroke:#384e54;stroke-width:0.39730874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#384e54;stroke-width:0.39730874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 4.3852457,1026.9152 c -1.158557,0.036 -1.346704,0.6303 -1.33881,0.6523"
id="path4499"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#384e54;stroke-width:0.39730874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 26.630533,1027.1724 c 1.17043,-1.0835 2.02697,-0.7721 2.04417,-0.7463"
id="path4501"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4503"
d="m 27.321773,1026.673 c 1.15856,0.036 1.3467,0.6302 1.3388,0.6522"
style="display:inline;fill:none;fill-rule:evenodd;stroke:#384e54;stroke-width:0.39730874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -203,7 +203,7 @@ To build without <code>cgo</code>, set the environment variable
Change to the directory that will be its parent
and make sure the <code>go</code> directory does not exist.
Then clone the repository and check out the latest release tag
(<code class="versionTag">go1.6</code>, for example):</p>
(<code class="versionTag">go1.7.1</code>, for example):</p>
<pre>
$ git clone https://go.googlesource.com/go
@@ -391,7 +391,7 @@ New releases are announced on the
<a href="//groups.google.com/group/golang-announce">golang-announce</a>
mailing list.
Each announcement mentions the latest release tag, for instance,
<code class="versionTag">go1.6</code>.
<code class="versionTag">go1.7.1</code>.
</p>
<p>

View File

@@ -17,7 +17,7 @@
<p>
<a href="https://golang.org/dl/" target="_blank">Official binary
distributions</a> are available for the FreeBSD (release 8-STABLE and above),
Linux, Mac OS X (10.7 and above), and Windows operating systems and
Linux, Mac OS X (10.8 and above), and Windows operating systems and
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
architectures.
</p>
@@ -49,7 +49,7 @@ If your OS or architecture is not on the list, you may be able to
<tr><td colspan="3"><hr></td></tr>
<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported</td></tr>
<tr><td>Mac OS X 10.7 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup></td></tr>
<tr><td>Mac OS X 10.7 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup> for <code>cgo</code> support</td></tr>
<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>&#8224;</sup>. No need for cygwin or msys.</td></tr>
</table>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -14,8 +14,7 @@ func dse(f *Func) {
defer f.retSparseSet(loadUse)
storeUse := f.newSparseSet(f.NumValues())
defer f.retSparseSet(storeUse)
shadowed := f.newSparseSet(f.NumValues())
defer f.retSparseSet(shadowed)
shadowed := newSparseMap(f.NumValues()) // TODO: cache
for _, b := range f.Blocks {
// Find all the stores in this block. Categorize their uses:
// loadUse contains stores which are used by a subsequent load.
@@ -81,17 +80,18 @@ func dse(f *Func) {
shadowed.clear()
}
if v.Op == OpStore || v.Op == OpZero {
if shadowed.contains(v.Args[0].ID) {
sz := v.AuxInt
if shadowedSize := int64(shadowed.get(v.Args[0].ID)); shadowedSize != -1 && shadowedSize >= sz {
// Modify store into a copy
if v.Op == OpStore {
// store addr value mem
v.SetArgs1(v.Args[2])
} else {
// zero addr mem
sz := v.Args[0].Type.ElemType().Size()
if v.AuxInt != sz {
typesz := v.Args[0].Type.ElemType().Size()
if sz != typesz {
f.Fatalf("mismatched zero/store sizes: %d and %d [%s]",
v.AuxInt, sz, v.LongString())
sz, typesz, v.LongString())
}
v.SetArgs1(v.Args[1])
}
@@ -99,7 +99,10 @@ func dse(f *Func) {
v.AuxInt = 0
v.Op = OpCopy
} else {
shadowed.add(v.Args[0].ID)
if sz > 0x7fffffff { // work around sparseMap's int32 value type
sz = 0x7fffffff
}
shadowed.set(v.Args[0].ID, int32(sz))
}
}
// walk to previous store

View File

@@ -8,7 +8,7 @@ import "testing"
func TestDeadStore(t *testing.T) {
c := testConfig(t)
elemType := &TypeImpl{Size_: 8, Name: "testtype"}
elemType := &TypeImpl{Size_: 1, Name: "testtype"}
ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr", Elem_: elemType} // dummy for testing
fun := Fun(c, "entry",
Bloc("entry",
@@ -18,7 +18,7 @@ func TestDeadStore(t *testing.T) {
Valu("addr1", OpAddr, ptrType, 0, nil, "sb"),
Valu("addr2", OpAddr, ptrType, 0, nil, "sb"),
Valu("addr3", OpAddr, ptrType, 0, nil, "sb"),
Valu("zero1", OpZero, TypeMem, 8, nil, "addr3", "start"),
Valu("zero1", OpZero, TypeMem, 1, nil, "addr3", "start"),
Valu("store1", OpStore, TypeMem, 1, nil, "addr1", "v", "zero1"),
Valu("store2", OpStore, TypeMem, 1, nil, "addr2", "v", "store1"),
Valu("store3", OpStore, TypeMem, 1, nil, "addr1", "v", "store2"),
@@ -95,3 +95,32 @@ func TestDeadStoreTypes(t *testing.T) {
t.Errorf("store %s incorrectly removed", v)
}
}
func TestDeadStoreUnsafe(t *testing.T) {
// Make sure a narrow store can't shadow a wider one. The test above
// covers the case of two different types, but unsafe pointer casting
// can get to a point where the size is changed but type unchanged.
c := testConfig(t)
ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing
fun := Fun(c, "entry",
Bloc("entry",
Valu("start", OpInitMem, TypeMem, 0, nil),
Valu("sb", OpSB, TypeInvalid, 0, nil),
Valu("v", OpConstBool, TypeBool, 1, nil),
Valu("addr1", OpAddr, ptrType, 0, nil, "sb"),
Valu("store1", OpStore, TypeMem, 8, nil, "addr1", "v", "start"), // store 8 bytes
Valu("store2", OpStore, TypeMem, 1, nil, "addr1", "v", "store1"), // store 1 byte
Goto("exit")),
Bloc("exit",
Exit("store2")))
CheckFunc(fun.f)
cse(fun.f)
dse(fun.f)
CheckFunc(fun.f)
v := fun.values["store1"]
if v.Op == OpCopy {
t.Errorf("store %s incorrectly removed", v)
}
}

View File

@@ -724,7 +724,7 @@ func (w *Writer) Close() error {
// the result of NewWriter or NewWriterDict called with dst
// and w's level and dictionary.
func (w *Writer) Reset(dst io.Writer) {
if dw, ok := w.d.w.w.(*dictWriter); ok {
if dw, ok := w.d.w.writer.(*dictWriter); ok {
// w was created with NewWriterDict
dw.w = dst
w.d.reset(dw)

View File

@@ -6,6 +6,7 @@ package flate
import (
"bytes"
"errors"
"fmt"
"internal/testenv"
"io"
@@ -631,3 +632,52 @@ func TestBestSpeed(t *testing.T) {
}
}
}
var errIO = errors.New("IO error")
// failWriter fails with errIO exactly at the nth call to Write.
type failWriter struct{ n int }
func (w *failWriter) Write(b []byte) (int, error) {
w.n--
if w.n == -1 {
return 0, errIO
}
return len(b), nil
}
func TestWriterPersistentError(t *testing.T) {
d, err := ioutil.ReadFile("../testdata/Mark.Twain-Tom.Sawyer.txt")
if err != nil {
t.Fatalf("ReadFile: %v", err)
}
d = d[:10000] // Keep this test short
zw, err := NewWriter(nil, DefaultCompression)
if err != nil {
t.Fatalf("NewWriter: %v", err)
}
// Sweep over the threshold at which an error is returned.
// The variable i makes it such that the ith call to failWriter.Write will
// return errIO. Since failWriter errors are not persistent, we must ensure
// that flate.Writer errors are persistent.
for i := 0; i < 1000; i++ {
fw := &failWriter{i}
zw.Reset(fw)
_, werr := zw.Write(d)
cerr := zw.Close()
if werr != errIO && werr != nil {
t.Errorf("test %d, mismatching Write error: got %v, want %v", i, werr, errIO)
}
if cerr != errIO && fw.n < 0 {
t.Errorf("test %d, mismatching Close error: got %v, want %v", i, cerr, errIO)
}
if fw.n >= 0 {
// At this point, the failure threshold was sufficiently high enough
// that we wrote the whole stream without any errors.
return
}
}
}

View File

@@ -77,7 +77,11 @@ var offsetBase = []uint32{
var codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
type huffmanBitWriter struct {
w io.Writer
// writer is the underlying writer.
// Do not use it directly; use the write method, which ensures
// that Write errors are sticky.
writer io.Writer
// Data waiting to be written is bytes[0:nbytes]
// and then the low nbits of bits.
bits uint64
@@ -96,7 +100,7 @@ type huffmanBitWriter struct {
func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
return &huffmanBitWriter{
w: w,
writer: w,
literalFreq: make([]int32, maxNumLit),
offsetFreq: make([]int32, offsetCodeCount),
codegen: make([]uint8, maxNumLit+offsetCodeCount+1),
@@ -107,7 +111,7 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
}
func (w *huffmanBitWriter) reset(writer io.Writer) {
w.w = writer
w.writer = writer
w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil
w.bytes = [bufferSize]byte{}
}
@@ -129,11 +133,21 @@ func (w *huffmanBitWriter) flush() {
n++
}
w.bits = 0
_, w.err = w.w.Write(w.bytes[:n])
w.write(w.bytes[:n])
w.nbytes = 0
}
func (w *huffmanBitWriter) write(b []byte) {
if w.err != nil {
return
}
_, w.err = w.writer.Write(b)
}
func (w *huffmanBitWriter) writeBits(b int32, nb uint) {
if w.err != nil {
return
}
w.bits |= uint64(b) << w.nbits
w.nbits += nb
if w.nbits >= 48 {
@@ -150,7 +164,7 @@ func (w *huffmanBitWriter) writeBits(b int32, nb uint) {
bytes[5] = byte(bits >> 40)
n += 6
if n >= bufferFlushSize {
_, w.err = w.w.Write(w.bytes[:n])
w.write(w.bytes[:n])
n = 0
}
w.nbytes = n
@@ -173,13 +187,10 @@ func (w *huffmanBitWriter) writeBytes(bytes []byte) {
n++
}
if n != 0 {
_, w.err = w.w.Write(w.bytes[:n])
if w.err != nil {
return
}
w.write(w.bytes[:n])
}
w.nbytes = 0
_, w.err = w.w.Write(bytes)
w.write(bytes)
}
// RFC 1951 3.2.7 specifies a special run-length encoding for specifying
@@ -341,7 +352,7 @@ func (w *huffmanBitWriter) writeCode(c hcode) {
bytes[5] = byte(bits >> 40)
n += 6
if n >= bufferFlushSize {
_, w.err = w.w.Write(w.bytes[:n])
w.write(w.bytes[:n])
n = 0
}
w.nbytes = n
@@ -572,6 +583,9 @@ func (w *huffmanBitWriter) indexTokens(tokens []token) (numLiterals, numOffsets
// writeTokens writes a slice of tokens to the output.
// codes for literal and offset encoding must be supplied.
func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode) {
if w.err != nil {
return
}
for _, t := range tokens {
if t < matchType {
w.writeCode(leCodes[t.literal()])
@@ -676,9 +690,9 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte) {
if n < bufferFlushSize {
continue
}
_, w.err = w.w.Write(w.bytes[:n])
w.write(w.bytes[:n])
if w.err != nil {
return
return // Return early in the event of write failures
}
n = 0
}

View File

@@ -4,14 +4,9 @@
package crc32
import (
"unsafe"
)
const (
vxMinLen = 64
vxAlignment = 16
vxAlignMask = vxAlignment - 1
vxAlignMask = 15 // align to 16 bytes
)
// hasVectorFacility reports whether the machine has the z/Architecture
@@ -49,20 +44,13 @@ func genericIEEE(crc uint32, p []byte) uint32 {
return update(crc, IEEETable, p)
}
// updateCastagnoli calculates the checksum of p using genericCastagnoli to
// align the data appropriately for vectorCastagnoli. It avoids using
// vectorCastagnoli entirely if the length of p is less than or equal to
// vxMinLen.
// updateCastagnoli calculates the checksum of p using
// vectorizedCastagnoli if possible and falling back onto
// genericCastagnoli as needed.
func updateCastagnoli(crc uint32, p []byte) uint32 {
// Use vectorized function if vector facility is available and
// data length is above threshold.
if hasVX && len(p) > vxMinLen {
pAddr := uintptr(unsafe.Pointer(&p[0]))
if pAddr&vxAlignMask != 0 {
prealign := vxAlignment - int(pAddr&vxAlignMask)
crc = genericCastagnoli(crc, p[:prealign])
p = p[prealign:]
}
if hasVX && len(p) >= vxMinLen {
aligned := len(p) & ^vxAlignMask
crc = vectorizedCastagnoli(crc, p[:aligned])
p = p[aligned:]
@@ -75,19 +63,12 @@ func updateCastagnoli(crc uint32, p []byte) uint32 {
return genericCastagnoli(crc, p)
}
// updateIEEE calculates the checksum of p using genericIEEE to align the data
// appropriately for vectorIEEE. It avoids using vectorIEEE entirely if the length
// of p is less than or equal to vxMinLen.
// updateIEEE calculates the checksum of p using vectorizedIEEE if
// possible and falling back onto genericIEEE as needed.
func updateIEEE(crc uint32, p []byte) uint32 {
// Use vectorized function if vector facility is available and
// data length is above threshold.
if hasVX && len(p) > vxMinLen {
pAddr := uintptr(unsafe.Pointer(&p[0]))
if pAddr&vxAlignMask != 0 {
prealign := vxAlignment - int(pAddr&vxAlignMask)
crc = genericIEEE(crc, p[:prealign])
p = p[prealign:]
}
if hasVX && len(p) >= vxMinLen {
aligned := len(p) & ^vxAlignMask
crc = vectorizedIEEE(crc, p[:aligned])
p = p[aligned:]

View File

@@ -128,6 +128,10 @@ TEXT vectorizedBody<>(SB),NOSPLIT,$0
VZERO V0
VLVGF $3, R2, V0
// Crash if the input size is less than 64-bytes.
CMP R4, $64
BLT crash
// Load a 64-byte data chunk and XOR with CRC
VLM 0(R3), V1, V4 // 64-bytes into V1..V4
@@ -243,3 +247,6 @@ done:
XOR $0xffffffff, R2 // NOTW R2
MOVWZ R2, ret + 32(FP)
RET
crash:
MOVD $0, (R0) // input size is less than 64-bytes

View File

@@ -18,15 +18,16 @@ func (mr *multiReader) Read(p []byte) (n int, err error) {
}
}
n, err = mr.readers[0].Read(p)
if err == EOF {
mr.readers = mr.readers[1:]
}
if n > 0 || err != EOF {
if err == EOF {
// Don't return EOF yet. There may be more bytes
// in the remaining readers.
if err == EOF && len(mr.readers) > 0 {
// Don't return EOF yet. More readers remain.
err = nil
}
return
}
mr.readers = mr.readers[1:]
}
return 0, EOF
}

View File

@@ -196,3 +196,41 @@ func TestMultiReaderFlatten(t *testing.T) {
myDepth+2, readDepth)
}
}
// byteAndEOFReader is a Reader which reads one byte (the underlying
// byte) and io.EOF at once in its Read call.
type byteAndEOFReader byte
func (b byteAndEOFReader) Read(p []byte) (n int, err error) {
if len(p) == 0 {
// Read(0 bytes) is useless. We expect no such useless
// calls in this test.
panic("unexpected call")
}
p[0] = byte(b)
return 1, EOF
}
// In Go 1.7, this yielded bytes forever.
func TestMultiReaderSingleByteWithEOF(t *testing.T) {
got, err := ioutil.ReadAll(LimitReader(MultiReader(byteAndEOFReader('a'), byteAndEOFReader('b')), 10))
if err != nil {
t.Fatal(err)
}
const want = "ab"
if string(got) != want {
t.Errorf("got %q; want %q", got, want)
}
}
// Test that a reader returning (n, EOF) at the end of an MultiReader
// chain continues to return EOF on its final read, rather than
// yielding a (0, EOF).
func TestMultiReaderFinalEOF(t *testing.T) {
r := MultiReader(bytes.NewReader(nil), byteAndEOFReader('a'))
buf := make([]byte, 2)
n, err := r.Read(buf)
if n != 1 || err != EOF {
t.Errorf("got %v, %v; want 1, EOF", n, err)
}
}

View File

@@ -141,7 +141,7 @@ func (d *Dialer) dialDNS(ctx context.Context, network, server string) (dnsConn,
}
// exchange sends a query on the connection and hopes for a response.
func exchange(ctx context.Context, server, name string, qtype uint16) (*dnsMsg, error) {
func exchange(ctx context.Context, server, name string, qtype uint16, timeout time.Duration) (*dnsMsg, error) {
d := testHookDNSDialer()
out := dnsMsg{
dnsMsgHdr: dnsMsgHdr{
@@ -152,6 +152,12 @@ func exchange(ctx context.Context, server, name string, qtype uint16) (*dnsMsg,
},
}
for _, network := range []string{"udp", "tcp"} {
// TODO(mdempsky): Refactor so defers from UDP-based
// exchanges happen before TCP-based exchange.
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
defer cancel()
c, err := d.dialDNS(ctx, network, server)
if err != nil {
return nil, err
@@ -180,17 +186,10 @@ func tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype uint16)
return "", nil, &DNSError{Err: "no DNS servers", Name: name}
}
deadline := time.Now().Add(cfg.timeout)
if old, ok := ctx.Deadline(); !ok || deadline.Before(old) {
var cancel context.CancelFunc
ctx, cancel = context.WithDeadline(ctx, deadline)
defer cancel()
}
var lastErr error
for i := 0; i < cfg.attempts; i++ {
for _, server := range cfg.servers {
msg, err := exchange(ctx, server, name, qtype)
msg, err := exchange(ctx, server, name, qtype, cfg.timeout)
if err != nil {
lastErr = &DNSError{
Err: err.Error(),
@@ -338,8 +337,9 @@ func lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs [
}
// avoidDNS reports whether this is a hostname for which we should not
// use DNS. Currently this includes only .onion and .local names,
// per RFC 7686 and RFC 6762, respectively. See golang.org/issue/13705.
// use DNS. Currently this includes only .onion, per RFC 7686. See
// golang.org/issue/13705. Does not cover .local names (RFC 6762),
// see golang.org/issue/16739.
func avoidDNS(name string) bool {
if name == "" {
return true
@@ -347,7 +347,7 @@ func avoidDNS(name string) bool {
if name[len(name)-1] == '.' {
name = name[:len(name)-1]
}
return stringsHasSuffixFold(name, ".onion") || stringsHasSuffixFold(name, ".local")
return stringsHasSuffixFold(name, ".onion")
}
// nameList returns a list of names for sequential DNS queries.

View File

@@ -40,9 +40,9 @@ func TestDNSTransportFallback(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
for _, tt := range dnsTransportFallbackTests {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(tt.timeout)*time.Second)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
msg, err := exchange(ctx, tt.server, tt.name, tt.qtype)
msg, err := exchange(ctx, tt.server, tt.name, tt.qtype, time.Second)
if err != nil {
t.Error(err)
continue
@@ -82,9 +82,9 @@ func TestSpecialDomainName(t *testing.T) {
server := "8.8.8.8:53"
for _, tt := range specialDomainNameTests {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
msg, err := exchange(ctx, server, tt.name, tt.qtype)
msg, err := exchange(ctx, server, tt.name, tt.qtype, 3*time.Second)
if err != nil {
t.Error(err)
continue
@@ -112,10 +112,11 @@ func TestAvoidDNSName(t *testing.T) {
{"foo.ONION", true},
{"foo.ONION.", true},
{"foo.local.", true},
{"foo.local", true},
{"foo.LOCAL", true},
{"foo.LOCAL.", true},
// But do resolve *.local address; Issue 16739
{"foo.local.", false},
{"foo.local", false},
{"foo.LOCAL", false},
{"foo.LOCAL.", false},
{"", true}, // will be rejected earlier too
@@ -500,7 +501,7 @@ func TestErrorForOriginalNameWhenSearching(t *testing.T) {
d := &fakeDNSDialer{}
testHookDNSDialer = func() dnsDialer { return d }
d.rh = func(s string, q *dnsMsg) (*dnsMsg, error) {
d.rh = func(s string, q *dnsMsg, _ time.Time) (*dnsMsg, error) {
r := &dnsMsg{
dnsMsgHdr: dnsMsgHdr{
id: q.id,
@@ -539,14 +540,15 @@ func TestIgnoreLameReferrals(t *testing.T) {
}
defer conf.teardown()
if err := conf.writeAndUpdate([]string{"nameserver 192.0.2.1", "nameserver 192.0.2.2"}); err != nil {
if err := conf.writeAndUpdate([]string{"nameserver 192.0.2.1", // the one that will give a lame referral
"nameserver 192.0.2.2"}); err != nil {
t.Fatal(err)
}
d := &fakeDNSDialer{}
testHookDNSDialer = func() dnsDialer { return d }
d.rh = func(s string, q *dnsMsg) (*dnsMsg, error) {
d.rh = func(s string, q *dnsMsg, _ time.Time) (*dnsMsg, error) {
t.Log(s, q)
r := &dnsMsg{
dnsMsgHdr: dnsMsgHdr{
@@ -633,28 +635,30 @@ func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
type fakeDNSDialer struct {
// reply handler
rh func(s string, q *dnsMsg) (*dnsMsg, error)
rh func(s string, q *dnsMsg, t time.Time) (*dnsMsg, error)
}
func (f *fakeDNSDialer) dialDNS(_ context.Context, n, s string) (dnsConn, error) {
return &fakeDNSConn{f.rh, s}, nil
return &fakeDNSConn{f.rh, s, time.Time{}}, nil
}
type fakeDNSConn struct {
rh func(s string, q *dnsMsg) (*dnsMsg, error)
rh func(s string, q *dnsMsg, t time.Time) (*dnsMsg, error)
s string
t time.Time
}
func (f *fakeDNSConn) Close() error {
return nil
}
func (f *fakeDNSConn) SetDeadline(time.Time) error {
func (f *fakeDNSConn) SetDeadline(t time.Time) error {
f.t = t
return nil
}
func (f *fakeDNSConn) dnsRoundTrip(q *dnsMsg) (*dnsMsg, error) {
return f.rh(f.s, q)
return f.rh(f.s, q, f.t)
}
// UDP round-tripper algorithm should ignore invalid DNS responses (issue 13281).
@@ -724,3 +728,72 @@ func TestIgnoreDNSForgeries(t *testing.T) {
t.Errorf("got address %v, want %v", got, TestAddr)
}
}
// Issue 16865. If a name server times out, continue to the next.
func TestRetryTimeout(t *testing.T) {
origTestHookDNSDialer := testHookDNSDialer
defer func() { testHookDNSDialer = origTestHookDNSDialer }()
conf, err := newResolvConfTest()
if err != nil {
t.Fatal(err)
}
defer conf.teardown()
if err := conf.writeAndUpdate([]string{"nameserver 192.0.2.1", // the one that will timeout
"nameserver 192.0.2.2"}); err != nil {
t.Fatal(err)
}
d := &fakeDNSDialer{}
testHookDNSDialer = func() dnsDialer { return d }
var deadline0 time.Time
d.rh = func(s string, q *dnsMsg, deadline time.Time) (*dnsMsg, error) {
t.Log(s, q, deadline)
if deadline.IsZero() {
t.Error("zero deadline")
}
if s == "192.0.2.1:53" {
deadline0 = deadline
time.Sleep(10 * time.Millisecond)
return nil, errTimeout
}
if deadline == deadline0 {
t.Error("deadline didn't change")
}
r := &dnsMsg{
dnsMsgHdr: dnsMsgHdr{
id: q.id,
response: true,
recursion_available: true,
},
question: q.question,
answer: []dnsRR{
&dnsRR_CNAME{
Hdr: dnsRR_Header{
Name: q.question[0].Name,
Rrtype: dnsTypeCNAME,
Class: dnsClassINET,
},
Cname: "golang.org",
},
},
}
return r, nil
}
_, err = goLookupCNAME(context.Background(), "www.golang.org")
if err != nil {
t.Fatal(err)
}
if deadline0.IsZero() {
t.Error("deadline0 still zero", deadline0)
}
}

View File

@@ -28,6 +28,7 @@ import (
"io"
"io/ioutil"
"log"
"math"
"net"
"net/http/httptrace"
"net/textproto"
@@ -403,9 +404,17 @@ func (e http2ConnectionError) Error() string {
type http2StreamError struct {
StreamID uint32
Code http2ErrCode
Cause error // optional additional detail
}
func http2streamError(id uint32, code http2ErrCode) http2StreamError {
return http2StreamError{StreamID: id, Code: code}
}
func (e http2StreamError) Error() string {
if e.Cause != nil {
return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
}
return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
}
@@ -1366,7 +1375,7 @@ func http2parseWindowUpdateFrame(fh http2FrameHeader, p []byte) (http2Frame, err
if fh.StreamID == 0 {
return nil, http2ConnectionError(http2ErrCodeProtocol)
}
return nil, http2StreamError{fh.StreamID, http2ErrCodeProtocol}
return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
}
return &http2WindowUpdateFrame{
http2FrameHeader: fh,
@@ -1444,7 +1453,7 @@ func http2parseHeadersFrame(fh http2FrameHeader, p []byte) (_ http2Frame, err er
}
}
if len(p)-int(padLength) <= 0 {
return nil, http2StreamError{fh.StreamID, http2ErrCodeProtocol}
return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
}
hf.headerFragBuf = p[:len(p)-int(padLength)]
return hf, nil
@@ -1911,6 +1920,9 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr
hdec.SetEmitEnabled(true)
hdec.SetMaxStringLength(fr.maxHeaderStringLen())
hdec.SetEmitFunc(func(hf hpack.HeaderField) {
if http2VerboseLogs && http2logFrameReads {
log.Printf("http2: decoded hpack field %+v", hf)
}
if !httplex.ValidHeaderFieldValue(hf.Value) {
invalid = http2headerFieldValueError(hf.Value)
}
@@ -1969,11 +1981,17 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr
}
if invalid != nil {
fr.errDetail = invalid
return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol}
if http2VerboseLogs {
log.Printf("http2: invalid header: %v", invalid)
}
return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, invalid}
}
if err := mh.checkPseudos(); err != nil {
fr.errDetail = err
return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol}
if http2VerboseLogs {
log.Printf("http2: invalid pseudo headers: %v", err)
}
return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, err}
}
return mh, nil
}
@@ -3604,7 +3622,7 @@ func (sc *http2serverConn) wroteFrame(res http2frameWriteResult) {
case http2stateOpen:
st.state = http2stateHalfClosedLocal
errCancel := http2StreamError{st.id, http2ErrCodeCancel}
errCancel := http2streamError(st.id, http2ErrCodeCancel)
sc.resetStream(errCancel)
case http2stateHalfClosedRemote:
sc.closeStream(st, http2errHandlerComplete)
@@ -3797,7 +3815,7 @@ func (sc *http2serverConn) processWindowUpdate(f *http2WindowUpdateFrame) error
return nil
}
if !st.flow.add(int32(f.Increment)) {
return http2StreamError{f.StreamID, http2ErrCodeFlowControl}
return http2streamError(f.StreamID, http2ErrCodeFlowControl)
}
default:
if !sc.flow.add(int32(f.Increment)) {
@@ -3819,7 +3837,7 @@ func (sc *http2serverConn) processResetStream(f *http2RSTStreamFrame) error {
if st != nil {
st.gotReset = true
st.cancelCtx()
sc.closeStream(st, http2StreamError{f.StreamID, f.ErrCode})
sc.closeStream(st, http2streamError(f.StreamID, f.ErrCode))
}
return nil
}
@@ -3922,13 +3940,13 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error {
if !ok || st.state != http2stateOpen || st.gotTrailerHeader {
if sc.inflow.available() < int32(f.Length) {
return http2StreamError{id, http2ErrCodeFlowControl}
return http2streamError(id, http2ErrCodeFlowControl)
}
sc.inflow.take(int32(f.Length))
sc.sendWindowUpdate(nil, int(f.Length))
return http2StreamError{id, http2ErrCodeStreamClosed}
return http2streamError(id, http2ErrCodeStreamClosed)
}
if st.body == nil {
panic("internal error: should have a body in this state")
@@ -3936,19 +3954,19 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error {
if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
return http2StreamError{id, http2ErrCodeStreamClosed}
return http2streamError(id, http2ErrCodeStreamClosed)
}
if f.Length > 0 {
if st.inflow.available() < int32(f.Length) {
return http2StreamError{id, http2ErrCodeFlowControl}
return http2streamError(id, http2ErrCodeFlowControl)
}
st.inflow.take(int32(f.Length))
if len(data) > 0 {
wrote, err := st.body.Write(data)
if err != nil {
return http2StreamError{id, http2ErrCodeStreamClosed}
return http2streamError(id, http2ErrCodeStreamClosed)
}
if wrote != len(data) {
panic("internal error: bad Writer")
@@ -4046,10 +4064,10 @@ func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
if sc.unackedSettings == 0 {
return http2StreamError{st.id, http2ErrCodeProtocol}
return http2streamError(st.id, http2ErrCodeProtocol)
}
return http2StreamError{st.id, http2ErrCodeRefusedStream}
return http2streamError(st.id, http2ErrCodeRefusedStream)
}
rw, req, err := sc.newWriterAndRequest(st, f)
@@ -4083,18 +4101,18 @@ func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error {
}
st.gotTrailerHeader = true
if !f.StreamEnded() {
return http2StreamError{st.id, http2ErrCodeProtocol}
return http2streamError(st.id, http2ErrCodeProtocol)
}
if len(f.PseudoFields()) > 0 {
return http2StreamError{st.id, http2ErrCodeProtocol}
return http2streamError(st.id, http2ErrCodeProtocol)
}
if st.trailer != nil {
for _, hf := range f.RegularFields() {
key := sc.canonicalHeader(hf.Name)
if !http2ValidTrailerHeader(key) {
return http2StreamError{st.id, http2ErrCodeProtocol}
return http2streamError(st.id, http2ErrCodeProtocol)
}
st.trailer[key] = append(st.trailer[key], hf.Value)
}
@@ -4148,18 +4166,18 @@ func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHead
isConnect := method == "CONNECT"
if isConnect {
if path != "" || scheme != "" || authority == "" {
return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol}
return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol)
}
} else if method == "" || path == "" ||
(scheme != "https" && scheme != "http") {
return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol}
return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol)
}
bodyOpen := !f.StreamEnded()
if method == "HEAD" && bodyOpen {
return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol}
return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol)
}
var tlsState *tls.ConnectionState // nil if not scheme https
@@ -4216,7 +4234,7 @@ func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHead
var err error
url_, err = url.ParseRequestURI(path)
if err != nil {
return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol}
return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol)
}
requestURI = path
}
@@ -4993,14 +5011,14 @@ type http2ClientConn struct {
br *bufio.Reader
fr *http2Framer
lastActive time.Time
// Settings from peer:
// Settings from peer: (also guarded by mu)
maxFrameSize uint32
maxConcurrentStreams uint32
initialWindowSize uint32
hbuf bytes.Buffer // HPACK encoder writes into this
henc *hpack.Encoder
freeBuf [][]byte
hbuf bytes.Buffer // HPACK encoder writes into this
henc *hpack.Encoder
freeBuf [][]byte
wmu sync.Mutex // held while writing; acquire AFTER mu if holding both
werr error // first write error that has occurred
@@ -5244,10 +5262,6 @@ func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) {
}
func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2ClientConn, error) {
if http2VerboseLogs {
t.vlogf("http2: Transport creating client conn to %v", c.RemoteAddr())
}
cc := &http2ClientConn{
t: t,
tconn: c,
@@ -5260,6 +5274,10 @@ func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2Client
singleUse: singleUse,
wantSettingsAck: true,
}
if http2VerboseLogs {
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
}
cc.cond = sync.NewCond(&cc.mu)
cc.flow.add(int32(http2initialWindowSize))
@@ -5324,7 +5342,7 @@ func (cc *http2ClientConn) canTakeNewRequestLocked() bool {
}
return cc.goAway == nil && !cc.closed &&
int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
cc.nextStreamID < 2147483647
cc.nextStreamID < math.MaxInt32
}
func (cc *http2ClientConn) closeIfIdle() {
@@ -5334,9 +5352,13 @@ func (cc *http2ClientConn) closeIfIdle() {
return
}
cc.closed = true
nextID := cc.nextStreamID
cc.mu.Unlock()
if http2VerboseLogs {
cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
}
cc.tconn.Close()
}
@@ -5438,12 +5460,15 @@ func http2bodyAndLength(req *Request) (body io.Reader, contentLen int64) {
// We have a body but a zero content length. Test to see if
// it's actually zero or just unset.
var buf [1]byte
n, rerr := io.ReadFull(body, buf[:])
n, rerr := body.Read(buf[:])
if rerr != nil && rerr != io.EOF {
return http2errorReader{rerr}, -1
}
if n == 1 {
if rerr == io.EOF {
return bytes.NewReader(buf[:]), 1
}
return io.MultiReader(bytes.NewReader(buf[:]), body), -1
}
@@ -5692,8 +5717,13 @@ func (cs *http2clientStream) writeRequestBody(body io.Reader, bodyCloser io.Clos
}
}
if sentEnd {
return nil
}
var trls []byte
if !sentEnd && hasTrailers {
if hasTrailers {
cc.mu.Lock()
defer cc.mu.Unlock()
trls = cc.encodeTrailers(req)
@@ -5986,11 +6016,15 @@ func (rl *http2clientConnReadLoop) run() error {
for {
f, err := cc.fr.ReadFrame()
if err != nil {
cc.vlogf("Transport readFrame error: (%T) %v", err, err)
cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
}
if se, ok := err.(http2StreamError); ok {
if cs := cc.streamByID(se.StreamID, true); cs != nil {
rl.endStreamError(cs, cc.fr.errDetail)
cs.cc.writeStreamReset(cs.ID, se.Code, err)
if se.Cause == nil {
se.Cause = cc.fr.errDetail
}
rl.endStreamError(cs, se)
}
continue
} else if err != nil {
@@ -6034,6 +6068,9 @@ func (rl *http2clientConnReadLoop) run() error {
cc.logf("Transport: unhandled response frame type %T", f)
}
if err != nil {
if http2VerboseLogs {
cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, http2summarizeFrame(f), err)
}
return err
}
if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
@@ -6381,6 +6418,11 @@ func (rl *http2clientConnReadLoop) endStreamError(cs *http2clientStream, err err
if http2isConnectionCloseRequest(cs.req) {
rl.closeWhenIdle = true
}
select {
case cs.resc <- http2resAndError{err: err}:
default:
}
}
func (cs *http2clientStream) copyTrailers() {
@@ -6425,6 +6467,16 @@ func (rl *http2clientConnReadLoop) processSettings(f *http2SettingsFrame) error
cc.maxConcurrentStreams = s.Val
case http2SettingInitialWindowSize:
if s.Val > math.MaxInt32 {
return http2ConnectionError(http2ErrCodeFlowControl)
}
delta := int32(s.Val) - int32(cc.initialWindowSize)
for _, cs := range cc.streams {
cs.flow.add(delta)
}
cc.cond.Broadcast()
cc.initialWindowSize = s.Val
default:
@@ -6475,7 +6527,7 @@ func (rl *http2clientConnReadLoop) processResetStream(f *http2RSTStreamFrame) er
case <-cs.peerReset:
default:
err := http2StreamError{cs.ID, f.ErrCode}
err := http2streamError(cs.ID, f.ErrCode)
cs.resetErr = err
close(cs.peerReset)
cs.bufPipe.CloseWithError(err)

View File

@@ -398,6 +398,15 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) {
// HTTP request on a new connection. The non-nil input error is the
// error from roundTrip.
func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool {
if err == http2ErrNoCachedConn {
// Issue 16582: if the user started a bunch of
// requests at once, they can all pick the same conn
// and violate the server's max concurrent streams.
// Instead, match the HTTP/1 behavior for now and dial
// again to get a new TCP connection, rather than failing
// this request.
return true
}
if err == errMissingHost {
// User error.
return false
@@ -489,8 +498,9 @@ func (t *Transport) CloseIdleConnections() {
// CancelRequest cancels an in-flight request by closing its connection.
// CancelRequest should only be called after RoundTrip has returned.
//
// Deprecated: Use Request.Cancel instead. CancelRequest cannot cancel
// HTTP/2 requests.
// Deprecated: Use Request.WithContext to create a request with a
// cancelable context instead. CancelRequest cannot cancel HTTP/2
// requests.
func (t *Transport) CancelRequest(req *Request) {
t.reqMu.Lock()
cancel := t.reqCanceler[req]
@@ -580,6 +590,7 @@ var (
errReadLoopExiting = errors.New("http: persistConn.readLoop exiting")
errServerClosedIdle = errors.New("http: server closed idle connection")
errIdleConnTimeout = errors.New("http: idle connection timeout")
errNotCachingH2Conn = errors.New("http: not caching alternate protocol's connections")
)
// transportReadFromServerError is used by Transport.readLoop when the
@@ -623,6 +634,9 @@ func (t *Transport) tryPutIdleConn(pconn *persistConn) error {
if pconn.isBroken() {
return errConnBroken
}
if pconn.alt != nil {
return errNotCachingH2Conn
}
pconn.markReused()
key := pconn.cacheKey

View File

@@ -3511,6 +3511,61 @@ func TestTransportIdleConnTimeout(t *testing.T) {
}
}
// Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
// HTTP/2 connection was established but but its caller no longer
// wanted it. (Assuming the connection cache was enabled, which it is
// by default)
//
// This test reproduced the crash by setting the IdleConnTimeout low
// (to make the test reasonable) and then making a request which is
// canceled by the DialTLS hook, which then also waits to return the
// real connection until after the RoundTrip saw the error. Then we
// know the successful tls.Dial from DialTLS will need to go into the
// idle pool. Then we give it a of time to explode.
func TestIdleConnH2Crash(t *testing.T) {
cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
// nothing
}))
defer cst.close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
gotErr := make(chan bool, 1)
cst.tr.IdleConnTimeout = 5 * time.Millisecond
cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
cancel()
<-gotErr
c, err := tls.Dial(network, addr, &tls.Config{
InsecureSkipVerify: true,
NextProtos: []string{"h2"},
})
if err != nil {
t.Error(err)
return nil, err
}
if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
c.Close()
return nil, errors.New("bogus")
}
return c, nil
}
req, _ := NewRequest("GET", cst.ts.URL, nil)
req = req.WithContext(ctx)
res, err := cst.c.Do(req)
if err == nil {
res.Body.Close()
t.Fatal("unexpected success")
}
gotErr <- true
// Wait for the explosion.
time.Sleep(cst.tr.IdleConnTimeout * 10)
}
type funcConn struct {
net.Conn
read func([]byte) (int, error)

View File

@@ -28,6 +28,12 @@ func (p *Process) blockUntilWaitable() (bool, error) {
_, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
runtime.KeepAlive(psig)
if e != 0 {
// waitid has been available since Linux 2.6.9, but
// reportedly is not available in Ubuntu on Windows.
// See issue 16610.
if e == syscall.ENOSYS {
return false, nil
}
return false, NewSyscallError("waitid", e)
}
return true, nil

View File

@@ -4,4 +4,7 @@
package filepath
var ToNorm = toNorm
var (
ToNorm = toNorm
NormBase = normBase
)

View File

@@ -840,7 +840,7 @@ func TestEvalSymlinks(t *testing.T) {
if p, err := filepath.EvalSymlinks(path); err != nil {
t.Errorf("EvalSymlinks(%q) error: %v", d.path, err)
} else if filepath.Clean(p) != filepath.Clean(dest) {
t.Errorf("Clean(%q)=%q, want %q", path, p, dest)
t.Errorf("EvalSymlinks(%q)=%q, want %q", path, p, dest)
}
// test EvalSymlinks(".")
@@ -872,6 +872,34 @@ func TestEvalSymlinks(t *testing.T) {
t.Errorf(`EvalSymlinks(".") in %q directory returns %q, want "." or %q`, d.path, p, want)
}()
// test EvalSymlinks(".."+path)
func() {
defer func() {
err := os.Chdir(wd)
if err != nil {
t.Fatal(err)
}
}()
err := os.Chdir(simpleJoin(tmpDir, "test"))
if err != nil {
t.Error(err)
return
}
path := simpleJoin("..", d.path)
dest := simpleJoin("..", d.dest)
if filepath.IsAbs(d.dest) || os.IsPathSeparator(d.dest[0]) {
dest = d.dest
}
if p, err := filepath.EvalSymlinks(path); err != nil {
t.Errorf("EvalSymlinks(%q) error: %v", d.path, err)
} else if filepath.Clean(p) != filepath.Clean(dest) {
t.Errorf("EvalSymlinks(%q)=%q, want %q", path, p, dest)
}
}()
// test EvalSymlinks where parameter is relative path
func() {
defer func() {
@@ -889,7 +917,7 @@ func TestEvalSymlinks(t *testing.T) {
if p, err := filepath.EvalSymlinks(d.path); err != nil {
t.Errorf("EvalSymlinks(%q) error: %v", d.path, err)
} else if filepath.Clean(p) != filepath.Clean(d.dest) {
t.Errorf("Clean(%q)=%q, want %q", d.path, p, d.dest)
t.Errorf("EvalSymlinks(%q)=%q, want %q", d.path, p, d.dest)
}
}()
}

View File

@@ -329,9 +329,106 @@ func TestToNorm(t *testing.T) {
for _, test := range tests {
got, err := filepath.ToNorm(test.arg, stubBase)
if err != nil {
t.Errorf("unexpected toNorm error, arg: %s, err: %v\n", test.arg, err)
t.Errorf("toNorm(%s) failed: %v\n", test.arg, err)
} else if got != test.want {
t.Errorf("toNorm error, arg: %s, want: %s, got: %s\n", test.arg, test.want, got)
t.Errorf("toNorm(%s) returns %s, but %s expected\n", test.arg, got, test.want)
}
}
testPath := `{{tmp}}\test\foo\bar`
testsDir := []struct {
wd string
arg string
want string
}{
// test absolute paths
{".", `{{tmp}}\test\foo\bar`, `{{tmp}}\test\foo\bar`},
{".", `{{tmp}}\.\test/foo\bar`, `{{tmp}}\test\foo\bar`},
{".", `{{tmp}}\test\..\test\foo\bar`, `{{tmp}}\test\foo\bar`},
{".", `{{tmp}}\TEST\FOO\BAR`, `{{tmp}}\test\foo\bar`},
// test relative paths begin with drive letter
{`{{tmp}}\test`, `{{tmpvol}}.`, `{{tmpvol}}.`},
{`{{tmp}}\test`, `{{tmpvol}}..`, `{{tmpvol}}..`},
{`{{tmp}}\test`, `{{tmpvol}}foo\bar`, `{{tmpvol}}foo\bar`},
{`{{tmp}}\test`, `{{tmpvol}}.\foo\bar`, `{{tmpvol}}foo\bar`},
{`{{tmp}}\test`, `{{tmpvol}}foo\..\foo\bar`, `{{tmpvol}}foo\bar`},
{`{{tmp}}\test`, `{{tmpvol}}FOO\BAR`, `{{tmpvol}}foo\bar`},
// test relative paths begin with '\'
{".", `{{tmpnovol}}\test\foo\bar`, `{{tmpnovol}}\test\foo\bar`},
{".", `{{tmpnovol}}\.\test\foo\bar`, `{{tmpnovol}}\test\foo\bar`},
{".", `{{tmpnovol}}\test\..\test\foo\bar`, `{{tmpnovol}}\test\foo\bar`},
{".", `{{tmpnovol}}\TEST\FOO\BAR`, `{{tmpnovol}}\test\foo\bar`},
// test relative paths begin without '\'
{`{{tmp}}\test`, ".", `.`},
{`{{tmp}}\test`, "..", `..`},
{`{{tmp}}\test`, `foo\bar`, `foo\bar`},
{`{{tmp}}\test`, `.\foo\bar`, `foo\bar`},
{`{{tmp}}\test`, `foo\..\foo\bar`, `foo\bar`},
{`{{tmp}}\test`, `FOO\BAR`, `foo\bar`},
}
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
defer func() {
err := os.Chdir(cwd)
if err != nil {
t.Fatal(err)
}
}()
tmp, err := ioutil.TempDir("", "testToNorm")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
// ioutil.TempDir might return "non-canonical" name.
tmp, err = filepath.EvalSymlinks(tmp)
if err != nil {
t.Fatal(err)
}
err = os.MkdirAll(strings.Replace(testPath, "{{tmp}}", tmp, -1), 0777)
if err != nil {
t.Fatal(err)
}
tmpVol := filepath.VolumeName(tmp)
tmpNoVol := tmp[len(tmpVol):]
for _, test := range testsDir {
wd := strings.Replace(strings.Replace(strings.Replace(test.wd, "{{tmp}}", tmp, -1), "{{tmpvol}}", tmpVol, -1), "{{tmpnovol}}", tmpNoVol, -1)
arg := strings.Replace(strings.Replace(strings.Replace(test.arg, "{{tmp}}", tmp, -1), "{{tmpvol}}", tmpVol, -1), "{{tmpnovol}}", tmpNoVol, -1)
want := strings.Replace(strings.Replace(strings.Replace(test.want, "{{tmp}}", tmp, -1), "{{tmpvol}}", tmpVol, -1), "{{tmpnovol}}", tmpNoVol, -1)
if test.wd == "." {
err := os.Chdir(cwd)
if err != nil {
t.Error(err)
continue
}
} else {
err := os.Chdir(wd)
if err != nil {
t.Error(err)
continue
}
}
got, err := filepath.ToNorm(arg, filepath.NormBase)
if err != nil {
t.Errorf("toNorm(%s) failed: %v (wd=%s)\n", arg, err, wd)
} else if got != want {
t.Errorf("toNorm(%s) returns %s, but %s expected (wd=%s)\n", arg, got, want, wd)
}
}
}

View File

@@ -22,7 +22,7 @@ func normVolumeName(path string) string {
return strings.ToUpper(volume)
}
// normBase retruns the last element of path.
// normBase returns the last element of path with correct case.
func normBase(path string) (string, error) {
p, err := syscall.UTF16PtrFromString(path)
if err != nil {
@@ -40,7 +40,24 @@ func normBase(path string) (string, error) {
return syscall.UTF16ToString(data.FileName[:]), nil
}
func toNorm(path string, base func(string) (string, error)) (string, error) {
// baseIsDotDot returns whether the last element of path is "..".
// The given path should be 'Clean'-ed in advance.
func baseIsDotDot(path string) bool {
i := strings.LastIndexByte(path, Separator)
return path[i+1:] == ".."
}
// toNorm returns the normalized path that is guranteed to be unique.
// It should accept the following formats:
// * UNC paths (e.g \\server\share\foo\bar)
// * absolute paths (e.g C:\foo\bar)
// * relative paths begin with drive letter (e.g C:foo\bar, C:..\foo\bar, C:.., C:.)
// * relative paths begin with '\' (e.g \foo\bar)
// * relative paths begin without '\' (e.g foo\bar, ..\foo\bar, .., .)
// The returned normalized path will be in the same form (of 5 listed above) as the input path.
// If two paths A and B are indicating the same file with the same format, toNorm(A) should be equal to toNorm(B).
// The normBase parameter should be equal to the normBase func, except for in tests. See docs on the normBase func.
func toNorm(path string, normBase func(string) (string, error)) (string, error) {
if path == "" {
return path, nil
}
@@ -58,7 +75,13 @@ func toNorm(path string, base func(string) (string, error)) (string, error) {
var normPath string
for {
name, err := base(volume + path)
if baseIsDotDot(path) {
normPath = path + `\` + normPath
break
}
name, err := normBase(volume + path)
if err != nil {
return "", err
}

View File

@@ -5720,6 +5720,8 @@ func TestTypeStrings(t *testing.T) {
{TypeOf(new(XM)), "*reflect_test.XM"},
{TypeOf(new(XM).String), "func() string"},
{TypeOf(new(XM)).Method(0).Type, "func(*reflect_test.XM) string"},
{ChanOf(3, TypeOf(XM{})), "chan reflect_test.XM"},
{MapOf(TypeOf(int(0)), TypeOf(XM{})), "map[int]reflect_test.XM"},
}
for i, test := range stringTests {

View File

@@ -1848,6 +1848,7 @@ func ChanOf(dir ChanDir, t Type) Type {
prototype := *(**chanType)(unsafe.Pointer(&ichan))
ch := new(chanType)
*ch = *prototype
ch.tflag = 0
ch.dir = uintptr(dir)
ch.str = resolveReflectName(newName(s, "", "", false))
ch.hash = fnv1(typ.hash, 'c', byte(dir))
@@ -1892,6 +1893,7 @@ func MapOf(key, elem Type) Type {
mt := new(mapType)
*mt = **(**mapType)(unsafe.Pointer(&imap))
mt.str = resolveReflectName(newName(s, "", "", false))
mt.tflag = 0
mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
mt.key = ktyp
mt.elem = etyp

View File

@@ -917,7 +917,9 @@ func scavengelist(list *mSpanList, now, limit uint64) uintptr {
// more memory than we want.)
start = (start + sys.PhysPageSize - 1) &^ (sys.PhysPageSize - 1)
end &^= sys.PhysPageSize - 1
if start == end {
if end <= start {
// start and end don't span a
// whole physical page.
continue
}
}

View File

@@ -12,13 +12,18 @@ TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x48
// Note: This function calls external C code, which might required 16-byte stack
// alignment after cmd/internal/obj applies its transformations.
TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x50
MOVQ SP, AX
ANDQ $-16, SP
MOVQ BX, 0x10(SP)
MOVQ BP, 0x18(SP)
MOVQ R12, 0x20(SP)
MOVQ R13, 0x28(SP)
MOVQ R14, 0x30(SP)
MOVQ R15, 0x38(SP)
MOVQ AX, 0x40(SP)
MOVQ DI, _rt0_amd64_linux_lib_argc<>(SB)
MOVQ SI, _rt0_amd64_linux_lib_argv<>(SB)
@@ -50,6 +55,7 @@ restore:
MOVQ 0x28(SP), R13
MOVQ 0x30(SP), R14
MOVQ 0x38(SP), R15
MOVQ 0x40(SP), SP
RET
TEXT _rt0_amd64_linux_lib_go(SB),NOSPLIT,$0

View File

@@ -162,11 +162,15 @@ TEXT runtime·mincore(SB),NOSPLIT,$0
TEXT time·now(SB), 7, $32
MOVW $8(R13), R0 // timeval
MOVW $0, R1 // zone
MOVW $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R12
SWI $0x80 // Note: R0 is tv_sec, R1 is tv_usec
CMP $0, R0
BNE inreg
MOVW 8(R13), R0
MOVW 12(R13), R1
inreg:
MOVW R1, R2 // usec
MOVW R0, sec+0(FP)
MOVW $0, R1
MOVW R1, loc+4(FP)
@@ -178,9 +182,14 @@ TEXT time·now(SB), 7, $32
TEXT runtime·nanotime(SB),NOSPLIT,$32
MOVW $8(R13), R0 // timeval
MOVW $0, R1 // zone
MOVW $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R12
SWI $0x80 // Note: R0 is tv_sec, R1 is tv_usec
CMP $0, R0
BNE inreg
MOVW 8(R13), R0
MOVW 12(R13), R1
inreg:
MOVW R1, R2
MOVW $1000000000, R3
MULLU R0, R3, (R1, R0)

View File

@@ -155,9 +155,14 @@ TEXT time·now(SB),NOSPLIT,$40-12
MOVD RSP, R0 // timeval
MOVD R0, R9 // this is how dyld calls gettimeofday
MOVW $0, R1 // zone
MOVD $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R16
SVC $0x80 // Note: x0 is tv_sec, w1 is tv_usec
CMP $0, R0
BNE inreg
MOVD 0(RSP), R0
MOVW 8(RSP), R1
inreg:
MOVD R0, sec+0(FP)
MOVW $1000, R3
MUL R3, R1
@@ -168,9 +173,14 @@ TEXT runtime·nanotime(SB),NOSPLIT,$40
MOVD RSP, R0 // timeval
MOVD R0, R9 // this is how dyld calls gettimeofday
MOVW $0, R1 // zone
MOVD $0, R2 // see issue 16570
MOVW $SYS_gettimeofday, R16
SVC $0x80 // Note: x0 is tv_sec, w1 is tv_usec
CMP $0, R0
BNE inreg
MOVD 0(RSP), R0
MOVW 8(RSP), R1
inreg:
MOVW $1000000000, R3
MUL R3, R0
MOVW $1000, R3

View File

@@ -7,28 +7,45 @@
package syscall_test
import (
"os/exec"
"syscall"
"testing"
)
const MNT_WAIT = 1
const MNT_NOWAIT = 2
func TestGetfsstat(t *testing.T) {
n, err := syscall.Getfsstat(nil, MNT_WAIT)
const flags = MNT_NOWAIT // see Issue 16937
n, err := syscall.Getfsstat(nil, flags)
t.Logf("Getfsstat(nil, %d) = (%v, %v)", flags, n, err)
if err != nil {
t.Fatal(err)
}
data := make([]syscall.Statfs_t, n)
n, err = syscall.Getfsstat(data, MNT_WAIT)
n2, err := syscall.Getfsstat(data, flags)
t.Logf("Getfsstat([]syscall.Statfs_t, %d) = (%v, %v)", flags, n2, err)
if err != nil {
t.Fatal(err)
}
empty := syscall.Statfs_t{}
for _, stat := range data {
if stat == empty {
t.Fatal("an empty Statfs_t struct was returned")
if n != n2 {
t.Errorf("Getfsstat(nil) = %d, but subsequent Getfsstat(slice) = %d", n, n2)
}
for i, stat := range data {
if stat == (syscall.Statfs_t{}) {
t.Errorf("index %v is an empty Statfs_t struct", i)
}
}
if t.Failed() {
for i, stat := range data[:n2] {
t.Logf("data[%v] = %+v", i, stat)
}
mount, err := exec.Command("mount").CombinedOutput()
if err != nil {
t.Logf("mount: %v\n%s", err, mount)
} else {
t.Logf("mount: %s", mount)
}
}
}

View File

@@ -26,14 +26,21 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
}
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// in the two registers.
func Gettimeofday(tv *Timeval) error {
// The tv passed to gettimeofday must be non-nil.
// Before macOS Sierra (10.12), tv was otherwise unused and
// the answers came back in the two registers.
// As of Sierra, gettimeofday return zeros and populates
// tv itself.
sec, usec, err := gettimeofday(tv)
tv.Sec = int32(sec)
tv.Usec = int32(usec)
return err
if err != nil {
return err
}
if sec != 0 || usec != 0 {
tv.Sec = int32(sec)
tv.Usec = int32(usec)
}
return nil
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@@ -26,14 +26,21 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
}
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// in the two registers.
func Gettimeofday(tv *Timeval) error {
// The tv passed to gettimeofday must be non-nil.
// Before macOS Sierra (10.12), tv was otherwise unused and
// the answers came back in the two registers.
// As of Sierra, gettimeofday return zeros and populates
// tv itself.
sec, usec, err := gettimeofday(tv)
tv.Sec = sec
tv.Usec = usec
return err
if err != nil {
return err
}
if sec != 0 || usec != 0 {
tv.Sec = sec
tv.Usec = usec
}
return nil
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@@ -26,14 +26,19 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
}
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
func Gettimeofday(tv *Timeval) error {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
tv.Sec = int32(sec)
tv.Usec = int32(usec)
return err
if err != nil {
return err
}
if sec != 0 || usec != 0 {
tv.Sec = int32(sec)
tv.Usec = int32(usec)
}
return nil
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@@ -26,14 +26,19 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
}
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
func Gettimeofday(tv *Timeval) error {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
tv.Sec = sec
tv.Usec = usec
return err
if err != nil {
return err
}
if sec != 0 || usec != 0 {
tv.Sec = sec
tv.Usec = usec
}
return nil
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@@ -0,0 +1,23 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin
// +build amd64 386 arm arm64
package syscall_test
import (
"syscall"
"testing"
)
func TestDarwinGettimeofday(t *testing.T) {
tv := &syscall.Timeval{}
if err := syscall.Gettimeofday(tv); err != nil {
t.Fatal(err)
}
if tv.Sec == 0 && tv.Usec == 0 {
t.Fatal("Sec and Usec both zero")
}
}