libgo: update to Go 1.15.3 release

Change-Id: Id414d567a1a57ca9529eb83c64fbfc4f16afafd1
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/265717
Trust: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/libgo/MERGE b/libgo/MERGE
index cfbf488..4b158c0 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-9706f510a5e2754595d716bd64be8375997311fb
+1984ee00048b63eacd2155cd6d74a2d13e998272
 
 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 c19def3..93c7b2d 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.15.2
+go1.15.3
diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go
index aa07b9f..ce52649 100644
--- a/libgo/go/bytes/bytes.go
+++ b/libgo/go/bytes/bytes.go
@@ -227,19 +227,26 @@
 			continue
 		}
 		r, width = utf8.DecodeRune(s[i:])
-		if r == utf8.RuneError {
-			for _, r = range chars {
-				if r == utf8.RuneError {
+		if r != utf8.RuneError {
+			// r is 2 to 4 bytes
+			if len(chars) == width {
+				if chars == string(r) {
 					return i
 				}
+				continue
 			}
-			continue
+			// Use bytealg.IndexString for performance if available.
+			if bytealg.MaxLen >= width {
+				if bytealg.IndexString(chars, string(r)) >= 0 {
+					return i
+				}
+				continue
+			}
 		}
-		// r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes
-		// package should not import the strings package, use bytealg.IndexString
-		// instead. And this does not seem to lose much performance.
-		if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 {
-			return i
+		for _, ch := range chars {
+			if r == ch {
+				return i
+			}
 		}
 	}
 	return -1
@@ -304,19 +311,26 @@
 		}
 		r, size := utf8.DecodeLastRune(s[:i])
 		i -= size
-		if r == utf8.RuneError {
-			for _, r = range chars {
-				if r == utf8.RuneError {
+		if r != utf8.RuneError {
+			// r is 2 to 4 bytes
+			if len(chars) == size {
+				if chars == string(r) {
 					return i
 				}
+				continue
 			}
-			continue
+			// Use bytealg.IndexString for performance if available.
+			if bytealg.MaxLen >= size {
+				if bytealg.IndexString(chars, string(r)) >= 0 {
+					return i
+				}
+				continue
+			}
 		}
-		// r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes
-		// package should not import the strings package, use bytealg.IndexString
-		// instead. And this does not seem to lose much performance.
-		if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 {
-			return i
+		for _, ch := range chars {
+			if r == ch {
+				return i
+			}
 		}
 	}
 	return -1
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go
index f774cbb..37bafcf 100644
--- a/libgo/go/cmd/cgo/gcc.go
+++ b/libgo/go/cmd/cgo/gcc.go
@@ -2459,6 +2459,18 @@
 			tt := *t
 			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
 			tt.Go = c.Ident("struct{}")
+			if dt.Kind == "struct" {
+				// We don't know what the representation of this struct is, so don't let
+				// anyone allocate one on the Go side. As a side effect of this annotation,
+				// pointers to this type will not be considered pointers in Go. They won't
+				// get writebarrier-ed or adjusted during a stack copy. This should handle
+				// all the cases badPointerTypedef used to handle, but hopefully will
+				// continue to work going forward without any more need for cgo changes.
+				tt.NotInHeap = true
+				// TODO: we should probably do the same for unions. Unions can't live
+				// on the Go heap, right? It currently doesn't work for unions because
+				// they are defined as a type alias for struct{}, not a defined type.
+			}
 			typedef[name.Name] = &tt
 			break
 		}
@@ -2529,6 +2541,7 @@
 		}
 		t.Go = name
 		t.BadPointer = sub.BadPointer
+		t.NotInHeap = sub.NotInHeap
 		if unionWithPointer[sub.Go] {
 			unionWithPointer[t.Go] = true
 		}
@@ -2539,6 +2552,7 @@
 			tt := *t
 			tt.Go = sub.Go
 			tt.BadPointer = sub.BadPointer
+			tt.NotInHeap = sub.NotInHeap
 			typedef[name.Name] = &tt
 		}
 
@@ -3047,6 +3061,7 @@
 // non-pointers in this type.
 // TODO: Currently our best solution is to find these manually and list them as
 // they come up. A better solution is desired.
+// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file.
 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
 	if c.badCFType(dt) {
 		return true
diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go
index 6de6d69..7fc2508 100644
--- a/libgo/go/cmd/cgo/main.go
+++ b/libgo/go/cmd/cgo/main.go
@@ -151,7 +151,8 @@
 	Go         ast.Expr
 	EnumValues map[string]int64
 	Typedef    string
-	BadPointer bool
+	BadPointer bool // this pointer type should be represented as a uintptr (deprecated)
+	NotInHeap  bool // this type should have a go:notinheap annotation
 }
 
 // A FuncType collects information about a function type in both the C and Go worlds.
diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go
index 1d23fc1..dd03f7d 100644
--- a/libgo/go/cmd/cgo/out.go
+++ b/libgo/go/cmd/cgo/out.go
@@ -113,6 +113,9 @@
 	sort.Strings(typedefNames)
 	for _, name := range typedefNames {
 		def := typedef[name]
+		if def.NotInHeap {
+			fmt.Fprintf(fgo2, "//go:notinheap\n")
+		}
 		fmt.Fprintf(fgo2, "type %s ", name)
 		// We don't have source info for these types, so write them out without source info.
 		// Otherwise types would look like:
diff --git a/libgo/go/cmd/go/internal/base/goflags.go b/libgo/go/cmd/go/internal/base/goflags.go
index 3476613..f29cc3c 100644
--- a/libgo/go/cmd/go/internal/base/goflags.go
+++ b/libgo/go/cmd/go/internal/base/goflags.go
@@ -153,3 +153,20 @@
 		}
 	}
 }
+
+// InGOFLAGS returns whether GOFLAGS contains the given flag, such as "-mod".
+func InGOFLAGS(flag string) bool {
+	for _, goflag := range GOFLAGS() {
+		name := goflag
+		if strings.HasPrefix(name, "--") {
+			name = name[1:]
+		}
+		if i := strings.Index(name, "="); i >= 0 {
+			name = name[:i]
+		}
+		if name == flag {
+			return true
+		}
+	}
+	return false
+}
diff --git a/libgo/go/cmd/go/internal/version/version.go b/libgo/go/cmd/go/internal/version/version.go
index ac2ae50..a5b1365 100644
--- a/libgo/go/cmd/go/internal/version/version.go
+++ b/libgo/go/cmd/go/internal/version/version.go
@@ -53,7 +53,14 @@
 
 func runVersion(cmd *base.Command, args []string) {
 	if len(args) == 0 {
-		if *versionM || *versionV {
+		// If any of this command's flags were passed explicitly, error
+		// out, because they only make sense with arguments.
+		//
+		// Don't error if the flags came from GOFLAGS, since that can be
+		// a reasonable use case. For example, imagine GOFLAGS=-v to
+		// turn "verbose mode" on for all Go commands, which should not
+		// break "go version".
+		if (!base.InGOFLAGS("-m") && *versionM) || (!base.InGOFLAGS("-v") && *versionV) {
 			fmt.Fprintf(os.Stderr, "go version: flags can only be used with arguments\n")
 			base.SetExitStatus(2)
 			return
diff --git a/libgo/go/cmd/go/internal/work/init.go b/libgo/go/cmd/go/internal/work/init.go
index dad3b10..c168364 100644
--- a/libgo/go/cmd/go/internal/work/init.go
+++ b/libgo/go/cmd/go/internal/work/init.go
@@ -254,34 +254,18 @@
 	case "":
 		// ok
 	case "readonly", "vendor", "mod":
-		if !cfg.ModulesEnabled && !inGOFLAGS("-mod") {
+		if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") {
 			base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
 		}
 	default:
 		base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod)
 	}
 	if !cfg.ModulesEnabled {
-		if cfg.ModCacheRW && !inGOFLAGS("-modcacherw") {
+		if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") {
 			base.Fatalf("build flag -modcacherw only valid when using modules")
 		}
-		if cfg.ModFile != "" && !inGOFLAGS("-mod") {
+		if cfg.ModFile != "" && !base.InGOFLAGS("-mod") {
 			base.Fatalf("build flag -modfile only valid when using modules")
 		}
 	}
 }
-
-func inGOFLAGS(flag string) bool {
-	for _, goflag := range base.GOFLAGS() {
-		name := goflag
-		if strings.HasPrefix(name, "--") {
-			name = name[1:]
-		}
-		if i := strings.Index(name, "="); i >= 0 {
-			name = name[:i]
-		}
-		if name == flag {
-			return true
-		}
-	}
-	return false
-}
diff --git a/libgo/go/cmd/go/testdata/script/version.txt b/libgo/go/cmd/go/testdata/script/version.txt
index 0123ac6..87cb6be 100644
--- a/libgo/go/cmd/go/testdata/script/version.txt
+++ b/libgo/go/cmd/go/testdata/script/version.txt
@@ -9,6 +9,12 @@
 ! go version -v
 stderr 'with arguments'
 
+# Neither of the two flags above should be an issue via GOFLAGS.
+env GOFLAGS='-m -v'
+go version
+stdout '^go version'
+env GOFLAGS=
+
 env GO111MODULE=on
 # Skip the builds below if we are running in short mode.
 [short] skip
diff --git a/libgo/go/internal/bytealg/index_generic.go b/libgo/go/internal/bytealg/index_generic.go
index 3dc1c6b..c595c23 100644
--- a/libgo/go/internal/bytealg/index_generic.go
+++ b/libgo/go/internal/bytealg/index_generic.go
@@ -17,42 +17,8 @@
 
 // IndexString returns the index of the first instance of b in a, or -1 if b is not present in a.
 // Requires 2 <= len(b) <= MaxLen.
-func IndexString(s, substr string) int {
-	// This is a partial copy of strings.Index, here because bytes.IndexAny and bytes.LastIndexAny
-	// call bytealg.IndexString. Some platforms have an optimized assembly version of this function.
-	// This implementation is used for those that do not. Although the pure Go implementation here
-	// works for the case of len(b) > MaxLen, we do not require that its assembly implementation also
-	// supports the case of len(b) > MaxLen. And we do not guarantee that this function supports the
-	// case of len(b) > MaxLen.
-	n := len(substr)
-	c0 := substr[0]
-	c1 := substr[1]
-	i := 0
-	t := len(s) - n + 1
-	fails := 0
-	for i < t {
-		if s[i] != c0 {
-			o := IndexByteString(s[i:t], c0)
-			if o < 0 {
-				return -1
-			}
-			i += o
-		}
-		if s[i+1] == c1 && s[i:i+n] == substr {
-			return i
-		}
-		i++
-		fails++
-		if fails >= 4+i>>4 && i < t {
-			// See comment in src/bytes/bytes.go.
-			j := IndexRabinKarp(s[i:], substr)
-			if j < 0 {
-				return -1
-			}
-			return i + j
-		}
-	}
-	return -1
+func IndexString(a, b string) int {
+	panic("unimplemented")
 }
 
 // Cutover reports the number of failures of IndexByte we should tolerate
diff --git a/libgo/go/internal/poll/fd_unix.go b/libgo/go/internal/poll/fd_unix.go
index f177ccf..10cf173 100644
--- a/libgo/go/internal/poll/fd_unix.go
+++ b/libgo/go/internal/poll/fd_unix.go
@@ -152,7 +152,7 @@
 		p = p[:maxRW]
 	}
 	for {
-		n, err := ignoringEINTR(syscall.Read, fd.Sysfd, p)
+		n, err := ignoringEINTR(func() (int, error) { return syscall.Read(fd.Sysfd, p) })
 		if err != nil {
 			n = 0
 			if err == syscall.EAGAIN && fd.pd.pollable() {
@@ -264,7 +264,7 @@
 		if fd.IsStream && max-nn > maxRW {
 			max = nn + maxRW
 		}
-		n, err := ignoringEINTR(syscall.Write, fd.Sysfd, p[nn:max])
+		n, err := ignoringEINTR(func() (int, error) { return syscall.Write(fd.Sysfd, p[nn:max]) })
 		if n > 0 {
 			nn += n
 		}
@@ -423,7 +423,7 @@
 	}
 	defer fd.decref()
 	for {
-		n, err := ignoringEINTR(syscall.ReadDirent, fd.Sysfd, buf)
+		n, err := ignoringEINTR(func() (int, error) { return syscall.ReadDirent(fd.Sysfd, buf) })
 		if err != nil {
 			n = 0
 			if err == syscall.EAGAIN && fd.pd.pollable() {
@@ -514,7 +514,7 @@
 		return 0, err
 	}
 	defer fd.writeUnlock()
-	return ignoringEINTR(syscall.Write, fd.Sysfd, p)
+	return ignoringEINTR(func() (int, error) { return syscall.Write(fd.Sysfd, p) })
 }
 
 // RawRead invokes the user-defined function f for a read operation.
@@ -562,9 +562,9 @@
 // installed without setting SA_RESTART. None of these are the common case,
 // but there are enough of them that it seems that we can't avoid
 // an EINTR loop.
-func ignoringEINTR(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) {
+func ignoringEINTR(fn func() (int, error)) (int, error) {
 	for {
-		n, err := fn(fd, p)
+		n, err := fn()
 		if err != syscall.EINTR {
 			return n, err
 		}
diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go
index de1d80a..b909d47 100644
--- a/libgo/go/runtime/chan.go
+++ b/libgo/go/runtime/chan.go
@@ -267,6 +267,11 @@
 	gp.waiting = mysg
 	gp.param = nil
 	c.sendq.enqueue(mysg)
+	// Signal to anyone trying to shrink our stack that we're about
+	// to park on a channel. The window between when this G's status
+	// changes and when we set gp.activeStackChans is not safe for
+	// stack shrinking.
+	atomic.Store8(&gp.parkingOnChan, 1)
 	gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanSend, traceEvGoBlockSend, 2)
 	// Ensure the value being sent is kept alive until the
 	// receiver copies it out. The sudog has a pointer to the
@@ -586,6 +591,11 @@
 	mysg.c = c
 	gp.param = nil
 	c.recvq.enqueue(mysg)
+	// Signal to anyone trying to shrink our stack that we're about
+	// to park on a channel. The window between when this G's status
+	// changes and when we set gp.activeStackChans is not safe for
+	// stack shrinking.
+	atomic.Store8(&gp.parkingOnChan, 1)
 	gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanReceive, traceEvGoBlockRecv, 2)
 
 	// someone woke us up
@@ -663,7 +673,19 @@
 func chanparkcommit(gp *g, chanLock unsafe.Pointer) bool {
 	// There are unlocked sudogs that point into gp's stack. Stack
 	// copying must lock the channels of those sudogs.
+	// Set activeStackChans here instead of before we try parking
+	// because we could self-deadlock in stack growth on the
+	// channel lock.
 	gp.activeStackChans = true
+	// Mark that it's safe for stack shrinking to occur now,
+	// because any thread acquiring this G's stack for shrinking
+	// is guaranteed to observe activeStackChans after this store.
+	atomic.Store8(&gp.parkingOnChan, 0)
+	// Make sure we unlock after setting activeStackChans and
+	// unsetting parkingOnChan. The moment we unlock chanLock
+	// we risk gp getting readied by a channel operation and
+	// so gp could continue running before everything before
+	// the unlock is visible (even to gp itself).
 	unlock((*mutex)(chanLock))
 	return true
 }
diff --git a/libgo/go/runtime/chan_test.go b/libgo/go/runtime/chan_test.go
index ac81d40..85d3e04 100644
--- a/libgo/go/runtime/chan_test.go
+++ b/libgo/go/runtime/chan_test.go
@@ -628,6 +628,62 @@
 	<-done
 }
 
+func TestNoShrinkStackWhileParking(t *testing.T) {
+	// The goal of this test is to trigger a "racy sudog adjustment"
+	// throw. Basically, there's a window between when a goroutine
+	// becomes available for preemption for stack scanning (and thus,
+	// stack shrinking) but before the goroutine has fully parked on a
+	// channel. See issue 40641 for more details on the problem.
+	//
+	// The way we try to induce this failure is to set up two
+	// goroutines: a sender and a reciever that communicate across
+	// a channel. We try to set up a situation where the sender
+	// grows its stack temporarily then *fully* blocks on a channel
+	// often. Meanwhile a GC is triggered so that we try to get a
+	// mark worker to shrink the sender's stack and race with the
+	// sender parking.
+	//
+	// Unfortunately the race window here is so small that we
+	// either need a ridiculous number of iterations, or we add
+	// "usleep(1000)" to park_m, just before the unlockf call.
+	const n = 10
+	send := func(c chan<- int, done chan struct{}) {
+		for i := 0; i < n; i++ {
+			c <- i
+			// Use lots of stack briefly so that
+			// the GC is going to want to shrink us
+			// when it scans us. Make sure not to
+			// do any function calls otherwise
+			// in order to avoid us shrinking ourselves
+			// when we're preempted.
+			stackGrowthRecursive(20)
+		}
+		done <- struct{}{}
+	}
+	recv := func(c <-chan int, done chan struct{}) {
+		for i := 0; i < n; i++ {
+			// Sleep here so that the sender always
+			// fully blocks.
+			time.Sleep(10 * time.Microsecond)
+			<-c
+		}
+		done <- struct{}{}
+	}
+	for i := 0; i < n*20; i++ {
+		c := make(chan int)
+		done := make(chan struct{})
+		go recv(c, done)
+		go send(c, done)
+		// Wait a little bit before triggering
+		// the GC to make sure the sender and
+		// reciever have gotten into their groove.
+		time.Sleep(50 * time.Microsecond)
+		runtime.GC()
+		<-done
+		<-done
+	}
+}
+
 func TestSelectDuplicateChannel(t *testing.T) {
 	// This test makes sure we can queue a G on
 	// the same channel multiple times.
diff --git a/libgo/go/runtime/export_test.go b/libgo/go/runtime/export_test.go
index 482d014..369230a 100644
--- a/libgo/go/runtime/export_test.go
+++ b/libgo/go/runtime/export_test.go
@@ -355,7 +355,11 @@
 		}
 
 		for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
-			pg := mheap_.pages.chunkOf(i).scavenged.popcntRange(0, pallocChunkPages)
+			chunk := mheap_.pages.tryChunkOf(i)
+			if chunk == nil {
+				continue
+			}
+			pg := chunk.scavenged.popcntRange(0, pallocChunkPages)
 			slow.HeapReleased += uint64(pg) * pageSize
 		}
 		for _, p := range allp {
@@ -752,11 +756,7 @@
 // Returns nil if the PallocData's L2 is missing.
 func (p *PageAlloc) PallocData(i ChunkIdx) *PallocData {
 	ci := chunkIdx(i)
-	l2 := (*pageAlloc)(p).chunks[ci.l1()]
-	if l2 == nil {
-		return nil
-	}
-	return (*PallocData)(&l2[ci.l2()])
+	return (*PallocData)((*pageAlloc)(p).tryChunkOf(ci))
 }
 
 // AddrRange represents a range over addresses.
@@ -896,7 +896,10 @@
 		lock(&mheap_.lock)
 	chunkLoop:
 		for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
-			chunk := mheap_.pages.chunkOf(i)
+			chunk := mheap_.pages.tryChunkOf(i)
+			if chunk == nil {
+				continue
+			}
 			for j := 0; j < pallocChunkPages/64; j++ {
 				// Run over each 64-bit bitmap section and ensure
 				// scavenged is being cleared properly on allocation.
@@ -977,10 +980,9 @@
 }
 
 func MSpanCountAlloc(bits []byte) int {
-	s := mspan{
-		nelems:     uintptr(len(bits) * 8),
-		gcmarkBits: (*gcBits)(unsafe.Pointer(&bits[0])),
-	}
+	s := (*mspan)(mheap_.spanalloc.alloc())
+	s.nelems = uintptr(len(bits) * 8)
+	s.gcmarkBits = (*gcBits)(unsafe.Pointer(&bits[0]))
 	return s.countAlloc()
 }
 
diff --git a/libgo/go/runtime/internal/atomic/atomic_test.go b/libgo/go/runtime/internal/atomic/atomic_test.go
index 0c1125c..b0a8fa0 100644
--- a/libgo/go/runtime/internal/atomic/atomic_test.go
+++ b/libgo/go/runtime/internal/atomic/atomic_test.go
@@ -220,3 +220,13 @@
 		}
 	}
 }
+
+func TestStorepNoWB(t *testing.T) {
+	var p [2]*int
+	for i := range p {
+		atomic.StorepNoWB(unsafe.Pointer(&p[i]), unsafe.Pointer(new(int)))
+	}
+	if p[0] == p[1] {
+		t.Error("Bad escape analysis of StorepNoWB")
+	}
+}
diff --git a/libgo/go/runtime/mpagealloc.go b/libgo/go/runtime/mpagealloc.go
index 8b3c62c..c90a637 100644
--- a/libgo/go/runtime/mpagealloc.go
+++ b/libgo/go/runtime/mpagealloc.go
@@ -326,7 +326,20 @@
 	s.scav.scavLWM = maxSearchAddr
 }
 
+// tryChunkOf returns the bitmap data for the given chunk.
+//
+// Returns nil if the chunk data has not been mapped.
+func (s *pageAlloc) tryChunkOf(ci chunkIdx) *pallocData {
+	l2 := s.chunks[ci.l1()]
+	if l2 == nil {
+		return nil
+	}
+	return &l2[ci.l2()]
+}
+
 // chunkOf returns the chunk at the given chunk index.
+//
+// The chunk index must be valid or this method may throw.
 func (s *pageAlloc) chunkOf(ci chunkIdx) *pallocData {
 	return &s.chunks[ci.l1()][ci.l2()]
 }
diff --git a/libgo/go/runtime/proc_test.go b/libgo/go/runtime/proc_test.go
index b9828d9..a8f0dc3 100644
--- a/libgo/go/runtime/proc_test.go
+++ b/libgo/go/runtime/proc_test.go
@@ -529,9 +529,17 @@
 	<-done
 }
 
+var padData [128]uint64
+
 func stackGrowthRecursive(i int) {
 	var pad [128]uint64
-	if i != 0 && pad[0] == 0 {
+	pad = padData
+	for j := range pad {
+		if pad[j] != 0 {
+			return
+		}
+	}
+	if i != 0 {
 		stackGrowthRecursive(i - 1)
 	}
 }
diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go
index 5029dba..bf3fbac 100644
--- a/libgo/go/runtime/runtime2.go
+++ b/libgo/go/runtime/runtime2.go
@@ -450,6 +450,10 @@
 	// copying needs to acquire channel locks to protect these
 	// areas of the stack.
 	activeStackChans bool
+	// parkingOnChan indicates that the goroutine is about to
+	// park on a chansend or chanrecv. Used to signal an unsafe point
+	// for stack shrinking. It's a boolean value, but is updated atomically.
+	parkingOnChan uint8
 
 	raceignore     int8     // ignore race detection events
 	sysblocktraced bool     // StartTrace has emitted EvGoInSyscall about this goroutine
@@ -940,11 +944,6 @@
 
 // panics
 // This is the gccgo version.
-//
-// This is marked go:notinheap because _panic values must only ever
-// live on the stack.
-//
-//go:notinheap
 type _panic struct {
 	// The next entry in the stack.
 	link *_panic
diff --git a/libgo/go/runtime/select.go b/libgo/go/runtime/select.go
index cf5d0c7..c8910b8 100644
--- a/libgo/go/runtime/select.go
+++ b/libgo/go/runtime/select.go
@@ -7,6 +7,7 @@
 // This file contains the implementation of Go select statements.
 
 import (
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -72,7 +73,20 @@
 func selparkcommit(gp *g, _ unsafe.Pointer) bool {
 	// There are unlocked sudogs that point into gp's stack. Stack
 	// copying must lock the channels of those sudogs.
+	// Set activeStackChans here instead of before we try parking
+	// because we could self-deadlock in stack growth on a
+	// channel lock.
 	gp.activeStackChans = true
+	// Mark that it's safe for stack shrinking to occur now,
+	// because any thread acquiring this G's stack for shrinking
+	// is guaranteed to observe activeStackChans after this store.
+	atomic.Store8(&gp.parkingOnChan, 0)
+	// Make sure we unlock after setting activeStackChans and
+	// unsetting parkingOnChan. The moment we unlock any of the
+	// channel locks we risk gp getting readied by a channel operation
+	// and so gp could continue running before everything before the
+	// unlock is visible (even to gp itself).
+
 	// This must not access gp's stack (see gopark). In
 	// particular, it must not access the *hselect. That's okay,
 	// because by the time this is called, gp.waiting has all
@@ -313,6 +327,11 @@
 
 	// wait for someone to wake us up
 	gp.param = nil
+	// Signal to anyone trying to shrink our stack that we're about
+	// to park on a channel. The window between when this G's status
+	// changes and when we set gp.activeStackChans is not safe for
+	// stack shrinking.
+	atomic.Store8(&gp.parkingOnChan, 1)
 	gopark(selparkcommit, nil, waitReasonSelect, traceEvGoBlockSelect, 1)
 	gp.activeStackChans = false
 
diff --git a/libgo/go/runtime/trace/trace_stack_test.go b/libgo/go/runtime/trace/trace_stack_test.go
index cfc0419..f856fdc 100644
--- a/libgo/go/runtime/trace/trace_stack_test.go
+++ b/libgo/go/runtime/trace/trace_stack_test.go
@@ -252,6 +252,7 @@
 			{trace.EvGoSysCall, []frame{
 				{"syscall.read", 0},
 				{"syscall.Read", 0},
+				{"internal/poll.(*FD).Read.func1", 0},
 				{"internal/poll.ignoringEINTR", 0},
 				{"internal/poll.(*FD).Read", 0},
 				{"os.(*File).read", 0},
diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go
index 5276600..e9687bf 100644
--- a/libgo/go/testing/benchmark.go
+++ b/libgo/go/testing/benchmark.go
@@ -242,7 +242,7 @@
 		if b.skipped {
 			tag = "SKIP"
 		}
-		if b.chatty && (len(b.output) > 0 || b.finished) {
+		if b.chatty != nil && (len(b.output) > 0 || b.finished) {
 			b.trimOutput()
 			fmt.Fprintf(b.w, "--- %s: %s\n%s", tag, b.name, b.output)
 		}
@@ -523,10 +523,9 @@
 	}
 	main := &B{
 		common: common{
-			name:   "Main",
-			w:      os.Stdout,
-			chatty: *chatty,
-			bench:  true,
+			name:  "Main",
+			w:     os.Stdout,
+			bench: true,
 		},
 		importPath: importPath,
 		benchFunc: func(b *B) {
@@ -537,6 +536,9 @@
 		benchTime: benchTime,
 		context:   ctx,
 	}
+	if Verbose() {
+		main.chatty = newChattyPrinter(main.w)
+	}
 	main.runN(1)
 	return !main.failed
 }
@@ -549,7 +551,7 @@
 			benchName := benchmarkName(b.name, procs)
 
 			// If it's chatty, we've already printed this information.
-			if !b.chatty {
+			if b.chatty == nil {
 				fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName)
 			}
 			// Recompute the running time for all but the first iteration.
@@ -576,7 +578,7 @@
 				continue
 			}
 			results := r.String()
-			if b.chatty {
+			if b.chatty != nil {
 				fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName)
 			}
 			if *benchmarkMemory || b.showAllocResult {
@@ -639,7 +641,7 @@
 		atomic.StoreInt32(&sub.hasSub, 1)
 	}
 
-	if b.chatty {
+	if b.chatty != nil {
 		labelsOnce.Do(func() {
 			fmt.Printf("goos: %s\n", runtime.GOOS)
 			fmt.Printf("goarch: %s\n", runtime.GOARCH)
diff --git a/libgo/go/testing/sub_test.go b/libgo/go/testing/sub_test.go
index 8eb0084..5ed3fc4 100644
--- a/libgo/go/testing/sub_test.go
+++ b/libgo/go/testing/sub_test.go
@@ -483,10 +483,12 @@
 					signal: make(chan bool),
 					name:   "Test",
 					w:      buf,
-					chatty: tc.chatty,
 				},
 				context: ctx,
 			}
+			if tc.chatty {
+				root.chatty = newChattyPrinter(root.w)
+			}
 			ok := root.Run(tc.desc, tc.f)
 			ctx.release()
 
@@ -665,11 +667,13 @@
 					signal: make(chan bool),
 					name:   "root",
 					w:      buf,
-					chatty: tc.chatty,
 				},
 				benchFunc: func(b *B) { ok = b.Run("test", tc.f) }, // Use Run to catch failure.
 				benchTime: benchTimeFlag{d: 1 * time.Microsecond},
 			}
+			if tc.chatty {
+				root.chatty = newChattyPrinter(root.w)
+			}
 			root.runN(1)
 			if ok != !tc.failed {
 				t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, !tc.failed)
@@ -741,9 +745,13 @@
 	}
 }
 
-type funcWriter func([]byte) (int, error)
+type funcWriter struct {
+	write func([]byte) (int, error)
+}
 
-func (fw funcWriter) Write(b []byte) (int, error) { return fw(b) }
+func (fw *funcWriter) Write(b []byte) (int, error) {
+	return fw.write(b)
+}
 
 func TestRacyOutput(t *T) {
 	var runs int32  // The number of running Writes
@@ -761,9 +769,10 @@
 
 	var wg sync.WaitGroup
 	root := &T{
-		common:  common{w: funcWriter(raceDetector), chatty: true},
+		common:  common{w: &funcWriter{raceDetector}},
 		context: newTestContext(1, newMatcher(regexp.MatchString, "", "")),
 	}
+	root.chatty = newChattyPrinter(root.w)
 	root.Run("", func(t *T) {
 		for i := 0; i < 100; i++ {
 			wg.Add(1)
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index fe6929d..80282fc 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -325,7 +325,6 @@
 	cpuListStr           *string
 	parallel             *int
 	testlog              *string
-	printer              *testPrinter
 
 	haveExamples bool // are there examples?
 
@@ -335,55 +334,45 @@
 	numFailed uint32 // number of test failures
 )
 
-type testPrinter struct {
-	chatty bool
-
+type chattyPrinter struct {
+	w          io.Writer
 	lastNameMu sync.Mutex // guards lastName
 	lastName   string     // last printed test name in chatty mode
 }
 
-func newTestPrinter(chatty bool) *testPrinter {
-	return &testPrinter{
-		chatty: chatty,
-	}
+func newChattyPrinter(w io.Writer) *chattyPrinter {
+	return &chattyPrinter{w: w}
 }
 
-func (p *testPrinter) Print(testName, out string) {
-	p.Fprint(os.Stdout, testName, out)
-}
-
-func (p *testPrinter) Fprint(w io.Writer, testName, out string) {
+// Updatef prints a message about the status of the named test to w.
+//
+// The formatted message must include the test name itself.
+func (p *chattyPrinter) Updatef(testName, format string, args ...interface{}) {
 	p.lastNameMu.Lock()
 	defer p.lastNameMu.Unlock()
 
-	if !p.chatty ||
-		strings.HasPrefix(out, "--- PASS: ") ||
-		strings.HasPrefix(out, "--- FAIL: ") ||
-		strings.HasPrefix(out, "--- SKIP: ") ||
-		strings.HasPrefix(out, "=== RUN   ") ||
-		strings.HasPrefix(out, "=== CONT  ") ||
-		strings.HasPrefix(out, "=== PAUSE ") {
-		// If we're buffering test output (!p.chatty), we don't really care which
-		// test is emitting which line so long as they are serialized.
-		//
-		// If the message already implies an association with a specific new test,
-		// we don't need to check what the old test name was or log an extra CONT
-		// line for it. (We're updating it anyway, and the current message already
-		// includes the test name.)
-		p.lastName = testName
-		fmt.Fprint(w, out)
-		return
-	}
+	// Since the message already implies an association with a specific new test,
+	// we don't need to check what the old test name was or log an extra CONT line
+	// for it. (We're updating it anyway, and the current message already includes
+	// the test name.)
+	p.lastName = testName
+	fmt.Fprintf(p.w, format, args...)
+}
+
+// Printf prints a message, generated by the named test, that does not
+// necessarily mention that tests's name itself.
+func (p *chattyPrinter) Printf(testName, format string, args ...interface{}) {
+	p.lastNameMu.Lock()
+	defer p.lastNameMu.Unlock()
 
 	if p.lastName == "" {
 		p.lastName = testName
 	} else if p.lastName != testName {
-		// Always printed as-is, with 0 decoration or indentation. So, we skip
-		// printing to w.
-		fmt.Printf("=== CONT  %s\n", testName)
+		fmt.Fprintf(p.w, "=== CONT  %s\n", testName)
 		p.lastName = testName
 	}
-	fmt.Fprint(w, out)
+
+	fmt.Fprintf(p.w, format, args...)
 }
 
 // The maximum number of stack frames to go through when skipping helper functions for
@@ -405,12 +394,12 @@
 	cleanupName string              // Name of the cleanup function.
 	cleanupPc   []uintptr           // The stack trace at the point where Cleanup was called.
 
-	chatty     bool   // A copy of the chatty flag.
-	bench      bool   // Whether the current test is a benchmark.
-	finished   bool   // Test function has completed.
-	hasSub     int32  // Written atomically.
-	raceErrors int    // Number of races detected during test.
-	runner     string // Function name of tRunner running the test.
+	chatty     *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
+	bench      bool           // Whether the current test is a benchmark.
+	finished   bool           // Test function has completed.
+	hasSub     int32          // Written atomically.
+	raceErrors int            // Number of races detected during test.
+	runner     string         // Function name of tRunner running the test.
 
 	parent   *common
 	level    int       // Nesting depth of test or benchmark.
@@ -572,12 +561,31 @@
 	p.mu.Lock()
 	defer p.mu.Unlock()
 
-	printer.Fprint(p.w, testName, fmt.Sprintf(format, args...))
-
 	c.mu.Lock()
 	defer c.mu.Unlock()
-	io.Copy(p.w, bytes.NewReader(c.output))
-	c.output = c.output[:0]
+
+	if len(c.output) > 0 {
+		format += "%s"
+		args = append(args[:len(args):len(args)], c.output)
+		c.output = c.output[:0] // but why?
+	}
+
+	if c.chatty != nil && p.w == c.chatty.w {
+		// We're flushing to the actual output, so track that this output is
+		// associated with a specific test (and, specifically, that the next output
+		// is *not* associated with that test).
+		//
+		// Moreover, if c.output is non-empty it is important that this write be
+		// atomic with respect to the output of other tests, so that we don't end up
+		// with confusing '=== CONT' lines in the middle of our '--- PASS' block.
+		// Neither humans nor cmd/test2json can parse those easily.
+		// (See https://golang.org/issue/40771.)
+		c.chatty.Updatef(testName, format, args...)
+	} else {
+		// We're flushing to the output buffer of the parent test, which will
+		// itself follow a test-name header when it is finally flushed to stdout.
+		fmt.Fprintf(p.w, format, args...)
+	}
 }
 
 type indenter struct {
@@ -746,13 +754,13 @@
 		}
 		panic("Log in goroutine after " + c.name + " has completed")
 	} else {
-		if c.chatty {
+		if c.chatty != nil {
 			if c.bench {
 				// Benchmarks don't print === CONT, so we should skip the test
 				// printer and just print straight to stdout.
 				fmt.Print(c.decorate(s, depth+1))
 			} else {
-				printer.Print(c.name, c.decorate(s, depth+1))
+				c.chatty.Printf(c.name, "%s", c.decorate(s, depth+1))
 			}
 
 			return
@@ -1019,34 +1027,22 @@
 	t.parent.sub = append(t.parent.sub, t)
 	t.raceErrors += race.Errors()
 
-	if t.chatty {
-		// Print directly to root's io.Writer so there is no delay.
-		root := t.parent
-		for ; root.parent != nil; root = root.parent {
-		}
-		root.mu.Lock()
+	if t.chatty != nil {
 		// Unfortunately, even though PAUSE indicates that the named test is *no
 		// longer* running, cmd/test2json interprets it as changing the active test
 		// for the purpose of log parsing. We could fix cmd/test2json, but that
 		// won't fix existing deployments of third-party tools that already shell
 		// out to older builds of cmd/test2json — so merely fixing cmd/test2json
 		// isn't enough for now.
-		printer.Fprint(root.w, t.name, fmt.Sprintf("=== PAUSE %s\n", t.name))
-		root.mu.Unlock()
+		t.chatty.Updatef(t.name, "=== PAUSE %s\n", t.name)
 	}
 
 	t.signal <- true   // Release calling test.
 	<-t.parent.barrier // Wait for the parent test to complete.
 	t.context.waitParallel()
 
-	if t.chatty {
-		// Print directly to root's io.Writer so there is no delay.
-		root := t.parent
-		for ; root.parent != nil; root = root.parent {
-		}
-		root.mu.Lock()
-		printer.Fprint(root.w, t.name, fmt.Sprintf("=== CONT  %s\n", t.name))
-		root.mu.Unlock()
+	if t.chatty != nil {
+		t.chatty.Updatef(t.name, "=== CONT  %s\n", t.name)
 	}
 
 	t.start = time.Now()
@@ -1197,14 +1193,8 @@
 	}
 	t.w = indenter{&t.common}
 
-	if t.chatty {
-		// Print directly to root's io.Writer so there is no delay.
-		root := t.parent
-		for ; root.parent != nil; root = root.parent {
-		}
-		root.mu.Lock()
-		printer.Fprint(root.w, t.name, fmt.Sprintf("=== RUN   %s\n", t.name))
-		root.mu.Unlock()
+	if t.chatty != nil {
+		t.chatty.Updatef(t.name, "=== RUN   %s\n", t.name)
 	}
 	// Instead of reducing the running count of this test before calling the
 	// tRunner and increasing it afterwards, we rely on tRunner keeping the
@@ -1369,8 +1359,6 @@
 		flag.Parse()
 	}
 
-	printer = newTestPrinter(Verbose())
-
 	if *parallel < 1 {
 		fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
 		flag.Usage()
@@ -1415,7 +1403,7 @@
 	format := "--- %s: %s (%s)\n"
 	if t.Failed() {
 		t.flushToParent(t.name, format, "FAIL", t.name, dstr)
-	} else if t.chatty {
+	} else if t.chatty != nil {
 		if t.Skipped() {
 			t.flushToParent(t.name, format, "SKIP", t.name, dstr)
 		} else {
@@ -1476,10 +1464,12 @@
 					signal:  make(chan bool),
 					barrier: make(chan bool),
 					w:       os.Stdout,
-					chatty:  *chatty,
 				},
 				context: ctx,
 			}
+			if Verbose() {
+				t.chatty = newChattyPrinter(t.w)
+			}
 			tRunner(t, func(t *T) {
 				for _, test := range tests {
 					t.Run(test.Name, test.F)
diff --git a/libgo/misc/cgo/test/testdata/issue41761.go b/libgo/misc/cgo/test/testdata/issue41761.go
new file mode 100644
index 0000000..919c749
--- /dev/null
+++ b/libgo/misc/cgo/test/testdata/issue41761.go
@@ -0,0 +1,20 @@
+// Copyright 2020 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 cgotest
+
+/*
+   typedef struct S S;
+*/
+import "C"
+
+import (
+	"cgotest/issue41761a"
+	"testing"
+)
+
+func test41761(t *testing.T) {
+	var x issue41761a.T
+	_ = (*C.struct_S)(x.X)
+}
diff --git a/libgo/misc/cgo/test/testdata/issue41761a/a.go b/libgo/misc/cgo/test/testdata/issue41761a/a.go
new file mode 100644
index 0000000..ca5c181
--- /dev/null
+++ b/libgo/misc/cgo/test/testdata/issue41761a/a.go
@@ -0,0 +1,14 @@
+// Copyright 2020 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 issue41761a
+
+/*
+   typedef struct S S;
+*/
+import "C"
+
+type T struct {
+	X *C.S
+}