]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: eliminate scase.receivedp
authorMatthew Dempsky <mdempsky@google.com>
Tue, 7 Mar 2017 23:12:11 +0000 (15:12 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 1 May 2018 03:17:54 +0000 (03:17 +0000)
Make selectgo return recvOK as a result parameter instead.

Change-Id: Iffd436371d360bf666b76d4d7503e7c3037a9f1d
Reviewed-on: https://go-review.googlesource.com/37935
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/builtin/runtime.go
src/cmd/compile/internal/gc/select.go
src/runtime/select.go

index 47f0c38a00dce789bcbb26579739d5cf693babdd..4223a5e3fe2e7dd70491de8c0e0af49a4087b505 100644 (file)
@@ -242,7 +242,7 @@ func runtimeTypes() []*types.Type {
        typs[88] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[77])}, []*Node{anonfield(typs[11])})
        typs[89] = types.NewPtr(typs[11])
        typs[90] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[89]), anonfield(typs[77])}, []*Node{anonfield(typs[11])})
-       typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[32])})
+       typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[32]), anonfield(typs[11])})
        typs[92] = types.NewSlice(typs[2])
        typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[92])})
        typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[92])})
index dc0a8b22222403d796237c1f628da1b1f72d92f9..17bdf362e94d5fae55f1be449d16dfe7ae8ea32c 100644 (file)
@@ -146,7 +146,7 @@ func selectnbrecv(elem *any, hchan <-chan any) bool
 func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool
 
 func selectsetpc(cas *byte)
-func selectgo(cas0 *byte, order0 *byte, ncases int) int
+func selectgo(cas0 *byte, order0 *byte, ncases int) (int, bool)
 func block()
 
 func makeslice(typ *byte, len int, cap int) (ary []any)
index 6663ff6862fe2c3e9532dcd97956963f40e4ea7b..eb37e32bf1dd2bce3598cd46df1d46b62065034b 100644 (file)
@@ -187,10 +187,6 @@ func walkselectcases(cases *Nodes) []*Node {
                        if n.Op == OSELRECV2 && n.List.Len() == 0 {
                                n.Op = OSELRECV
                        }
-                       if n.Op == OSELRECV2 {
-                               n.List.SetFirst(nod(OADDR, n.List.First(), nil))
-                               n.List.SetFirst(typecheck(n.List.First(), Erv))
-                       }
 
                        if n.Left != nil {
                                n.Left = nod(OADDR, n.Left, nil)
@@ -225,7 +221,7 @@ func walkselectcases(cases *Nodes) []*Node {
                        r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[TBOOL], &r.Ninit, ch, n.Right)
 
                case OSELRECV:
-                       // if c != nil && selectnbrecv(&v, c) { body } else { default body }
+                       // if selectnbrecv(&v, c) { body } else { default body }
                        r = nod(OIF, nil, nil)
                        r.Ninit.Set(cas.Ninit.Slice())
                        ch := n.Right.Left
@@ -236,7 +232,7 @@ func walkselectcases(cases *Nodes) []*Node {
                        r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, ch)
 
                case OSELRECV2:
-                       // if c != nil && selectnbrecv2(&v, c) { body } else { default body }
+                       // if selectnbrecv2(&v, &received, c) { body } else { default body }
                        r = nod(OIF, nil, nil)
                        r.Ninit.Set(cas.Ninit.Slice())
                        ch := n.Right.Left
@@ -244,7 +240,9 @@ func walkselectcases(cases *Nodes) []*Node {
                        if elem == nil {
                                elem = nodnil()
                        }
-                       r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, n.List.First(), ch)
+                       receivedp := nod(OADDR, n.List.First(), nil)
+                       receivedp = typecheck(receivedp, Erv)
+                       r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, receivedp, ch)
                }
 
                r.Left = typecheck(r.Left, Erv)
@@ -282,7 +280,7 @@ func walkselectcases(cases *Nodes) []*Node {
                        caseDefault
                )
 
-               var c, elem, receivedp *Node
+               var c, elem *Node
                var kind int64 = caseDefault
 
                if n := cas.Left; n != nil {
@@ -295,15 +293,10 @@ func walkselectcases(cases *Nodes) []*Node {
                                kind = caseSend
                                c = n.Left
                                elem = n.Right
-                       case OSELRECV:
-                               kind = caseRecv
-                               c = n.Right.Left
-                               elem = n.Left
-                       case OSELRECV2:
+                       case OSELRECV, OSELRECV2:
                                kind = caseRecv
                                c = n.Right.Left
                                elem = n.Left
-                               receivedp = n.List.First()
                        }
                }
 
@@ -324,11 +317,6 @@ func walkselectcases(cases *Nodes) []*Node {
                        elem.Type = types.Types[TUNSAFEPTR]
                        setField("elem", elem)
                }
-               if receivedp != nil {
-                       receivedp = nod(OCONVNOP, receivedp, nil)
-                       receivedp.Type = types.NewPtr(types.Types[TBOOL])
-                       setField("receivedp", receivedp)
-               }
 
                // TODO(mdempsky): There should be a cleaner way to
                // handle this.
@@ -341,7 +329,11 @@ func walkselectcases(cases *Nodes) []*Node {
        // run the select
        lineno = sellineno
        chosen := temp(types.Types[TINT])
-       r = nod(OAS, chosen, mkcall("selectgo", types.Types[TINT], nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), nodintconst(int64(n))))
+       recvOK := temp(types.Types[TBOOL])
+       r = nod(OAS2, nil, nil)
+       r.List.Set2(chosen, recvOK)
+       fn := syslook("selectgo")
+       r.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), nodintconst(int64(n))))
        r = typecheck(r, Etop)
        init = append(init, r)
 
@@ -358,6 +350,13 @@ func walkselectcases(cases *Nodes) []*Node {
                cond = defaultlit(cond, nil)
 
                r = nod(OIF, cond, nil)
+
+               if n := cas.Left; n != nil && n.Op == OSELRECV2 {
+                       x := nod(OAS, n.List.First(), recvOK)
+                       x = typecheck(x, Etop)
+                       r.Nbody.Append(x)
+               }
+
                r.Nbody.AppendNodes(&cas.Nbody)
                r.Nbody.Append(nod(OBREAK, nil, nil))
                init = append(init, r)
@@ -382,7 +381,6 @@ func scasetype() *types.Type {
                scase = tostruct([]*Node{
                        namedfield("c", types.Types[TUNSAFEPTR]),
                        namedfield("elem", types.Types[TUNSAFEPTR]),
-                       namedfield("receivedp", types.NewPtr(types.Types[TBOOL])),
                        namedfield("kind", types.Types[TUINT16]),
                        namedfield("pc", types.Types[TUINTPTR]),
                        namedfield("releasetime", types.Types[TUINT64]),
index 6e6849c7d3bd82b02d7f78482a63085e1e30bfec..7935b4fd86bfb1e415a26cda937f95ed02099b01 100644 (file)
@@ -28,7 +28,6 @@ const (
 type scase struct {
        c           *hchan         // chan
        elem        unsafe.Pointer // data element
-       receivedp   *bool          // pointer to received bool, if any
        kind        uint16
        pc          uintptr // race pc (for race detector / msan)
        releasetime int64
@@ -111,7 +110,9 @@ func block() {
 //
 // selectgo returns the index of the chosen scase, which matches the
 // ordinal position of its respective select{recv,send,default} call.
-func selectgo(cas0 *scase, order0 *uint16, ncases int) int {
+// Also, if the chosen scase was a receive operation, it returns whether
+// a value was received.
+func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) {
        if debugSelect {
                print("select: cas0=", cas0, "\n")
        }
@@ -219,6 +220,7 @@ loop:
        var dfl *scase
        var casi int
        var cas *scase
+       var recvOK bool
        for i := 0; i < ncases; i++ {
                casi = int(pollorder[i])
                cas = &scases[casi]
@@ -375,8 +377,8 @@ loop:
                print("wait-return: cas0=", cas0, " c=", c, " cas=", cas, " kind=", cas.kind, "\n")
        }
 
-       if cas.kind == caseRecv && cas.receivedp != nil {
-               *cas.receivedp = true
+       if cas.kind == caseRecv {
+               recvOK = true
        }
 
        if raceenabled {
@@ -409,9 +411,7 @@ bufrecv:
        if msanenabled && cas.elem != nil {
                msanwrite(cas.elem, c.elemtype.size)
        }
-       if cas.receivedp != nil {
-               *cas.receivedp = true
-       }
+       recvOK = true
        qp = chanbuf(c, c.recvx)
        if cas.elem != nil {
                typedmemmove(c.elemtype, cas.elem, qp)
@@ -450,17 +450,13 @@ recv:
        if debugSelect {
                print("syncrecv: cas0=", cas0, " c=", c, "\n")
        }
-       if cas.receivedp != nil {
-               *cas.receivedp = true
-       }
+       recvOK = true
        goto retc
 
 rclose:
        // read at end of closed channel
        selunlock(scases, lockorder)
-       if cas.receivedp != nil {
-               *cas.receivedp = false
-       }
+       recvOK = false
        if cas.elem != nil {
                typedmemclr(c.elemtype, cas.elem)
        }
@@ -487,7 +483,7 @@ retc:
        if cas.releasetime > 0 {
                blockevent(cas.releasetime-t0, 1)
        }
-       return casi
+       return casi, recvOK
 
 sclose:
        // send on closed channel
@@ -521,13 +517,12 @@ const (
 )
 
 //go:linkname reflect_rselect reflect.rselect
-func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) {
+func reflect_rselect(cases []runtimeSelect) (int, bool) {
        if len(cases) == 0 {
                block()
        }
        sel := make([]scase, len(cases))
        order := make([]uint16, 2*len(cases))
-       r := new(bool)
        for i := range cases {
                rc := &cases[i]
                switch rc.dir {
@@ -536,16 +531,14 @@ func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) {
                case selectSend:
                        sel[i] = scase{kind: caseSend, c: rc.ch, elem: rc.val}
                case selectRecv:
-                       sel[i] = scase{kind: caseRecv, c: rc.ch, elem: rc.val, receivedp: r}
+                       sel[i] = scase{kind: caseRecv, c: rc.ch, elem: rc.val}
                }
                if raceenabled || msanenabled {
                        selectsetpc(&sel[i])
                }
        }
 
-       chosen = selectgo(&sel[0], &order[0], len(cases))
-       recvOK = *r
-       return
+       return selectgo(&sel[0], &order[0], len(cases))
 }
 
 func (q *waitq) dequeueSudoG(sgp *sudog) {