mirror of https://github.com/golang/go.git
cmd/gc: relax address-of escape analysis
Make the loop nesting depth of &x depend on where x is declared, not on where the &x appears. The latter is only a conservative estimate of the former. Being more careful can avoid some variables escaping, and it is easier to reason about. It would have avoided issue 7313, although that was still a bug worth fixing. Not much effect in the tree: one variable in the whole tree is saved from a heap allocation (something in x509 parsing). LGTM=daniel.morsing R=daniel.morsing CC=golang-codereviews https://golang.org/cl/62380043
This commit is contained in:
parent
e0bb5ba52c
commit
e5d742fcad
|
|
@ -328,6 +328,7 @@ escfunc(EscState *e, Node *func)
|
|||
ll->n->escloopdepth = 0;
|
||||
break;
|
||||
case PPARAM:
|
||||
ll->n->escloopdepth = 1;
|
||||
if(ll->n->type && !haspointers(ll->n->type))
|
||||
break;
|
||||
if(curfn->nbody == nil && !curfn->noescape)
|
||||
|
|
@ -335,7 +336,6 @@ escfunc(EscState *e, Node *func)
|
|||
else
|
||||
ll->n->esc = EscNone; // prime for escflood later
|
||||
e->noesc = list(e->noesc, ll->n);
|
||||
ll->n->escloopdepth = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -630,7 +630,6 @@ esc(EscState *e, Node *n)
|
|||
escassign(e, n, a);
|
||||
}
|
||||
// fallthrough
|
||||
case OADDR:
|
||||
case OMAKECHAN:
|
||||
case OMAKEMAP:
|
||||
case OMAKESLICE:
|
||||
|
|
@ -639,6 +638,24 @@ esc(EscState *e, Node *n)
|
|||
n->esc = EscNone; // until proven otherwise
|
||||
e->noesc = list(e->noesc, n);
|
||||
break;
|
||||
|
||||
case OADDR:
|
||||
n->esc = EscNone; // until proven otherwise
|
||||
e->noesc = list(e->noesc, n);
|
||||
// current loop depth is an upper bound on actual loop depth
|
||||
// of addressed value.
|
||||
n->escloopdepth = e->loopdepth;
|
||||
// for &x, use loop depth of x.
|
||||
if(n->left->op == ONAME) {
|
||||
switch(n->left->class) {
|
||||
case PAUTO:
|
||||
case PPARAM:
|
||||
case PPARAMOUT:
|
||||
n->escloopdepth = n->left->escloopdepth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
lineno = lno;
|
||||
|
|
|
|||
|
|
@ -1389,3 +1389,13 @@ func foo148(l List) { // ERROR " l does not escape"
|
|||
for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
|
||||
}
|
||||
}
|
||||
|
||||
// related: address of variable should have depth of variable, not of loop
|
||||
|
||||
func foo149(l List) { // ERROR " l does not escape"
|
||||
var p *List
|
||||
for {
|
||||
for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue