Commit 2e29eb57 authored by Daniel Martí's avatar Daniel Martí Committed by Brad Fitzpatrick

runtime: remove unused *chantype parameters

The chanrecv funcs don't use it at all. The chansend ones do, but the
element type is now part of the hchan struct, which is already a
parameter.

hchan can be nil in chansend when sending to a nil channel, so when
instrumenting we must copy to the stack to be able to read the channel
type.

name             old time/op  new time/op  delta
ChanUncontended  6.42µs ± 1%  6.22µs ± 0%  -3.06%  (p=0.000 n=19+18)

Initially found by github.com/mvdan/unparam.

Fixes #19591.

Change-Id: I3a5e8a0082e8445cc3f0074695e3593fd9c88412
Reviewed-on: https://go-review.googlesource.com/38351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent c65ceff1
......@@ -106,46 +106,46 @@ var runtimeDecls = [...]struct {
{"selectnbrecv", funcTag, 83},
{"selectnbrecv2", funcTag, 85},
{"newselect", funcTag, 86},
{"selectsend", funcTag, 75},
{"selectrecv", funcTag, 87},
{"selectsend", funcTag, 87},
{"selectrecv", funcTag, 88},
{"selectdefault", funcTag, 56},
{"selectgo", funcTag, 88},
{"selectgo", funcTag, 89},
{"block", funcTag, 5},
{"makeslice", funcTag, 90},
{"makeslice64", funcTag, 91},
{"growslice", funcTag, 92},
{"memmove", funcTag, 93},
{"memclrNoHeapPointers", funcTag, 95},
{"memclrHasPointers", funcTag, 95},
{"memequal", funcTag, 96},
{"memequal8", funcTag, 97},
{"memequal16", funcTag, 97},
{"memequal32", funcTag, 97},
{"memequal64", funcTag, 97},
{"memequal128", funcTag, 97},
{"int64div", funcTag, 98},
{"uint64div", funcTag, 99},
{"int64mod", funcTag, 98},
{"uint64mod", funcTag, 99},
{"float64toint64", funcTag, 100},
{"float64touint64", funcTag, 101},
{"float64touint32", funcTag, 103},
{"int64tofloat64", funcTag, 104},
{"uint64tofloat64", funcTag, 105},
{"uint32tofloat64", funcTag, 106},
{"complex128div", funcTag, 107},
{"racefuncenter", funcTag, 108},
{"makeslice", funcTag, 91},
{"makeslice64", funcTag, 92},
{"growslice", funcTag, 93},
{"memmove", funcTag, 94},
{"memclrNoHeapPointers", funcTag, 96},
{"memclrHasPointers", funcTag, 96},
{"memequal", funcTag, 97},
{"memequal8", funcTag, 98},
{"memequal16", funcTag, 98},
{"memequal32", funcTag, 98},
{"memequal64", funcTag, 98},
{"memequal128", funcTag, 98},
{"int64div", funcTag, 99},
{"uint64div", funcTag, 100},
{"int64mod", funcTag, 99},
{"uint64mod", funcTag, 100},
{"float64toint64", funcTag, 101},
{"float64touint64", funcTag, 102},
{"float64touint32", funcTag, 104},
{"int64tofloat64", funcTag, 105},
{"uint64tofloat64", funcTag, 106},
{"uint32tofloat64", funcTag, 107},
{"complex128div", funcTag, 108},
{"racefuncenter", funcTag, 109},
{"racefuncexit", funcTag, 5},
{"raceread", funcTag, 108},
{"racewrite", funcTag, 108},
{"racereadrange", funcTag, 109},
{"racewriterange", funcTag, 109},
{"msanread", funcTag, 109},
{"msanwrite", funcTag, 109},
{"raceread", funcTag, 109},
{"racewrite", funcTag, 109},
{"racereadrange", funcTag, 110},
{"racewriterange", funcTag, 110},
{"msanread", funcTag, 110},
{"msanwrite", funcTag, 110},
}
func runtimeTypes() []*Type {
var typs [110]*Type
var typs [111]*Type
typs[0] = bytetype
typs[1] = typPtr(typs[0])
typs[2] = Types[TANY]
......@@ -218,43 +218,44 @@ func runtimeTypes() []*Type {
typs[69] = typChan(typs[2], Cboth)
typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[69])})
typs[71] = typChan(typs[2], Crecv)
typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3])}, nil)
typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[72] = functype(nil, []*Node{anonfield(typs[71]), anonfield(typs[3])}, nil)
typs[73] = functype(nil, []*Node{anonfield(typs[71]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[74] = typChan(typs[2], Csend)
typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[74]), anonfield(typs[3])}, nil)
typs[75] = functype(nil, []*Node{anonfield(typs[74]), anonfield(typs[3])}, nil)
typs[76] = typArray(typs[0], 3)
typs[77] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[76]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
typs[78] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil)
typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[74]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[71])}, []*Node{anonfield(typs[11])})
typs[82] = functype(nil, []*Node{anonfield(typs[74]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[83] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[71])}, []*Node{anonfield(typs[11])})
typs[84] = typPtr(typs[11])
typs[85] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[84]), anonfield(typs[71])}, []*Node{anonfield(typs[11])})
typs[85] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[84]), anonfield(typs[71])}, []*Node{anonfield(typs[11])})
typs[86] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[8])}, nil)
typs[87] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3]), anonfield(typs[84])}, nil)
typs[88] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])})
typs[89] = typSlice(typs[2])
typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[89])})
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[89])})
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[89]), anonfield(typs[32])}, []*Node{anonfield(typs[89])})
typs[93] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[49])}, nil)
typs[94] = Types[TUNSAFEPTR]
typs[95] = functype(nil, []*Node{anonfield(typs[94]), anonfield(typs[49])}, nil)
typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[49])}, []*Node{anonfield(typs[11])})
typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[98] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
typs[99] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
typs[100] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
typs[101] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
typs[102] = Types[TUINT32]
typs[103] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[102])})
typs[104] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
typs[105] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
typs[106] = functype(nil, []*Node{anonfield(typs[102])}, []*Node{anonfield(typs[13])})
typs[107] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[108] = functype(nil, []*Node{anonfield(typs[49])}, nil)
typs[109] = functype(nil, []*Node{anonfield(typs[49]), anonfield(typs[49])}, nil)
typs[87] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[74]), anonfield(typs[3])}, nil)
typs[88] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[71]), anonfield(typs[3]), anonfield(typs[84])}, nil)
typs[89] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])})
typs[90] = typSlice(typs[2])
typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[90])})
typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[90])})
typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[90]), anonfield(typs[32])}, []*Node{anonfield(typs[90])})
typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[49])}, nil)
typs[95] = Types[TUNSAFEPTR]
typs[96] = functype(nil, []*Node{anonfield(typs[95]), anonfield(typs[49])}, nil)
typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[49])}, []*Node{anonfield(typs[11])})
typs[98] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
typs[99] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
typs[100] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
typs[101] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
typs[102] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
typs[103] = Types[TUINT32]
typs[104] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[103])})
typs[105] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
typs[106] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
typs[107] = functype(nil, []*Node{anonfield(typs[103])}, []*Node{anonfield(typs[13])})
typs[108] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
typs[109] = functype(nil, []*Node{anonfield(typs[49])}, nil)
typs[110] = functype(nil, []*Node{anonfield(typs[49]), anonfield(typs[49])}, nil)
return typs[:]
}
......@@ -115,9 +115,9 @@ func mapiternext(hiter *any)
// *byte is really *runtime.Type
func makechan(chanType *byte, hint int64) (hchan chan any)
func chanrecv1(chanType *byte, hchan <-chan any, elem *any)
func chanrecv2(chanType *byte, hchan <-chan any, elem *any) bool
func chansend1(chanType *byte, hchan chan<- any, elem *any)
func chanrecv1(hchan <-chan any, elem *any)
func chanrecv2(hchan <-chan any, elem *any) bool
func chansend1(hchan chan<- any, elem *any)
func closechan(hchan any)
var writeBarrier struct {
......@@ -135,9 +135,9 @@ func typedmemmove(typ *byte, dst *any, src *any)
func typedmemclr(typ *byte, dst *any)
func typedslicecopy(typ *byte, dst any, src any) int
func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool
func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool
func selectnbsend(hchan chan<- any, elem *any) bool
func selectnbrecv(elem *any, hchan <-chan any) bool
func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool
func newselect(sel *byte, selsize int64, size int32)
func selectsend(sel *byte, hchan chan<- any, elem *any)
......
......@@ -916,7 +916,13 @@ func orderstmt(n *Node, order *Order) {
n.Left = orderexpr(n.Left, order, nil)
n.Right = orderexpr(n.Right, order, nil)
n.Right = orderaddrtemp(n.Right, order)
if instrumenting {
// Force copying to the stack so that (chan T)(nil) <- x
// is still instrumented as a read of x.
n.Right = ordercopyexpr(n.Right, n.Right.Type, order, 0)
} else {
n.Right = orderaddrtemp(n.Right, order)
}
order.out = append(order.out, n)
cleantemp(t, order)
......
......@@ -225,21 +225,21 @@ func walkselect(sel *Node) {
case OSEND:
// if selectnbsend(c, v) { body } else { default body }
ch := n.Left
r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), Types[TBOOL], &r.Ninit, typename(ch.Type), ch, n.Right)
r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), Types[TBOOL], &r.Ninit, ch, n.Right)
case OSELRECV:
// if c != nil && selectnbrecv(&v, c) { body } else { default body }
r = nod(OIF, nil, nil)
r.Ninit.Set(cas.Ninit.Slice())
ch := n.Right.Left
r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), Types[TBOOL], &r.Ninit, typename(ch.Type), n.Left, ch)
r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), Types[TBOOL], &r.Ninit, n.Left, ch)
case OSELRECV2:
// if c != nil && selectnbrecv2(&v, c) { body } else { default body }
r = nod(OIF, nil, nil)
r.Ninit.Set(cas.Ninit.Slice())
ch := n.Right.Left
r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), Types[TBOOL], &r.Ninit, typename(ch.Type), n.Left, n.List.First(), ch)
r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), Types[TBOOL], &r.Ninit, n.Left, n.List.First(), ch)
}
r.Left = typecheck(r.Left, Erv)
......
......@@ -203,7 +203,7 @@ func walkstmt(n *Node) *Node {
n.Ninit.Set(nil)
n.Left = walkexpr(n.Left, &init)
n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, typename(n.Left.Type), n.Left, nodnil())
n = mkcall1(chanfn("chanrecv1", 2, n.Left.Type), nil, &init, n.Left, nodnil())
n = walkexpr(n, &init)
n = addinit(n, init.Slice())
......@@ -719,7 +719,7 @@ opswitch:
n1 := nod(OADDR, n.Left, nil)
r := n.Right.Left // the channel
n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, typename(r.Type), r, n1)
n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, r, n1)
n = walkexpr(n, init)
break opswitch
......@@ -790,7 +790,7 @@ opswitch:
n1.Etype = 1 // addr does not escape
fn := chanfn("chanrecv2", 2, r.Left.Type)
ok := n.List.Second()
call := mkcall1(fn, ok.Type, init, typename(r.Left.Type), r.Left, n1)
call := mkcall1(fn, ok.Type, init, r.Left, n1)
n = nod(OAS, ok, call)
n = typecheck(n, Etop)
......@@ -1599,7 +1599,7 @@ opswitch:
n1 = assignconv(n1, n.Left.Type.Elem(), "chan send")
n1 = walkexpr(n1, init)
n1 = nod(OADDR, n1, nil)
n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, typename(n.Left.Type), n.Left, n1)
n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, n.Left, n1)
case OCLOSURE:
n = walkclosure(n, init)
......
......@@ -1298,7 +1298,7 @@ func (v Value) recv(nb bool) (val Value, ok bool) {
} else {
p = unsafe.Pointer(&val.ptr)
}
selected, ok := chanrecv(v.typ, v.pointer(), nb, p)
selected, ok := chanrecv(v.pointer(), nb, p)
if !selected {
val = Value{}
}
......@@ -1329,7 +1329,7 @@ func (v Value) send(x Value, nb bool) (selected bool) {
} else {
p = unsafe.Pointer(&x.ptr)
}
return chansend(v.typ, v.pointer(), p, nb)
return chansend(v.pointer(), p, nb)
}
// Set assigns x to the value v.
......@@ -2465,10 +2465,10 @@ func chanlen(ch unsafe.Pointer) int
// (due to the escapes() call in ValueOf).
//go:noescape
func chanrecv(t *rtype, ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
//go:noescape
func chansend(t *rtype, ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
func makemap(t *rtype) (m unsafe.Pointer)
......
......@@ -109,8 +109,8 @@ func chanbuf(c *hchan, i uint) unsafe.Pointer {
// entry point for c <- x from compiled code
//go:nosplit
func chansend1(t *chantype, c *hchan, elem unsafe.Pointer) {
chansend(t, c, elem, true, getcallerpc(unsafe.Pointer(&t)))
func chansend1(c *hchan, elem unsafe.Pointer) {
chansend(c, elem, true, getcallerpc(unsafe.Pointer(&c)))
}
/*
......@@ -125,14 +125,7 @@ func chansend1(t *chantype, c *hchan, elem unsafe.Pointer) {
* been closed. it is easiest to loop and re-run
* the operation; we'll see that it's now closed.
*/
func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
if raceenabled {
raceReadObjectPC(t.elem, ep, callerpc, funcPC(chansend))
}
if msanenabled {
msanread(ep, t.elem.size)
}
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
if c == nil {
if !block {
return false
......@@ -391,13 +384,13 @@ func closechan(c *hchan) {
// entry points for <- c from compiled code
//go:nosplit
func chanrecv1(t *chantype, c *hchan, elem unsafe.Pointer) {
chanrecv(t, c, elem, true)
func chanrecv1(c *hchan, elem unsafe.Pointer) {
chanrecv(c, elem, true)
}
//go:nosplit
func chanrecv2(t *chantype, c *hchan, elem unsafe.Pointer) (received bool) {
_, received = chanrecv(t, c, elem, true)
func chanrecv2(c *hchan, elem unsafe.Pointer) (received bool) {
_, received = chanrecv(c, elem, true)
return
}
......@@ -407,7 +400,7 @@ func chanrecv2(t *chantype, c *hchan, elem unsafe.Pointer) (received bool) {
// Otherwise, if c is closed, zeros *ep and returns (true, false).
// Otherwise, fills in *ep with an element and returns (true, true).
// A non-nil ep must point to the heap or the caller's stack.
func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
// raceenabled: don't need to check ep, as it is always on the stack
// or is new memory allocated by reflect.
......@@ -600,8 +593,8 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
// ... bar
// }
//
func selectnbsend(t *chantype, c *hchan, elem unsafe.Pointer) (selected bool) {
return chansend(t, c, elem, false, getcallerpc(unsafe.Pointer(&t)))
func selectnbsend(c *hchan, elem unsafe.Pointer) (selected bool) {
return chansend(c, elem, false, getcallerpc(unsafe.Pointer(&c)))
}
// compiler implements
......@@ -621,8 +614,8 @@ func selectnbsend(t *chantype, c *hchan, elem unsafe.Pointer) (selected bool) {
// ... bar
// }
//
func selectnbrecv(t *chantype, elem unsafe.Pointer, c *hchan) (selected bool) {
selected, _ = chanrecv(t, c, elem, false)
func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected bool) {
selected, _ = chanrecv(c, elem, false)
return
}
......@@ -643,20 +636,20 @@ func selectnbrecv(t *chantype, elem unsafe.Pointer, c *hchan) (selected bool) {
// ... bar
// }
//
func selectnbrecv2(t *chantype, elem unsafe.Pointer, received *bool, c *hchan) (selected bool) {
func selectnbrecv2(elem unsafe.Pointer, received *bool, c *hchan) (selected bool) {
// TODO(khr): just return 2 values from this function, now that it is in Go.
selected, *received = chanrecv(t, c, elem, false)
selected, *received = chanrecv(c, elem, false)
return
}
//go:linkname reflect_chansend reflect.chansend
func reflect_chansend(t *chantype, c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
return chansend(t, c, elem, !nb, getcallerpc(unsafe.Pointer(&t)))
func reflect_chansend(c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
return chansend(c, elem, !nb, getcallerpc(unsafe.Pointer(&c)))
}
//go:linkname reflect_chanrecv reflect.chanrecv
func reflect_chanrecv(t *chantype, c *hchan, nb bool, elem unsafe.Pointer) (selected bool, received bool) {
return chanrecv(t, c, elem, !nb)
func reflect_chanrecv(c *hchan, nb bool, elem unsafe.Pointer) (selected bool, received bool) {
return chanrecv(c, elem, !nb)
}
//go:linkname reflect_chanlen reflect.chanlen
......
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