mirror of
https://github.com/golang/go
synced 2024-11-20 05:44:44 -07:00
cmd/gc: racewalk: fix instrumentation of structs
+ do not instrument go.itab.* R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6819106
This commit is contained in:
parent
e33b9f7815
commit
96833d3a25
@ -382,6 +382,27 @@ ret:
|
|||||||
*np = n;
|
*np = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
isartificial(Node *n)
|
||||||
|
{
|
||||||
|
// compiler-emitted artificial things that we do not want to instrument,
|
||||||
|
// cant' possibly participate in a data race.
|
||||||
|
if(n->op == ONAME && n->sym != S && n->sym->name != nil) {
|
||||||
|
if(strcmp(n->sym->name, "_") == 0)
|
||||||
|
return 1;
|
||||||
|
// autotmp's are always local
|
||||||
|
if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0)
|
||||||
|
return 1;
|
||||||
|
// statictmp's are read-only
|
||||||
|
if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0)
|
||||||
|
return 1;
|
||||||
|
// go.itab is accessed only by the compiler and runtime (assume safe)
|
||||||
|
if(n->sym->pkg && n->sym->pkg->name && strcmp(n->sym->pkg->name, "go.itab") == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
callinstr(Node **np, NodeList **init, int wr, int skip)
|
callinstr(Node **np, NodeList **init, int wr, int skip)
|
||||||
{
|
{
|
||||||
@ -390,25 +411,18 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
|
|||||||
int class, res, hascalls;
|
int class, res, hascalls;
|
||||||
|
|
||||||
n = *np;
|
n = *np;
|
||||||
//print("callinstr for %N [ %s ] etype=%d class=%d\n",
|
//print("callinstr for %+N [ %O ] etype=%d class=%d\n",
|
||||||
// n, opnames[n->op], n->type ? n->type->etype : -1, n->class);
|
// n, n->op, n->type ? n->type->etype : -1, n->class);
|
||||||
|
|
||||||
if(skip || n->type == T || n->type->etype >= TIDEAL)
|
if(skip || n->type == T || n->type->etype >= TIDEAL)
|
||||||
return 0;
|
return 0;
|
||||||
t = n->type;
|
t = n->type;
|
||||||
if(n->op == ONAME) {
|
if(isartificial(n))
|
||||||
if(n->sym != S) {
|
return 0;
|
||||||
if(n->sym->name != nil) {
|
|
||||||
if(strcmp(n->sym->name, "_") == 0)
|
|
||||||
return 0;
|
|
||||||
if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0)
|
|
||||||
return 0;
|
|
||||||
if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(t->etype == TSTRUCT) {
|
if(t->etype == TSTRUCT) {
|
||||||
|
// PARAMs w/o PHEAP are not interesting.
|
||||||
|
if(n->class == PPARAM || n->class == PPARAMOUT)
|
||||||
|
return 0;
|
||||||
res = 0;
|
res = 0;
|
||||||
hascalls = 0;
|
hascalls = 0;
|
||||||
foreach(n, hascallspred, &hascalls);
|
foreach(n, hascallspred, &hascalls);
|
||||||
@ -420,6 +434,7 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
|
|||||||
if(t1->sym && strcmp(t1->sym->name, "_")) {
|
if(t1->sym && strcmp(t1->sym->name, "_")) {
|
||||||
n = treecopy(n);
|
n = treecopy(n);
|
||||||
f = nod(OXDOT, n, newname(t1->sym));
|
f = nod(OXDOT, n, newname(t1->sym));
|
||||||
|
f->type = t1;
|
||||||
if(callinstr(&f, init, wr, 0)) {
|
if(callinstr(&f, init, wr, 0)) {
|
||||||
typecheck(&f, Erv);
|
typecheck(&f, Erv);
|
||||||
res = 1;
|
res = 1;
|
||||||
@ -430,6 +445,9 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
b = basenod(n);
|
b = basenod(n);
|
||||||
|
// it skips e.g. stores to ... parameter array
|
||||||
|
if(isartificial(b))
|
||||||
|
return 0;
|
||||||
class = b->class;
|
class = b->class;
|
||||||
// BUG: we _may_ want to instrument PAUTO sometimes
|
// BUG: we _may_ want to instrument PAUTO sometimes
|
||||||
// e.g. if we've got a local variable/method receiver
|
// e.g. if we've got a local variable/method receiver
|
||||||
@ -467,7 +485,7 @@ static Node*
|
|||||||
basenod(Node *n)
|
basenod(Node *n)
|
||||||
{
|
{
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(n->op == ODOT || n->op == OPAREN) {
|
if(n->op == ODOT || n->op == OXDOT || n->op == OCONVNOP || n->op == OCONV || n->op == OPAREN) {
|
||||||
n = n->left;
|
n = n->left;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user