From 52d9479e3be6cc94256f3ad07a0bd71df2aa4f60 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 26 Feb 2016 13:33:48 -0800 Subject: [PATCH] cmd/compile: convert Func.Cvars from *NodeList to *[]*Node Passes toolstash -cmp. Update #14473. Change-Id: I7285175b1992a29033fdc9e81d6f30545e5cc30d Reviewed-on: https://go-review.googlesource.com/19967 Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/closure.go | 28 ++++++++------------------ src/cmd/compile/internal/gc/dcl.go | 2 +- src/cmd/compile/internal/gc/esc.go | 4 +--- src/cmd/compile/internal/gc/order.go | 2 +- src/cmd/compile/internal/gc/sinit.go | 2 +- src/cmd/compile/internal/gc/syntax.go | 27 ++++++++++++++++++++++--- 6 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index df36db118d..c8c59ef201 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -67,9 +67,7 @@ func closurebody(body *NodeList) *Node { // ordinary ones in the symbol table; see oldname. // unhook them. // make the list of pointers for the closure call. - var v *Node - for l := func_.Func.Cvars; l != nil; l = l.Next { - v = l.N + for _, v := range func_.Func.Cvars() { v.Name.Param.Closure.Name.Param.Closure = v.Name.Param.Outer v.Name.Param.Outerexpr = oldname(v.Sym) } @@ -78,10 +76,8 @@ func closurebody(body *NodeList) *Node { } func typecheckclosure(func_ *Node, top int) { - var n *Node - - for l := func_.Func.Cvars; l != nil; l = l.Next { - n = l.N.Name.Param.Closure + for _, ln := range func_.Func.Cvars() { + n := ln.Name.Param.Closure if !n.Name.Captured { n.Name.Captured = true if n.Name.Decldepth == 0 { @@ -221,7 +217,6 @@ func makeclosure(func_ *Node) *Node { // We use value capturing for values <= 128 bytes that are never reassigned // after capturing (effectively constant). func capturevars(xfunc *Node) { - var v *Node var outer *Node lno := int(lineno) @@ -229,8 +224,7 @@ func capturevars(xfunc *Node) { func_ := xfunc.Func.Closure func_.Func.Enter = nil - for l := func_.Func.Cvars; l != nil; l = l.Next { - v = l.N + for _, v := range func_.Func.Cvars() { if v.Type == nil { // if v->type is nil, it means v looked like it was // going to be used in the closure but wasn't. @@ -310,11 +304,9 @@ func transformclosure(xfunc *Node) { original_dcl := xfunc.Func.Dcl xfunc.Func.Dcl = nil - var v *Node var addr *Node var fld *Type - for l := func_.Func.Cvars; l != nil; l = l.Next { - v = l.N + for _, v := range func_.Func.Cvars() { if v.Op == OXXX { continue } @@ -363,10 +355,8 @@ func transformclosure(xfunc *Node) { var body *NodeList offset := int64(Widthptr) var addr *Node - var v *Node var cv *Node - for l := func_.Func.Cvars; l != nil; l = l.Next { - v = l.N + for _, v := range func_.Func.Cvars() { if v.Op == OXXX { continue } @@ -417,7 +407,7 @@ func transformclosure(xfunc *Node) { func walkclosure(func_ *Node, init **NodeList) *Node { // If no closure vars, don't bother wrapping. - if func_.Func.Cvars == nil { + if len(func_.Func.Cvars()) == 0 { return func_.Func.Closure.Func.Nname } @@ -439,9 +429,7 @@ func walkclosure(func_ *Node, init **NodeList) *Node { typ.List = list1(Nod(ODCLFIELD, newname(Lookup(".F")), typenod(Types[TUINTPTR]))) var typ1 *Node - var v *Node - for l := func_.Func.Cvars; l != nil; l = l.Next { - v = l.N + for _, v := range func_.Func.Cvars() { if v.Op == OXXX { continue } diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index e485f9d79f..ab7af0ecc3 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -426,7 +426,7 @@ func oldname(s *Sym) *Node { n.Name.Param.Closure = c c.Name.Param.Closure = n c.Xoffset = 0 - Curfn.Func.Cvars = list(Curfn.Func.Cvars, c) + Curfn.Func.CvarAppend(c) } // return ref to closure var, not original diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 4cafc839cf..fe20057703 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -864,9 +864,7 @@ func esc(e *EscState, n *Node, up *Node) { // Link addresses of captured variables to closure. case OCLOSURE: var a *Node - var v *Node - for ll := n.Func.Cvars; ll != nil; ll = ll.Next { - v = ll.N + for _, v := range n.Func.Cvars() { if v.Op == OXXX { // unnamed out argument; see dcl.go:/^funcargs continue } diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index a3a8441f50..b74b025505 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -1137,7 +1137,7 @@ func orderexpr(np **Node, order *Order, lhs *Node) { } case OCLOSURE: - if n.Noescape && n.Func.Cvars != nil { + if n.Noescape && len(n.Func.Cvars()) > 0 { prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type } diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index b7f7ea0bea..88ccb7e2b0 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -475,7 +475,7 @@ func staticassign(l *Node, r *Node, out **NodeList) bool { break case OCLOSURE: - if r.Func.Cvars == nil { + if len(r.Func.Cvars()) == 0 { // Closures with no captured variables are globals, // so the assignment can be done at link time. n := *l diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index 83ee4aedeb..8b4fe8708a 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -151,9 +151,9 @@ type Func struct { Shortname *Node Enter *NodeList Exit *NodeList - Cvars *NodeList // closure params - Dcl []*Node // autodcl for this func/closure - Inldcl []*Node // copy of dcl for use in inlining + cvars *[]*Node // closure params + Dcl []*Node // autodcl for this func/closure + Inldcl []*Node // copy of dcl for use in inlining Closgen int Outerfunc *Node Fieldtrack []*Type @@ -177,6 +177,27 @@ type Func struct { Needctxt bool // function uses context register (has closure variables) } +// Cvars returns the closure variables for this Func. +// These are referenced variables that are defined in enclosing +// functions. +// The cvars field is a pointer to save space, since most Func values +// have no cvars. +func (f *Func) Cvars() []*Node { + if f.cvars == nil { + return nil + } + return *f.cvars +} + +// AppendCvar appends a new closure variable. +func (f *Func) CvarAppend(n *Node) { + if f.cvars == nil { + f.cvars = &[]*Node{n} + } else { + *f.cvars = append(*f.cvars, n) + } +} + type Op uint8 // Node ops. -- 2.48.1