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:
parent
ec71ee078f
commit
e59fe206e7
@ -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)
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user