// case ODCLFIELD:
// unimplemented - handled by default case
- case OAS, OASWB:
+ case OAS:
// Don't export "v = <N>" initializing statements, hope they're always
// preceded by the DCL which will be re-parsed and typecheck to reproduce
// the "v = <N>" again.
// This assignment is a no-op for escape analysis,
// it does not store any new pointers into b that were not already there.
// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
- case OAS, OASOP, OASWB:
+ case OAS, OASOP:
if (n.Left.Op == OIND || n.Left.Op == ODOTPTR) && n.Left.Left.Op == ONAME && // dst is ONAME dereference
(n.Right.Op == OSLICE || n.Right.Op == OSLICE3 || n.Right.Op == OSLICESTR) && // src is slice operation
(n.Right.Left.Op == OIND || n.Right.Left.Op == ODOTPTR) && n.Right.Left.Left.Op == ONAME && // slice is applied to ONAME dereference
// Don't export "v = <N>" initializing statements, hope they're always
// preceded by the DCL which will be re-parsed and typechecked to reproduce
// the "v = <N>" again.
- case OAS, OASWB:
+ case OAS:
if n.Colas && !complexinit {
fmt.Fprintf(s, "%v := %v", n.Left, n.Right)
} else {
case ODCLFUNC, ODCLCONST, ODCLTYPE, OEMPTY:
break
- case OAS, OASWB:
+ case OAS:
if isblank(ln.Left) && candiscard(ln.Right) {
break
}
OAS2MAPR: "AS2MAPR",
OAS2DOTTYPE: "AS2DOTTYPE",
OASOP: "ASOP",
- OASWB: "ASWB",
OCALL: "CALL",
OCALLFUNC: "CALLFUNC",
OCALLMETH: "CALLMETH",
default:
Fatalf("instrument: unknown node type %v", n.Op)
- case OAS, OASWB, OAS2FUNC:
+ case OAS, OAS2FUNC:
instrumentnode(&n.Left, init, 1, 0)
instrumentnode(&n.Right, init, 0, 0)
goto ret
switch kind {
case initKindStatic:
a = walkexpr(a, init) // add any assignments in r to top
- if a.Op == OASWB {
- // Static initialization never needs
- // write barriers.
- a.Op = OAS
- }
if a.Op != OAS {
Fatalf("fixedlit: not as, is %v", a)
}
b := s.endBlock()
b.AddEdgeTo(lab.target)
- case OAS, OASWB:
+ case OAS:
// Generate static data rather than code, if possible.
if n.IsStatic {
if !genAsInitNoCheck(n) {
}
var r *ssa.Value
var isVolatile bool
- needwb := n.Op == OASWB
+ needwb := n.Right != nil && needwritebarrier(n.Left, n.Right)
deref := !canSSAType(t)
if deref {
if rhs == nil {
// They get similar wb-removal treatment in walk.go:OAS.
needwb = true
}
+ if needwb && Debug_wb > 1 {
+ Warnl(n.Pos, "marking %v for barrier", n.Left)
+ }
var skip skipMask
if rhs != nil && (rhs.Op == OSLICE || rhs.Op == OSLICE3 || rhs.Op == OSLICESTR) && samesafeexpr(rhs.Left, n.Left) {
}
goto out
- case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OASWB:
+ case OAS:
+ if !needwritebarrier(n.Left, n.Right) {
+ break
+ }
+ fallthrough
+ case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
ul = UINF
goto out
OAS2MAPR // List = Rlist (x, ok = m["foo"])
OAS2DOTTYPE // List = Rlist (x, ok = I.(int))
OASOP // Left Etype= Right (x += y)
- OASWB // Left = Right (with write barrier)
OCALL // Left(List) (function call, method call or type conversion)
OCALLFUNC // Left(List) (function call f(args))
OCALLMETH // Left(List) (direct method call x.Method(args))
ll := ascompatee(n.Op, rl, n.List.Slice(), &n.Ninit)
n.List.Set(reorder3(ll))
- ls := n.List.Slice()
- for i, n := range ls {
- ls[i] = applywritebarrier(n)
- }
break
}
break
}
- if !instrumenting && iszero(n.Right) && !needwritebarrier(n.Left, n.Right) {
+ if !instrumenting && iszero(n.Right) {
break
}
static := n.IsStatic
n = convas(n, init)
n.IsStatic = static
- n = applywritebarrier(n)
}
case OAS2:
walkexprlistsafe(n.Rlist.Slice(), init)
ll := ascompatee(OAS, n.List.Slice(), n.Rlist.Slice(), init)
ll = reorder3(ll)
- for i, n := range ll {
- ll[i] = applywritebarrier(n)
- }
n = liststmt(ll)
// a,b,... = fn()
init.Append(r)
ll := ascompatet(n.Op, n.List, r.Type)
- for i, n := range ll {
- ll[i] = applywritebarrier(n)
- }
n = liststmt(ll)
// x, y = <-c
return true
}
-// TODO(rsc): Perhaps componentgen should run before this.
-
-func applywritebarrier(n *Node) *Node {
- if n.Left != nil && n.Right != nil && needwritebarrier(n.Left, n.Right) {
- if Debug_wb > 1 {
- Warnl(n.Pos, "marking %v for barrier", n.Left)
- }
- n.Op = OASWB
- return n
- }
- return n
-}
-
func convas(n *Node, init *Nodes) *Node {
if n.Op != OAS {
Fatalf("convas: not OAS %v", n.Op)