summaryrefslogtreecommitdiff
path: root/src/cmd/gc/racewalk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/racewalk.c')
-rw-r--r--src/cmd/gc/racewalk.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index 285bd78a2..c9e27fe56 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -208,6 +208,26 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
goto ret;
case OCALLFUNC:
+ // Instrument dst argument of runtime.writebarrier* calls
+ // as we do not instrument runtime code.
+ if(n->left->sym != S && n->left->sym->pkg == runtimepkg && strncmp(n->left->sym->name, "writebarrier", 12) == 0) {
+ // Find the dst argument.
+ // The list can be reordered, so it's not necessary just the first or the second element.
+ for(l = n->list; l; l = l->next) {
+ if(strcmp(n->left->sym->name, "writebarrierfat") == 0) {
+ if(l->n->left->xoffset == widthptr)
+ break;
+ } else {
+ if(l->n->left->xoffset == 0)
+ break;
+ }
+ }
+ if(l == nil)
+ fatal("racewalk: writebarrier no arg");
+ if(l->n->right->op != OADDR)
+ fatal("racewalk: writebarrier bad arg");
+ callinstr(&l->n->right->left, init, 1, 0);
+ }
racewalknode(&n->left, init, 0, 0);
goto ret;
@@ -419,8 +439,10 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
ret:
if(n->op != OBLOCK) // OBLOCK is handled above in a special way.
racewalklist(n->list, init);
- racewalknode(&n->ntest, &n->ntest->ninit, 0, 0);
- racewalknode(&n->nincr, &n->nincr->ninit, 0, 0);
+ if(n->ntest != N)
+ racewalknode(&n->ntest, &n->ntest->ninit, 0, 0);
+ if(n->nincr != N)
+ racewalknode(&n->nincr, &n->nincr->ninit, 0, 0);
racewalklist(n->nbody, nil);
racewalklist(n->nelse, nil);
racewalklist(n->rlist, nil);