mirror of
https://github.com/golang/go
synced 2024-11-26 05:17:58 -07:00
cmd/gc: improve escape analysis for &T{...}
Currently all PTRLIT element initializers escape. There is no reason for that. This change links STRUCTLIT to PTRLIT; STRUCTLIT element initializers are already linked to the STRUCTLIT. As the result, PTRLIT element initializers escape when PTRLIT itself escapes. Change-Id: I89ecd8677cbf81addcfd469cd2fd461c0e9bf7dd Reviewed-on: https://go-review.googlesource.com/3031 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
2059ffbc8d
commit
1b87f01239
@ -615,15 +615,15 @@ esc(EscState *e, Node *n, Node *up)
|
|||||||
for(ll=n->list; ll; ll=ll->next)
|
for(ll=n->list; ll; ll=ll->next)
|
||||||
escassign(e, n, ll->n->right);
|
escassign(e, n, ll->n->right);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTRLIT:
|
case OPTRLIT:
|
||||||
n->esc = EscNone; // until proven otherwise
|
n->esc = EscNone; // until proven otherwise
|
||||||
e->noesc = list(e->noesc, n);
|
e->noesc = list(e->noesc, n);
|
||||||
n->escloopdepth = e->loopdepth;
|
n->escloopdepth = e->loopdepth;
|
||||||
// Contents make it to memory, lose track.
|
// Link OSTRUCTLIT to OPTRLIT; if OPTRLIT escapes, OSTRUCTLIT elements do too.
|
||||||
escassign(e, &e->theSink, n->left);
|
escassign(e, n, n->left);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
n->esc = EscNone; // until proven otherwise
|
n->esc = EscNone; // until proven otherwise
|
||||||
e->noesc = list(e->noesc, n);
|
e->noesc = list(e->noesc, n);
|
||||||
@ -730,6 +730,7 @@ escassign(EscState *e, Node *dst, Node *src)
|
|||||||
case OCONVNOP:
|
case OCONVNOP:
|
||||||
case OMAPLIT:
|
case OMAPLIT:
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
|
case OPTRLIT:
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1492,3 +1492,30 @@ func g() (x interface{}) { // ERROR "moved to heap: x"
|
|||||||
x = &x // ERROR "&x escapes to heap"
|
x = &x // ERROR "&x escapes to heap"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sink interface{}
|
||||||
|
|
||||||
|
type Lit struct {
|
||||||
|
p *int
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrlitNoescape() {
|
||||||
|
// Both literal and element do not escape.
|
||||||
|
i := 0
|
||||||
|
x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i does not escape"
|
||||||
|
_ = x
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrlitNoEscape2() {
|
||||||
|
// Literal does not escape, but element does.
|
||||||
|
i := 0 // ERROR "moved to heap: i"
|
||||||
|
x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i escapes to heap"
|
||||||
|
sink = *x
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrlitEscape() {
|
||||||
|
// Both literal and element escape.
|
||||||
|
i := 0 // ERROR "moved to heap: i"
|
||||||
|
x := &Lit{&i} // ERROR "&Lit literal escapes to heap" "&i escapes to heap"
|
||||||
|
sink = x
|
||||||
|
}
|
||||||
|
@ -1492,3 +1492,30 @@ func g() (x interface{}) { // ERROR "moved to heap: x"
|
|||||||
x = &x // ERROR "&x escapes to heap"
|
x = &x // ERROR "&x escapes to heap"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sink interface{}
|
||||||
|
|
||||||
|
type Lit struct {
|
||||||
|
p *int
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrlitNoescape() {
|
||||||
|
// Both literal and element do not escape.
|
||||||
|
i := 0
|
||||||
|
x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i does not escape"
|
||||||
|
_ = x
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrlitNoEscape2() {
|
||||||
|
// Literal does not escape, but element does.
|
||||||
|
i := 0 // ERROR "moved to heap: i"
|
||||||
|
x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i escapes to heap"
|
||||||
|
sink = *x
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrlitEscape() {
|
||||||
|
// Both literal and element escape.
|
||||||
|
i := 0 // ERROR "moved to heap: i"
|
||||||
|
x := &Lit{&i} // ERROR "&Lit literal escapes to heap" "&i escapes to heap"
|
||||||
|
sink = x
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user