cmd/compile: enforce nowritebarrier in SSA compiler
Make sure we don't generate write barriers in runtime
code that is marked to forbid write barriers.
Implement the optimization that if we're writing a sliced
slice back to the location it came from, we don't need a
write barrier.
Fixes #14784
Change-Id: I04b6a3b2ac303c19817e932a36a3b006de103aaa
Reviewed-on: https://go-review.googlesource.com/20791
Reviewed-by: Austin Clements <austin@google.com>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index b0c7c5f..1d3c1f6 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -96,6 +96,14 @@
if fn.Func.Pragma&CgoUnsafeArgs != 0 {
s.cgoUnsafeArgs = true
}
+ if fn.Func.Pragma&Nowritebarrier != 0 {
+ s.noWB = true
+ }
+ defer func() {
+ if s.WBLineno != 0 {
+ fn.Func.WBLineno = s.WBLineno
+ }
+ }()
// TODO(khr): build config just once at the start of the compiler binary
ssaExp.log = printssa
@@ -271,6 +279,8 @@
returns []*Node
cgoUnsafeArgs bool
+ noWB bool
+ WBLineno int32 // line number of first write barrier. 0=no write barriers
}
type funcLine struct {
@@ -2780,6 +2790,13 @@
// } else {
// *left = *right
// }
+
+ if s.noWB {
+ s.Fatalf("write barrier prohibited")
+ }
+ if s.WBLineno == 0 {
+ s.WBLineno = left.Line
+ }
bThen := s.f.NewBlock(ssa.BlockPlain)
bElse := s.f.NewBlock(ssa.BlockPlain)
bEnd := s.f.NewBlock(ssa.BlockPlain)
@@ -2823,6 +2840,12 @@
// store pointer fields
// }
+ if s.noWB {
+ s.Fatalf("write barrier prohibited")
+ }
+ if s.WBLineno == 0 {
+ s.WBLineno = left.Line
+ }
s.storeTypeScalars(t, left, right)
bThen := s.f.NewBlock(ssa.BlockPlain)