mirror of
https://github.com/golang/go
synced 2024-11-16 20:54:48 -07:00
cmd/compile: allow non-pointer writes in the middle of a write barrier
This lets us combine more write barriers, getting rid of some of the test+branch and gcWriteBarrier* calls. With the new write barriers, it's easy to add a few non-pointer writes to the set of values written. We allow up to 2 non-pointer writes between pointer writes. This is enough for, for example, adjacent slice fields. Fixes #62126 Change-Id: I872d0fa9cc4eb855e270ffc0223b39fde1723c4b Reviewed-on: https://go-review.googlesource.com/c/go/+/521498 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
0163b3b32c
commit
556e9c5f3e
@ -250,6 +250,7 @@ func writebarrier(f *Func) {
|
|||||||
// to a new block.
|
// to a new block.
|
||||||
var last *Value
|
var last *Value
|
||||||
var start, end int
|
var start, end int
|
||||||
|
var nonPtrStores int
|
||||||
values := b.Values
|
values := b.Values
|
||||||
FindSeq:
|
FindSeq:
|
||||||
for i := len(values) - 1; i >= 0; i-- {
|
for i := len(values) - 1; i >= 0; i-- {
|
||||||
@ -261,8 +262,17 @@ func writebarrier(f *Func) {
|
|||||||
last = w
|
last = w
|
||||||
end = i + 1
|
end = i + 1
|
||||||
}
|
}
|
||||||
|
nonPtrStores = 0
|
||||||
case OpVarDef, OpVarLive:
|
case OpVarDef, OpVarLive:
|
||||||
continue
|
continue
|
||||||
|
case OpStore:
|
||||||
|
if last == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nonPtrStores++
|
||||||
|
if nonPtrStores > 2 {
|
||||||
|
break FindSeq
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if last == nil {
|
if last == nil {
|
||||||
continue
|
continue
|
||||||
@ -484,6 +494,10 @@ func writebarrier(f *Func) {
|
|||||||
mem.Aux = w.Aux
|
mem.Aux = w.Aux
|
||||||
case OpVarDef, OpVarLive:
|
case OpVarDef, OpVarLive:
|
||||||
mem = bEnd.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, mem)
|
mem = bEnd.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, mem)
|
||||||
|
case OpStore:
|
||||||
|
ptr := w.Args[0]
|
||||||
|
val := w.Args[1]
|
||||||
|
mem = bEnd.NewValue3A(pos, OpStore, types.TypeMem, w.Aux, ptr, val, mem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
test/codegen/writebarrier.go
Normal file
55
test/codegen/writebarrier.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// asmcheck
|
||||||
|
|
||||||
|
// Copyright 2023 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 codegen
|
||||||
|
|
||||||
|
func combine2string(p *[2]string, a, b string) {
|
||||||
|
// amd64:`.*runtime[.]gcWriteBarrier4\(SB\)`
|
||||||
|
// arm64:`.*runtime[.]gcWriteBarrier4\(SB\)`
|
||||||
|
p[0] = a
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[1] = b
|
||||||
|
}
|
||||||
|
|
||||||
|
func combine4string(p *[4]string, a, b, c, d string) {
|
||||||
|
// amd64:`.*runtime[.]gcWriteBarrier8\(SB\)`
|
||||||
|
// arm64:`.*runtime[.]gcWriteBarrier8\(SB\)`
|
||||||
|
p[0] = a
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[1] = b
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[2] = c
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[3] = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func combine2slice(p *[2][]byte, a, b []byte) {
|
||||||
|
// amd64:`.*runtime[.]gcWriteBarrier4\(SB\)`
|
||||||
|
// arm64:`.*runtime[.]gcWriteBarrier4\(SB\)`
|
||||||
|
p[0] = a
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[1] = b
|
||||||
|
}
|
||||||
|
|
||||||
|
func combine4slice(p *[4][]byte, a, b, c, d []byte) {
|
||||||
|
// amd64:`.*runtime[.]gcWriteBarrier8\(SB\)`
|
||||||
|
// arm64:`.*runtime[.]gcWriteBarrier8\(SB\)`
|
||||||
|
p[0] = a
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[1] = b
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[2] = c
|
||||||
|
// amd64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
|
p[3] = d
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user