cmd/compile: move Node.Paramfld to Node.Param.Field
$ sizeof -p cmd/compile/internal/gc Node
Node 264
$
Change-Id: I5c90089dcf5df51c874250f28a1bc3ec32f764b9
Reviewed-on: https://go-review.googlesource.com/10522
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go
index 4a9cb29..35c4c4b 100644
--- a/src/cmd/compile/internal/gc/dcl.go
+++ b/src/cmd/compile/internal/gc/dcl.go
@@ -913,7 +913,7 @@
// esc.c needs to find f given a PPARAM to add the tag.
if l.N.Left != nil && l.N.Left.Class == PPARAM {
- l.N.Left.Paramfld = f
+ l.N.Left.Param.Field = f
}
*tp = f
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index f9d83a2..d6ebf13 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -1774,7 +1774,7 @@
case EscNone, // not touched by escflood
EscReturn:
if haspointers(ll.N.Type) { // don't bother tagging for scalars
- ll.N.Paramfld.Note = mktag(int(ll.N.Esc))
+ ll.N.Param.Field.Note = mktag(int(ll.N.Esc))
}
case EscHeap, // touched by escflood, moved to heap
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index 815f723..7ed661f 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -448,8 +448,8 @@
gcargs = makefuncdatasym("gcargs·%d", obj.FUNCDATA_ArgsPointerMaps)
gclocals = makefuncdatasym("gclocals·%d", obj.FUNCDATA_LocalsPointerMaps)
- for t := Curfn.Paramfld; t != nil; t = t.Down {
- gtrack(tracksym(t.Type))
+ for _, t := range Curfn.Func.Fieldtrack {
+ gtrack(tracksym(t))
}
for l := fn.Func.Dcl; l != nil; l = l.Next {
diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go
index f8f2248..eb368a3 100644
--- a/src/cmd/compile/internal/gc/syntax.go
+++ b/src/cmd/compile/internal/gc/syntax.go
@@ -29,19 +29,16 @@
Func *Func
// ONAME
- Name *Name
- Defn *Node // ONAME: initializing assignment; OLABEL: labeled statement
- Pack *Node // real package for import . names
- Curfn *Node // function for local variables
- Paramfld *Type // TFIELD for this PPARAM; also for ODOT, curfn
- Alloc *Node // allocation call
- Param *Param
+ Name *Name
+ Defn *Node // ONAME: initializing assignment; OLABEL: labeled statement
+ Pack *Node // real package for import . names
+ Curfn *Node // function for local variables
+ Alloc *Node // allocation call
+ Param *Param
// OPACK
Pkg *Pkg
- // OARRAYLIT, OMAPLIT, OSTRUCTLIT.
-
// Escape analysis.
Escflowsrc *NodeList // flow(this, src)
Escretval *NodeList // on OCALLxxx, list of dummy return values
@@ -116,6 +113,9 @@
Outerexpr *Node // expression copied into closure for variable
Stackparam *Node // OPARAM node referring to stack copy of param
+ // ONAME PPARAM
+ Field *Type // TFIELD in arg struct
+
// ONAME closure param with PPARAMREF
Outer *Node // outer PPARAMREF in nested closure
Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF
@@ -124,14 +124,15 @@
// Func holds Node fields used only with function-like nodes.
type Func struct {
- Shortname *Node
- Enter *NodeList
- Exit *NodeList
- Cvars *NodeList // closure params
- Dcl *NodeList // autodcl for this func/closure
- Inldcl *NodeList // copy of dcl for use in inlining
- Closgen int
- Outerfunc *Node
+ Shortname *Node
+ Enter *NodeList
+ Exit *NodeList
+ Cvars *NodeList // closure params
+ Dcl *NodeList // autodcl for this func/closure
+ Inldcl *NodeList // copy of dcl for use in inlining
+ Closgen int
+ Outerfunc *Node
+ Fieldtrack []*Type
Inl *NodeList // copy of the body for use in inlining
InlCost int32
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index 351f26f..490468f 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -2489,6 +2489,15 @@
return t
}
+type typeSym struct {
+ t *Type
+ s *Sym
+}
+
+// dotField maps (*Type, *Sym) pairs to the corresponding struct field (*Type with Etype==TFIELD).
+// It is a cache for use during usefield in walk.go, only enabled when field tracking.
+var dotField = map[typeSym]*Type{}
+
func lookdot(n *Node, t *Type, dostrcmp int) *Type {
s := n.Right.Sym
@@ -2521,7 +2530,9 @@
}
n.Xoffset = f1.Width
n.Type = f1.Type
- n.Paramfld = f1
+ if obj.Fieldtrack_enabled > 0 {
+ dotField[typeSym{t, s}] = f1
+ }
if t.Etype == TINTER {
if Isptr[n.Left.Type.Etype] {
n.Left = Nod(OIND, n.Left, nil) // implicitstar
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index cd7db02..442f746 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3857,7 +3857,11 @@
break
}
- field := n.Paramfld
+ t := n.Left.Type
+ if Isptr[t.Etype] {
+ t = t.Type
+ }
+ field := dotField[typeSym{t, n.Right.Sym}]
if field == nil {
Fatal("usefield %v %v without paramfld", n.Left.Type, n.Right.Sym)
}
@@ -3881,10 +3885,7 @@
Yyerror("tracked field must be exported (upper case)")
}
- l := typ(0)
- l.Type = field
- l.Down = Curfn.Paramfld
- Curfn.Paramfld = l
+ Curfn.Func.Fieldtrack = append(Curfn.Func.Fieldtrack, field)
}
func candiscardlist(l *NodeList) bool {