]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: []T where T is go:notinheap does not need write barriers
authorAustin Clements <austin@google.com>
Thu, 2 Nov 2017 16:37:25 +0000 (12:37 -0400)
committerAustin Clements <austin@google.com>
Mon, 6 Nov 2017 21:07:57 +0000 (21:07 +0000)
Currently, assigning a []T where T is a go:notinheap type generates an
unnecessary write barrier for storing the slice pointer.

This fixes this by teaching HasHeapPointer that this type does not
have a heap pointer, and tweaking the lowering of slice assignments so
the pointer store retains the correct type rather than simply lowering
it to a *uint8 store.

Change-Id: I8bf7c66e64a7fefdd14f2bd0de8a5a3596340bab
Reviewed-on: https://go-review.googlesource.com/76027
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/types/type.go
test/notinheap3.go

index 9e743c0874572fa6f5c4b284f189e629af6e4017..339c6be7a49add455d672d721c30b735a4364c9a 100644 (file)
@@ -3736,8 +3736,9 @@ func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
                ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, right)
                s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, s.f.Config.Types.BytePtr, left, ptr, s.mem())
        case t.IsSlice():
-               ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, right)
-               s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, s.f.Config.Types.BytePtr, left, ptr, s.mem())
+               elType := types.NewPtr(t.Elem())
+               ptr := s.newValue1(ssa.OpSlicePtr, elType, right)
+               s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, elType, left, ptr, s.mem())
        case t.IsInterface():
                // itab field is treated as a scalar.
                idata := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, right)
index 82829a11792378aff99479c55dfd92cde5b12327..44cdabcb30d5cfaa9a24e3ab27f369776b02f226 100644 (file)
@@ -1391,7 +1391,7 @@ func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
                }
                return false
 
-       case TPTR32, TPTR64:
+       case TPTR32, TPTR64, TSLICE:
                return !(ignoreNotInHeap && t.Elem().NotInHeap())
        }
 
index b37d73df6dd9fe0e7e6fd58f7821a759057ea277..d48c2a0cc974fab8d0a19a4b52c0b346354105fd 100644 (file)
@@ -10,11 +10,13 @@ package p
 
 type t1 struct {
        x *nih
+       s []nih
        y [1024]byte // Prevent write decomposition
 }
 
 type t2 struct {
        x *ih
+       s []ih
        y [1024]byte
 }
 
@@ -37,8 +39,10 @@ var (
 
 func f() {
        // Test direct writes
-       v1.x = nil // no barrier
-       v2.x = nil // ERROR "write barrier"
+       v1.x = nil        // no barrier
+       v2.x = nil        // ERROR "write barrier"
+       v1.s = []nih(nil) // no barrier
+       v2.s = []ih(nil)  // ERROR "write barrier"
 }
 
 func g() {