1
0
mirror of https://github.com/golang/go synced 2024-11-20 09:14:46 -07:00

cmd/compile: mark closure structs as Noalg

Avoids generating useless equality and hash functions.

Shrinks cmd/go executable size on linux/amd64 by ~17kB.

Change-Id: Ifde5315cc5cbceb3a7260195c8803cace952359f
Reviewed-on: https://go-review.googlesource.com/66650
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Matthew Dempsky 2017-09-27 12:55:23 -07:00
parent ec71ee078f
commit e59fe206e7
2 changed files with 22 additions and 14 deletions

View File

@ -480,28 +480,30 @@ func walkclosure(func_ *Node, init *Nodes) *Node {
// the struct is unnamed so that closures in multiple packages with the // the struct is unnamed so that closures in multiple packages with the
// same struct type can share the descriptor. // same struct type can share the descriptor.
typ := nod(OTSTRUCT, nil, nil) fields := []*Node{
namedfield(".F", types.Types[TUINTPTR]),
typ.List.Set1(namedfield(".F", types.Types[TUINTPTR])) }
for _, v := range func_.Func.Cvars.Slice() { for _, v := range func_.Func.Cvars.Slice() {
if v.Op == OXXX { if v.Op == OXXX {
continue continue
} }
typ1 := typenod(v.Type) typ := v.Type
if !v.Name.Byval() { if !v.Name.Byval() {
typ1 = nod(OIND, typ1, nil) typ = types.NewPtr(typ)
} }
typ.List.Append(nod(ODCLFIELD, newname(v.Sym), typ1)) fields = append(fields, symfield(v.Sym, typ))
} }
typ := tostruct(fields)
typ.SetNoalg(true)
typ.SetLocal(true)
clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil)) clos := nod(OCOMPLIT, nil, nod(OIND, typenod(typ), nil))
clos.Esc = func_.Esc clos.Esc = func_.Esc
clos.Right.SetImplicit(true) clos.Right.SetImplicit(true)
clos.List.Set(append([]*Node{nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)}, func_.Func.Enter.Slice()...)) clos.List.Set(append([]*Node{nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)}, func_.Func.Enter.Slice()...))
// Force type conversion from *struct to the func type. // Force type conversion from *struct to the func type.
clos = nod(OCONVNOP, clos, nil) clos = nod(OCONVNOP, clos, nil)
clos.Type = func_.Type clos.Type = func_.Type
clos = typecheck(clos, Erv) clos = typecheck(clos, Erv)
@ -682,11 +684,14 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
checknil(n.Left, init) checknil(n.Left, init)
} }
typ := nod(OTSTRUCT, nil, nil) typ := tostruct([]*Node{
typ.List.Set1(namedfield("F", types.Types[TUINTPTR])) namedfield("F", types.Types[TUINTPTR]),
typ.List.Append(namedfield("R", n.Left.Type)) namedfield("R", n.Left.Type),
})
typ.SetNoalg(true)
typ.SetLocal(true)
clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil)) clos := nod(OCOMPLIT, nil, nod(OIND, typenod(typ), nil))
clos.Esc = n.Esc clos.Esc = n.Esc
clos.Right.SetImplicit(true) clos.Right.SetImplicit(true)
clos.List.Set1(nod(OCFUNC, n.Func.Nname, nil)) clos.List.Set1(nod(OCFUNC, n.Func.Nname, nil))
@ -694,7 +699,6 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
// Force type conversion from *struct to the func type. // Force type conversion from *struct to the func type.
clos = nod(OCONVNOP, clos, nil) clos = nod(OCONVNOP, clos, nil)
clos.Type = n.Type clos.Type = n.Type
clos = typecheck(clos, Erv) clos = typecheck(clos, Erv)

View File

@ -254,7 +254,11 @@ func anonfield(typ *types.Type) *Node {
} }
func namedfield(s string, typ *types.Type) *Node { func namedfield(s string, typ *types.Type) *Node {
return nod(ODCLFIELD, newname(lookup(s)), typenod(typ)) return symfield(lookup(s), typ)
}
func symfield(s *types.Sym, typ *types.Type) *Node {
return nod(ODCLFIELD, newname(s), typenod(typ))
} }
// oldname returns the Node that declares symbol s in the current scope. // oldname returns the Node that declares symbol s in the current scope.