mirror of
https://github.com/golang/go
synced 2024-11-18 08:14:41 -07:00
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/32051 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
c78d072c8e
commit
d89b70d433
@ -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 := functypefield(fakethisfield(), nil, []*Field{field})
|
||||
|
||||
f := typ(TFUNC)
|
||||
f.FuncType().Receiver = rcvr
|
||||
f.FuncType().Results = out
|
||||
f.FuncType().Params = in
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user