]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/gc: cleanup esc.go
authorHiroshi Ioka <hirochachacha@gmail.com>
Wed, 12 Oct 2016 02:34:47 +0000 (11:34 +0900)
committerDavid Chase <drchase@google.com>
Thu, 13 Oct 2016 03:06:06 +0000 (03:06 +0000)
* convert important functions to methods
* rename EscXXX to XXX in NodeEscState
* rename local variables more friendly
* simplify redundant code
* update comments

Change-Id: I8442bf4f8dde84523d9a2ad3d04b1cd326bd4719
Reviewed-on: https://go-review.googlesource.com/30893
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/fmt.go

index d03a97ef3303c1cc740f9d249ac625926f1e2dee..2cb4510332ee311df2c2cc2fac372411f8083c10 100644 (file)
@@ -14,11 +14,11 @@ import (
 // or single non-recursive functions, bottom up.
 //
 // Finding these sets is finding strongly connected components
-// in the static call graph. The algorithm for doing that is taken
-// from Sedgewick, Algorithms, Second Edition, p. 482, with two
-// adaptations.
+// by reverse topological order in the static call graph.
+// The algorithm (known as Tarjan's algorithm) for doing that is taken from
+// Sedgewick, Algorithms, Second Edition, p. 482, with two adaptations.
 //
-// First, a hidden closure function (n->curfn != N) cannot be the
+// First, a hidden closure function (n.Func.FCurfn != nil) cannot be the
 // root of a connected component. Refusing to use it as a root
 // forces it into the component of the function in which it appears.
 // This is more convenient for escape analysis.
@@ -81,8 +81,8 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 {
        if (min == id || min == id+1) && n.Func.FCurfn == nil {
                // This node is the root of a strongly connected component.
 
-               // The original min passed to visitcodelist was n->walkgen+1.
-               // If visitcodelist found its way back to n->walkgen, then this
+               // The original min passed to visitcodelist was v.nodeID[n]+1.
+               // If visitcodelist found its way back to v.nodeID[n], then this
                // block is a set of mutually recursive functions.
                // Otherwise it's just a lone function that does not recurse.
                recursive := min == id
@@ -160,7 +160,7 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 {
 //
 // First escfunc, esc and escassign recurse over the ast of each
 // function to dig out flow(dst,src) edges between any
-// pointer-containing nodes and store them in dst->escflowsrc. For
+// pointer-containing nodes and store them in e.nodeEscState(dst).Flowsrc. For
 // variables assigned to a variable in an outer scope or used as a
 // return value, they store a flow(theSink, src) edge to a fake node
 // 'the Sink'.  For variables referenced in closures, an edge
@@ -309,10 +309,10 @@ type EscStep struct {
 
 type NodeEscState struct {
        Curfn             *Node
-       Escflowsrc        []EscStep // flow(this, src)
-       Escretval         Nodes     // on OCALLxxx, list of dummy return values
-       Escloopdepth      int32     // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
-       Esclevel          Level
+       Flowsrc           []EscStep // flow(this, src)
+       Retval            Nodes     // on OCALLxxx, list of dummy return values
+       Loopdepth         int32     // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
+       Level             Level
        Walkgen           uint32
        Maxextraloopdepth int32
 }
@@ -324,8 +324,9 @@ func (e *EscState) nodeEscState(n *Node) *NodeEscState {
        if n.Opt() != nil {
                Fatalf("nodeEscState: opt in use (%T)", n.Opt())
        }
-       nE := new(NodeEscState)
-       nE.Curfn = Curfn
+       nE := &NodeEscState{
+               Curfn: Curfn,
+       }
        n.SetOpt(nE)
        e.opts = append(e.opts, n)
        return nE
@@ -337,7 +338,7 @@ func (e *EscState) track(n *Node) {
        }
        n.Esc = EscNone // until proven otherwise
        nE := e.nodeEscState(n)
-       nE.Escloopdepth = e.loopdepth
+       nE.Loopdepth = e.loopdepth
        e.noesc = append(e.noesc, n)
 }
 
@@ -409,6 +410,17 @@ type EscState struct {
        walkgen   uint32
 }
 
+func newEscState(recursive bool) *EscState {
+       e := new(EscState)
+       e.theSink.Op = ONAME
+       e.theSink.Orig = &e.theSink
+       e.theSink.Class = PEXTERN
+       e.theSink.Sym = lookup(".sink")
+       e.nodeEscState(&e.theSink).Loopdepth = -1
+       e.recursive = recursive
+       return e
+}
+
 func (e *EscState) stepWalk(dst, src *Node, why string, parent *EscStep) *EscStep {
        // TODO: keep a cache of these, mark entry/exit in escwalk to avoid allocation
        // Or perhaps never mind, since it is disabled unless printing is on.
@@ -446,14 +458,7 @@ func (e *EscState) curfnSym(n *Node) *Sym {
 }
 
 func escAnalyze(all []*Node, recursive bool) {
-       var es EscState
-       e := &es
-       e.theSink.Op = ONAME
-       e.theSink.Orig = &e.theSink
-       e.theSink.Class = PEXTERN
-       e.theSink.Sym = lookup(".sink")
-       e.nodeEscState(&e.theSink).Escloopdepth = -1
-       e.recursive = recursive
+       e := newEscState(recursive)
 
        for _, n := range all {
                if n.Op == ODCLFUNC {
@@ -464,11 +469,11 @@ func escAnalyze(all []*Node, recursive bool) {
        // flow-analyze functions
        for _, n := range all {
                if n.Op == ODCLFUNC {
-                       escfunc(e, n)
+                       e.escfunc(n)
                }
        }
 
-       // print("escapes: %d e->dsts, %d edges\n", e->dstcount, e->edgecount);
+       // print("escapes: %d e.dsts, %d edges\n", e.dstcount, e.edgecount);
 
        // visit the upstream of each dst, mark address nodes with
        // addrescapes, mark parameters unsafe
@@ -477,7 +482,7 @@ func escAnalyze(all []*Node, recursive bool) {
                escapes[i] = n.Esc
        }
        for _, n := range e.dsts {
-               escflood(e, n)
+               e.escflood(n)
        }
        for {
                done := true
@@ -488,7 +493,7 @@ func escAnalyze(all []*Node, recursive bool) {
                                        Warnl(n.Lineno, "Reflooding %v %S", e.curfnSym(n), n)
                                }
                                escapes[i] = n.Esc
-                               escflood(e, n)
+                               e.escflood(n)
                        }
                }
                if done {
@@ -499,7 +504,7 @@ func escAnalyze(all []*Node, recursive bool) {
        // for all top level functions, tag the typenodes corresponding to the param nodes
        for _, n := range all {
                if n.Op == ODCLFUNC {
-                       esctag(e, n)
+                       e.esctag(n)
                }
        }
 
@@ -510,35 +515,36 @@ func escAnalyze(all []*Node, recursive bool) {
                        }
                }
        }
+
        for _, x := range e.opts {
                x.SetOpt(nil)
        }
 }
 
-func escfunc(e *EscState, func_ *Node) {
-       //      print("escfunc %N %s\n", func->nname, e->recursive?"(recursive)":"");
-       if func_.Esc != 1 {
-               Fatalf("repeat escfunc %v", func_.Func.Nname)
+func (e *EscState) escfunc(fn *Node) {
+       //      print("escfunc %N %s\n", fn.Func.Nname, e.recursive?"(recursive)":"");
+       if fn.Esc != EscFuncPlanned {
+               Fatalf("repeat escfunc %v", fn.Func.Nname)
        }
-       func_.Esc = EscFuncStarted
+       fn.Esc = EscFuncStarted
 
        saveld := e.loopdepth
        e.loopdepth = 1
        savefn := Curfn
-       Curfn = func_
+       Curfn = fn
 
        for _, ln := range Curfn.Func.Dcl {
                if ln.Op != ONAME {
                        continue
                }
-               llNE := e.nodeEscState(ln)
+               lnE := e.nodeEscState(ln)
                switch ln.Class {
                // out params are in a loopdepth between the sink and all local variables
                case PPARAMOUT:
-                       llNE.Escloopdepth = 0
+                       lnE.Loopdepth = 0
 
                case PPARAM:
-                       llNE.Escloopdepth = 1
+                       lnE.Loopdepth = 1
                        if ln.Type != nil && !haspointers(ln.Type) {
                                break
                        }
@@ -555,36 +561,36 @@ func escfunc(e *EscState, func_ *Node) {
        if e.recursive {
                for _, ln := range Curfn.Func.Dcl {
                        if ln.Op == ONAME && ln.Class == PPARAMOUT {
-                               escflows(e, &e.theSink, ln, e.stepAssign(nil, ln, ln, "returned from recursive function"))
+                               e.escflows(&e.theSink, ln, e.stepAssign(nil, ln, ln, "returned from recursive function"))
                        }
                }
        }
 
-       escloopdepthlist(e, Curfn.Nbody)
-       esclist(e, Curfn.Nbody, Curfn)
+       e.escloopdepthlist(Curfn.Nbody)
+       e.esclist(Curfn.Nbody, Curfn)
        Curfn = savefn
        e.loopdepth = saveld
 }
 
-// Mark labels that have no backjumps to them as not increasing e->loopdepth.
-// Walk hasn't generated (goto|label)->left->sym->label yet, so we'll cheat
+// Mark labels that have no backjumps to them as not increasing e.loopdepth.
+// Walk hasn't generated (goto|label).Left.Sym.Label yet, so we'll cheat
 // and set it to one of the following two. Then in esc we'll clear it again.
 var looping Label
 
 var nonlooping Label
 
-func escloopdepthlist(e *EscState, l Nodes) {
+func (e *EscState) escloopdepthlist(l Nodes) {
        for _, n := range l.Slice() {
-               escloopdepth(e, n)
+               e.escloopdepth(n)
        }
 }
 
-func escloopdepth(e *EscState, n *Node) {
+func (e *EscState) escloopdepth(n *Node) {
        if n == nil {
                return
        }
 
-       escloopdepthlist(e, n.Ninit)
+       e.escloopdepthlist(n.Ninit)
 
        switch n.Op {
        case OLABEL:
@@ -594,7 +600,7 @@ func escloopdepth(e *EscState, n *Node) {
 
                // Walk will complain about this label being already defined, but that's not until
                // after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc
-               // if(n->left->sym->label != nil)
+               // if(n.Left.Sym.Label != nil)
                //      fatal("escape analysis messed up analyzing label: %+N", n);
                n.Left.Sym.Label = &nonlooping
 
@@ -610,20 +616,20 @@ func escloopdepth(e *EscState, n *Node) {
                }
        }
 
-       escloopdepth(e, n.Left)
-       escloopdepth(e, n.Right)
-       escloopdepthlist(e, n.List)
-       escloopdepthlist(e, n.Nbody)
-       escloopdepthlist(e, n.Rlist)
+       e.escloopdepth(n.Left)
+       e.escloopdepth(n.Right)
+       e.escloopdepthlist(n.List)
+       e.escloopdepthlist(n.Nbody)
+       e.escloopdepthlist(n.Rlist)
 }
 
-func esclist(e *EscState, l Nodes, up *Node) {
+func (e *EscState) esclist(l Nodes, parent *Node) {
        for _, n := range l.Slice() {
-               esc(e, n, up)
+               e.esc(n, parent)
        }
 }
 
-func esc(e *EscState, n *Node, up *Node) {
+func (e *EscState) esc(n *Node, parent *Node) {
        if n == nil {
                return
        }
@@ -637,7 +643,7 @@ func esc(e *EscState, n *Node, up *Node) {
        lno := setlineno(n)
 
        // ninit logically runs at a different loopdepth than the rest of the for loop.
-       esclist(e, n.Ninit, n)
+       e.esclist(n.Ninit, n)
 
        if n.Op == OFOR || n.Op == ORANGE {
                e.loopdepth++
@@ -651,7 +657,7 @@ func esc(e *EscState, n *Node, up *Node) {
                for _, n1 := range n.List.Slice() { // cases
                        // it.N().Rlist is the variable per case
                        if n1.Rlist.Len() != 0 {
-                               e.nodeEscState(n1.Rlist.First()).Escloopdepth = e.loopdepth
+                               e.nodeEscState(n1.Rlist.First()).Loopdepth = e.loopdepth
                        }
                }
        }
@@ -667,14 +673,14 @@ func esc(e *EscState, n *Node, up *Node) {
                }
                n.Esc = EscHeap
                addrescapes(n)
-               escassignSinkNilWhy(e, n, n, "too large for stack") // TODO category: tooLarge
+               e.escassignSinkNilWhy(n, n, "too large for stack") // TODO category: tooLarge
        }
 
-       esc(e, n.Left, n)
-       esc(e, n.Right, n)
-       esclist(e, n.Nbody, n)
-       esclist(e, n.List, n)
-       esclist(e, n.Rlist, n)
+       e.esc(n.Left, n)
+       e.esc(n.Right, n)
+       e.esclist(n.Nbody, n)
+       e.esclist(n.List, n)
+       e.esclist(n.Rlist, n)
 
        if n.Op == OFOR || n.Op == ORANGE {
                e.loopdepth--
@@ -688,7 +694,7 @@ func esc(e *EscState, n *Node, up *Node) {
        // Record loop depth at declaration.
        case ODCL:
                if n.Left != nil {
-                       e.nodeEscState(n.Left).Escloopdepth = e.loopdepth
+                       e.nodeEscState(n.Left).Loopdepth = e.loopdepth
                }
 
        case OLABEL:
@@ -704,7 +710,7 @@ func esc(e *EscState, n *Node, up *Node) {
                }
 
                // See case OLABEL in escloopdepth above
-               // else if(n->left->sym->label == nil)
+               // else if(n.Left.Sym.Label == nil)
                //      fatal("escape analysis missed or messed up a label: %+N", n);
 
                n.Left.Sym.Label = nil
@@ -718,9 +724,9 @@ func esc(e *EscState, n *Node, up *Node) {
                        // dereferenced (see #12588)
                        if n.Type.IsArray() &&
                                !(n.Right.Type.IsPtr() && eqtype(n.Right.Type.Elem(), n.Type)) {
-                               escassignNilWhy(e, n.List.Second(), n.Right, "range")
+                               e.escassignNilWhy(n.List.Second(), n.Right, "range")
                        } else {
-                               escassignDereference(e, n.List.Second(), n.Right, e.stepAssign(nil, n.List.Second(), n.Right, "range-deref"))
+                               e.escassignDereference(n.List.Second(), n.Right, e.stepAssign(nil, n.List.Second(), n.Right, "range-deref"))
                        }
                }
 
@@ -731,7 +737,7 @@ func esc(e *EscState, n *Node, up *Node) {
                                // n.Left.Right is the argument of the .(type),
                                // it.N().Rlist is the variable per case
                                if n2.Rlist.Len() != 0 {
-                                       escassignNilWhy(e, n2.Rlist.First(), n.Left.Right, "switch case")
+                                       e.escassignNilWhy(n2.Rlist.First(), n.Left.Right, "switch case")
                                }
                        }
                }
@@ -769,25 +775,25 @@ func esc(e *EscState, n *Node, up *Node) {
                        break
                }
 
-               escassign(e, n.Left, n.Right, nil)
+               e.escassign(n.Left, n.Right, nil)
 
        case OAS2: // x,y = a,b
                if n.List.Len() == n.Rlist.Len() {
                        rs := n.Rlist.Slice()
                        for i, n := range n.List.Slice() {
-                               escassignNilWhy(e, n, rs[i], "assign-pair")
+                               e.escassignNilWhy(n, rs[i], "assign-pair")
                        }
                }
 
        case OAS2RECV: // v, ok = <-ch
-               escassignNilWhy(e, n.List.First(), n.Rlist.First(), "assign-pair-receive")
+               e.escassignNilWhy(n.List.First(), n.Rlist.First(), "assign-pair-receive")
        case OAS2MAPR: // v, ok = m[k]
-               escassignNilWhy(e, n.List.First(), n.Rlist.First(), "assign-pair-mapr")
+               e.escassignNilWhy(n.List.First(), n.Rlist.First(), "assign-pair-mapr")
        case OAS2DOTTYPE: // v, ok = x.(type)
-               escassignNilWhy(e, n.List.First(), n.Rlist.First(), "assign-pair-dot-type")
+               e.escassignNilWhy(n.List.First(), n.Rlist.First(), "assign-pair-dot-type")
 
        case OSEND: // ch <- x
-               escassignSinkNilWhy(e, n, n.Right, "send")
+               e.escassignSinkNilWhy(n, n.Right, "send")
 
        case ODEFER:
                if e.loopdepth == 1 { // top level
@@ -796,96 +802,96 @@ func esc(e *EscState, n *Node, up *Node) {
                // arguments leak out of scope
                // TODO: leak to a dummy node instead
                // defer f(x) - f and x escape
-               escassignSinkNilWhy(e, n, n.Left.Left, "defer func")
+               e.escassignSinkNilWhy(n, n.Left.Left, "defer func")
 
-               escassignSinkNilWhy(e, n, n.Left.Right, "defer func ...") // ODDDARG for call
+               e.escassignSinkNilWhy(n, n.Left.Right, "defer func ...") // ODDDARG for call
                for _, n4 := range n.Left.List.Slice() {
-                       escassignSinkNilWhy(e, n, n4, "defer func arg")
+                       e.escassignSinkNilWhy(n, n4, "defer func arg")
                }
 
        case OPROC:
                // go f(x) - f and x escape
-               escassignSinkNilWhy(e, n, n.Left.Left, "go func")
+               e.escassignSinkNilWhy(n, n.Left.Left, "go func")
 
-               escassignSinkNilWhy(e, n, n.Left.Right, "go func ...") // ODDDARG for call
+               e.escassignSinkNilWhy(n, n.Left.Right, "go func ...") // ODDDARG for call
                for _, n4 := range n.Left.List.Slice() {
-                       escassignSinkNilWhy(e, n, n4, "go func arg")
+                       e.escassignSinkNilWhy(n, n4, "go func arg")
                }
 
        case OCALLMETH, OCALLFUNC, OCALLINTER:
-               esccall(e, n, up)
+               e.esccall(n, parent)
 
-               // esccall already done on n->rlist->n. tie it's escretval to n->list
+               // esccall already done on n.Rlist.First(). tie it's Retval to n.List
        case OAS2FUNC: // x,y = f()
-               rs := e.nodeEscState(n.Rlist.First()).Escretval.Slice()
+               rs := e.nodeEscState(n.Rlist.First()).Retval.Slice()
                for i, n := range n.List.Slice() {
                        if i >= len(rs) {
                                break
                        }
-                       escassignNilWhy(e, n, rs[i], "assign-pair-func-call")
+                       e.escassignNilWhy(n, rs[i], "assign-pair-func-call")
                }
                if n.List.Len() != len(rs) {
                        Fatalf("esc oas2func")
                }
 
        case ORETURN:
-               ll := n.List
-               if n.List.Len() == 1 && Curfn.Type.Results().NumFields() > 1 {
+               retList := n.List
+               if retList.Len() == 1 && Curfn.Type.Results().NumFields() > 1 {
                        // OAS2FUNC in disguise
-                       // esccall already done on n->list->n
-                       // tie n->list->n->escretval to curfn->dcl PPARAMOUT's
-                       ll = e.nodeEscState(n.List.First()).Escretval
+                       // esccall already done on n.List.First()
+                       // tie e.nodeEscState(n.List.First()).Retval to Curfn.Func.Dcl PPARAMOUT's
+                       retList = e.nodeEscState(n.List.First()).Retval
                }
 
                i := 0
                for _, lrn := range Curfn.Func.Dcl {
-                       if i >= ll.Len() {
+                       if i >= retList.Len() {
                                break
                        }
                        if lrn.Op != ONAME || lrn.Class != PPARAMOUT {
                                continue
                        }
-                       escassignNilWhy(e, lrn, ll.Index(i), "return")
+                       e.escassignNilWhy(lrn, retList.Index(i), "return")
                        i++
                }
 
-               if i < ll.Len() {
+               if i < retList.Len() {
                        Fatalf("esc return list")
                }
 
                // Argument could leak through recover.
        case OPANIC:
-               escassignSinkNilWhy(e, n, n.Left, "panic")
+               e.escassignSinkNilWhy(n, n.Left, "panic")
 
        case OAPPEND:
                if !n.Isddd {
                        for _, nn := range n.List.Slice()[1:] {
-                               escassignSinkNilWhy(e, n, nn, "appended to slice") // lose track of assign to dereference
+                               e.escassignSinkNilWhy(n, nn, "appended to slice") // lose track of assign to dereference
                        }
                } else {
                        // append(slice1, slice2...) -- slice2 itself does not escape, but contents do.
                        slice2 := n.List.Second()
-                       escassignDereference(e, &e.theSink, slice2, e.stepAssign(nil, n, slice2, "appended slice...")) // lose track of assign of dereference
+                       e.escassignDereference(&e.theSink, slice2, e.stepAssign(nil, n, slice2, "appended slice...")) // lose track of assign of dereference
                        if Debug['m'] > 3 {
                                Warnl(n.Lineno, "%v special treatment of append(slice1, slice2...) %S", e.curfnSym(n), n)
                        }
                }
-               escassignDereference(e, &e.theSink, n.List.First(), e.stepAssign(nil, n, n.List.First(), "appendee slice")) // The original elements are now leaked, too
+               e.escassignDereference(&e.theSink, n.List.First(), e.stepAssign(nil, n, n.List.First(), "appendee slice")) // The original elements are now leaked, too
 
        case OCOPY:
-               escassignDereference(e, &e.theSink, n.Right, e.stepAssign(nil, n, n.Right, "copied slice")) // lose track of assign of dereference
+               e.escassignDereference(&e.theSink, n.Right, e.stepAssign(nil, n, n.Right, "copied slice")) // lose track of assign of dereference
 
        case OCONV, OCONVNOP:
-               escassignNilWhy(e, n, n.Left, "converted")
+               e.escassignNilWhy(n, n.Left, "converted")
 
        case OCONVIFACE:
                e.track(n)
-               escassignNilWhy(e, n, n.Left, "interface-converted")
+               e.escassignNilWhy(n, n.Left, "interface-converted")
 
        case OARRAYLIT:
                // Link values to array
                for _, n5 := range n.List.Slice() {
-                       escassign(e, n, n5.Right, e.stepAssign(nil, n, n5.Right, "array literal element"))
+                       e.escassign(n, n5.Right, e.stepAssign(nil, n, n5.Right, "array literal element"))
                }
 
        case OSLICELIT:
@@ -893,33 +899,33 @@ func esc(e *EscState, n *Node, up *Node) {
                e.track(n)
                // Link values to slice
                for _, n5 := range n.List.Slice() {
-                       escassign(e, n, n5.Right, e.stepAssign(nil, n, n5.Right, "slice literal element"))
+                       e.escassign(n, n5.Right, e.stepAssign(nil, n, n5.Right, "slice literal element"))
                }
 
                // Link values to struct.
        case OSTRUCTLIT:
                for _, n6 := range n.List.Slice() {
-                       escassignNilWhy(e, n, n6.Right, "struct literal element")
+                       e.escassignNilWhy(n, n6.Right, "struct literal element")
                }
 
        case OPTRLIT:
                e.track(n)
 
                // Link OSTRUCTLIT to OPTRLIT; if OPTRLIT escapes, OSTRUCTLIT elements do too.
-               escassignNilWhy(e, n, n.Left, "pointer literal [assign]")
+               e.escassignNilWhy(n, n.Left, "pointer literal [assign]")
 
        case OCALLPART:
                e.track(n)
 
                // Contents make it to memory, lose track.
-               escassignSinkNilWhy(e, n, n.Left, "call part")
+               e.escassignSinkNilWhy(n, n.Left, "call part")
 
        case OMAPLIT:
                e.track(n)
                // Keys and values make it to memory, lose track.
                for _, n7 := range n.List.Slice() {
-                       escassignSinkNilWhy(e, n, n7.Left, "map literal key")
-                       escassignSinkNilWhy(e, n, n7.Right, "map literal value")
+                       e.escassignSinkNilWhy(n, n7.Left, "map literal key")
+                       e.escassignSinkNilWhy(n, n7.Right, "map literal value")
                }
 
        case OCLOSURE:
@@ -932,11 +938,11 @@ func esc(e *EscState, n *Node, up *Node) {
                        if !v.Name.Byval {
                                a = nod(OADDR, a, nil)
                                a.Lineno = v.Lineno
-                               e.nodeEscState(a).Escloopdepth = e.loopdepth
+                               e.nodeEscState(a).Loopdepth = e.loopdepth
                                a = typecheck(a, Erv)
                        }
 
-                       escassignNilWhy(e, n, a, "captured by a closure")
+                       e.escassignNilWhy(n, a, "captured by a closure")
                }
                fallthrough
 
@@ -968,8 +974,8 @@ func esc(e *EscState, n *Node, up *Node) {
                        case PAUTO:
                                nE := e.nodeEscState(n)
                                leftE := e.nodeEscState(n.Left)
-                               if leftE.Escloopdepth != 0 {
-                                       nE.Escloopdepth = leftE.Escloopdepth
+                               if leftE.Loopdepth != 0 {
+                                       nE.Loopdepth = leftE.Loopdepth
                                }
 
                        // PPARAM is loop depth 1 always.
@@ -980,7 +986,7 @@ func esc(e *EscState, n *Node, up *Node) {
                        // first result move to the heap.
                        case PPARAM, PPARAMOUT:
                                nE := e.nodeEscState(n)
-                               nE.Escloopdepth = 1
+                               nE.Loopdepth = 1
                        }
                }
        }
@@ -990,29 +996,29 @@ func esc(e *EscState, n *Node, up *Node) {
 
 // escassignNilWhy bundles a common case of
 // escassign(e, dst, src, e.stepAssign(nil, dst, src, reason))
-func escassignNilWhy(e *EscState, dst, src *Node, reason string) {
+func (e *EscState) escassignNilWhy(dst, src *Node, reason string) {
        var step *EscStep
        if Debug['m'] != 0 {
                step = e.stepAssign(nil, dst, src, reason)
        }
-       escassign(e, dst, src, step)
+       e.escassign(dst, src, step)
 }
 
 // escassignSinkNilWhy bundles a common case of
 // escassign(e, &e.theSink, src, e.stepAssign(nil, dst, src, reason))
-func escassignSinkNilWhy(e *EscState, dst, src *Node, reason string) {
+func (e *EscState) escassignSinkNilWhy(dst, src *Node, reason string) {
        var step *EscStep
        if Debug['m'] != 0 {
                step = e.stepAssign(nil, dst, src, reason)
        }
-       escassign(e, &e.theSink, src, step)
+       e.escassign(&e.theSink, src, step)
 }
 
 // Assert that expr somehow gets assigned to dst, if non nil.  for
 // dst==nil, any name node expr still must be marked as being
 // evaluated in curfn. For expr==nil, dst must still be examined for
 // evaluations inside it (e.g *f(x) = y)
-func escassign(e *EscState, dst, src *Node, step *EscStep) {
+func (e *EscState) escassign(dst, src *Node, step *EscStep) {
        if isblank(dst) || dst == nil || src == nil || src.Op == ONONAME || src.Op == OXXX {
                return
        }
@@ -1030,7 +1036,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
        dstwhy := "assigned"
 
        // Analyze lhs of assignment.
-       // Replace dst with e->theSink if we can't track it.
+       // Replace dst with &e.theSink if we can't track it.
        switch dst.Op {
        default:
                Dump("dst", dst)
@@ -1047,7 +1053,6 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                OPTRLIT,
                ODDDARG,
                OCALLPART:
-               break
 
        case ONAME:
                if dst.Class == PEXTERN {
@@ -1056,12 +1061,12 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                }
 
        case ODOT: // treat "dst.x = src" as "dst = src"
-               escassign(e, dst.Left, src, e.stepAssign(step, originalDst, src, "dot-equals"))
+               e.escassign(dst.Left, src, e.stepAssign(step, originalDst, src, "dot-equals"))
                return
 
        case OINDEX:
                if dst.Left.Type.IsArray() {
-                       escassign(e, dst.Left, src, e.stepAssign(step, originalDst, src, "array-element-equals"))
+                       e.escassign(dst.Left, src, e.stepAssign(step, originalDst, src, "array-element-equals"))
                        return
                }
 
@@ -1078,7 +1083,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
 
                // lose track of key and value
        case OINDEXMAP:
-               escassign(e, &e.theSink, dst.Right, e.stepAssign(nil, originalDst, src, "key of map put"))
+               e.escassign(&e.theSink, dst.Right, e.stepAssign(nil, originalDst, src, "key of map put"))
                dstwhy = "value of map put"
                dst = &e.theSink
        }
@@ -1109,22 +1114,22 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                OCALLPART,
                ORUNESTR,
                OCONVIFACE:
-               escflows(e, dst, src, e.stepAssign(step, originalDst, src, dstwhy))
+               e.escflows(dst, src, e.stepAssign(step, originalDst, src, dstwhy))
 
        case OCLOSURE:
                // OCLOSURE is lowered to OPTRLIT,
                // insert OADDR to account for the additional indirection.
                a := nod(OADDR, src, nil)
                a.Lineno = src.Lineno
-               e.nodeEscState(a).Escloopdepth = e.nodeEscState(src).Escloopdepth
+               e.nodeEscState(a).Loopdepth = e.nodeEscState(src).Loopdepth
                a.Type = ptrto(src.Type)
-               escflows(e, dst, a, e.stepAssign(nil, originalDst, src, dstwhy))
+               e.escflows(dst, a, e.stepAssign(nil, originalDst, src, dstwhy))
 
        // Flowing multiple returns to a single dst happens when
        // analyzing "go f(g())": here g() flows to sink (issue 4529).
        case OCALLMETH, OCALLFUNC, OCALLINTER:
-               for _, n := range e.nodeEscState(src).Escretval.Slice() {
-                       escflows(e, dst, n, e.stepAssign(nil, originalDst, n, dstwhy))
+               for _, n := range e.nodeEscState(src).Retval.Slice() {
+                       e.escflows(dst, n, e.stepAssign(nil, originalDst, n, dstwhy))
                }
 
                // A non-pointer escaping from a struct does not concern us.
@@ -1146,26 +1151,26 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                OSLICE3ARR,
                OSLICESTR:
                // Conversions, field access, slice all preserve the input value.
-               escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
+               e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
 
        case ODOTTYPE,
                ODOTTYPE2:
                if src.Type != nil && !haspointers(src.Type) {
                        break
                }
-               escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
+               e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
 
        case OAPPEND:
                // Append returns first argument.
                // Subsequent arguments are already leaked because they are operands to append.
-               escassign(e, dst, src.List.First(), e.stepAssign(step, dst, src.List.First(), dstwhy))
+               e.escassign(dst, src.List.First(), e.stepAssign(step, dst, src.List.First(), dstwhy))
 
        case OINDEX:
                // Index of array preserves input value.
                if src.Left.Type.IsArray() {
-                       escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
+                       e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
                } else {
-                       escflows(e, dst, src, e.stepAssign(step, originalDst, src, dstwhy))
+                       e.escflows(dst, src, e.stepAssign(step, originalDst, src, dstwhy))
                }
 
        // Might be pointer arithmetic, in which case
@@ -1185,9 +1190,9 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
                OPLUS,
                OMINUS,
                OCOM:
-               escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
+               e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
 
-               escassign(e, dst, src.Right, e.stepAssign(step, originalDst, src, dstwhy))
+               e.escassign(dst, src.Right, e.stepAssign(step, originalDst, src, dstwhy))
        }
 
        e.pdepth--
@@ -1207,8 +1212,6 @@ var tags [1 << (bitsPerOutputInTag + EscReturnBits)]string
 func mktag(mask int) string {
        switch mask & EscMask {
        case EscNone, EscReturn:
-               break
-
        default:
                Fatalf("escape mktag")
        }
@@ -1291,7 +1294,7 @@ func describeEscape(em uint16) string {
 
 // escassignfromtag models the input-to-output assignment flow of one of a function
 // calls arguments, where the flow is encoded in "note".
-func escassignfromtag(e *EscState, note string, dsts Nodes, src *Node) uint16 {
+func (e *EscState) escassignfromtag(note string, dsts Nodes, src *Node) uint16 {
        em := parsetag(note)
        if src.Op == OLITERAL {
                return em
@@ -1303,7 +1306,7 @@ func escassignfromtag(e *EscState, note string, dsts Nodes, src *Node) uint16 {
        }
 
        if em == EscUnknown {
-               escassignSinkNilWhy(e, src, src, "passed to function[unknown]")
+               e.escassignSinkNilWhy(src, src, "passed to function[unknown]")
                return em
        }
 
@@ -1314,7 +1317,7 @@ func escassignfromtag(e *EscState, note string, dsts Nodes, src *Node) uint16 {
        // If content inside parameter (reached via indirection)
        // escapes to heap, mark as such.
        if em&EscContentEscapes != 0 {
-               escassign(e, &e.theSink, e.addDereference(src), e.stepAssign(nil, src, src, "passed to function[content escapes]"))
+               e.escassign(&e.theSink, e.addDereference(src), e.stepAssign(nil, src, src, "passed to function[content escapes]"))
        }
 
        em0 := em
@@ -1331,7 +1334,7 @@ func escassignfromtag(e *EscState, note string, dsts Nodes, src *Node) uint16 {
                        for i := uint16(0); i < embits-1; i++ {
                                n = e.addDereference(n) // encode level>0 as indirections
                        }
-                       escassign(e, dsts.Index(dstsi), n, e.stepAssign(nil, dsts.Index(dstsi), src, "passed-to-and-returned-from-function"))
+                       e.escassign(dsts.Index(dstsi), n, e.stepAssign(nil, dsts.Index(dstsi), src, "passed-to-and-returned-from-function"))
                }
                dstsi++
        }
@@ -1345,11 +1348,11 @@ func escassignfromtag(e *EscState, note string, dsts Nodes, src *Node) uint16 {
        return em0
 }
 
-func escassignDereference(e *EscState, dst *Node, src *Node, step *EscStep) {
+func (e *EscState) escassignDereference(dst *Node, src *Node, step *EscStep) {
        if src.Op == OLITERAL {
                return
        }
-       escassign(e, dst, e.addDereference(src), step)
+       e.escassign(dst, e.addDereference(src), step)
 }
 
 // addDereference constructs a suitable OIND note applied to src.
@@ -1357,7 +1360,7 @@ func escassignDereference(e *EscState, dst *Node, src *Node, step *EscStep) {
 // some semantically dubious node combinations are (currently) possible.
 func (e *EscState) addDereference(n *Node) *Node {
        ind := nod(OIND, n, nil)
-       e.nodeEscState(ind).Escloopdepth = e.nodeEscState(n).Escloopdepth
+       e.nodeEscState(ind).Loopdepth = e.nodeEscState(n).Loopdepth
        ind.Lineno = n.Lineno
        t := n.Type
        if t.IsKind(Tptr) {
@@ -1404,147 +1407,145 @@ func escNoteOutputParamFlow(e uint16, vargen int32, level Level) uint16 {
        return (e &^ (bitsMaskForTag << shift)) | encodedFlow
 }
 
-func initEscretval(e *EscState, n *Node, fntype *Type) {
-       i := 0
-       nE := e.nodeEscState(n)
-       nE.Escretval.Set(nil) // Suspect this is not nil for indirect calls.
-       for _, t := range fntype.Results().Fields().Slice() {
-               src := nod(ONAME, nil, nil)
+func (e *EscState) initEscRetval(call *Node, fntype *Type) {
+       cE := e.nodeEscState(call)
+       cE.Retval.Set(nil) // Suspect this is not nil for indirect calls.
+       for i, f := range fntype.Results().Fields().Slice() {
+               ret := nod(ONAME, nil, nil)
                buf := fmt.Sprintf(".out%d", i)
-               i++
-               src.Sym = lookup(buf)
-               src.Type = t.Type
-               src.Class = PAUTO
-               src.Name.Curfn = Curfn
-               e.nodeEscState(src).Escloopdepth = e.loopdepth
-               src.Used = true
-               src.Lineno = n.Lineno
-               nE.Escretval.Append(src)
+               ret.Sym = lookup(buf)
+               ret.Type = f.Type
+               ret.Class = PAUTO
+               ret.Name.Curfn = Curfn
+               e.nodeEscState(ret).Loopdepth = e.loopdepth
+               ret.Used = true
+               ret.Lineno = call.Lineno
+               cE.Retval.Append(ret)
        }
 }
 
 // This is a bit messier than fortunate, pulled out of esc's big
-// switch for clarity. We either have the paramnodes, which may be
+// switch for clarity. We either have the paramnodes, which may be
 // connected to other things through flows or we have the parameter type
 // nodes, which may be marked "noescape". Navigating the ast is slightly
 // different for methods vs plain functions and for imported vs
 // this-package
-func esccall(e *EscState, n *Node, up *Node) {
+func (e *EscState) esccall(call *Node, parent *Node) {
        var fntype *Type
        var indirect bool
        var fn *Node
-       switch n.Op {
+       switch call.Op {
        default:
                Fatalf("esccall")
 
        case OCALLFUNC:
-               fn = n.Left
+               fn = call.Left
                fntype = fn.Type
                indirect = fn.Op != ONAME || fn.Class != PFUNC
 
        case OCALLMETH:
-               fn = n.Left.Sym.Def
+               fn = call.Left.Sym.Def
                if fn != nil {
                        fntype = fn.Type
                } else {
-                       fntype = n.Left.Type
+                       fntype = call.Left.Type
                }
 
        case OCALLINTER:
-               fntype = n.Left.Type
+               fntype = call.Left.Type
                indirect = true
        }
 
-       ll := n.List
-       if n.List.Len() == 1 {
-               a := n.List.First()
-               if a.Type.IsFuncArgStruct() { // f(g())
-                       ll = e.nodeEscState(a).Escretval
+       argList := call.List
+       if argList.Len() == 1 {
+               arg := argList.First()
+               if arg.Type.IsFuncArgStruct() { // f(g())
+                       argList = e.nodeEscState(arg).Retval
                }
        }
 
+       args := argList.Slice()
+
        if indirect {
                // We know nothing!
                // Leak all the parameters
-               for _, n1 := range ll.Slice() {
-                       escassignSinkNilWhy(e, n, n1, "parameter to indirect call")
+               for _, arg := range args {
+                       e.escassignSinkNilWhy(call, arg, "parameter to indirect call")
                        if Debug['m'] > 3 {
-                               fmt.Printf("%v::esccall:: indirect call <- %S, untracked\n", linestr(lineno), n1)
+                               fmt.Printf("%v::esccall:: indirect call <- %S, untracked\n", linestr(lineno), arg)
                        }
                }
                // Set up bogus outputs
-               initEscretval(e, n, fntype)
+               e.initEscRetval(call, fntype)
                // If there is a receiver, it also leaks to heap.
-               if n.Op != OCALLFUNC {
-                       t := fntype.Recv()
-                       src := n.Left.Left
-                       if haspointers(t.Type) {
-                               escassignSinkNilWhy(e, n, src, "receiver in indirect call")
+               if call.Op != OCALLFUNC {
+                       rf := fntype.Recv()
+                       r := call.Left.Left
+                       if haspointers(rf.Type) {
+                               e.escassignSinkNilWhy(call, r, "receiver in indirect call")
                        }
                } else { // indirect and OCALLFUNC = could be captured variables, too. (#14409)
-                       ll := e.nodeEscState(n).Escretval.Slice()
-                       for _, llN := range ll {
-                               escassignDereference(e, llN, fn, e.stepAssign(nil, llN, fn, "captured by called closure"))
+                       rets := e.nodeEscState(call).Retval.Slice()
+                       for _, ret := range rets {
+                               e.escassignDereference(ret, fn, e.stepAssign(nil, ret, fn, "captured by called closure"))
                        }
                }
                return
        }
 
-       nE := e.nodeEscState(n)
+       cE := e.nodeEscState(call)
        if fn != nil && fn.Op == ONAME && fn.Class == PFUNC &&
                fn.Name.Defn != nil && fn.Name.Defn.Nbody.Len() != 0 && fn.Name.Param.Ntype != nil && fn.Name.Defn.Esc < EscFuncTagged {
                if Debug['m'] > 3 {
-                       fmt.Printf("%v::esccall:: %S in recursive group\n", linestr(lineno), n)
+                       fmt.Printf("%v::esccall:: %S in recursive group\n", linestr(lineno), call)
                }
 
                // function in same mutually recursive group. Incorporate into flow graph.
-               //              print("esc local fn: %N\n", fn->ntype);
-               if fn.Name.Defn.Esc == EscFuncUnknown || nE.Escretval.Len() != 0 {
+               //              print("esc local fn: %N\n", fn.Func.Ntype);
+               if fn.Name.Defn.Esc == EscFuncUnknown || cE.Retval.Len() != 0 {
                        Fatalf("graph inconsistency")
                }
 
-               lls := ll.Slice()
                sawRcvr := false
-               var src *Node
-               for _, n2 := range fn.Name.Defn.Func.Dcl {
-                       switch n2.Class {
+               for _, n := range fn.Name.Defn.Func.Dcl {
+                       switch n.Class {
                        case PPARAM:
-                               if n.Op != OCALLFUNC && !sawRcvr {
-                                       escassignNilWhy(e, n2, n.Left.Left, "call receiver")
+                               if call.Op != OCALLFUNC && !sawRcvr {
+                                       e.escassignNilWhy(n, call.Left.Left, "call receiver")
                                        sawRcvr = true
                                        continue
                                }
-                               if len(lls) == 0 {
+                               if len(args) == 0 {
                                        continue
                                }
-                               src = lls[0]
-                               if n2.Isddd && !n.Isddd {
+                               arg := args[0]
+                               if n.Isddd && !call.Isddd {
                                        // Introduce ODDDARG node to represent ... allocation.
-                                       src = nod(ODDDARG, nil, nil)
-                                       arr := typArray(n2.Type.Elem(), int64(len(lls)))
-                                       src.Type = ptrto(arr) // make pointer so it will be tracked
-                                       src.Lineno = n.Lineno
-                                       e.track(src)
-                                       n.Right = src
+                                       arg = nod(ODDDARG, nil, nil)
+                                       arr := typArray(n.Type.Elem(), int64(len(args)))
+                                       arg.Type = ptrto(arr) // make pointer so it will be tracked
+                                       arg.Lineno = call.Lineno
+                                       e.track(arg)
+                                       call.Right = arg
                                }
-                               escassignNilWhy(e, n2, src, "arg to recursive call")
-                               if src != lls[0] {
+                               e.escassignNilWhy(n, arg, "arg to recursive call")
+                               if arg != args[0] {
                                        // "..." arguments are untracked
-                                       for _, n2 := range lls {
+                                       for _, a := range args {
                                                if Debug['m'] > 3 {
-                                                       fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), n2)
+                                                       fmt.Printf("%v::esccall:: ... <- %S, untracked\n", linestr(lineno), a)
                                                }
-                                               escassignSinkNilWhy(e, src, n2, "... arg to recursive call")
+                                               e.escassignSinkNilWhy(arg, a, "... arg to recursive call")
                                        }
                                        // No more PPARAM processing, but keep
                                        // going for PPARAMOUT.
-                                       lls = nil
+                                       args = nil
                                        continue
                                }
-                               lls = lls[1:]
+                               args = args[1:]
 
                        case PPARAMOUT:
-                               nE.Escretval.Append(n2)
+                               cE.Retval.Append(n)
                        }
                }
 
@@ -1552,48 +1553,48 @@ func esccall(e *EscState, n *Node, up *Node) {
        }
 
        // Imported or completely analyzed function. Use the escape tags.
-       if nE.Escretval.Len() != 0 {
-               Fatalf("esc already decorated call %+v\n", n)
+       if cE.Retval.Len() != 0 {
+               Fatalf("esc already decorated call %+v\n", call)
        }
 
        if Debug['m'] > 3 {
-               fmt.Printf("%v::esccall:: %S not recursive\n", linestr(lineno), n)
+               fmt.Printf("%v::esccall:: %S not recursive\n", linestr(lineno), call)
        }
 
        // set up out list on this call node with dummy auto ONAMES in the current (calling) function.
-       initEscretval(e, n, fntype)
+       e.initEscRetval(call, fntype)
 
-       //      print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, n->escretval);
+       //      print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, e.nodeEscState(call).Retval);
 
        // Receiver.
-       if n.Op != OCALLFUNC {
-               t := fntype.Recv()
-               src := n.Left.Left
-               if haspointers(t.Type) {
-                       escassignfromtag(e, t.Note, nE.Escretval, src)
+       if call.Op != OCALLFUNC {
+               rf := fntype.Recv()
+               r := call.Left.Left
+               if haspointers(rf.Type) {
+                       e.escassignfromtag(rf.Note, cE.Retval, r)
                }
        }
 
-       var src *Node
-       note := ""
+       var arg *Node
+       var note string
+       param, it := iterFields(fntype.Params())
        i := 0
-       lls := ll.Slice()
-       for t, it := iterFields(fntype.Params()); i < len(lls); i++ {
-               src = lls[i]
-               note = t.Note
-               if t.Isddd && !n.Isddd {
+       for ; i < len(args); i++ {
+               arg = args[i]
+               note = param.Note
+               if param.Isddd && !call.Isddd {
                        // Introduce ODDDARG node to represent ... allocation.
-                       src = nod(ODDDARG, nil, nil)
-                       src.Lineno = n.Lineno
-                       arr := typArray(t.Type.Elem(), int64(len(lls)-i))
-                       src.Type = ptrto(arr) // make pointer so it will be tracked
-                       e.track(src)
-                       n.Right = src
+                       arg = nod(ODDDARG, nil, nil)
+                       arg.Lineno = call.Lineno
+                       arr := typArray(param.Type.Elem(), int64(len(args)-i))
+                       arg.Type = ptrto(arr) // make pointer so it will be tracked
+                       e.track(arg)
+                       call.Right = arg
                }
 
-               if haspointers(t.Type) {
-                       if escassignfromtag(e, note, nE.Escretval, src)&EscMask == EscNone && up.Op != ODEFER && up.Op != OPROC {
-                               a := src
+               if haspointers(param.Type) {
+                       if e.escassignfromtag(note, cE.Retval, arg)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OPROC {
+                               a := arg
                                for a.Op == OCONVNOP {
                                        a = a.Left
                                }
@@ -1604,8 +1605,8 @@ func esccall(e *EscState, n *Node, up *Node) {
                                // synthesizing this expression can be reclaimed when
                                // the function returns.
                                // This 'noescape' is even stronger than the usual esc == EscNone.
-                               // src->esc == EscNone means that src does not escape the current function.
-                               // src->noescape = 1 here means that src does not escape this statement
+                               // arg.Esc == EscNone means that arg does not escape the current function.
+                               // arg.Noescape = true here means that arg does not escape this statement
                                // in the current function.
                                case OCALLPART,
                                        OCLOSURE,
@@ -1619,34 +1620,34 @@ func esccall(e *EscState, n *Node, up *Node) {
                        }
                }
 
-               if src != lls[i] {
-                       // This occurs when function parameter type Isddd and n not Isddd
+               if arg != args[i] {
+                       // This occurs when function parameter field Isddd and call not Isddd
                        break
                }
 
                if note == uintptrEscapesTag {
-                       escassignSinkNilWhy(e, src, src, "escaping uintptr")
+                       e.escassignSinkNilWhy(arg, arg, "escaping uintptr")
                }
 
-               t = it.Next()
+               param = it.Next()
        }
 
        // Store arguments into slice for ... arg.
-       for ; i < len(lls); i++ {
+       for ; i < len(args); i++ {
                if Debug['m'] > 3 {
-                       fmt.Printf("%v::esccall:: ... <- %S\n", linestr(lineno), lls[i])
+                       fmt.Printf("%v::esccall:: ... <- %S\n", linestr(lineno), args[i])
                }
                if note == uintptrEscapesTag {
-                       escassignSinkNilWhy(e, src, lls[i], "arg to uintptrescapes ...")
+                       e.escassignSinkNilWhy(arg, args[i], "arg to uintptrescapes ...")
                } else {
-                       escassignNilWhy(e, src, lls[i], "arg to ...")
+                       e.escassignNilWhy(arg, args[i], "arg to ...")
                }
        }
 }
 
 // escflows records the link src->dst in dst, throwing out some quick wins,
 // and also ensuring that dst is noted as a flow destination.
-func escflows(e *EscState, dst, src *Node, why *EscStep) {
+func (e *EscState) escflows(dst, src *Node, why *EscStep) {
        if dst == nil || src == nil || dst == src {
                return
        }
@@ -1661,7 +1662,7 @@ func escflows(e *EscState, dst, src *Node, why *EscStep) {
        }
 
        dstE := e.nodeEscState(dst)
-       if len(dstE.Escflowsrc) == 0 {
+       if len(dstE.Flowsrc) == 0 {
                e.dsts = append(e.dsts, dst)
                e.dstcount++
        }
@@ -1669,11 +1670,11 @@ func escflows(e *EscState, dst, src *Node, why *EscStep) {
        e.edgecount++
 
        if why == nil {
-               dstE.Escflowsrc = append(dstE.Escflowsrc, EscStep{src: src})
+               dstE.Flowsrc = append(dstE.Flowsrc, EscStep{src: src})
        } else {
                starwhy := *why
                starwhy.src = src // TODO: need to reconcile this w/ needs of explanations.
-               dstE.Escflowsrc = append(dstE.Escflowsrc, starwhy)
+               dstE.Flowsrc = append(dstE.Flowsrc, starwhy)
        }
 }
 
@@ -1683,27 +1684,26 @@ func escflows(e *EscState, dst, src *Node, why *EscStep) {
 // so this address doesn't leak (yet).
 // If level == 0, it means the /value/ of this node can reach the root of this flood.
 // so if this node is an OADDR, its argument should be marked as escaping iff
-// its currfn/e->loopdepth are different from the flood's root.
+// its currfn/e.loopdepth are different from the flood's root.
 // Once an object has been moved to the heap, all of its upstream should be considered
 // escaping to the global scope.
-func escflood(e *EscState, dst *Node) {
+func (e *EscState) escflood(dst *Node) {
        switch dst.Op {
        case ONAME, OCLOSURE:
-               break
-
        default:
                return
        }
 
        dstE := e.nodeEscState(dst)
        if Debug['m'] > 2 {
-               fmt.Printf("\nescflood:%d: dst %S scope:%v[%d]\n", e.walkgen, dst, e.curfnSym(dst), dstE.Escloopdepth)
+               fmt.Printf("\nescflood:%d: dst %S scope:%v[%d]\n", e.walkgen, dst, e.curfnSym(dst), dstE.Loopdepth)
        }
 
-       for i, l := range dstE.Escflowsrc {
+       for i := range dstE.Flowsrc {
                e.walkgen++
-               dstE.Escflowsrc[i].parent = nil
-               escwalk(e, levelFrom(0), dst, l.src, &dstE.Escflowsrc[i])
+               s := &dstE.Flowsrc[i]
+               s.parent = nil
+               e.escwalk(levelFrom(0), dst, s.src, s)
        }
 }
 
@@ -1740,11 +1740,11 @@ func (es *EscStep) describe(src *Node) {
 
 const NOTALOOPDEPTH = -1
 
-func escwalk(e *EscState, level Level, dst *Node, src *Node, step *EscStep) {
-       escwalkBody(e, level, dst, src, step, NOTALOOPDEPTH)
+func (e *EscState) escwalk(level Level, dst *Node, src *Node, step *EscStep) {
+       e.escwalkBody(level, dst, src, step, NOTALOOPDEPTH)
 }
 
-func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep, extraloopdepth int32) {
+func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep, extraloopdepth int32) {
        if src.Op == OLITERAL {
                return
        }
@@ -1753,12 +1753,12 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                // Esclevels are vectors, do not compare as integers,
                // and must use "min" of old and new to guarantee
                // convergence.
-               level = level.min(srcE.Esclevel)
-               if level == srcE.Esclevel {
+               level = level.min(srcE.Level)
+               if level == srcE.Level {
                        // Have we been here already with an extraloopdepth,
                        // or is the extraloopdepth provided no improvement on
                        // what's already been seen?
-                       if srcE.Maxextraloopdepth >= extraloopdepth || srcE.Escloopdepth >= extraloopdepth {
+                       if srcE.Maxextraloopdepth >= extraloopdepth || srcE.Loopdepth >= extraloopdepth {
                                return
                        }
                        srcE.Maxextraloopdepth = extraloopdepth
@@ -1768,8 +1768,8 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
        }
 
        srcE.Walkgen = e.walkgen
-       srcE.Esclevel = level
-       modSrcLoopdepth := srcE.Escloopdepth
+       srcE.Level = level
+       modSrcLoopdepth := srcE.Loopdepth
 
        if extraloopdepth > modSrcLoopdepth {
                modSrcLoopdepth = extraloopdepth
@@ -1777,7 +1777,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
 
        if Debug['m'] > 2 {
                fmt.Printf("escwalk: level:%d depth:%d %.*s op=%v %S(%0j) scope:%v[%d] extraloopdepth=%v\n",
-                       level, e.pdepth, e.pdepth, "\t\t\t\t\t\t\t\t\t\t", src.Op, src, src, e.curfnSym(src), srcE.Escloopdepth, extraloopdepth)
+                       level, e.pdepth, e.pdepth, "\t\t\t\t\t\t\t\t\t\t", src.Op, src, src, e.curfnSym(src), srcE.Loopdepth, extraloopdepth)
        }
 
        e.pdepth++
@@ -1820,13 +1820,13 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                }
        }
 
-       leaks = level.int() <= 0 && level.guaranteedDereference() <= 0 && dstE.Escloopdepth < modSrcLoopdepth
+       leaks = level.int() <= 0 && level.guaranteedDereference() <= 0 && dstE.Loopdepth < modSrcLoopdepth
        leaks = leaks || level.int() <= 0 && dst.Esc&EscMask == EscHeap
 
        osrcesc = src.Esc
        switch src.Op {
        case ONAME:
-               if src.Class == PPARAM && (leaks || dstE.Escloopdepth < 0) && src.Esc&EscMask < EscScope {
+               if src.Class == PPARAM && (leaks || dstE.Loopdepth < 0) && src.Esc&EscMask < EscScope {
                        if level.guaranteedDereference() > 0 {
                                src.Esc = escMax(EscContentEscapes|src.Esc, EscNone)
                                if Debug['m'] != 0 {
@@ -1837,7 +1837,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                                                }
                                        } else {
                                                Warnl(src.Lineno, "leaking param content: %S level=%v dst.eld=%v src.eld=%v dst=%S",
-                                                       src, level, dstE.Escloopdepth, modSrcLoopdepth, dst)
+                                                       src, level, dstE.Loopdepth, modSrcLoopdepth, dst)
                                        }
                                }
                        } else {
@@ -1849,7 +1849,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                                                step.describe(src)
                                        } else {
                                                Warnl(src.Lineno, "leaking param: %S level=%v dst.eld=%v src.eld=%v dst=%S",
-                                                       src, level, dstE.Escloopdepth, modSrcLoopdepth, dst)
+                                                       src, level, dstE.Loopdepth, modSrcLoopdepth, dst)
                                        }
                                }
                        }
@@ -1862,7 +1862,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                                Warnl(src.Lineno, "leaking closure reference %S", src)
                                step.describe(src)
                        }
-                       escwalk(e, level, dst, src.Name.Defn, e.stepWalk(dst, src.Name.Defn, "closure-var", step))
+                       e.escwalk(level, dst, src.Name.Defn, e.stepWalk(dst, src.Name.Defn, "closure-var", step))
                }
 
        case OPTRLIT, OADDR:
@@ -1879,21 +1879,21 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                                }
                                if Debug['m'] > 2 {
                                        Warnl(src.Lineno, "%S escapes to heap, level=%v, dst=%v dst.eld=%v, src.eld=%v",
-                                               p, level, dst, dstE.Escloopdepth, modSrcLoopdepth)
+                                               p, level, dst, dstE.Loopdepth, modSrcLoopdepth)
                                } else {
                                        Warnl(src.Lineno, "%S escapes to heap", p)
                                        step.describe(src)
                                }
                        }
                        addrescapes(src.Left)
-                       escwalkBody(e, level.dec(), dst, src.Left, e.stepWalk(dst, src.Left, why, step), modSrcLoopdepth)
+                       e.escwalkBody(level.dec(), dst, src.Left, e.stepWalk(dst, src.Left, why, step), modSrcLoopdepth)
                        extraloopdepth = modSrcLoopdepth // passes to recursive case, seems likely a no-op
                } else {
-                       escwalk(e, level.dec(), dst, src.Left, e.stepWalk(dst, src.Left, why, step))
+                       e.escwalk(level.dec(), dst, src.Left, e.stepWalk(dst, src.Left, why, step))
                }
 
        case OAPPEND:
-               escwalk(e, level, dst, src.List.First(), e.stepWalk(dst, src.List.First(), "append-first-arg", step))
+               e.escwalk(level, dst, src.List.First(), e.stepWalk(dst, src.List.First(), "append-first-arg", step))
 
        case ODDDARG:
                if leaks {
@@ -1909,7 +1909,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
 
        case OSLICELIT:
                for _, n1 := range src.List.Slice() {
-                       escwalk(e, level.dec(), dst, n1.Right, e.stepWalk(dst, n1.Right, "slice-literal-element", step))
+                       e.escwalk(level.dec(), dst, n1.Right, e.stepWalk(dst, n1.Right, "slice-literal-element", step))
                }
 
                fallthrough
@@ -1939,7 +1939,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
 
        case ODOT,
                ODOTTYPE:
-               escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "dot", step))
+               e.escwalk(level, dst, src.Left, e.stepWalk(dst, src.Left, "dot", step))
 
        case
                OSLICE,
@@ -1947,21 +1947,21 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                OSLICE3,
                OSLICE3ARR,
                OSLICESTR:
-               escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "slice", step))
+               e.escwalk(level, dst, src.Left, e.stepWalk(dst, src.Left, "slice", step))
 
        case OINDEX:
                if src.Left.Type.IsArray() {
-                       escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "fixed-array-index-of", step))
+                       e.escwalk(level, dst, src.Left, e.stepWalk(dst, src.Left, "fixed-array-index-of", step))
                        break
                }
                fallthrough
 
        case ODOTPTR:
-               escwalk(e, level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "dot of pointer", step))
+               e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "dot of pointer", step))
        case OINDEXMAP:
-               escwalk(e, level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "map index", step))
+               e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "map index", step))
        case OIND:
-               escwalk(e, level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "indirection", step))
+               e.escwalk(level.inc(), dst, src.Left, e.stepWalk(dst, src.Left, "indirection", step))
 
        // In this case a link went directly to a call, but should really go
        // to the dummy .outN outputs that were created for the call that
@@ -1969,23 +1969,25 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
        // See e.g. #10466
        // This can only happen with functions returning a single result.
        case OCALLMETH, OCALLFUNC, OCALLINTER:
-               if srcE.Escretval.Len() != 0 {
+               if srcE.Retval.Len() != 0 {
                        if Debug['m'] > 2 {
                                fmt.Printf("%v:[%d] dst %S escwalk replace src: %S with %S\n",
                                        linestr(lineno), e.loopdepth,
-                                       dst, src, srcE.Escretval.First())
+                                       dst, src, srcE.Retval.First())
                        }
-                       src = srcE.Escretval.First()
+                       src = srcE.Retval.First()
                        srcE = e.nodeEscState(src)
                }
        }
 
 recurse:
        level = level.copy()
-       for i, ll := range srcE.Escflowsrc {
-               srcE.Escflowsrc[i].parent = step
-               escwalkBody(e, level, dst, ll.src, &srcE.Escflowsrc[i], extraloopdepth)
-               srcE.Escflowsrc[i].parent = nil
+
+       for i := range srcE.Flowsrc {
+               s := &srcE.Flowsrc[i]
+               s.parent = step
+               e.escwalkBody(level, dst, s.src, s, extraloopdepth)
+               s.parent = nil
        }
 
        e.pdepth--
@@ -2002,8 +2004,8 @@ var unsafeUintptrTag = "unsafe-uintptr"
 // marked go:uintptrescapes.
 const uintptrEscapesTag = "uintptr-escapes"
 
-func esctag(e *EscState, func_ *Node) {
-       func_.Esc = EscFuncTagged
+func (e *EscState) esctag(fn *Node) {
+       fn.Esc = EscFuncTagged
 
        name := func(s *Sym, narg int) string {
                if s != nil {
@@ -2014,11 +2016,11 @@ func esctag(e *EscState, func_ *Node) {
 
        // External functions are assumed unsafe,
        // unless //go:noescape is given before the declaration.
-       if func_.Nbody.Len() == 0 {
-               if func_.Noescape {
-                       for _, t := range func_.Type.Params().Fields().Slice() {
-                               if haspointers(t.Type) {
-                                       t.Note = mktag(EscNone)
+       if fn.Nbody.Len() == 0 {
+               if fn.Noescape {
+                       for _, f := range fn.Type.Params().Fields().Slice() {
+                               if haspointers(f.Type) {
+                                       f.Note = mktag(EscNone)
                                }
                        }
                }
@@ -2030,44 +2032,41 @@ func esctag(e *EscState, func_ *Node) {
                // but we are reusing the ability to annotate an individual function
                // argument and pass those annotations along to importing code.
                narg := 0
-               for _, t := range func_.Type.Params().Fields().Slice() {
+               for _, f := range fn.Type.Params().Fields().Slice() {
                        narg++
-                       if t.Type.Etype == TUINTPTR {
+                       if f.Type.Etype == TUINTPTR {
                                if Debug['m'] != 0 {
-                                       Warnl(func_.Lineno, "%v assuming %v is unsafe uintptr", funcSym(func_), name(t.Sym, narg))
+                                       Warnl(fn.Lineno, "%v assuming %v is unsafe uintptr", funcSym(fn), name(f.Sym, narg))
                                }
-                               t.Note = unsafeUintptrTag
+                               f.Note = unsafeUintptrTag
                        }
                }
 
                return
        }
 
-       if func_.Func.Pragma&UintptrEscapes != 0 {
+       if fn.Func.Pragma&UintptrEscapes != 0 {
                narg := 0
-               for _, t := range func_.Type.Params().Fields().Slice() {
+               for _, f := range fn.Type.Params().Fields().Slice() {
                        narg++
-                       if t.Type.Etype == TUINTPTR {
+                       if f.Type.Etype == TUINTPTR {
                                if Debug['m'] != 0 {
-                                       Warnl(func_.Lineno, "%v marking %v as escaping uintptr", funcSym(func_), name(t.Sym, narg))
+                                       Warnl(fn.Lineno, "%v marking %v as escaping uintptr", funcSym(fn), name(f.Sym, narg))
                                }
-                               t.Note = uintptrEscapesTag
+                               f.Note = uintptrEscapesTag
                        }
 
-                       if t.Isddd && t.Type.Elem().Etype == TUINTPTR {
+                       if f.Isddd && f.Type.Elem().Etype == TUINTPTR {
                                // final argument is ...uintptr.
                                if Debug['m'] != 0 {
-                                       Warnl(func_.Lineno, "%v marking %v as escaping ...uintptr", funcSym(func_), name(t.Sym, narg))
+                                       Warnl(fn.Lineno, "%v marking %v as escaping ...uintptr", funcSym(fn), name(f.Sym, narg))
                                }
-                               t.Note = uintptrEscapesTag
+                               f.Note = uintptrEscapesTag
                        }
                }
        }
 
-       savefn := Curfn
-       Curfn = func_
-
-       for _, ln := range Curfn.Func.Dcl {
+       for _, ln := range fn.Func.Dcl {
                if ln.Op != ONAME {
                        continue
                }
@@ -2083,9 +2082,6 @@ func esctag(e *EscState, func_ *Node) {
 
                case EscHeap, // touched by escflood, moved to heap
                        EscScope: // touched by escflood, value leaves scope
-                       break
                }
        }
-
-       Curfn = savefn
 }
index 1fa718270581c7f8a28a20371658e8a9b51bfdaf..a62865d815dc368653727d38dbc686cc05cf6936 100644 (file)
@@ -330,8 +330,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
                fmt.Fprintf(s, " esc(%d)", n.Esc)
        }
 
-       if e, ok := n.Opt().(*NodeEscState); ok && e.Escloopdepth != 0 {
-               fmt.Fprintf(s, " ld(%d)", e.Escloopdepth)
+       if e, ok := n.Opt().(*NodeEscState); ok && e.Loopdepth != 0 {
+               fmt.Fprintf(s, " ld(%d)", e.Loopdepth)
        }
 
        if c == 0 && n.Typecheck != 0 {