]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: rework how fieldtrack is implemented
authorMatthew Dempsky <mdempsky@google.com>
Fri, 11 Mar 2016 00:15:44 +0000 (16:15 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Sun, 13 Mar 2016 16:58:00 +0000 (16:58 +0000)
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>
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/reflect.go
src/cmd/compile/internal/gc/sizeof_test.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/type.go
src/cmd/compile/internal/gc/walk.go

index 75829aa2dfa8642dec9d5ebb7d56a51764b8e7b5..269a86c398959ba5273b2b2ae703a32d5cc2eaef 100644 (file)
@@ -459,8 +459,15 @@ func compile(fn *Node) {
        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 {
index 5ca292c39e368cafd1bc42a892a0a43bdd344413..05910b52268187a445bf079d4ae51bb996015008 100644 (file)
@@ -798,8 +798,10 @@ func typesym(t *Type) *Sym {
        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 {
index 489dfaa6f8444de5dc2261da6abf436bfa634a14..29e51e5c0860cfceeabbceab58bad0a558a3c749 100644 (file)
@@ -23,11 +23,11 @@ func TestSizeof(t *testing.T) {
                _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 {
index 8831143e165d7ad11f710680b4a6f141136993ef..2ddc8cbbab40933592694b604452fffde484eeaa 100644 (file)
@@ -156,7 +156,7 @@ type Func struct {
        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)
index a8b52201a3dca03f3475b8f3c6a730556c8c5fdc..2b7010a0380e0ee329141e9d624fe3bffe206a39 100644 (file)
@@ -141,9 +141,8 @@ type Type struct {
        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
@@ -159,8 +158,6 @@ type Type struct {
 
        // for TFORW, where to copy the eventual value to
        Copyto []*Node
-
-       Lastfn *Node // for usefield
 }
 
 // typ returns a new Type of the specified kind.
index 0284fb613cd02881667e973c1db5d223224c5202..fe9b0e5dc767d5b284294e0553ea83663e985725 100644 (file)
@@ -3838,23 +3838,22 @@ func usefield(n *Node) {
                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 {