[Pkg-golang-commits] [golang] 01/03: Imported Upstream version 1.6.2

Michael Hudson-Doyle mwhudson-guest at moszumanska.debian.org
Fri Jun 3 02:36:14 UTC 2016


This is an automated email from the git hooks/post-receive script.

mwhudson-guest pushed a commit to branch debian-sid
in repository golang.

commit 15be393e05ed7e06c2e62cde6401d54a0584658a
Author: Michael Hudson-Doyle <michael.hudson at canonical.com>
Date:   Fri Jun 3 14:06:42 2016 +1200

    Imported Upstream version 1.6.2
---
 CONTRIBUTING.md                           |  3 +-
 VERSION                                   |  2 +-
 doc/contribute.html                       |  2 +-
 doc/devel/release.html                    |  8 +++++
 doc/go1.6.html                            |  4 +--
 doc/go_faq.html                           |  3 +-
 doc/install-source.html                   | 15 ++++++---
 misc/cgo/errors/ptr.go                    | 10 ++++++
 src/cmd/cgo/gcc.go                        | 11 ++++---
 src/cmd/compile/internal/gc/esc.go        |  5 +++
 src/cmd/go/get.go                         |  8 +++++
 src/cmd/go/go_test.go                     | 12 +++++++
 src/cmd/go/pkg.go                         | 10 ++++--
 src/cmd/go/vendor_test.go                 | 26 +++++++++++++++
 src/cmd/link/internal/ld/macho.go         |  5 +--
 src/mime/multipart/formdata_test.go       | 36 +++++++++++++++++++++
 src/mime/multipart/multipart.go           | 20 +++++++++++-
 src/net/http/export_test.go               |  6 ++--
 src/net/http/serve_test.go                | 26 +++++++++++++++
 src/net/http/server.go                    | 28 ++++++++--------
 src/net/http/transport.go                 | 10 ++++--
 src/net/http/transport_test.go            |  5 +++
 src/runtime/cgocall.go                    |  3 ++
 src/runtime/crash_cgo_test.go             | 53 +++++++++++++++++++++++++++++++
 src/runtime/export_test.go                | 16 ++++++++++
 src/runtime/gc_test.go                    | 17 ++++++++++
 src/runtime/mgc.go                        | 14 +++++---
 src/runtime/mheap.go                      |  2 +-
 src/runtime/os1_windows.go                | 35 +++++++++++---------
 src/runtime/os_linux_386.go               |  5 ---
 src/runtime/panic.go                      | 17 ++++++++++
 src/runtime/proc.go                       |  3 ++
 src/runtime/rt0_darwin_arm.s              | 28 ++++++++++------
 src/runtime/rt0_darwin_arm64.s            | 28 ++++++++++++----
 src/runtime/rt0_linux_386.s               |  8 -----
 src/runtime/rt0_linux_arm64.s             | 27 ++++++++++++----
 src/runtime/runtime1.go                   |  2 +-
 src/runtime/signal_386.go                 | 25 +--------------
 src/runtime/symtab.go                     |  2 +-
 src/runtime/sys_linux_386.s               | 25 ++++++---------
 src/runtime/sys_linux_amd64.s             |  6 +++-
 src/runtime/testdata/testprogcgo/aprof.go | 48 ++++++++++++++++++++++++++++
 src/runtime/testdata/testprogcgo/cgo.go   | 20 ++++++++++++
 src/sort/sort.go                          | 14 ++++----
 src/sort/sort_test.go                     | 37 +++++++++++++++++++++
 src/syscall/asm_linux_386.s               | 13 ++------
 src/syscall/types_linux.go                |  3 ++
 src/syscall/ztypes_linux_ppc64.go         |  7 ++--
 src/syscall/ztypes_linux_ppc64le.go       |  7 ++--
 test/escape_closure.go                    | 26 +++++++++++++++
 50 files changed, 584 insertions(+), 162 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 712431c..4120daf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,7 +26,8 @@ Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html
 before sending patches.
 
 **We do not accept GitHub pull requests**
-(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
+(we use [an instance](https://go-review.googlesource.com/) of the
+[Gerrit](https://www.gerritcodereview.com/) code review system instead).
 
 Unless otherwise noted, the Go source files are distributed under
 the BSD-style license found in the LICENSE file.
diff --git a/VERSION b/VERSION
index e1bf218..17df20d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.6.1
\ No newline at end of file
+go1.6.2
\ No newline at end of file
diff --git a/doc/contribute.html b/doc/contribute.html
index 4619c81..59b3d20 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -78,7 +78,7 @@ no matter who makes the change.
 A custom git command called <code>git-codereview</code>,
 discussed below, helps manage the code review process through a Google-hosted
 <a href="https://go-review.googlesource.com/">instance</a> of the code review
-system called <a href="https://code.google.com/p/gerrit/">Gerrit</a>.
+system called <a href="https://www.gerritcodereview.com/">Gerrit</a>.
 </p>
 
 <h3 id="auth">Set up authentication for code review</h3>
diff --git a/doc/devel/release.html b/doc/devel/release.html
index e72f86d..a1a615f 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -45,6 +45,14 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.6.1">Go
 1.6.1 milestone</a> on our issue tracker for details.
 </p>
 
+<p>
+go1.6.2 (released 2016/04/20) includes fixes to the compiler, runtime, tools,
+documentation, and the <code>mime/multipart</code>, <code>net/http</code>, and
+<code>sort</code> packages.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.6.2">Go
+1.6.2 milestone</a> on our issue tracker for details.
+</p>
+
 <h2 id="go1.5">go1.5 (released 2015/08/19)</h2>
 
 <p>
diff --git a/doc/go1.6.html b/doc/go1.6.html
index 17c3536..8dea862 100644
--- a/doc/go1.6.html
+++ b/doc/go1.6.html
@@ -168,9 +168,7 @@ Go 1.7 will remove support for the old syntax.
 <p>
 The release schedules for the GCC and Go projects do not coincide.
 GCC release 5 contains the Go 1.4 version of gccgo.
-The next release, GCC 6, will have the Go 1.5 version of gccgo.
-Due to release scheduling, it is likely that
-Go 1.6 will not be in a GCC release until GCC 7.
+The next release, GCC 6, will have the Go 1.6 version of gccgo.
 </p>
 
 <h3 id="go_command">Go command</h3>
diff --git a/doc/go_faq.html b/doc/go_faq.html
index b5f9772..c4c506b 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -335,7 +335,8 @@ code that does what generics would enable, if less smoothly.
 </p>
 
 <p>
-This remains an open issue.
+This remains an open issue. See <a href="https://golang.org/issue/15292">the generics proposal issue</a>
+for more information.
 </p>
 
 <h3 id="exceptions">
diff --git a/doc/install-source.html b/doc/install-source.html
index 7da5675..da71f47 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -194,14 +194,19 @@ To build without <code>cgo</code>, set the environment variable
 <p>Go will install to a directory named <code>go</code>.
 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:</p>
+Then clone the repository and check out the latest release tag
+(<code class="versionTag">go1.6</code>, for example):</p>
 
 <pre>
 $ git clone https://go.googlesource.com/go
 $ cd go
-$ git checkout go1.6
+$ git checkout <span class="versionTag"><i><tag></i></span>
 </pre>
 
+<p class="whereTag">
+Where <code><tag></code> is the version string of the release.
+</p>
+
 <h2 id="head">(Optional) Switch to the master branch</h2>
 
 <p>If you intend to modify the go source code, and
@@ -378,7 +383,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>go1.6</code>.
+<code class="versionTag">go1.6</code>.
 </p>
 
 <p>
@@ -388,11 +393,13 @@ To update an existing tree to the latest release, you can run:
 <pre>
 $ cd go/src
 $ git fetch
-$ git checkout <i><tag></i>
+$ git checkout <span class="versionTag"><i><tag></i></psan>
 $ ./all.bash
 </pre>
 
+<p class="whereTag">
 Where <code><tag></code> is the version string of the release.
+</p>
 
 
 <h2 id="environment">Optional environment variables</h2>
diff --git a/misc/cgo/errors/ptr.go b/misc/cgo/errors/ptr.go
index 834cde9..bbcaaab 100644
--- a/misc/cgo/errors/ptr.go
+++ b/misc/cgo/errors/ptr.go
@@ -123,6 +123,16 @@ var ptrTests = []ptrTest{
 		fail:    false,
 	},
 	{
+		// Passing the address of a slice of an array that is
+		// an element in a struct, with a type conversion.
+		name:    "slice-ok-4",
+		c:       `typedef void* PV; void f(PV p) {}`,
+		imports: []string{"unsafe"},
+		support: `type S struct { p *int; a [4]byte }`,
+		body:    `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`,
+		fail:    false,
+	},
+	{
 		// Passing the address of a static variable with no
 		// pointers doesn't matter.
 		name:    "varok",
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index fb5049c..e1456cb 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -819,14 +819,17 @@ func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
 func (p *Package) isType(t ast.Expr) bool {
 	switch t := t.(type) {
 	case *ast.SelectorExpr:
-		if t.Sel.Name != "Pointer" {
-			return false
-		}
 		id, ok := t.X.(*ast.Ident)
 		if !ok {
 			return false
 		}
-		return id.Name == "unsafe"
+		if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
+			return true
+		}
+		if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
+			return true
+		}
+		return false
 	case *ast.Ident:
 		// TODO: This ignores shadowing.
 		switch t.Name {
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index ff983e7..06b6082 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -1376,6 +1376,11 @@ func esccall(e *EscState, n *Node, up *Node) {
 			if haspointers(t.Type) {
 				escassign(e, &e.theSink, src)
 			}
+		} else { // indirect and OCALLFUNC = could be captured variables, too. (#14409)
+			ll = e.nodeEscState(n).Escretval
+			for ; ll != nil; ll = ll.Next {
+				escassignDereference(e, ll.N, fn)
+			}
 		}
 		return
 	}
diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go
index a298049..9d4b94a 100644
--- a/src/cmd/go/get.go
+++ b/src/cmd/go/get.go
@@ -119,6 +119,14 @@ func runGet(cmd *Command, args []string) {
 		delete(packageCache, name)
 	}
 
+	// In order to rebuild packages information completely,
+	// we need to clear commands cache. Command packages are
+	// referring to evicted packages from the package cache.
+	// This leads to duplicated loads of the standard packages.
+	for name := range cmdCache {
+		delete(cmdCache, name)
+	}
+
 	args = importPaths(args)
 	packagesForBuild(args)
 
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 39e0f3e..acf4a39 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2759,3 +2759,15 @@ func TestParallelTest(t *testing.T) {
 	tg.setenv("GOPATH", tg.path("."))
 	tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
 }
+
+// Issue 14444: go get -u .../ duplicate loads errors
+func TestGoGetUpdateAllDoesNotTryToLoadDuplicates(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "-u", ".../")
+	tg.grepStderrNot("duplicate loads of", "did not remove old packages from cache")
+}
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 0c0cf07..599c2b4 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -441,6 +441,12 @@ func vendoredImportPath(parent *Package, path string) (found string) {
 		}
 		targ := filepath.Join(dir[:i], vpath)
 		if isDir(targ) && hasGoFiles(targ) {
+			importPath := parent.ImportPath
+			if importPath == "command-line-arguments" {
+				// If parent.ImportPath is 'command-line-arguments'.
+				// set to relative directory to root (also chopped root directory)
+				importPath = dir[len(root)+1:]
+			}
 			// We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
 			// We know the import path for parent's dir.
 			// We chopped off some number of path elements and
@@ -450,14 +456,14 @@ func vendoredImportPath(parent *Package, path string) (found string) {
 			// (actually the same number of bytes) from parent's import path
 			// and then append /vendor/path.
 			chopped := len(dir) - i
-			if chopped == len(parent.ImportPath)+1 {
+			if chopped == len(importPath)+1 {
 				// We walked up from c:\gopath\src\foo\bar
 				// and found c:\gopath\src\vendor\path.
 				// We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
 				// Use "vendor/path" without any prefix.
 				return vpath
 			}
-			return parent.ImportPath[:len(parent.ImportPath)-chopped] + "/" + vpath
+			return importPath[:len(importPath)-chopped] + "/" + vpath
 		}
 	}
 	return path
diff --git a/src/cmd/go/vendor_test.go b/src/cmd/go/vendor_test.go
index 006a8c9..4cf2b0c 100644
--- a/src/cmd/go/vendor_test.go
+++ b/src/cmd/go/vendor_test.go
@@ -244,6 +244,32 @@ func TestVendorTest2(t *testing.T) {
 	tg.run("test", "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2")
 }
 
+func TestVendorTest3(t *testing.T) {
+	testenv.MustHaveExternalNetwork(t)
+
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+	tg.setenv("GOPATH", tg.path("."))
+	tg.run("get", "github.com/clsung/go-vendor-issue-14613")
+
+	tg.run("build", "-i", "github.com/clsung/go-vendor-issue-14613")
+
+	// test folder should work
+	tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613")
+	tg.run("test", "github.com/clsung/go-vendor-issue-14613")
+
+	// test with specified _test.go should work too
+	tg.cd(filepath.Join(tg.path("."), "src"))
+	tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613/vendor_test.go")
+	tg.run("test", "github.com/clsung/go-vendor-issue-14613/vendor_test.go")
+
+	// test with imported and not used
+	tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go")
+	tg.runFail("test", "github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go")
+	tg.grepStderr("imported and not used:", `should say "imported and not used"`)
+}
+
 func TestVendorList(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index 1c7f3a0..cf3fba1 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -356,8 +356,9 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
 	buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
 
 	var msect *MachoSect
-	if sect.Rwx&1 == 0 && (Thearch.Thechar == '7' || (Thearch.Thechar == '6' && Buildmode == BuildmodeCShared)) {
-		// Darwin external linker on arm64 and on amd64 in c-shared buildmode
+	if sect.Rwx&1 == 0 && (Thearch.Thechar == '7' || // arm64
+		(Thearch.Thechar == '6' && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive))) { // amd64
+		// Darwin external linker on arm64 and on amd64 in c-shared/c-archive buildmode
 		// complains about absolute relocs in __TEXT, so if the section is not
 		// executable, put it in __DATA segment.
 		msect = newMachoSect(mseg, buf, "__DATA")
diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go
index 6e2388b..1deca0b 100644
--- a/src/mime/multipart/formdata_test.go
+++ b/src/mime/multipart/formdata_test.go
@@ -88,3 +88,39 @@ Content-Disposition: form-data; name="textb"
 ` + textbValue + `
 --MyBoundary--
 `
+
+func TestReadForm_NoReadAfterEOF(t *testing.T) {
+	maxMemory := int64(32) << 20
+	boundary := `---------------------------8d345eef0d38dc9`
+	body := `
+-----------------------------8d345eef0d38dc9
+Content-Disposition: form-data; name="version"
+
+171
+-----------------------------8d345eef0d38dc9--`
+
+	mr := NewReader(&failOnReadAfterErrorReader{t: t, r: strings.NewReader(body)}, boundary)
+
+	f, err := mr.ReadForm(maxMemory)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("Got: %#v", f)
+}
+
+// failOnReadAfterErrorReader is an io.Reader wrapping r.
+// It fails t if any Read is called after a failing Read.
+type failOnReadAfterErrorReader struct {
+	t      *testing.T
+	r      io.Reader
+	sawErr error
+}
+
+func (r *failOnReadAfterErrorReader) Read(p []byte) (n int, err error) {
+	if r.sawErr != nil {
+		r.t.Fatalf("unexpected Read on Reader after previous read saw error %v", r.sawErr)
+	}
+	n, err = r.r.Read(p)
+	r.sawErr = err
+	return
+}
diff --git a/src/mime/multipart/multipart.go b/src/mime/multipart/multipart.go
index 3b746a5..c21c3fc 100644
--- a/src/mime/multipart/multipart.go
+++ b/src/mime/multipart/multipart.go
@@ -96,7 +96,7 @@ func (p *Part) parseContentDisposition() {
 func NewReader(r io.Reader, boundary string) *Reader {
 	b := []byte("\r\n--" + boundary + "--")
 	return &Reader{
-		bufReader:        bufio.NewReaderSize(r, peekBufferSize),
+		bufReader:        bufio.NewReaderSize(&stickyErrorReader{r: r}, peekBufferSize),
 		nl:               b[:2],
 		nlDashBoundary:   b[:len(b)-2],
 		dashBoundaryDash: b[2:],
@@ -104,6 +104,24 @@ func NewReader(r io.Reader, boundary string) *Reader {
 	}
 }
 
+// stickyErrorReader is an io.Reader which never calls Read on its
+// underlying Reader once an error has been seen. (the io.Reader
+// interface's contract promises nothing about the return values of
+// Read calls after an error, yet this package does do multiple Reads
+// after error)
+type stickyErrorReader struct {
+	r   io.Reader
+	err error
+}
+
+func (r *stickyErrorReader) Read(p []byte) (n int, _ error) {
+	if r.err != nil {
+		return 0, r.err
+	}
+	n, r.err = r.r.Read(p)
+	return n, r.err
+}
+
 func newPart(mr *Reader) (*Part, error) {
 	bp := &Part{
 		Header: make(map[string][]string),
diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go
index 52bccbd..7952e00 100644
--- a/src/net/http/export_test.go
+++ b/src/net/http/export_test.go
@@ -59,9 +59,9 @@ func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServ
 
 func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
 	return &timeoutHandler{
-		handler: handler,
-		timeout: func() <-chan time.Time { return ch },
-		// (no body and nil cancelTimer)
+		handler:     handler,
+		testTimeout: ch,
+		// (no body)
 	}
 }
 
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 384b453..f79c045 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -1888,6 +1888,32 @@ func TestTimeoutHandlerRaceHeaderTimeout(t *testing.T) {
 	}
 }
 
+// Issue 14568.
+func TestTimeoutHandlerStartTimerWhenServing(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping sleeping test in -short mode")
+	}
+	defer afterTest(t)
+	var handler HandlerFunc = func(w ResponseWriter, _ *Request) {
+		w.WriteHeader(StatusNoContent)
+	}
+	timeout := 300 * time.Millisecond
+	ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
+	defer ts.Close()
+	// Issue was caused by the timeout handler starting the timer when
+	// was created, not when the request. So wait for more than the timeout
+	// to ensure that's not the case.
+	time.Sleep(2 * timeout)
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	if res.StatusCode != StatusNoContent {
+		t.Errorf("got res.StatusCode %d, want %v", res.StatusCode, StatusNoContent)
+	}
+}
+
 // Verifies we don't path.Clean() on the wrong parts in redirects.
 func TestRedirectMunging(t *testing.T) {
 	req, _ := NewRequest("GET", "http://example.com/", nil)
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 5e3b608..f23ef73 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -2309,15 +2309,10 @@ func (srv *Server) onceSetNextProtoDefaults() {
 // TimeoutHandler buffers all Handler writes to memory and does not
 // support the Hijacker or Flusher interfaces.
 func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
-	t := time.NewTimer(dt)
 	return &timeoutHandler{
 		handler: h,
 		body:    msg,
-
-		// Effectively storing a *time.Timer, but decomposed
-		// for testing:
-		timeout:     func() <-chan time.Time { return t.C },
-		cancelTimer: t.Stop,
+		dt:      dt,
 	}
 }
 
@@ -2328,12 +2323,11 @@ var ErrHandlerTimeout = errors.New("http: Handler timeout")
 type timeoutHandler struct {
 	handler Handler
 	body    string
+	dt      time.Duration
 
-	// timeout returns the channel of a *time.Timer and
-	// cancelTimer cancels it.  They're stored separately for
-	// testing purposes.
-	timeout     func() <-chan time.Time // returns channel producing a timeout
-	cancelTimer func() bool             // optional
+	// When set, no timer will be created and this channel will
+	// be used instead.
+	testTimeout <-chan time.Time
 }
 
 func (h *timeoutHandler) errorBody() string {
@@ -2344,6 +2338,12 @@ func (h *timeoutHandler) errorBody() string {
 }
 
 func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
+	var t *time.Timer
+	timeout := h.testTimeout
+	if timeout == nil {
+		t = time.NewTimer(h.dt)
+		timeout = t.C
+	}
 	done := make(chan struct{})
 	tw := &timeoutWriter{
 		w: w,
@@ -2363,10 +2363,10 @@ func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
 		}
 		w.WriteHeader(tw.code)
 		w.Write(tw.wbuf.Bytes())
-		if h.cancelTimer != nil {
-			h.cancelTimer()
+		if t != nil {
+			t.Stop()
 		}
-	case <-h.timeout():
+	case <-timeout:
 		tw.mu.Lock()
 		defer tw.mu.Unlock()
 		w.WriteHeader(StatusServiceUnavailable)
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index baf71d5..1e3ea11 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -176,9 +176,13 @@ func (t *Transport) onceSetNextProtoDefaults() {
 		// Issue 14275.
 		return
 	}
-	if t.ExpectContinueTimeout != 0 {
-		// Unsupported in http2, so disable http2 for now.
-		// Issue 13851.
+	if t.ExpectContinueTimeout != 0 && t != DefaultTransport {
+		// ExpectContinueTimeout is unsupported in http2, so
+		// if they explicitly asked for it (as opposed to just
+		// using the DefaultTransport, which sets it), then
+		// disable http2 for now.
+		//
+		// Issue 13851. (and changed in Issue 14391)
 		return
 	}
 	t2, err := http2configureTransport(t)
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 0c901b3..d9da078 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -2888,6 +2888,11 @@ func TestTransportAutomaticHTTP2(t *testing.T) {
 	testTransportAutoHTTP(t, &Transport{}, true)
 }
 
+// golang.org/issue/14391: also check DefaultTransport
+func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
+	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
+}
+
 func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
 	testTransportAutoHTTP(t, &Transport{
 		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 66115fd..fef8add 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -463,6 +463,9 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
 		if !top {
 			panic(errorString(msg))
 		}
+		if st.elem.kind&kindNoPointers != 0 {
+			return
+		}
 		for i := 0; i < s.cap; i++ {
 			cgoCheckArg(st.elem, p, true, false, msg)
 			p = add(p, st.elem.size)
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index d7b367f..1802e49 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -7,10 +7,13 @@
 package runtime_test
 
 import (
+	"fmt"
+	"internal/testenv"
 	"os/exec"
 	"runtime"
 	"strings"
 	"testing"
+	"time"
 )
 
 func TestCgoCrashHandler(t *testing.T) {
@@ -147,3 +150,53 @@ func TestEnsureDropM(t *testing.T) {
 		t.Errorf("expected %q, got %v", want, got)
 	}
 }
+
+// Test for issue 14387.
+// Test that the program that doesn't need any cgo pointer checking
+// takes about the same amount of time with it as without it.
+func TestCgoCheckBytes(t *testing.T) {
+	// Make sure we don't count the build time as part of the run time.
+	testenv.MustHaveGoBuild(t)
+	exe, err := buildTestProg(t, "testprogcgo")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Try it 10 times to avoid flakiness.
+	const tries = 10
+	var tot1, tot2 time.Duration
+	for i := 0; i < tries; i++ {
+		cmd := testEnv(exec.Command(exe, "CgoCheckBytes"))
+		cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
+
+		start := time.Now()
+		cmd.Run()
+		d1 := time.Since(start)
+
+		cmd = testEnv(exec.Command(exe, "CgoCheckBytes"))
+		cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
+
+		start = time.Now()
+		cmd.Run()
+		d2 := time.Since(start)
+
+		if d1*20 > d2 {
+			// The slow version (d2) was less than 20 times
+			// slower than the fast version (d1), so OK.
+			return
+		}
+
+		tot1 += d1
+		tot2 += d2
+	}
+
+	t.Errorf("cgo check too slow: got %v, expected at most %v", tot2/tries, (tot1/tries)*20)
+}
+
+func TestCgoCCodeSIGPROF(t *testing.T) {
+	got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF")
+	want := "OK\n"
+	if got != want {
+		t.Errorf("expected %q got %v", want, got)
+	}
+}
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 5400c1d..4380908 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -171,3 +171,19 @@ func SetTracebackEnv(level string) {
 	setTraceback(level)
 	traceback_env = traceback_cache
 }
+
+func CountPagesInUse() (pagesInUse, counted uintptr) {
+	stopTheWorld("CountPagesInUse")
+
+	pagesInUse = uintptr(mheap_.pagesInUse)
+
+	for _, s := range h_allspans {
+		if s.state == mSpanInUse {
+			counted += s.npages
+		}
+	}
+
+	startTheWorld()
+
+	return
+}
diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
index c8c96bb..d53d3ee 100644
--- a/src/runtime/gc_test.go
+++ b/src/runtime/gc_test.go
@@ -473,3 +473,20 @@ func testIfaceEqual(x interface{}) {
 		a = true
 	}
 }
+
+func TestPageAccounting(t *testing.T) {
+	// Grow the heap in small increments. This used to drop the
+	// pages-in-use count below zero because of a rounding
+	// mismatch (golang.org/issue/15022).
+	const blockSize = 64 << 10
+	blocks := make([]*[blockSize]byte, (64<<20)/blockSize)
+	for i := range blocks {
+		blocks[i] = new([blockSize]byte)
+	}
+
+	// Check that the running page count matches reality.
+	pagesInUse, counted := runtime.CountPagesInUse()
+	if pagesInUse != counted {
+		t.Fatalf("mheap_.pagesInUse is %d, but direct count is %d", pagesInUse, counted)
+	}
+}
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 94301c6..ab099d8 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -932,6 +932,9 @@ func gcStart(mode gcMode, forceTrigger bool) {
 	if mode == gcBackgroundMode {
 		gcBgMarkStartWorkers()
 	}
+
+	gcResetMarkState()
+
 	now := nanotime()
 	work.stwprocs, work.maxprocs = gcprocs(), gomaxprocs
 	work.tSweepTerm = now
@@ -949,8 +952,6 @@ func gcStart(mode gcMode, forceTrigger bool) {
 	// reclaimed until the next GC cycle.
 	clearpools()
 
-	gcResetMarkState()
-
 	work.finalizersDone = false
 
 	if mode == gcBackgroundMode { // Do as much work concurrently as possible
@@ -1559,7 +1560,8 @@ func gcMark(start_time int64) {
 	gcDrain(&gcw, gcDrainBlock)
 	gcw.dispose()
 
-	gcMarkRootCheck()
+	// TODO: Re-enable once this is cheap.
+	//gcMarkRootCheck()
 	if work.full != 0 {
 		throw("work.full != 0")
 	}
@@ -1723,8 +1725,10 @@ func gcCopySpans() {
 }
 
 // gcResetMarkState resets global state prior to marking (concurrent
-// or STW) and resets the stack scan state of all Gs. Any Gs created
-// after this will also be in the reset state.
+// or STW) and resets the stack scan state of all Gs.
+//
+// This is safe to do without the world stopped because any Gs created
+// during or after this will start out in the reset state.
 func gcResetMarkState() {
 	// This may be called during a concurrent phase, so make sure
 	// allgs doesn't change.
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index e818954..a153df0 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -671,7 +671,7 @@ func (h *mheap) grow(npage uintptr) bool {
 	}
 	atomic.Store(&s.sweepgen, h.sweepgen)
 	s.state = _MSpanInUse
-	h.pagesInUse += uint64(npage)
+	h.pagesInUse += uint64(s.npages)
 	h.freeSpanLocked(s, false, true, 0)
 	return true
 }
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
index b4411da..8e41ac3 100644
--- a/src/runtime/os1_windows.go
+++ b/src/runtime/os1_windows.go
@@ -108,23 +108,28 @@ func asmstdcall(fn unsafe.Pointer)
 
 var asmstdcallAddr unsafe.Pointer
 
+func windowsFindfunc(name []byte, lib uintptr) stdFunction {
+	f := stdcall2(_GetProcAddress, lib, uintptr(unsafe.Pointer(&name[0])))
+	return stdFunction(unsafe.Pointer(f))
+}
+
 func loadOptionalSyscalls() {
-	var buf [50]byte // large enough for longest string
-	strtoptr := func(s string) uintptr {
-		buf[copy(buf[:], s)] = 0 // nil-terminated for OS
-		return uintptr(noescape(unsafe.Pointer(&buf[0])))
-	}
-	l := stdcall1(_LoadLibraryA, strtoptr("kernel32.dll"))
-	findfunc := func(name string) stdFunction {
-		f := stdcall2(_GetProcAddress, l, strtoptr(name))
-		return stdFunction(unsafe.Pointer(f))
-	}
-	if l != 0 {
-		_AddDllDirectory = findfunc("AddDllDirectory")
-		_AddVectoredContinueHandler = findfunc("AddVectoredContinueHandler")
-		_GetQueuedCompletionStatusEx = findfunc("GetQueuedCompletionStatusEx")
-		_LoadLibraryExW = findfunc("LoadLibraryExW")
+	var (
+		kernel32dll                 = []byte("kernel32.dll\000")
+		addVectoredContinueHandler  = []byte("AddVectoredContinueHandler\000")
+		getQueuedCompletionStatusEx = []byte("GetQueuedCompletionStatusEx\000")
+		addDllDirectory             = []byte("AddDllDirectory\000")
+		loadLibraryExW              = []byte("LoadLibraryExW\000")
+	)
+
+	k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
+	if k32 == 0 {
+		throw("kernel32.dll not found")
 	}
+	_AddDllDirectory = windowsFindfunc(addDllDirectory, k32)
+	_AddVectoredContinueHandler = windowsFindfunc(addVectoredContinueHandler, k32)
+	_GetQueuedCompletionStatusEx = windowsFindfunc(getQueuedCompletionStatusEx, k32)
+	_LoadLibraryExW = windowsFindfunc(loadLibraryExW, k32)
 }
 
 //go:nosplit
diff --git a/src/runtime/os_linux_386.go b/src/runtime/os_linux_386.go
index 3577a24..0f39cad 100644
--- a/src/runtime/os_linux_386.go
+++ b/src/runtime/os_linux_386.go
@@ -15,8 +15,6 @@ const (
 	_AT_SYSINFO = 32
 )
 
-var _vdso uint32
-
 func sysargs(argc int32, argv **byte) {
 	// skip over argv, envv to get to auxv
 	n := argc + 1
@@ -28,9 +26,6 @@ func sysargs(argc int32, argv **byte) {
 
 	for i := 0; auxv[i] != _AT_NULL; i += 2 {
 		switch auxv[i] {
-		case _AT_SYSINFO:
-			_vdso = auxv[i+1]
-
 		case _AT_RANDOM:
 			startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
 		}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index ba07330..3d9d035 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -9,39 +9,56 @@ import (
 	"unsafe"
 )
 
+// Calling panic with one of the errors below will call errorString.Error
+// which will call mallocgc to concatenate strings. That will fail if
+// malloc is locked, causing a confusing error message. Throw a better
+// error message instead.
+func panicCheckMalloc(err error) {
+	gp := getg()
+	if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
+		throw(string(err.(errorString)))
+	}
+}
+
 var indexError = error(errorString("index out of range"))
 
 func panicindex() {
+	panicCheckMalloc(indexError)
 	panic(indexError)
 }
 
 var sliceError = error(errorString("slice bounds out of range"))
 
 func panicslice() {
+	panicCheckMalloc(sliceError)
 	panic(sliceError)
 }
 
 var divideError = error(errorString("integer divide by zero"))
 
 func panicdivide() {
+	panicCheckMalloc(divideError)
 	panic(divideError)
 }
 
 var overflowError = error(errorString("integer overflow"))
 
 func panicoverflow() {
+	panicCheckMalloc(overflowError)
 	panic(overflowError)
 }
 
 var floatError = error(errorString("floating point error"))
 
 func panicfloat() {
+	panicCheckMalloc(floatError)
 	panic(floatError)
 }
 
 var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
 
 func panicmem() {
+	panicCheckMalloc(memoryError)
 	panic(memoryError)
 }
 
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index d1f5088..47ccb37 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -443,6 +443,9 @@ func schedinit() {
 
 	sched.lastpoll = uint64(nanotime())
 	procs := int(ncpu)
+	if procs > _MaxGomaxprocs {
+		procs = _MaxGomaxprocs
+	}
 	if n := atoi(gogetenv("GOMAXPROCS")); n > 0 {
 		if n > _MaxGomaxprocs {
 			n = _MaxGomaxprocs
diff --git a/src/runtime/rt0_darwin_arm.s b/src/runtime/rt0_darwin_arm.s
index cbbea80..59733d3 100644
--- a/src/runtime/rt0_darwin_arm.s
+++ b/src/runtime/rt0_darwin_arm.s
@@ -16,12 +16,15 @@ TEXT _rt0_arm_darwin(SB),7,$-4
 //
 // Note that all currently shipping darwin/arm platforms require
 // cgo and do not support c-shared.
-TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
-	// R11 is REGTMP, reserved for liblink. It is used below to
-	// move R0/R1 into globals. However in the darwin ARMv7 calling
-	// convention, it is a callee-saved register. So we save it to a
-	// temporary register.
-	MOVW  R11, R2
+TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$32
+	// Preserve callee-save registers.
+	MOVW    R4, 12(R13)
+	MOVW    R5, 16(R13)
+	MOVW    R6, 20(R13)
+	MOVW    R7, 24(R13)
+	MOVW    R8, 28(R13)
+	MOVW    R11, 32(R13)
+
 	MOVW  R0, _rt0_arm_darwin_lib_argc<>(SB)
 	MOVW  R1, _rt0_arm_darwin_lib_argv<>(SB)
 
@@ -35,9 +38,8 @@ TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
 	B.EQ  nocgo
 	MOVW  $_rt0_arm_darwin_lib_go(SB), R0
 	MOVW  $0, R1
-	MOVW  R2, R11
 	BL    (R3)
-	RET
+	B rr
 nocgo:
 	MOVW  $0x400000, R0
 	MOVW  R0, (R13) // stacksize
@@ -46,10 +48,18 @@ nocgo:
 	MOVW  $0, R0
 	MOVW  R0, 8(R13) // fnarg
 	MOVW  $runtime·newosproc0(SB), R3
-	MOVW  R2, R11
 	BL    (R3)
+rr:
+	// Restore callee-save registers and return.
+	MOVW    12(R13), R4
+	MOVW    16(R13), R5
+	MOVW    20(R13), R6
+	MOVW    24(R13), R7
+	MOVW    28(R13), R8
+	MOVW    32(R13), R11
 	RET
 
+
 TEXT _rt0_arm_darwin_lib_go(SB),NOSPLIT,$0
 	MOVW  _rt0_arm_darwin_lib_argc<>(SB), R0
 	MOVW  _rt0_arm_darwin_lib_argv<>(SB), R1
diff --git a/src/runtime/rt0_darwin_arm64.s b/src/runtime/rt0_darwin_arm64.s
index fa676c0..0a1feb1 100644
--- a/src/runtime/rt0_darwin_arm64.s
+++ b/src/runtime/rt0_darwin_arm64.s
@@ -16,12 +16,17 @@ TEXT _rt0_arm64_darwin(SB),NOSPLIT,$-8
 //
 // Note that all currently shipping darwin/arm64 platforms require
 // cgo and do not support c-shared.
-TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
-	// R27 is REGTMP, reserved for liblink. It is used below to
-	// move R0/R1 into globals. However in the standard ARM64 calling
-	// convention, it is a callee-saved register. So we save it to a
-	// temporary register.
-	MOVD  R27, R7
+TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$88
+	// Preserve callee-save registers.
+	MOVD R19, 24(RSP)
+	MOVD R20, 32(RSP)
+	MOVD R21, 40(RSP)
+	MOVD R22, 48(RSP)
+	MOVD R23, 56(RSP)
+	MOVD R24, 64(RSP)
+	MOVD R25, 72(RSP)
+	MOVD R26, 80(RSP)
+	MOVD R27, 88(RSP)
 
 	MOVD  R0, _rt0_arm64_darwin_lib_argc<>(SB)
 	MOVD  R1, _rt0_arm64_darwin_lib_argv<>(SB)
@@ -36,7 +41,16 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
 	MOVD  $0, R1
 	BL    (R4)
 
-	MOVD  R7, R27
+	// Restore callee-save registers.
+	MOVD 24(RSP), R19
+	MOVD 32(RSP), R20
+	MOVD 40(RSP), R21
+	MOVD 48(RSP), R22
+	MOVD 56(RSP), R23
+	MOVD 64(RSP), R24
+	MOVD 72(RSP), R25
+	MOVD 80(RSP), R26
+	MOVD 88(RSP), R27
 	RET
 
 TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0
diff --git a/src/runtime/rt0_linux_386.s b/src/runtime/rt0_linux_386.s
index 59a30b4..23bfc98 100644
--- a/src/runtime/rt0_linux_386.s
+++ b/src/runtime/rt0_linux_386.s
@@ -73,11 +73,3 @@ GLOBL _rt0_386_linux_lib_argv<>(SB),NOPTR, $4
 
 TEXT main(SB),NOSPLIT,$0
 	JMP	runtime·rt0_go(SB)
-
-TEXT _fallback_vdso(SB),NOSPLIT,$0
-	INT	$0x80
-	RET
-
-DATA	runtime·_vdso(SB)/4, $_fallback_vdso(SB)
-GLOBL	runtime·_vdso(SB), NOPTR, $4
-
diff --git a/src/runtime/rt0_linux_arm64.s b/src/runtime/rt0_linux_arm64.s
index 2b32e35..31c2367 100644
--- a/src/runtime/rt0_linux_arm64.s
+++ b/src/runtime/rt0_linux_arm64.s
@@ -11,11 +11,17 @@ TEXT _rt0_arm64_linux(SB),NOSPLIT,$-8
 
 // When building with -buildmode=c-shared, this symbol is called when the shared
 // library is loaded.
-TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$40
-	// R27 is REGTMP, reserved for liblink. It is used below to
-	// move R0/R1 into globals. However in the standard ARM64 calling
-	// convention, it is a callee-saved register.
-	MOVD	R27, 24(RSP)
+TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$88
+	// Preserve callee-save registers.
+	MOVD R19, 24(RSP)
+	MOVD R20, 32(RSP)
+	MOVD R21, 40(RSP)
+	MOVD R22, 48(RSP)
+	MOVD R23, 56(RSP)
+	MOVD R24, 64(RSP)
+	MOVD R25, 72(RSP)
+	MOVD R26, 80(RSP)
+	MOVD R27, 88(RSP)
 
 	MOVD	R0, _rt0_arm64_linux_lib_argc<>(SB)
 	MOVD	R1, _rt0_arm64_linux_lib_argv<>(SB)
@@ -42,7 +48,16 @@ nocgo:
 	BL	(R4)
 
 restore:
-	MOVD	24(RSP), R27
+	// Restore callee-save registers.
+	MOVD 24(RSP), R19
+	MOVD 32(RSP), R20
+	MOVD 40(RSP), R21
+	MOVD 48(RSP), R22
+	MOVD 56(RSP), R23
+	MOVD 64(RSP), R24
+	MOVD 72(RSP), R25
+	MOVD 80(RSP), R26
+	MOVD 88(RSP), R27
 	RET
 
 TEXT _rt0_arm64_linux_lib_go(SB),NOSPLIT,$0
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index f63e09c..400ea29 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -52,7 +52,7 @@ var (
 	argv **byte
 )
 
-// nosplit for use in linux/386 startup linux_setup_vdso
+// nosplit for use in linux startup sysargs
 //go:nosplit
 func argv_index(argv **byte, i int32) *byte {
 	return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*sys.PtrSize))
diff --git a/src/runtime/signal_386.go b/src/runtime/signal_386.go
index 0374f4a..25187da 100644
--- a/src/runtime/signal_386.go
+++ b/src/runtime/signal_386.go
@@ -142,30 +142,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
 	level, _, docrash := gotraceback()
 	if level > 0 {
 		goroutineheader(gp)
-
-		// On Linux/386, all system calls go through the vdso kernel_vsyscall routine.
-		// Normally we don't see those PCs, but during signals we can.
-		// If we see a PC in the vsyscall area (it moves around, but near the top of memory),
-		// assume we're blocked in the vsyscall routine, which has saved
-		// three words on the stack after the initial call saved the caller PC.
-		// Pop all four words off SP and use the saved PC.
-		// The check of the stack bounds here should suffice to avoid a fault
-		// during the actual PC pop.
-		// If we do load a bogus PC, not much harm done: we weren't going
-		// to get a decent traceback anyway.
-		// TODO(rsc): Make this more precise: we should do more checks on the PC,
-		// and we should find out whether different versions of the vdso page
-		// use different prologues that store different amounts on the stack.
-		pc := uintptr(c.eip())
-		sp := uintptr(c.esp())
-		if GOOS == "linux" && pc >= 0xf4000000 && gp.stack.lo <= sp && sp+16 <= gp.stack.hi {
-			// Assume in vsyscall page.
-			sp += 16
-			pc = *(*uintptr)(unsafe.Pointer(sp - 4))
-			print("runtime: unwind vdso kernel_vsyscall: pc=", hex(pc), " sp=", hex(sp), "\n")
-		}
-
-		tracebacktrap(pc, sp, 0, gp)
+		tracebacktrap(uintptr(c.eip()), uintptr(c.esp()), 0, gp)
 		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
 			// tracebackothers on original m skipped this one; trace it now.
 			goroutineheader(_g_.m.curg)
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 00b0a85..6e02f1e 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -199,7 +199,7 @@ func (f *Func) FileLine(pc uintptr) (file string, line int) {
 
 func findmoduledatap(pc uintptr) *moduledata {
 	for datap := &firstmoduledata; datap != nil; datap = datap.next {
-		if datap.minpc <= pc && pc <= datap.maxpc {
+		if datap.minpc <= pc && pc < datap.maxpc {
 			return datap
 		}
 	}
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index 1a3aaf0..4a74196 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -12,16 +12,17 @@
 
 // Most linux systems use glibc's dynamic linker, which puts the
 // __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
-// independent code and setldt in this file does the same in the statically
-// linked case. Android, however, uses bionic's dynamic linker, which does not
-// save the helper anywhere, and so the only way to invoke a syscall from
-// position independent code is boring old int $0x80 (which is also what
-// bionic's syscall wrappers use).
-#ifdef GOOS_android
+// independent code and setldt in runtime does the same in the statically
+// linked case. However, systems that use alternative libc such as Android's
+// bionic and musl, do not save the helper anywhere, and so the only way to
+// invoke a syscall from position independent code is boring old int $0x80
+// (which is also what syscall wrappers in bionic/musl use).
+//
+// The benchmarks also showed that using int $0x80 is as fast as calling
+// *%gs:0x10 except on AMD Opteron. See https://golang.org/cl/19833
+// for the benchmark program and raw data.
+//#define INVOKE_SYSCALL	CALL	0x10(GS) // non-portable
 #define INVOKE_SYSCALL	INT	$0x80
-#else
-#define INVOKE_SYSCALL	CALL	0x10(GS)
-#endif
 
 TEXT runtime·exit(SB),NOSPLIT,$0
 	MOVL	$252, AX	// syscall number
@@ -434,12 +435,6 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
 	 */
 	ADDL	$0x4, DX	// address
 	MOVL	DX, 0(DX)
-        // We copy the glibc dynamic linker behaviour of storing the
-        // __kernel_vsyscall entry point at 0x10(GS) so that it can be invoked
-        // by "CALL 0x10(GS)" in all situations, not only those where the
-        // binary is actually dynamically linked.
-	MOVL	runtime·_vdso(SB), AX
-	MOVL	AX, 0x10(DX)
 #endif
 
 	// set up user_desc
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index aed85cb..f407078 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -258,7 +258,7 @@ TEXT runtime·sysMmap(SB),NOSPLIT,$0
 
 // Call the function stored in _cgo_mmap using the GCC calling convention.
 // This must be called on the system stack.
-TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
+TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
 	MOVQ	addr+0(FP), DI
 	MOVQ	n+8(FP), SI
 	MOVL	prot+16(FP), DX
@@ -266,7 +266,11 @@ TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
 	MOVL	fd+24(FP), R8
 	MOVL	off+28(FP), R9
 	MOVQ	_cgo_mmap(SB), AX
+	MOVQ	SP, BX
+	ANDQ	$~15, SP	// alignment as per amd64 psABI
+	MOVQ	BX, 0(SP)
 	CALL	AX
+	MOVQ	0(SP), SP
 	MOVQ	AX, ret+32(FP)
 	RET
 
diff --git a/src/runtime/testdata/testprogcgo/aprof.go b/src/runtime/testdata/testprogcgo/aprof.go
new file mode 100644
index 0000000..cf52107
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/aprof.go
@@ -0,0 +1,48 @@
+// 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.
+
+package main
+
+// Test that SIGPROF received in C code does not crash the process
+// looking for the C code's func pointer.
+
+// The test fails when the function is the first C function.
+// The exported functions are the first C functions, so we use that.
+
+// extern void GoNop();
+import "C"
+
+import (
+	"bytes"
+	"fmt"
+	"runtime/pprof"
+)
+
+func init() {
+	register("CgoCCodeSIGPROF", CgoCCodeSIGPROF)
+}
+
+//export GoNop
+func GoNop() {}
+
+func CgoCCodeSIGPROF() {
+	c := make(chan bool)
+	go func() {
+		for {
+			<-c
+			for i := 0; i < 1e7; i++ {
+				C.GoNop()
+			}
+			c <- true
+		}
+	}()
+
+	var buf bytes.Buffer
+	pprof.StartCPUProfile(&buf)
+	c <- true
+	<-c
+	pprof.StopCPUProfile()
+
+	fmt.Println("OK")
+}
diff --git a/src/runtime/testdata/testprogcgo/cgo.go b/src/runtime/testdata/testprogcgo/cgo.go
index cf1af82..7a2e013 100644
--- a/src/runtime/testdata/testprogcgo/cgo.go
+++ b/src/runtime/testdata/testprogcgo/cgo.go
@@ -6,17 +6,22 @@ package main
 
 /*
 void foo1(void) {}
+void foo2(void* p) {}
 */
 import "C"
 import (
 	"fmt"
+	"os"
 	"runtime"
+	"strconv"
 	"time"
+	"unsafe"
 )
 
 func init() {
 	register("CgoSignalDeadlock", CgoSignalDeadlock)
 	register("CgoTraceback", CgoTraceback)
+	register("CgoCheckBytes", CgoCheckBytes)
 }
 
 func CgoSignalDeadlock() {
@@ -78,3 +83,18 @@ func CgoTraceback() {
 	runtime.Stack(buf, true)
 	fmt.Printf("OK\n")
 }
+
+func CgoCheckBytes() {
+	try, _ := strconv.Atoi(os.Getenv("GO_CGOCHECKBYTES_TRY"))
+	if try <= 0 {
+		try = 1
+	}
+	b := make([]byte, 1e6*try)
+	start := time.Now()
+	for i := 0; i < 1e3*try; i++ {
+		C.foo2(unsafe.Pointer(&b[0]))
+		if time.Since(start) > time.Second {
+			break
+		}
+	}
+}
diff --git a/src/sort/sort.go b/src/sort/sort.go
index ac8f4a6..ee437d3 100644
--- a/src/sort/sort.go
+++ b/src/sort/sort.go
@@ -119,15 +119,15 @@ func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
 	pivot := lo
 	a, c := lo+1, hi-1
 
-	for ; a != c && data.Less(a, pivot); a++ {
+	for ; a < c && data.Less(a, pivot); a++ {
 	}
 	b := a
 	for {
-		for ; b != c && !data.Less(pivot, b); b++ { // data[b] <= pivot
+		for ; b < c && !data.Less(pivot, b); b++ { // data[b] <= pivot
 		}
-		for ; b != c && data.Less(pivot, c-1); c-- { // data[c-1] > pivot
+		for ; b < c && data.Less(pivot, c-1); c-- { // data[c-1] > pivot
 		}
-		if b == c {
+		if b >= c {
 			break
 		}
 		// data[b] > pivot; data[c-1] <= pivot
@@ -167,11 +167,11 @@ func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
 		//	data[a <= i < b] unexamined
 		//	data[b <= i < c] = pivot
 		for {
-			for ; a != b && !data.Less(b-1, pivot); b-- { // data[b] == pivot
+			for ; a < b && !data.Less(b-1, pivot); b-- { // data[b] == pivot
 			}
-			for ; a != b && data.Less(a, pivot); a++ { // data[a] < pivot
+			for ; a < b && data.Less(a, pivot); a++ { // data[a] < pivot
 			}
-			if a == b {
+			if a >= b {
 				break
 			}
 			// data[a] == pivot; data[b-1] < pivot
diff --git a/src/sort/sort_test.go b/src/sort/sort_test.go
index 6c36f30..a5da6b2 100644
--- a/src/sort/sort_test.go
+++ b/src/sort/sort_test.go
@@ -109,6 +109,43 @@ func TestReverseSortIntSlice(t *testing.T) {
 	}
 }
 
+type nonDeterministicTestingData struct {
+	r *rand.Rand
+}
+
+func (t *nonDeterministicTestingData) Len() int {
+	return 500
+}
+func (t *nonDeterministicTestingData) Less(i, j int) bool {
+	if i < 0 || j < 0 || i >= t.Len() || j >= t.Len() {
+		panic("nondeterministic comparison out of bounds")
+	}
+	return t.r.Float32() < 0.5
+}
+func (t *nonDeterministicTestingData) Swap(i, j int) {
+	if i < 0 || j < 0 || i >= t.Len() || j >= t.Len() {
+		panic("nondeterministic comparison out of bounds")
+	}
+}
+
+func TestNonDeterministicComparison(t *testing.T) {
+	// Ensure that sort.Sort does not panic when Less returns inconsistent results.
+	// See https://golang.org/issue/14377.
+	defer func() {
+		if r := recover(); r != nil {
+			t.Error(r)
+		}
+	}()
+
+	td := &nonDeterministicTestingData{
+		r: rand.New(rand.NewSource(0)),
+	}
+
+	for i := 0; i < 10; i++ {
+		Sort(td)
+	}
+}
+
 func BenchmarkSortString1K(b *testing.B) {
 	b.StopTimer()
 	for i := 0; i < b.N; i++ {
diff --git a/src/syscall/asm_linux_386.s b/src/syscall/asm_linux_386.s
index c940605..228a542 100644
--- a/src/syscall/asm_linux_386.s
+++ b/src/syscall/asm_linux_386.s
@@ -12,18 +12,9 @@
 // func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
 // Trap # in AX, args in BX CX DX SI DI, return in AX
 
-// Most linux systems use glibc's dynamic linker, which puts the
-// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
-// independent code and setldt in runtime does the same in the statically
-// linked case. Android, however, uses bionic's dynamic linker, which does not
-// save the helper anywhere, and so the only way to invoke a syscall from
-// position independent code is boring old int $0x80 (which is also what
-// bionic's syscall wrappers use).
-#ifdef GOOS_android
+// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
+// instead of the glibc-specific "CALL 0x10(GS)".
 #define INVOKE_SYSCALL	INT	$0x80
-#else
-#define INVOKE_SYSCALL	CALL	0x10(GS)
-#endif
 
 TEXT	·Syscall(SB),NOSPLIT,$0-28
 	CALL	runtime·entersyscall(SB)
diff --git a/src/syscall/types_linux.go b/src/syscall/types_linux.go
index cff4069..cb6836b 100644
--- a/src/syscall/types_linux.go
+++ b/src/syscall/types_linux.go
@@ -105,6 +105,9 @@ struct my_epoll_event {
 	// alignment requirements of EABI
 	int32_t padFd;
 #endif
+#ifdef  __powerpc64__
+	int32_t _padFd;
+#endif
 	int32_t fd;
 	int32_t pad;
 };
diff --git a/src/syscall/ztypes_linux_ppc64.go b/src/syscall/ztypes_linux_ppc64.go
index 33d1b7f..915ca95 100644
--- a/src/syscall/ztypes_linux_ppc64.go
+++ b/src/syscall/ztypes_linux_ppc64.go
@@ -574,9 +574,10 @@ type Ustat_t struct {
 }
 
 type EpollEvent struct {
-	Events uint32
-	Fd     int32
-	Pad    int32
+	Events  uint32
+	X_padFd int32
+	Fd      int32
+	Pad     int32
 }
 
 const (
diff --git a/src/syscall/ztypes_linux_ppc64le.go b/src/syscall/ztypes_linux_ppc64le.go
index 27ca004..a118055 100644
--- a/src/syscall/ztypes_linux_ppc64le.go
+++ b/src/syscall/ztypes_linux_ppc64le.go
@@ -574,9 +574,10 @@ type Ustat_t struct {
 }
 
 type EpollEvent struct {
-	Events uint32
-	Fd     int32
-	Pad    int32
+	Events  uint32
+	X_padFd int32
+	Fd      int32
+	Pad     int32
 }
 
 const (
diff --git a/test/escape_closure.go b/test/escape_closure.go
index 4cdb06e..f36073e 100644
--- a/test/escape_closure.go
+++ b/test/escape_closure.go
@@ -145,3 +145,29 @@ func ClosureCallArgs15() {
 		// BAD: p should not escape here
 	}(&p) // ERROR "&p escapes to heap" "\(func literal\)\(&p\) escapes to heap"
 }
+
+func ClosureLeak1(s string) string { // ERROR "ClosureLeak1 s does not escape"
+	t := s + "YYYY"         // ERROR "escapes to heap"
+	return ClosureLeak1a(t) // ERROR "ClosureLeak1 ... argument does not escape"
+}
+
+// See #14409 -- returning part of captured var leaks it.
+func ClosureLeak1a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
+	return func() string { // ERROR "ClosureLeak1a func literal does not escape"
+		return a[0]
+	}()
+}
+
+func ClosureLeak2(s string) string { // ERROR "ClosureLeak2 s does not escape"
+	t := s + "YYYY"       // ERROR "escapes to heap"
+	c := ClosureLeak2a(t) // ERROR "ClosureLeak2 ... argument does not escape"
+	return c
+}
+func ClosureLeak2a(a ...string) string { // ERROR "leaking param: a to result ~r1 level=1"
+	return ClosureLeak2b(func() string { // ERROR "ClosureLeak2a func literal does not escape"
+		return a[0]
+	})
+}
+func ClosureLeak2b(f func() string) string { // ERROR "leaking param: f to result ~r1 level=1"
+	return f()
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-golang/golang.git



More information about the pkg-golang-commits mailing list