gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/tools/go_types_memoize.patch (about) 1 diff --git a/go/src/go/types/scope.go b/src/go/types/scope.go 2 index 010727eb72..0f134b872e 100644 3 --- a/go/src/go/types/scope.go 4 +++ b/go/src/go/types/scope.go 5 @@ -25,6 +25,7 @@ type Scope struct { 6 children []*Scope 7 number int // parent.children[number-1] is this scope; 0 if there is no parent 8 elems map[string]Object // lazily allocated 9 + sorted []string // lazily allocated 10 pos, end token.Pos // scope extent; may be invalid 11 comment string // for debugging only 12 isFunc bool // set if this is a function scope (internal use only) 13 @@ -33,7 +34,7 @@ type Scope struct { 14 // NewScope returns a new, empty scope contained in the given parent 15 // scope, if any. The comment is for debugging only. 16 func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope { 17 - s := &Scope{parent, nil, 0, nil, pos, end, comment, false} 18 + s := &Scope{parent, nil, 0, nil, nil, pos, end, comment, false} 19 // don't add children to Universe scope! 20 if parent != nil && parent != Universe { 21 parent.children = append(parent.children, s) 22 @@ -50,14 +51,16 @@ func (s *Scope) Len() int { return len(s.elems) } 23 24 // Names returns the scope's element names in sorted order. 25 func (s *Scope) Names() []string { 26 - names := make([]string, len(s.elems)) 27 - i := 0 28 - for name := range s.elems { 29 - names[i] = name 30 - i++ 31 + if len(s.sorted) != len(s.elems) { 32 + s.sorted = make([]string, len(s.elems)) 33 + i := 0 34 + for name := range s.elems { 35 + s.sorted[i] = name 36 + i++ 37 + } 38 + sort.Strings(s.sorted) 39 } 40 - sort.Strings(names) 41 - return names 42 + return s.sorted 43 } 44 45 // NumChildren returns the number of scopes nested in s.