v2 = n.List.Second()
}
- // n->list has no meaning anymore, clear it
+ // n.List has no meaning anymore, clear it
// to avoid erroneous processing by racewalk.
n.List.Set(nil)
n.Right.Ninit.Set1(a)
}
- // orderstmt allocated the iterator for us.
- // we only use a once, so no copy needed.
case TMAP:
+ // orderstmt allocated the iterator for us.
+ // we only use a once, so no copy needed.
ha := a
th := hiter(t)
body = []*Node{a}
}
- // orderstmt arranged for a copy of the channel variable.
case TCHAN:
+ // orderstmt arranged for a copy of the channel variable.
ha := a
n.Left = nil
} else {
body = []*Node{Nod(OAS, v1, hv1)}
}
+ // Zero hv1. This prevents hv1 from being the sole, inaccessible
+ // reference to an otherwise GC-able value during the next channel receive.
+ // See issue 15281.
+ body = append(body, Nod(OAS, hv1, nil))
- // orderstmt arranged for a copy of the string variable.
case TSTRING:
+ // orderstmt arranged for a copy of the string variable.
ha := a
ohv1 := temp(Types[TINT])
--- /dev/null
+// run
+
+// 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
+
+import "runtime"
+
+func main() {
+ {
+ x := inuse()
+ c := make(chan []byte, 10)
+ c <- make([]byte, 10<<20)
+ close(c)
+ f1(c, x)
+ }
+ {
+ x := inuse()
+ c := make(chan []byte, 10)
+ c <- make([]byte, 10<<20)
+ close(c)
+ f2(c, x)
+ }
+}
+
+func f1(c chan []byte, start int64) {
+ for x := range c {
+ if delta := inuse() - start; delta < 9<<20 {
+ println("BUG: f1: after alloc: expected delta at least 9MB, got: ", delta)
+ println(x)
+ }
+ x = nil
+ if delta := inuse() - start; delta > 1<<20 {
+ println("BUG: f1: after alloc: expected delta below 1MB, got: ", delta)
+ println(x)
+ }
+ }
+}
+
+func f2(c chan []byte, start int64) {
+ for {
+ x, ok := <-c
+ if !ok {
+ break
+ }
+ if delta := inuse() - start; delta < 9<<20 {
+ println("BUG: f2: after alloc: expected delta at least 9MB, got: ", delta)
+ println(x)
+ }
+ x = nil
+ if delta := inuse() - start; delta > 1<<20 {
+ println("BUG: f2: after alloc: expected delta below 1MB, got: ", delta)
+ println(x)
+ }
+ }
+}
+
+func inuse() int64 {
+ runtime.GC()
+ var st runtime.MemStats
+ runtime.ReadMemStats(&st)
+ return int64(st.Alloc)
+}