mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: rework how fieldtrack is implemented
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>
This commit is contained in:
parent
f6ceed2cab
commit
a2a48069fe
6 changed files with 27 additions and 22 deletions
|
|
@ -459,8 +459,15 @@ func compile(fn *Node) {
|
||||||
gcargs := makefuncdatasym("gcargs·%d", obj.FUNCDATA_ArgsPointerMaps)
|
gcargs := makefuncdatasym("gcargs·%d", obj.FUNCDATA_ArgsPointerMaps)
|
||||||
gclocals := makefuncdatasym("gclocals·%d", obj.FUNCDATA_LocalsPointerMaps)
|
gclocals := makefuncdatasym("gclocals·%d", obj.FUNCDATA_LocalsPointerMaps)
|
||||||
|
|
||||||
for _, t := range Curfn.Func.Fieldtrack {
|
if obj.Fieldtrack_enabled != 0 && len(Curfn.Func.FieldTrack) > 0 {
|
||||||
gtrack(tracksym(t))
|
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 {
|
for _, n := range fn.Func.Dcl {
|
||||||
|
|
|
||||||
|
|
@ -798,8 +798,10 @@ func typesym(t *Type) *Sym {
|
||||||
return Pkglookup(Tconv(t, obj.FmtLeft), typepkg)
|
return Pkglookup(Tconv(t, obj.FmtLeft), typepkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tracksym(t *Type) *Sym {
|
// tracksym returns the symbol for tracking use of field/method f, assumed
|
||||||
return Pkglookup(Tconv(t.Outer, obj.FmtLeft)+"."+t.Sym.Name, trackpkg)
|
// 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 {
|
func typelinksym(t *Type) *Sym {
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ func TestSizeof(t *testing.T) {
|
||||||
_64bit uintptr // size on 64bit platforms
|
_64bit uintptr // size on 64bit platforms
|
||||||
}{
|
}{
|
||||||
{Flow{}, 52, 88},
|
{Flow{}, 52, 88},
|
||||||
{Func{}, 104, 184},
|
{Func{}, 96, 168},
|
||||||
{Name{}, 52, 80},
|
{Name{}, 52, 80},
|
||||||
{Node{}, 92, 144},
|
{Node{}, 92, 144},
|
||||||
{Sym{}, 60, 112},
|
{Sym{}, 60, 112},
|
||||||
{Type{}, 144, 240},
|
{Type{}, 136, 224},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ type Func struct {
|
||||||
Inldcl Nodes // copy of dcl for use in inlining
|
Inldcl Nodes // copy of dcl for use in inlining
|
||||||
Closgen int
|
Closgen int
|
||||||
Outerfunc *Node
|
Outerfunc *Node
|
||||||
Fieldtrack []*Type
|
FieldTrack map[*Sym]struct{}
|
||||||
Outer *Node // outer func for closure
|
Outer *Node // outer func for closure
|
||||||
Ntype *Node // signature
|
Ntype *Node // signature
|
||||||
Top int // top context (Ecall, Eproc, etc)
|
Top int // top context (Ecall, Eproc, etc)
|
||||||
|
|
|
||||||
|
|
@ -141,9 +141,8 @@ type Type struct {
|
||||||
Width int64 // offset in TFIELD, width in all others
|
Width int64 // offset in TFIELD, width in all others
|
||||||
|
|
||||||
// TFIELD
|
// TFIELD
|
||||||
Down *Type // next struct field, also key type in TMAP
|
Down *Type // next struct field, also key type in TMAP
|
||||||
Outer *Type // outer struct
|
Note *string // literal string annotation
|
||||||
Note *string // literal string annotation
|
|
||||||
|
|
||||||
// TARRAY
|
// TARRAY
|
||||||
Bound int64 // negative is slice
|
Bound int64 // negative is slice
|
||||||
|
|
@ -159,8 +158,6 @@ type Type struct {
|
||||||
|
|
||||||
// for TFORW, where to copy the eventual value to
|
// for TFORW, where to copy the eventual value to
|
||||||
Copyto []*Node
|
Copyto []*Node
|
||||||
|
|
||||||
Lastfn *Node // for usefield
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typ returns a new Type of the specified kind.
|
// typ returns a new Type of the specified kind.
|
||||||
|
|
|
||||||
|
|
@ -3838,23 +3838,22 @@ func usefield(n *Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// dedup on list
|
outer := n.Left.Type
|
||||||
if field.Lastfn == Curfn {
|
if Isptr[outer.Etype] {
|
||||||
return
|
outer = outer.Type
|
||||||
}
|
}
|
||||||
field.Lastfn = Curfn
|
if outer.Sym == nil {
|
||||||
field.Outer = n.Left.Type
|
|
||||||
if Isptr[field.Outer.Etype] {
|
|
||||||
field.Outer = field.Outer.Type
|
|
||||||
}
|
|
||||||
if field.Outer.Sym == nil {
|
|
||||||
Yyerror("tracked field must be in named struct type")
|
Yyerror("tracked field must be in named struct type")
|
||||||
}
|
}
|
||||||
if !exportname(field.Sym.Name) {
|
if !exportname(field.Sym.Name) {
|
||||||
Yyerror("tracked field must be exported (upper case)")
|
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 {
|
func candiscardlist(l Nodes) bool {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue