1
0
mirror of https://github.com/golang/go synced 2024-11-20 04:44:40 -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
// same struct type can share the descriptor.
typ := nod(OTSTRUCT, nil, nil)
typ.List.Set1(namedfield(".F", types.Types[TUINTPTR]))
fields := []*Node{
namedfield(".F", types.Types[TUINTPTR]),
}
for _, v := range func_.Func.Cvars.Slice() {
if v.Op == OXXX {
continue
}
typ1 := typenod(v.Type)
typ := v.Type
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.Right.SetImplicit(true)
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.
clos = nod(OCONVNOP, clos, nil)
clos.Type = func_.Type
clos = typecheck(clos, Erv)
@ -682,11 +684,14 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
checknil(n.Left, init)
}
typ := nod(OTSTRUCT, nil, nil)
typ.List.Set1(namedfield("F", types.Types[TUINTPTR]))
typ.List.Append(namedfield("R", n.Left.Type))
typ := tostruct([]*Node{
namedfield("F", types.Types[TUINTPTR]),
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.Right.SetImplicit(true)
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.
clos = nod(OCONVNOP, clos, nil)
clos.Type = n.Type
clos = typecheck(clos, Erv)

View File

@ -254,7 +254,11 @@ func anonfield(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.