summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-02-26 11:15:50 -0800
committerIan Lance Taylor <iant@golang.org>2020-02-26 12:19:13 -0800
commitc5decc83e4eb06103c801fd4f8215301ce746109 (patch)
tree5443f7ec2e16fac152fe1af564d10b0d29ff1b95 /libgo
parent051b9873e78fe1acb1a3fecd0c6e5685b6c12fb3 (diff)
libgo: update to final Go1.14 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/221158
Diffstat (limited to 'libgo')
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/VERSION2
-rw-r--r--libgo/go/cmd/go/internal/modcmd/mod.go5
-rw-r--r--libgo/go/cmd/go/internal/modload/import.go3
-rw-r--r--libgo/go/cmd/go/internal/vet/vet.go4
-rw-r--r--libgo/go/cmd/go/internal/web/api.go2
-rw-r--r--libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt59
-rw-r--r--libgo/go/cmd/go/testdata/script/mod_readonly.txt1
-rw-r--r--libgo/go/cmd/go/testdata/script/vet_flags.txt11
-rw-r--r--libgo/go/crypto/cipher/gcm.go7
-rw-r--r--libgo/go/crypto/cipher/gcm_test.go19
-rw-r--r--libgo/go/crypto/elliptic/elliptic.go19
-rw-r--r--libgo/go/crypto/x509/pkcs8.go2
-rw-r--r--libgo/go/go/build/build.go14
-rw-r--r--libgo/go/go/doc/doc.go9
-rw-r--r--libgo/go/hash/maphash/maphash.go14
-rw-r--r--libgo/go/hash/maphash/maphash_test.go23
-rw-r--r--libgo/go/math/big/int.go4
-rw-r--r--libgo/go/runtime/malloc.go7
-rw-r--r--libgo/go/runtime/mkpreempt.go9
-rw-r--r--libgo/go/runtime/netpoll_stub.go17
-rw-r--r--libgo/go/testing/benchmark.go1
-rw-r--r--libgo/go/testing/sub_test.go40
-rw-r--r--libgo/go/testing/testing.go1
24 files changed, 224 insertions, 51 deletions
diff --git a/libgo/MERGE b/libgo/MERGE
index 2d01b8759bf..233492ada69 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-a068054af141c01df5a4519844f4b77273605f4e
+20a838ab94178c55bc4dc23ddc332fce8545a493
The first line of this file holds the git revision number of the
last merge done from the master library sources.
diff --git a/libgo/VERSION b/libgo/VERSION
index 5304c505acd..f000507a7fe 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.14rc1
+go1.14
diff --git a/libgo/go/cmd/go/internal/modcmd/mod.go b/libgo/go/cmd/go/internal/modcmd/mod.go
index 17505221587..d72d0cacd68 100644
--- a/libgo/go/cmd/go/internal/modcmd/mod.go
+++ b/libgo/go/cmd/go/internal/modcmd/mod.go
@@ -7,7 +7,6 @@ package modcmd
import (
"cmd/go/internal/base"
- "cmd/go/internal/cfg"
)
var CmdMod = &base.Command{
@@ -32,7 +31,3 @@ See 'go help modules' for an overview of module functionality.
cmdWhy,
},
}
-
-func addModFlags(cmd *base.Command) {
- cmd.Flag.StringVar(&cfg.ModFile, "modfile", "", "")
-}
diff --git a/libgo/go/cmd/go/internal/modload/import.go b/libgo/go/cmd/go/internal/modload/import.go
index 5906d648b49..d7fca8fd2c5 100644
--- a/libgo/go/cmd/go/internal/modload/import.go
+++ b/libgo/go/cmd/go/internal/modload/import.go
@@ -184,8 +184,9 @@ func Import(path string) (m module.Version, dir string, err error) {
if !pathIsStd {
if cfg.BuildModReason == "" {
queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod)
+ } else {
+ queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
}
- queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
}
return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr}
}
diff --git a/libgo/go/cmd/go/internal/vet/vet.go b/libgo/go/cmd/go/internal/vet/vet.go
index 660a739fbbd..4e09c0fb9c9 100644
--- a/libgo/go/cmd/go/internal/vet/vet.go
+++ b/libgo/go/cmd/go/internal/vet/vet.go
@@ -51,7 +51,9 @@ func runVet(cmd *base.Command, args []string) {
work.BuildInit()
work.VetFlags = vetFlags
- work.VetExplicit = true
+ if len(vetFlags) > 0 {
+ work.VetExplicit = true
+ }
if vetTool != "" {
var err error
work.VetTool, err = filepath.Abs(vetTool)
diff --git a/libgo/go/cmd/go/internal/web/api.go b/libgo/go/cmd/go/internal/web/api.go
index ad99eb2f8c3..209ed6861a1 100644
--- a/libgo/go/cmd/go/internal/web/api.go
+++ b/libgo/go/cmd/go/internal/web/api.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package web defines minimal helper routines for accessing HTTP/HTTPS
-// resources without requiring external dependenicies on the net package.
+// resources without requiring external dependencies on the net package.
//
// If the cmd_go_bootstrap build tag is present, web avoids the use of the net
// package and returns errors for all network operations.
diff --git a/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt b/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt
index ae05250c5f6..948496241e9 100644
--- a/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt
@@ -2,49 +2,67 @@
# go/build's Import should find modules by invoking the go command
-go build -o $WORK/testimport.exe ./testimport
+go build -o $WORK ./testimport ./testfindonly
# GO111MODULE=off
env GO111MODULE=off
-! exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
+! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
# GO111MODULE=auto in GOPATH/src
env GO111MODULE=auto
-exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
+exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
# GO111MODULE=auto outside GOPATH/src
cd $GOPATH/other
env GO111MODULE=auto
-exec $WORK/testimport.exe other/x/y/z/w .
+exec $WORK/testimport$GOEXE other/x/y/z/w .
stdout w2.go
-! exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
+! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
stderr 'cannot find module providing package gobuild.example.com/x/y/z/w'
cd z
-exec $WORK/testimport.exe other/x/y/z/w .
+exec $WORK/testimport$GOEXE other/x/y/z/w .
stdout w2.go
# GO111MODULE=on outside GOPATH/src
env GO111MODULE=
-exec $WORK/testimport.exe other/x/y/z/w .
+exec $WORK/testimport$GOEXE other/x/y/z/w .
stdout w2.go
env GO111MODULE=on
-exec $WORK/testimport.exe other/x/y/z/w .
+exec $WORK/testimport$GOEXE other/x/y/z/w .
stdout w2.go
# GO111MODULE=on in GOPATH/src
cd $GOPATH/src
env GO111MODULE=
-exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
+exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
stdout w1.go
env GO111MODULE=on
-exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .
+exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
stdout w1.go
cd w
-exec $WORK/testimport.exe gobuild.example.com/x/y/z/w ..
+exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w ..
stdout w1.go
+# go/build's Import in FindOnly mode should find directories by invoking the go command
+#
+# Calling build.Import in build.FindOnly mode on an import path of a Go package
+# that produces errors when loading (e.g., due to build constraints not matching
+# the current build context) should return the package directory and nil error.
+
+# Issue 31603: Import with non-empty srcDir should work.
+env GO111MODULE=on
+exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i $WORK
+! stdout 'build constraints'
+stdout '^dir=\$WORK.+i err=<nil>$'
+
+# Issue 37153: Import with empty srcDir should work.
+env GO111MODULE=on
+exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i ''
+! stdout 'build constraints'
+stdout '^dir=\$WORK.+i err=<nil>$'
+
-- go.mod --
module gobuild.example.com/x/y/z
@@ -54,6 +72,11 @@ package z
-- w/w1.go --
package w
+-- i/i.go --
+// +build i
+
+package i
+
-- testimport/x.go --
package main
@@ -89,6 +112,20 @@ func main() {
fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " "))
}
+-- testfindonly/x.go --
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "os"
+)
+
+func main() {
+ p, err := build.Import(os.Args[1], os.Args[2], build.FindOnly)
+ fmt.Printf("dir=%s err=%v\n", p.Dir, err)
+}
+
-- $GOPATH/other/go.mod --
module other/x/y
diff --git a/libgo/go/cmd/go/testdata/script/mod_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_readonly.txt
index 77fc735d572..751f6e645e1 100644
--- a/libgo/go/cmd/go/testdata/script/mod_readonly.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_readonly.txt
@@ -7,6 +7,7 @@ go mod edit -fmt
cp go.mod go.mod.empty
! go list all
stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly'
+! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one.
cmp go.mod go.mod.empty
# -mod=readonly should be set implicitly if the go.mod file is read-only
diff --git a/libgo/go/cmd/go/testdata/script/vet_flags.txt b/libgo/go/cmd/go/testdata/script/vet_flags.txt
index 94bfd126c09..2d790c1ac99 100644
--- a/libgo/go/cmd/go/testdata/script/vet_flags.txt
+++ b/libgo/go/cmd/go/testdata/script/vet_flags.txt
@@ -9,6 +9,17 @@ go vet -n -unreachable=false encoding/binary
stderr '-unreachable=false'
! stderr '-unsafeptr=false'
+# Issue 37030: "go vet <std package>" without other flags should disable the
+# unsafeptr check by default.
+go vet -n encoding/binary
+stderr '-unsafeptr=false'
+! stderr '-unreachable=false'
+
+# However, it should be enabled if requested explicitly.
+go vet -n -unsafeptr encoding/binary
+stderr '-unsafeptr'
+! stderr '-unsafeptr=false'
+
[short] stop
env GOCACHE=$WORK/gocache
env GOTMPDIR=$WORK/tmp
diff --git a/libgo/go/crypto/cipher/gcm.go b/libgo/go/crypto/cipher/gcm.go
index 73d78550f89..ba0af84a9d0 100644
--- a/libgo/go/crypto/cipher/gcm.go
+++ b/libgo/go/crypto/cipher/gcm.go
@@ -86,7 +86,8 @@ func NewGCM(cipher Block) (AEAD, error) {
}
// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois
-// Counter Mode, which accepts nonces of the given length.
+// Counter Mode, which accepts nonces of the given length. The length must not
+// be zero.
//
// Only use this function if you require compatibility with an existing
// cryptosystem that uses non-standard nonce lengths. All other users should use
@@ -112,6 +113,10 @@ func newGCMWithNonceAndTagSize(cipher Block, nonceSize, tagSize int) (AEAD, erro
return nil, errors.New("cipher: incorrect tag size given to GCM")
}
+ if nonceSize <= 0 {
+ return nil, errors.New("cipher: the nonce can't have zero length, or the security of the key will be immediately compromised")
+ }
+
if cipher, ok := cipher.(gcmAble); ok {
return cipher.NewGCM(nonceSize, tagSize)
}
diff --git a/libgo/go/crypto/cipher/gcm_test.go b/libgo/go/crypto/cipher/gcm_test.go
index 64d5cc0db4f..0d53e471f95 100644
--- a/libgo/go/crypto/cipher/gcm_test.go
+++ b/libgo/go/crypto/cipher/gcm_test.go
@@ -217,6 +217,13 @@ var aesGCMTests = []struct {
"2b9680b886b3efb7c6354b38c63b5373",
"e2b7e5ed5ff27fc8664148f5a628a46dcbf2015184fffb82f2651c36",
},
+ {
+ "11754cd72aec309bf52f7687212e8957",
+ "",
+ "",
+ "",
+ "250327c674aaf477aef2675748cf6971",
+ },
}
func TestAESGCM(t *testing.T) {
@@ -234,14 +241,22 @@ func TestAESGCM(t *testing.T) {
var aesgcm cipher.AEAD
switch {
- // Handle non-standard nonce sizes
+ // Handle non-standard tag sizes
case tagSize != 16:
aesgcm, err = cipher.NewGCMWithTagSize(aes, tagSize)
if err != nil {
t.Fatal(err)
}
- // Handle non-standard tag sizes
+ // Handle 0 nonce size (expect error and continue)
+ case len(nonce) == 0:
+ aesgcm, err = cipher.NewGCMWithNonceSize(aes, 0)
+ if err == nil {
+ t.Fatal("expected error for zero nonce size")
+ }
+ continue
+
+ // Handle non-standard nonce sizes
case len(nonce) != 12:
aesgcm, err = cipher.NewGCMWithNonceSize(aes, len(nonce))
if err != nil {
diff --git a/libgo/go/crypto/elliptic/elliptic.go b/libgo/go/crypto/elliptic/elliptic.go
index c84657c5e36..e2f71cdb63b 100644
--- a/libgo/go/crypto/elliptic/elliptic.go
+++ b/libgo/go/crypto/elliptic/elliptic.go
@@ -372,7 +372,12 @@ func initP521() {
p521.BitSize = 521
}
-// P256 returns a Curve which implements P-256 (see FIPS 186-3, section D.2.3)
+// P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3),
+// also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is
+// "P-256".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
//
// The cryptographic operations are implemented using constant-time algorithms.
func P256() Curve {
@@ -380,7 +385,11 @@ func P256() Curve {
return p256
}
-// P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4)
+// P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4),
+// also known as secp384r1. The CurveParams.Name of this Curve is "P-384".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
//
// The cryptographic operations do not use constant-time algorithms.
func P384() Curve {
@@ -388,7 +397,11 @@ func P384() Curve {
return p384
}
-// P521 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
+// P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5),
+// also known as secp521r1. The CurveParams.Name of this Curve is "P-521".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
//
// The cryptographic operations do not use constant-time algorithms.
func P521() Curve {
diff --git a/libgo/go/crypto/x509/pkcs8.go b/libgo/go/crypto/x509/pkcs8.go
index d37fc9e1b3f..ec4ab10c573 100644
--- a/libgo/go/crypto/x509/pkcs8.go
+++ b/libgo/go/crypto/x509/pkcs8.go
@@ -79,7 +79,7 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
}
}
-// MarshalPKCS8PrivateKey converts an RSA private key to PKCS#8, ASN.1 DER form.
+// MarshalPKCS8PrivateKey converts a private key to PKCS#8, ASN.1 DER form.
//
// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
// and ed25519.PrivateKey. Unsupported key types result in an error.
diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go
index e250ae71125..d5987dd861e 100644
--- a/libgo/go/go/build/build.go
+++ b/libgo/go/go/build/build.go
@@ -1017,8 +1017,6 @@ var errNoModules = errors.New("not using modules")
// Then we reinvoke it for every dependency. But this is still better than not working at all.
// See golang.org/issue/26504.
func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) error {
- const debugImportGo = false
-
// To invoke the go command,
// we must not being doing special things like AllowBinary or IgnoreVendor,
// and all the file system callbacks must be nil (we're meant to use the local file system).
@@ -1137,15 +1135,15 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode)
}
dir := f[0]
errStr := strings.TrimSpace(f[4])
- if errStr != "" && p.Dir == "" {
- // If 'go list' could not locate the package, return the same error that
- // 'go list' reported.
- // If 'go list' did locate the package (p.Dir is not empty), ignore the
- // error. It was probably related to loading source files, and we'll
- // encounter it ourselves shortly.
+ if errStr != "" && dir == "" {
+ // If 'go list' could not locate the package (dir is empty),
+ // return the same error that 'go list' reported.
return errors.New(errStr)
}
+ // If 'go list' did locate the package, ignore the error.
+ // It was probably related to loading source files, and we'll
+ // encounter it ourselves shortly if the FindOnly flag isn't set.
p.Dir = dir
p.ImportPath = f[1]
p.Root = f[2]
diff --git a/libgo/go/go/doc/doc.go b/libgo/go/go/doc/doc.go
index 0e50af04f62..79d38998e7b 100644
--- a/libgo/go/go/doc/doc.go
+++ b/libgo/go/go/doc/doc.go
@@ -138,9 +138,12 @@ func New(pkg *ast.Package, importPath string, mode Mode) *Package {
// NewFromFiles computes documentation for a package.
//
// The package is specified by a list of *ast.Files and corresponding
-// file set, which must not be nil. NewFromFiles does not skip files
-// based on build constraints, so it is the caller's responsibility to
-// provide only the files that are matched by the build context.
+// file set, which must not be nil.
+// NewFromFiles uses all provided files when computing documentation,
+// so it is the caller's responsibility to provide only the files that
+// match the desired build context. "go/build".Context.MatchFile can
+// be used for determining whether a file matches a build context with
+// the desired GOOS and GOARCH values, and other build constraints.
// The import path of the package is specified by importPath.
//
// Examples found in _test.go files are associated with the corresponding
diff --git a/libgo/go/hash/maphash/maphash.go b/libgo/go/hash/maphash/maphash.go
index 3f406e9db63..071dc04b548 100644
--- a/libgo/go/hash/maphash/maphash.go
+++ b/libgo/go/hash/maphash/maphash.go
@@ -5,10 +5,13 @@
// Package maphash provides hash functions on byte sequences.
// These hash functions are intended to be used to implement hash tables or
// other data structures that need to map arbitrary strings or byte
-// sequences to a uniform distribution of integers.
+// sequences to a uniform distribution on unsigned 64-bit integers.
//
// The hash functions are collision-resistant but not cryptographically secure.
// (See crypto/sha256 and crypto/sha512 for cryptographic use.)
+//
+// The hash value of a given byte sequence is consistent within a
+// single process, but will be different in different processes.
package maphash
import "unsafe"
@@ -66,7 +69,7 @@ type Hash struct {
// which does call h.initSeed.)
func (h *Hash) initSeed() {
if h.seed.s == 0 {
- h.SetSeed(MakeSeed())
+ h.setSeed(MakeSeed())
}
}
@@ -121,12 +124,17 @@ func (h *Hash) Seed() Seed {
// Two Hash objects with different seeds will very likely behave differently.
// Any bytes added to h before this call will be discarded.
func (h *Hash) SetSeed(seed Seed) {
+ h.setSeed(seed)
+ h.n = 0
+}
+
+// setSeed sets seed without discarding accumulated data.
+func (h *Hash) setSeed(seed Seed) {
if seed.s == 0 {
panic("maphash: use of uninitialized Seed")
}
h.seed = seed
h.state = seed
- h.n = 0
}
// Reset discards all bytes added to h.
diff --git a/libgo/go/hash/maphash/maphash_test.go b/libgo/go/hash/maphash/maphash_test.go
index 31d84a3b50a..0164a9e20ae 100644
--- a/libgo/go/hash/maphash/maphash_test.go
+++ b/libgo/go/hash/maphash/maphash_test.go
@@ -83,6 +83,29 @@ func TestHashHighBytes(t *testing.T) {
}
}
+func TestRepeat(t *testing.T) {
+ h1 := new(Hash)
+ h1.WriteString("testing")
+ sum1 := h1.Sum64()
+
+ h1.Reset()
+ h1.WriteString("testing")
+ sum2 := h1.Sum64()
+
+ if sum1 != sum2 {
+ t.Errorf("different sum after reseting: %#x != %#x", sum1, sum2)
+ }
+
+ h2 := new(Hash)
+ h2.SetSeed(h1.Seed())
+ h2.WriteString("testing")
+ sum3 := h2.Sum64()
+
+ if sum1 != sum3 {
+ t.Errorf("different sum on the same seed: %#x != %#x", sum1, sum3)
+ }
+}
+
// Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces.
var _ hash.Hash = &Hash{}
var _ hash.Hash64 = &Hash{}
diff --git a/libgo/go/math/big/int.go b/libgo/go/math/big/int.go
index bec0a81b20b..18f122e953c 100644
--- a/libgo/go/math/big/int.go
+++ b/libgo/go/math/big/int.go
@@ -505,8 +505,8 @@ func (z *Int) Exp(x, y, m *Int) *Int {
// GCD sets z to the greatest common divisor of a and b and returns z.
// If x or y are not nil, GCD sets their value such that z = a*x + b*y.
//
-// a and b may be positive, zero or negative.
-// Regardless of the signs of a and b, z is always >= 0.
+// a and b may be positive, zero or negative. (Before Go 1.14 both had
+// to be > 0.) Regardless of the signs of a and b, z is always >= 0.
//
// If a == b == 0, GCD sets z = x = y = 0.
//
diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go
index 35ace7f073d..266f5eba747 100644
--- a/libgo/go/runtime/malloc.go
+++ b/libgo/go/runtime/malloc.go
@@ -62,9 +62,10 @@
// Allocating and freeing a large object uses the mheap
// directly, bypassing the mcache and mcentral.
//
-// Free object slots in an mspan are zeroed only if mspan.needzero is
-// false. If needzero is true, objects are zeroed as they are
-// allocated. There are various benefits to delaying zeroing this way:
+// If mspan.needzero is false, then free object slots in the mspan are
+// already zeroed. Otherwise if needzero is true, objects are zeroed as
+// they are allocated. There are various benefits to delaying zeroing
+// this way:
//
// 1. Stack frame allocation can avoid zeroing altogether.
//
diff --git a/libgo/go/runtime/mkpreempt.go b/libgo/go/runtime/mkpreempt.go
index 64e220772e1..31b6f5cbac3 100644
--- a/libgo/go/runtime/mkpreempt.go
+++ b/libgo/go/runtime/mkpreempt.go
@@ -244,6 +244,15 @@ func genAMD64() {
// TODO: MXCSR register?
+ // Apparently, the signal handling code path in darwin kernel leaves
+ // the upper bits of Y registers in a dirty state, which causes
+ // many SSE operations (128-bit and narrower) become much slower.
+ // Clear the upper bits to get to a clean state. See issue #37174.
+ // It is safe here as Go code don't use the upper bits of Y registers.
+ p("#ifdef GOOS_darwin")
+ p("VZEROUPPER")
+ p("#endif")
+
p("PUSHQ BP")
p("MOVQ SP, BP")
p("// Save flags before clobbering them")
diff --git a/libgo/go/runtime/netpoll_stub.go b/libgo/go/runtime/netpoll_stub.go
index fe45cfbd400..f86f2f61748 100644
--- a/libgo/go/runtime/netpoll_stub.go
+++ b/libgo/go/runtime/netpoll_stub.go
@@ -13,16 +13,23 @@ var netpollWaiters uint32
var netpollStubLock mutex
var netpollNote note
-var netpollBroken uint32
+
+// netpollBroken, protected by netpollBrokenLock, avoids a double notewakeup.
+var netpollBrokenLock mutex
+var netpollBroken bool
func netpollGenericInit() {
atomic.Store(&netpollInited, 1)
}
func netpollBreak() {
- if atomic.Cas(&netpollBroken, 0, 1) {
+ lock(&netpollBrokenLock)
+ broken := netpollBroken
+ netpollBroken = true
+ if !broken {
notewakeup(&netpollNote)
}
+ unlock(&netpollBrokenLock)
}
// Polls for ready network connections.
@@ -34,8 +41,12 @@ func netpoll(delay int64) gList {
// This lock ensures that only one goroutine tries to use
// the note. It should normally be completely uncontended.
lock(&netpollStubLock)
+
+ lock(&netpollBrokenLock)
noteclear(&netpollNote)
- atomic.Store(&netpollBroken, 0)
+ netpollBroken = false
+ unlock(&netpollBrokenLock)
+
notetsleep(&netpollNote, delay)
unlock(&netpollStubLock)
}
diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go
index 93f461b07a2..88ba0f02420 100644
--- a/libgo/go/testing/benchmark.go
+++ b/libgo/go/testing/benchmark.go
@@ -179,6 +179,7 @@ func (b *B) ReportAllocs() {
func (b *B) runN(n int) {
benchmarkLock.Lock()
defer benchmarkLock.Unlock()
+ defer b.runCleanup(normalPanic)
// Try to get a comparable environment for each run
// by clearing garbage from previous runs.
runtime.GC()
diff --git a/libgo/go/testing/sub_test.go b/libgo/go/testing/sub_test.go
index 3dc30ee72e2..95f8220f815 100644
--- a/libgo/go/testing/sub_test.go
+++ b/libgo/go/testing/sub_test.go
@@ -613,6 +613,46 @@ func TestBRun(t *T) {
t.Errorf("MemBytes was %v; want %v", got, 2*bufSize)
}
},
+ }, {
+ desc: "cleanup is called",
+ f: func(b *B) {
+ var calls, cleanups, innerCalls, innerCleanups int
+ b.Run("", func(b *B) {
+ calls++
+ b.Cleanup(func() {
+ cleanups++
+ })
+ b.Run("", func(b *B) {
+ b.Cleanup(func() {
+ innerCleanups++
+ })
+ innerCalls++
+ })
+ work(b)
+ })
+ if calls == 0 || calls != cleanups {
+ t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
+ }
+ if innerCalls == 0 || innerCalls != innerCleanups {
+ t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
+ }
+ },
+ }, {
+ desc: "cleanup is called on failure",
+ failed: true,
+ f: func(b *B) {
+ var calls, cleanups int
+ b.Run("", func(b *B) {
+ calls++
+ b.Cleanup(func() {
+ cleanups++
+ })
+ b.Fatalf("failure")
+ })
+ if calls == 0 || calls != cleanups {
+ t.Errorf("mismatched cleanups; got %d want %d", cleanups, calls)
+ }
+ },
}}
for _, tc := range testCases {
var ok bool
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index 67892d71fd0..0891142d2c4 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -571,7 +571,6 @@ var _ TB = (*T)(nil)
var _ TB = (*B)(nil)
// T is a type passed to Test functions to manage test state and support formatted test logs.
-// Logs are accumulated during execution and dumped to standard output when done.
//
// A test ends when its Test function returns or calls any of the methods
// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as