summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorR?my Oudompheng <oudomphe@phare.normalesup.org>2013-06-14 11:14:45 +0200
committerR?my Oudompheng <oudomphe@phare.normalesup.org>2013-06-14 11:14:45 +0200
commitbb665158525bb95362213b246d29ae8a00e9f819 (patch)
tree25efc98e913710b016848493336bad57742c5673 /src/cmd
parentf817b1751f23350f3d1d8d37f813e269cd7631fd (diff)
downloadgo-bb665158525bb95362213b246d29ae8a00e9f819.tar.gz
cmd/gc: instrument arrays properly in race detector.
The previous implementation would only record access to the address of the array but the memory access to the whole memory range must be recorded instead. R=golang-dev, dvyukov, r CC=golang-dev https://codereview.appspot.com/8053044
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/gc/builtin.c2
-rw-r--r--src/cmd/gc/racewalk.c37
-rw-r--r--src/cmd/gc/runtime.go2
3 files changed, 11 insertions, 30 deletions
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
index 9053dfe10..baa7d7845 100644
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -113,6 +113,8 @@ char *runtimeimport =
"func @\"\".racefuncexit ()\n"
"func @\"\".raceread (? uintptr)\n"
"func @\"\".racewrite (? uintptr)\n"
+ "func @\"\".racereadrange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n"
+ "func @\"\".racewriterange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n"
"\n"
"$$\n";
char *unsafeimport =
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index 74d852258..0c847d8bb 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -439,8 +439,8 @@ static int
callinstr(Node **np, NodeList **init, int wr, int skip)
{
Node *f, *b, *n;
- Type *t, *t1;
- int class, res, hascalls;
+ Type *t;
+ int class, hascalls;
n = *np;
//print("callinstr for %+N [ %O ] etype=%E class=%d\n",
@@ -451,33 +451,6 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
t = n->type;
if(isartificial(n))
return 0;
- if(t->etype == TSTRUCT) {
- // TODO: instrument arrays similarly.
- // PARAMs w/o PHEAP are not interesting.
- if(n->class == PPARAM || n->class == PPARAMOUT)
- return 0;
- res = 0;
- hascalls = 0;
- foreach(n, hascallspred, &hascalls);
- if(hascalls) {
- n = detachexpr(n, init);
- *np = n;
- }
- for(t1=t->type; t1; t1=t1->down) {
- if(t1->sym && strcmp(t1->sym->name, "_")) {
- n = treecopy(n);
- f = nod(OXDOT, n, newname(t1->sym));
- f->type = t1;
- if(f->type->etype == TFIELD)
- f->type = f->type->type;
- if(callinstr(&f, init, wr, 0)) {
- typecheck(&f, Erv);
- res = 1;
- }
- }
- }
- return res;
- }
b = basenod(n);
// it skips e.g. stores to ... parameter array
@@ -498,7 +471,11 @@ callinstr(Node **np, NodeList **init, int wr, int skip)
}
n = treecopy(n);
makeaddable(n);
- f = mkcall(wr ? "racewrite" : "raceread", T, init, uintptraddr(n));
+ if(t->etype == TSTRUCT || isfixedarray(t)) {
+ f = mkcall(wr ? "racewriterange" : "racereadrange", T, init, uintptraddr(n),
+ nodintconst(t->width));
+ } else
+ f = mkcall(wr ? "racewrite" : "raceread", T, init, uintptraddr(n));
*init = list(*init, f);
return 1;
}
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index 2139a95d9..d7032957b 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -149,3 +149,5 @@ func racefuncenter(uintptr)
func racefuncexit()
func raceread(uintptr)
func racewrite(uintptr)
+func racereadrange(addr, size uintptr)
+func racewriterange(addr, size uintptr)