if fn.Func.Pragma&Nosplit != 0 {
s.f.NoSplit = true
}
- defer func() {
- if s.f.WBPos.IsKnown() {
- fn.Func.WBPos = s.f.WBPos
- }
- }()
s.exitCode = fn.Func.Exit
s.panics = map[funcLine]*ssa.Block{}
return Debug_checknil != 0
}
-func (e *ssafn) Debug_wb() bool {
- return Debug_wb != 0
-}
-
func (e *ssafn) UseWriteBarrier() bool {
return use_writebarrier
}
return nil
}
+func (e *ssafn) SetWBPos(pos src.XPos) {
+ e.curfn.Func.setWBPos(pos)
+}
+
func (n *Node) Typ() *types.Type {
return n.Type
}
Label int32 // largest auto-generated label in this function
Endlineno src.XPos
- WBPos src.XPos // position of first write barrier
+ WBPos src.XPos // position of first write barrier; see SetWBPos
Pragma syntax.Pragma // go:xxx function annotations
func (f *Func) SetNilCheckDisabled(b bool) { f.flags.set(funcNilCheckDisabled, b) }
func (f *Func) SetInlinabilityChecked(b bool) { f.flags.set(funcInlinabilityChecked, b) }
+func (f *Func) setWBPos(pos src.XPos) {
+ if Debug_wb != 0 {
+ Warnl(pos, "write barrier")
+ }
+ if !f.WBPos.IsKnown() {
+ f.WBPos = pos
+ }
+}
+
type Op uint8
// Node ops.
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
nptr1.Etype = 1
nptr2 := l2
+ Curfn.Func.setWBPos(n.Pos)
fn := syslook("typedslicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
var ln Nodes
//
func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
if types.Haspointers(n.Left.Type.Elem()) {
+ Curfn.Func.setWBPos(n.Pos)
fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), n.Left, n.Right)
}
// Forwards the Debug flags from gc
Debug_checknil() bool
- Debug_wb() bool
}
type Frontend interface {
// UseWriteBarrier returns whether write barrier is enabled
UseWriteBarrier() bool
+
+ // SetWBPos indicates that a write barrier has been inserted
+ // in this function at position pos.
+ SetWBPos(pos src.XPos)
}
// interface used to hold a *gc.Node (a stack variable).
func (DummyFrontend) UseWriteBarrier() bool {
return true // only writebarrier_test cares
}
+func (DummyFrontend) SetWBPos(pos src.XPos) {
+}
func (d DummyFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, args...) }
func (d DummyFrontend) Log() bool { return true }
func (d DummyFrontend) Fatalf(_ src.XPos, msg string, args ...interface{}) { d.t.Fatalf(msg, args...) }
func (d DummyFrontend) Warnl(_ src.XPos, msg string, args ...interface{}) { d.t.Logf(msg, args...) }
func (d DummyFrontend) Debug_checknil() bool { return false }
-func (d DummyFrontend) Debug_wb() bool { return false }
var dummyTypes Types
scheduled bool // Values in Blocks are in final order
NoSplit bool // true if function is marked as nosplit. Used by schedule check pass.
- WBPos src.XPos // line number of first write barrier
-
// when register allocation is done, maps value ids to locations
RegAlloc []Location
if fn != nil {
// Note that we set up a writebarrier function call.
- if !f.WBPos.IsKnown() {
- f.WBPos = pos
- }
- if f.fe.Debug_wb() {
- f.Warnl(pos, "write barrier")
- }
+ f.fe.SetWBPos(pos)
}
}