go/types: less closure creations in gcimporter.
Closures are incredibly expensive on linux/arm due to
repetitive flush of instruction cache.
go test -short on ODROID-X:
Before:
ok exp/gotype 17.091s
ok go/types 2.225s
After:
ok exp/gotype 7.193s
ok go/types 1.143s
R=dave, minux.ma, rsc
CC=golang-dev, remy
https://golang.org/cl/7062045
diff --git a/src/pkg/go/types/gcimporter.go b/src/pkg/go/types/gcimporter.go
index 0e20d5c..38b9467 100644
--- a/src/pkg/go/types/gcimporter.go
+++ b/src/pkg/go/types/gcimporter.go
@@ -408,18 +408,13 @@
func (p *gcParser) parseStructType() Type {
var fields []*Field
- parseField := func() {
- fields = append(fields, p.parseField())
- }
-
p.expectKeyword("struct")
p.expect('{')
- if p.tok != '}' {
- parseField()
- for p.tok == ';' {
- p.next()
- parseField()
+ for p.tok != '}' {
+ if len(fields) > 0 {
+ p.expect(';')
}
+ fields = append(fields, p.parseField())
}
p.expect('}')
@@ -450,7 +445,11 @@
// ParameterList = { Parameter "," } Parameter .
//
func (p *gcParser) parseParameters() (list []*Var, isVariadic bool) {
- parseParameter := func() {
+ p.expect('(')
+ for p.tok != ')' {
+ if len(list) > 0 {
+ p.expect(',')
+ }
par, variadic := p.parseParameter()
list = append(list, par)
if variadic {
@@ -460,15 +459,6 @@
isVariadic = true
}
}
-
- p.expect('(')
- if p.tok != ')' {
- parseParameter()
- for p.tok == ',' {
- p.next()
- parseParameter()
- }
- }
p.expect(')')
return
@@ -509,21 +499,16 @@
func (p *gcParser) parseInterfaceType() Type {
var methods []*Method
- parseMethod := func() {
+ p.expectKeyword("interface")
+ p.expect('{')
+ for p.tok != '}' {
+ if len(methods) > 0 {
+ p.expect(';')
+ }
name := p.parseName()
typ := p.parseSignature()
methods = append(methods, &Method{name, typ})
}
-
- p.expectKeyword("interface")
- p.expect('{')
- if p.tok != '}' {
- parseMethod()
- for p.tok == ';' {
- p.next()
- parseMethod()
- }
- }
p.expect('}')
return &Interface{Methods: methods}