Commit 972a478d authored by Russ Cox's avatar Russ Cox

cmd/compile: don't cater to race detector in write barriers

The new lower-level barriers work fine and don't need special handling,
because they appear to the race detector as (visible) ordinary assignments.

Change-Id: I7477d73a3deecbebf68716580678c595cc4151e3
Reviewed-on: https://go-review.googlesource.com/10316Reviewed-by: default avatarAustin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 714291f2
......@@ -186,31 +186,6 @@ func racewalknode(np **Node, init **NodeList, wr int, skip int) {
// as we do not instrument runtime code.
// typedslicecopy is instrumented in runtime.
case OCALLFUNC:
if n.Left.Sym != nil && n.Left.Sym.Pkg == Runtimepkg && (strings.HasPrefix(n.Left.Sym.Name, "writebarrier") || n.Left.Sym.Name == "typedmemmove") {
// Find the dst argument.
// The list can be reordered, so it's not necessary just the first or the second element.
var l *NodeList
for l = n.List; l != nil; l = l.Next {
if n.Left.Sym.Name == "typedmemmove" {
if l.N.Left.Xoffset == int64(Widthptr) {
break
}
} else {
if l.N.Left.Xoffset == 0 {
break
}
}
}
if l == nil {
Fatal("racewalk: writebarrier no arg")
}
if l.N.Right.Op != OADDR {
Fatal("racewalk: writebarrier bad arg")
}
callinstr(&l.N.Right.Left, init, 1, 0)
}
racewalknode(&n.Left, init, 0, 0)
goto ret
......
......@@ -2226,65 +2226,11 @@ var applywritebarrier_bv Bvec
func applywritebarrier(n *Node, init **NodeList) *Node {
if n.Left != nil && n.Right != nil && needwritebarrier(n.Left, n.Right) {
if flag_race == 0 {
if Debug_wb > 1 {
Warnl(int(n.Lineno), "marking %v for barrier", Nconv(n.Left, 0))
}
n.Op = OASWB
return n
}
// Use slow path always for race detector.
if Curfn != nil && Curfn.Func.Nowritebarrier {
Yyerror("write barrier prohibited")
}
if Debug_wb > 0 {
Warnl(int(n.Lineno), "write barrier")
}
t := n.Left.Type
l := Nod(OADDR, n.Left, nil)
l.Etype = 1 // addr does not escape
if t.Width == int64(Widthptr) {
n = mkcall1(writebarrierfn("writebarrierptr", t, n.Right.Type), nil, init, l, n.Right)
} else if t.Etype == TSTRING {
n = mkcall1(writebarrierfn("writebarrierstring", t, n.Right.Type), nil, init, l, n.Right)
} else if Isslice(t) {
n = mkcall1(writebarrierfn("writebarrierslice", t, n.Right.Type), nil, init, l, n.Right)
} else if Isinter(t) {
n = mkcall1(writebarrierfn("writebarrieriface", t, n.Right.Type), nil, init, l, n.Right)
} else if t.Width <= int64(4*Widthptr) {
x := int64(0)
if applywritebarrier_bv.b == nil {
applywritebarrier_bv = bvalloc(4)
}
bvresetall(applywritebarrier_bv)
onebitwalktype1(t, &x, applywritebarrier_bv)
var name string
switch t.Width / int64(Widthptr) {
default:
Fatal("found writebarrierfat for %d-byte object of type %v", int(t.Width), t)
case 2:
name = fmt.Sprintf("writebarrierfat%d%d", bvget(applywritebarrier_bv, 0), bvget(applywritebarrier_bv, 1))
case 3:
name = fmt.Sprintf("writebarrierfat%d%d%d", bvget(applywritebarrier_bv, 0), bvget(applywritebarrier_bv, 1), bvget(applywritebarrier_bv, 2))
case 4:
name = fmt.Sprintf("writebarrierfat%d%d%d%d", bvget(applywritebarrier_bv, 0), bvget(applywritebarrier_bv, 1), bvget(applywritebarrier_bv, 2), bvget(applywritebarrier_bv, 3))
}
n = mkcall1(writebarrierfn(name, t, n.Right.Type), nil, init, l, Nodintconst(0), n.Right)
} else {
r := n.Right
for r.Op == OCONVNOP {
r = r.Left
}
r = Nod(OADDR, r, nil)
r.Etype = 1 // addr does not escape
//warnl(n->lineno, "typedmemmove %T %N", t, r);
n = mkcall1(writebarrierfn("typedmemmove", t, r.Left.Type), nil, init, typename(t), l, r)
if Debug_wb > 1 {
Warnl(int(n.Lineno), "marking %v for barrier", Nconv(n.Left, 0))
}
n.Op = OASWB
return n
}
return n
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment