Skip to content

Commit 556e9c5

Browse files
committed
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 <[email protected]> Run-TryBot: Keith Randall <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 0163b3b commit 556e9c5

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

src/cmd/compile/internal/ssa/writebarrier.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ func writebarrier(f *Func) {
250250
// to a new block.
251251
var last *Value
252252
var start, end int
253+
var nonPtrStores int
253254
values := b.Values
254255
FindSeq:
255256
for i := len(values) - 1; i >= 0; i-- {
@@ -261,8 +262,17 @@ func writebarrier(f *Func) {
261262
last = w
262263
end = i + 1
263264
}
265+
nonPtrStores = 0
264266
case OpVarDef, OpVarLive:
265267
continue
268+
case OpStore:
269+
if last == nil {
270+
continue
271+
}
272+
nonPtrStores++
273+
if nonPtrStores > 2 {
274+
break FindSeq
275+
}
266276
default:
267277
if last == nil {
268278
continue
@@ -484,6 +494,10 @@ func writebarrier(f *Func) {
484494
mem.Aux = w.Aux
485495
case OpVarDef, OpVarLive:
486496
mem = bEnd.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, mem)
497+
case OpStore:
498+
ptr := w.Args[0]
499+
val := w.Args[1]
500+
mem = bEnd.NewValue3A(pos, OpStore, types.TypeMem, w.Aux, ptr, val, mem)
487501
}
488502
}
489503

test/codegen/writebarrier.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// asmcheck
2+
3+
// Copyright 2023 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package codegen
8+
9+
func combine2string(p *[2]string, a, b string) {
10+
// amd64:`.*runtime[.]gcWriteBarrier4\(SB\)`
11+
// arm64:`.*runtime[.]gcWriteBarrier4\(SB\)`
12+
p[0] = a
13+
// amd64:-`.*runtime[.]gcWriteBarrier`
14+
// arm64:-`.*runtime[.]gcWriteBarrier`
15+
p[1] = b
16+
}
17+
18+
func combine4string(p *[4]string, a, b, c, d string) {
19+
// amd64:`.*runtime[.]gcWriteBarrier8\(SB\)`
20+
// arm64:`.*runtime[.]gcWriteBarrier8\(SB\)`
21+
p[0] = a
22+
// amd64:-`.*runtime[.]gcWriteBarrier`
23+
// arm64:-`.*runtime[.]gcWriteBarrier`
24+
p[1] = b
25+
// amd64:-`.*runtime[.]gcWriteBarrier`
26+
// arm64:-`.*runtime[.]gcWriteBarrier`
27+
p[2] = c
28+
// amd64:-`.*runtime[.]gcWriteBarrier`
29+
// arm64:-`.*runtime[.]gcWriteBarrier`
30+
p[3] = d
31+
}
32+
33+
func combine2slice(p *[2][]byte, a, b []byte) {
34+
// amd64:`.*runtime[.]gcWriteBarrier4\(SB\)`
35+
// arm64:`.*runtime[.]gcWriteBarrier4\(SB\)`
36+
p[0] = a
37+
// amd64:-`.*runtime[.]gcWriteBarrier`
38+
// arm64:-`.*runtime[.]gcWriteBarrier`
39+
p[1] = b
40+
}
41+
42+
func combine4slice(p *[4][]byte, a, b, c, d []byte) {
43+
// amd64:`.*runtime[.]gcWriteBarrier8\(SB\)`
44+
// arm64:`.*runtime[.]gcWriteBarrier8\(SB\)`
45+
p[0] = a
46+
// amd64:-`.*runtime[.]gcWriteBarrier`
47+
// arm64:-`.*runtime[.]gcWriteBarrier`
48+
p[1] = b
49+
// amd64:-`.*runtime[.]gcWriteBarrier`
50+
// arm64:-`.*runtime[.]gcWriteBarrier`
51+
p[2] = c
52+
// amd64:-`.*runtime[.]gcWriteBarrier`
53+
// arm64:-`.*runtime[.]gcWriteBarrier`
54+
p[3] = d
55+
}

0 commit comments

Comments
 (0)