Shrinks gc.Type and gc.Func slightly.
Passes "GOEXPERIMENT=fieldtrack ./all.bash" and "go test -a
-toolexec='toolstash -cmp' -ldflags=-k=rsc.io/tmp/fieldtrack.tracked
rsc.io/tmp/fieldtrack".
Change-Id: I785fe8a18eb830d9867d34247e4cd41a6a7921d4
Reviewed-on: https://go-review.googlesource.com/20557
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
gcargs := makefuncdatasym("gcargs·%d", obj.FUNCDATA_ArgsPointerMaps)
gclocals := makefuncdatasym("gclocals·%d", obj.FUNCDATA_LocalsPointerMaps)
- for _, t := range Curfn.Func.Fieldtrack {
- gtrack(tracksym(t))
+ if obj.Fieldtrack_enabled != 0 && len(Curfn.Func.FieldTrack) > 0 {
+ trackSyms := make([]*Sym, 0, len(Curfn.Func.FieldTrack))
+ for sym := range Curfn.Func.FieldTrack {
+ trackSyms = append(trackSyms, sym)
+ }
+ sort.Sort(symByName(trackSyms))
+ for _, sym := range trackSyms {
+ gtrack(sym)
+ }
}
for _, n := range fn.Func.Dcl {
return Pkglookup(Tconv(t, obj.FmtLeft), typepkg)
}
-func tracksym(t *Type) *Sym {
- return Pkglookup(Tconv(t.Outer, obj.FmtLeft)+"."+t.Sym.Name, trackpkg)
+// tracksym returns the symbol for tracking use of field/method f, assumed
+// to be a member of struct/interface type t.
+func tracksym(t, f *Type) *Sym {
+ return Pkglookup(Tconv(t, obj.FmtLeft)+"."+f.Sym.Name, trackpkg)
}
func typelinksym(t *Type) *Sym {
_64bit uintptr // size on 64bit platforms
}{
{Flow{}, 52, 88},
- {Func{}, 104, 184},
+ {Func{}, 96, 168},
{Name{}, 52, 80},
{Node{}, 92, 144},
{Sym{}, 60, 112},
- {Type{}, 144, 240},
+ {Type{}, 136, 224},
}
for _, tt := range tests {
Inldcl Nodes // copy of dcl for use in inlining
Closgen int
Outerfunc *Node
- Fieldtrack []*Type
+ FieldTrack map[*Sym]struct{}
Outer *Node // outer func for closure
Ntype *Node // signature
Top int // top context (Ecall, Eproc, etc)
Width int64 // offset in TFIELD, width in all others
// TFIELD
- Down *Type // next struct field, also key type in TMAP
- Outer *Type // outer struct
- Note *string // literal string annotation
+ Down *Type // next struct field, also key type in TMAP
+ Note *string // literal string annotation
// TARRAY
Bound int64 // negative is slice
// for TFORW, where to copy the eventual value to
Copyto []*Node
-
- Lastfn *Node // for usefield
}
// typ returns a new Type of the specified kind.
return
}
- // dedup on list
- if field.Lastfn == Curfn {
- return
- }
- field.Lastfn = Curfn
- field.Outer = n.Left.Type
- if Isptr[field.Outer.Etype] {
- field.Outer = field.Outer.Type
+ outer := n.Left.Type
+ if Isptr[outer.Etype] {
+ outer = outer.Type
}
- if field.Outer.Sym == nil {
+ if outer.Sym == nil {
Yyerror("tracked field must be in named struct type")
}
if !exportname(field.Sym.Name) {
Yyerror("tracked field must be exported (upper case)")
}
- Curfn.Func.Fieldtrack = append(Curfn.Func.Fieldtrack, field)
+ sym := tracksym(outer, field)
+ if Curfn.Func.FieldTrack == nil {
+ Curfn.Func.FieldTrack = make(map[*Sym]struct{})
+ }
+ Curfn.Func.FieldTrack[sym] = struct{}{}
}
func candiscardlist(l Nodes) bool {