]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: omit write barriers for slice clears of go:notinheap pointers
authorAustin Clements <austin@google.com>
Wed, 5 Dec 2018 20:23:26 +0000 (15:23 -0500)
committerAustin Clements <austin@google.com>
Wed, 5 Dec 2018 21:54:54 +0000 (21:54 +0000)
Currently,

  for i := range a {
    a[i] = nil
  }

will compile to have write barriers even if a is a slice of pointers
to go:notinheap types. This happens because the optimization that
transforms this into a memclr only asks it a's element type has
pointers, and not if it specifically has heap pointers.

Fix this by changing arrayClear to use HasHeapPointer instead of
types.Haspointers. We probably shouldn't have both of these functions,
since a pointer to a notinheap type is effectively a uintptr, but
that's not going to change in this CL.

Change-Id: I284b85bdec6ae1e641f894e8f577989facdb0cf1
Reviewed-on: https://go-review.googlesource.com/c/152723
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/range.go
test/notinheap3.go

index cbe69a1ebc16fdff770fd4637bbc90dc1671bbce..5c19d54e78d997bbd3a1e92aa72d75612b9d6fc2 100644 (file)
@@ -586,7 +586,7 @@ func arrayClear(n, v1, v2, a *Node) bool {
        n.Nbody.Append(nod(OAS, hn, tmp))
 
        var fn *Node
-       if types.Haspointers(a.Type.Elem()) {
+       if a.Type.Elem().HasHeapPointer() {
                // memclrHasPointers(hp, hn)
                Curfn.Func.setWBPos(stmt.Pos)
                fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
index d48c2a0cc974fab8d0a19a4b52c0b346354105fd..5ace8d6793f21bdb87252f7425143fd31f9b454c 100644 (file)
@@ -58,3 +58,19 @@ func h() {
        _ = append(v1s, v1s...) // no barrier
        _ = append(v2s, v2s...) // ERROR "write barrier"
 }
+
+// Slice clearing
+
+var (
+       sliceIH  []*ih
+       sliceNIH []*nih
+)
+
+func sliceClear() {
+       for i := range sliceIH {
+               sliceIH[i] = nil // ERROR "write barrier"
+       }
+       for i := range sliceNIH {
+               sliceNIH[i] = nil // no barrier
+       }
+}