mirror of
https://github.com/golang/go
synced 2024-11-26 21:21:34 -07:00
cmd/compile: []T where T is go:notinheap does not need write barriers
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>
This commit is contained in:
parent
0838c0f2f9
commit
3a446d8652
@ -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)
|
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())
|
s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, s.f.Config.Types.BytePtr, left, ptr, s.mem())
|
||||||
case t.IsSlice():
|
case t.IsSlice():
|
||||||
ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, right)
|
elType := types.NewPtr(t.Elem())
|
||||||
s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, s.f.Config.Types.BytePtr, left, ptr, s.mem())
|
ptr := s.newValue1(ssa.OpSlicePtr, elType, right)
|
||||||
|
s.vars[&memVar] = s.newValue3A(ssa.OpStore, types.TypeMem, elType, left, ptr, s.mem())
|
||||||
case t.IsInterface():
|
case t.IsInterface():
|
||||||
// itab field is treated as a scalar.
|
// itab field is treated as a scalar.
|
||||||
idata := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, right)
|
idata := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, right)
|
||||||
|
@ -1391,7 +1391,7 @@ func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case TPTR32, TPTR64:
|
case TPTR32, TPTR64, TSLICE:
|
||||||
return !(ignoreNotInHeap && t.Elem().NotInHeap())
|
return !(ignoreNotInHeap && t.Elem().NotInHeap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,13 @@ package p
|
|||||||
|
|
||||||
type t1 struct {
|
type t1 struct {
|
||||||
x *nih
|
x *nih
|
||||||
|
s []nih
|
||||||
y [1024]byte // Prevent write decomposition
|
y [1024]byte // Prevent write decomposition
|
||||||
}
|
}
|
||||||
|
|
||||||
type t2 struct {
|
type t2 struct {
|
||||||
x *ih
|
x *ih
|
||||||
|
s []ih
|
||||||
y [1024]byte
|
y [1024]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +41,8 @@ func f() {
|
|||||||
// Test direct writes
|
// Test direct writes
|
||||||
v1.x = nil // no barrier
|
v1.x = nil // no barrier
|
||||||
v2.x = nil // ERROR "write barrier"
|
v2.x = nil // ERROR "write barrier"
|
||||||
|
v1.s = []nih(nil) // no barrier
|
||||||
|
v2.s = []ih(nil) // ERROR "write barrier"
|
||||||
}
|
}
|
||||||
|
|
||||||
func g() {
|
func g() {
|
||||||
|
Loading…
Reference in New Issue
Block a user