mirror of
https://github.com/golang/go
synced 2024-11-22 05:04:40 -07:00
cmd/compile: compile cap(ch) as call to runtime.chancap
An upcoming CL will give this call more to do. For now, separate out the compiler change that stops inlining the computation. For #37196. Change-Id: I965426d446964b9b4958e4613246002a7660e7eb Reviewed-on: https://go-review.googlesource.com/c/go/+/568375 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Auto-Submit: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
24fa7544b0
commit
61d6817c83
@ -6350,6 +6350,9 @@ func (s *state) referenceTypeBuiltin(n *ir.UnaryExpr, x *ssa.Value) *ssa.Value {
|
||||
if n.X.Type().IsChan() && n.Op() == ir.OLEN {
|
||||
s.Fatalf("cannot inline len(chan)") // must use runtime.chanlen now
|
||||
}
|
||||
if n.X.Type().IsChan() && n.Op() == ir.OCAP {
|
||||
s.Fatalf("cannot inline cap(chan)") // must use runtime.chancap now
|
||||
}
|
||||
// if n == nil {
|
||||
// return 0
|
||||
// } else {
|
||||
|
@ -161,6 +161,7 @@ func chanrecv2(hchan <-chan any, elem *any) bool
|
||||
func chansend1(hchan chan<- any, elem *any)
|
||||
func closechan(hchan chan<- any)
|
||||
func chanlen(hchan any) int
|
||||
func chancap(hchan any) int
|
||||
|
||||
var writeBarrier struct {
|
||||
enabled bool
|
||||
|
@ -138,6 +138,7 @@ var runtimeDecls = [...]struct {
|
||||
{"chansend1", funcTag, 103},
|
||||
{"closechan", funcTag, 104},
|
||||
{"chanlen", funcTag, 105},
|
||||
{"chancap", funcTag, 105},
|
||||
{"writeBarrier", varTag, 107},
|
||||
{"typedmemmove", funcTag, 108},
|
||||
{"typedmemclr", funcTag, 109},
|
||||
|
@ -261,10 +261,14 @@ func walkLenCap(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
|
||||
_, len := backingArrayPtrLen(cheapExpr(conv.X, init))
|
||||
return len
|
||||
}
|
||||
if isChanLen(n) {
|
||||
if isChanLenCap(n) {
|
||||
name := "chanlen"
|
||||
if n.Op() == ir.OCAP {
|
||||
name = "chancap"
|
||||
}
|
||||
// cannot use chanfn - closechan takes any, not chan any,
|
||||
// because it accepts both send-only and recv-only channels.
|
||||
fn := typecheck.LookupRuntime("chanlen", n.X.Type())
|
||||
fn := typecheck.LookupRuntime(name, n.X.Type())
|
||||
return mkcall1(fn, n.Type(), init, n.X)
|
||||
}
|
||||
|
||||
@ -892,9 +896,9 @@ func isByteCount(n ir.Node) bool {
|
||||
(n.(*ir.UnaryExpr).X.Op() == ir.OBYTES2STR || n.(*ir.UnaryExpr).X.Op() == ir.OBYTES2STRTMP)
|
||||
}
|
||||
|
||||
// isChanLen reports whether n is of the form len(c) for a channel c.
|
||||
// isChanLenCap reports whether n is of the form len(c) or cap(c) for a channel c.
|
||||
// Note that this does not check for -n or instrumenting because this
|
||||
// is a correctness rewrite, not an optimization.
|
||||
func isChanLen(n ir.Node) bool {
|
||||
return n.Op() == ir.OLEN && n.(*ir.UnaryExpr).X.Type().IsChan()
|
||||
func isChanLenCap(n ir.Node) bool {
|
||||
return (n.Op() == ir.OLEN || n.Op() == ir.OCAP) && n.(*ir.UnaryExpr).X.Type().IsChan()
|
||||
}
|
||||
|
@ -731,6 +731,13 @@ func chanlen(c *hchan) int {
|
||||
return int(c.qcount)
|
||||
}
|
||||
|
||||
func chancap(c *hchan) int {
|
||||
if c == nil {
|
||||
return 0
|
||||
}
|
||||
return int(c.dataqsiz)
|
||||
}
|
||||
|
||||
//go:linkname reflect_chanlen reflect.chanlen
|
||||
func reflect_chanlen(c *hchan) int {
|
||||
return chanlen(c)
|
||||
@ -743,10 +750,7 @@ func reflectlite_chanlen(c *hchan) int {
|
||||
|
||||
//go:linkname reflect_chancap reflect.chancap
|
||||
func reflect_chancap(c *hchan) int {
|
||||
if c == nil {
|
||||
return 0
|
||||
}
|
||||
return int(c.dataqsiz)
|
||||
return chancap(c)
|
||||
}
|
||||
|
||||
//go:linkname reflect_chanclose reflect.chanclose
|
||||
|
Loading…
Reference in New Issue
Block a user