From 6454a09a97ff583bd81d59733777a000caf8b79a Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Wed, 5 Dec 2018 15:23:26 -0500 Subject: [PATCH] cmd/compile: omit write barriers for slice clears of go:notinheap pointers 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 TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/gc/range.go | 2 +- test/notinheap3.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index cbe69a1ebc..5c19d54e78 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -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) diff --git a/test/notinheap3.go b/test/notinheap3.go index d48c2a0cc9..5ace8d6793 100644 --- a/test/notinheap3.go +++ b/test/notinheap3.go @@ -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 + } +}