Commit d89b70d4 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: slightly regularize interface method types

Use a single *struct{} type instance rather than reconstructing one
for every declared/imported interface method. Minor allocations win:

name       old alloc/op    new alloc/op    delta
Template      41.8MB ± 0%     41.7MB ± 0%  -0.10%         (p=0.000 n=9+10)
Unicode       34.2MB ± 0%     34.2MB ± 0%    ~           (p=0.971 n=10+10)
GoTypes        123MB ± 0%      122MB ± 0%  -0.03%         (p=0.000 n=9+10)
Compiler       495MB ± 0%      495MB ± 0%  -0.01%        (p=0.000 n=10+10)

name       old allocs/op   new allocs/op   delta
Template        409k ± 0%       408k ± 0%  -0.13%        (p=0.000 n=10+10)
Unicode         354k ± 0%       354k ± 0%    ~           (p=0.516 n=10+10)
GoTypes        1.22M ± 0%      1.22M ± 0%  -0.03%        (p=0.009 n=10+10)
Compiler       4.43M ± 0%      4.43M ± 0%  -0.02%        (p=0.000 n=10+10)

Change-Id: Id3a4ca3dd09112bb96ccc982b06c9e79f661d31f
Reviewed-on: https://go-review.googlesource.com/32051Reviewed-by: 's avatarRobert Griesemer <gri@golang.org>
parent c78d072c
......@@ -988,34 +988,30 @@ func embedded(s *Sym, pkg *Pkg) *Node {
return n
}
// thisT is the singleton type used for interface method receivers.
var thisT *Type
func fakethis() *Node {
n := nod(ODCLFIELD, nil, typenod(ptrto(typ(TSTRUCT))))
return n
if thisT == nil {
thisT = ptrto(typ(TSTRUCT))
}
return nod(ODCLFIELD, nil, typenod(thisT))
}
func fakethisfield() *Field {
if thisT == nil {
thisT = ptrto(typ(TSTRUCT))
}
f := newField()
f.Type = ptrto(typ(TSTRUCT))
f.Type = thisT
return f
}
// Is this field a method on an interface?
// Those methods have an anonymous *struct{} as the receiver.
// Those methods have thisT as the receiver.
// (See fakethis above.)
func isifacemethod(f *Type) bool {
rcvr := f.Recv()
if rcvr.Sym != nil {
return false
}
t := rcvr.Type
if !t.IsPtr() {
return false
}
t = t.Elem()
if t.Sym != nil || !t.IsStruct() || t.NumFields() != 0 {
return false
}
return true
return f.Recv().Type == thisT
}
// turn a parsed function declaration into a type
......
......@@ -374,32 +374,16 @@ func typeinit() {
}
func makeErrorInterface() *Type {
rcvr := typ(TSTRUCT)
rcvr.StructType().Funarg = FunargRcvr
field := newField()
field.Type = ptrto(typ(TSTRUCT))
rcvr.SetFields([]*Field{field})
in := typ(TSTRUCT)
in.StructType().Funarg = FunargParams
out := typ(TSTRUCT)
out.StructType().Funarg = FunargResults
field = newField()
field.Type = Types[TSTRING]
out.SetFields([]*Field{field})
f := typ(TFUNC)
f.FuncType().Receiver = rcvr
f.FuncType().Results = out
f.FuncType().Params = in
f := functypefield(fakethisfield(), nil, []*Field{field})
t := typ(TINTER)
field = newField()
field.Sym = lookup("Error")
field.Type = f
t.SetFields([]*Field{field})
t := typ(TINTER)
t.SetFields([]*Field{field})
return t
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment