mirror of
https://github.com/golang/go
synced 2024-11-23 00:20:12 -07:00
[dev.regabi] cmd/compile: remove Func.ClosureType
The closure's type always matches the corresponding function's type, so just use one instance rather than carrying around two. Simplifies construction of closures, rewriting them during walk, and shrinks memory usage. Passes toolstash -cmp. Change-Id: I83b8b8f435b02ab25a30fb7aa15d5ec7ad97189d Reviewed-on: https://go-review.googlesource.com/c/go/+/283152 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
41352fd401
commit
d9acf6f3a3
@ -71,8 +71,6 @@ type Func struct {
|
||||
// Anonymous and blank PPARAMOUTs are declared as ~rNN and ~bNN Names, respectively.
|
||||
Dcl []*Name
|
||||
|
||||
ClosureType Ntype // closure representation type
|
||||
|
||||
// ClosureVars lists the free variables that are used within a
|
||||
// function literal, but formally declared in an enclosing
|
||||
// function. The variables in this slice are the closure function's
|
||||
|
@ -20,7 +20,7 @@ func TestSizeof(t *testing.T) {
|
||||
_32bit uintptr // size on 32bit platforms
|
||||
_64bit uintptr // size on 64bit platforms
|
||||
}{
|
||||
{Func{}, 196, 344},
|
||||
{Func{}, 188, 328},
|
||||
{Name{}, 116, 208},
|
||||
}
|
||||
|
||||
|
@ -1856,7 +1856,6 @@ func fakeRecv() *ir.Field {
|
||||
|
||||
func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
|
||||
xtype := p.typeExpr(expr.Type)
|
||||
ntype := p.typeExpr(expr.Type)
|
||||
|
||||
fn := ir.NewFunc(p.pos(expr))
|
||||
fn.SetIsHiddenClosure(ir.CurFunc != nil)
|
||||
@ -1867,7 +1866,6 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
|
||||
fn.Nname.Defn = fn
|
||||
|
||||
clo := ir.NewClosureExpr(p.pos(expr), fn)
|
||||
fn.ClosureType = ntype
|
||||
fn.OClosure = clo
|
||||
|
||||
p.funcBody(fn, expr.Body)
|
||||
|
@ -293,20 +293,20 @@ func tcClosure(clo *ir.ClosureExpr, top int) {
|
||||
fn.Iota = x
|
||||
}
|
||||
|
||||
fn.ClosureType = typecheckNtype(fn.ClosureType)
|
||||
clo.SetType(fn.ClosureType.Type())
|
||||
fn.SetClosureCalled(top&ctxCallee != 0)
|
||||
|
||||
// Do not typecheck fn twice, otherwise, we will end up pushing
|
||||
// fn to Target.Decls multiple times, causing initLSym called twice.
|
||||
// See #30709
|
||||
if fn.Typecheck() == 1 {
|
||||
clo.SetType(fn.Type())
|
||||
return
|
||||
}
|
||||
|
||||
fn.Nname.SetSym(closurename(ir.CurFunc))
|
||||
ir.MarkFunc(fn.Nname)
|
||||
Func(fn)
|
||||
clo.SetType(fn.Type())
|
||||
|
||||
// Type check the body now, but only if we're inside a function.
|
||||
// At top level (in a variable initialization: curfn==nil) we're not
|
||||
|
@ -64,10 +64,12 @@ func directClosureCall(n *ir.CallExpr) {
|
||||
|
||||
// f is ONAME of the actual function.
|
||||
f := clofn.Nname
|
||||
|
||||
// Prepend params and decls.
|
||||
typ := f.Type()
|
||||
typ.Params().SetFields(append(params, typ.Params().FieldSlice()...))
|
||||
|
||||
// Create new function type with parameters prepended, and
|
||||
// then update type and declarations.
|
||||
typ = types.NewSignature(typ.Pkg(), nil, append(params, typ.Params().FieldSlice()...), typ.Results().FieldSlice())
|
||||
f.SetType(typ)
|
||||
clofn.Dcl = append(decls, clofn.Dcl...)
|
||||
|
||||
// Rewrite call.
|
||||
@ -78,8 +80,6 @@ func directClosureCall(n *ir.CallExpr) {
|
||||
// because typecheck gave it the result type of the OCLOSURE
|
||||
// node, but we only rewrote the ONAME node's type. Logically,
|
||||
// they're the same, but the stack offsets probably changed.
|
||||
//
|
||||
// TODO(mdempsky): Reuse a single type for both.
|
||||
if typ.NumResults() == 1 {
|
||||
n.SetType(typ.Results().Field(0).Type)
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user