aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/slice.c
diff options
context:
space:
mode:
authorRémy Oudompheng <oudomphe@phare.normalesup.org>2013-01-30 01:55:02 +0100
committerRémy Oudompheng <oudomphe@phare.normalesup.org>2013-01-30 01:55:02 +0100
commitccc61eadd548e66c906a0a33e8a9c2d03238649a (patch)
tree668cbe9fff3a49001975caf5772f8541675429bb /src/pkg/runtime/slice.c
parent76c18a8c4894dcc094f357980bbca8fddf0e98ae (diff)
downloadgo-ccc61eadd548e66c906a0a33e8a9c2d03238649a.tar.xz
runtime: implement range access functions in race detector.
Range access functions are already available in TSan library but were not yet used. Time for go test -race -short: Before: compress/flate 24.244s exp/norm >200s go/printer 78.268s After: compress/flate 17.760s exp/norm 5.537s go/printer 5.738s Fixes #4250. R=dvyukov, golang-dev, fullung CC=golang-dev https://golang.org/cl/7229044
Diffstat (limited to 'src/pkg/runtime/slice.c')
-rw-r--r--src/pkg/runtime/slice.c64
1 files changed, 31 insertions, 33 deletions
diff --git a/src/pkg/runtime/slice.c b/src/pkg/runtime/slice.c
index e2c76eb8e7..eda14f85c1 100644
--- a/src/pkg/runtime/slice.c
+++ b/src/pkg/runtime/slice.c
@@ -71,31 +71,34 @@ makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
void
runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
{
- intgo m, i;
+ intgo m;
uintptr w;
void *pc;
m = x.len+y.len;
+ w = t->elem->size;
if(m < x.len)
runtime·throw("append: slice overflow");
- if(raceenabled) {
- pc = runtime·getcallerpc(&t);
- for(i=0; i<x.len; i++)
- runtime·racereadpc(x.array + i*t->elem->size, pc, runtime·appendslice);
- for(i=x.len; i<x.cap; i++)
- runtime·racewritepc(x.array + i*t->elem->size, pc, runtime·appendslice);
- for(i=0; i<y.len; i++)
- runtime·racereadpc(y.array + i*t->elem->size, pc, runtime·appendslice);
- }
-
if(m > x.cap)
growslice1(t, x, m, &ret);
else
ret = x;
- w = t->elem->size;
+ if(raceenabled) {
+ // Don't mark read/writes on the newly allocated slice.
+ pc = runtime·getcallerpc(&t);
+ // read x[:len]
+ if(m > x.cap)
+ runtime·racereadrangepc(x.array, x.len*w, w, pc, runtime·appendslice);
+ // read y
+ runtime·racereadrangepc(y.array, y.len*w, w, pc, runtime·appendslice);
+ // write x[len(x):len(x)+len(y)]
+ if(m <= x.cap)
+ runtime·racewriterangepc(ret.array+ret.len*w, y.len*w, w, pc, runtime·appendslice);
+ }
+
runtime·memmove(ret.array + ret.len*w, y.array, y.len*w);
ret.len += y.len;
FLUSH(&ret);
@@ -107,7 +110,7 @@ runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
void
runtime·appendstr(SliceType *t, Slice x, String y, Slice ret)
{
- intgo m, i;
+ intgo m;
void *pc;
m = x.len+y.len;
@@ -115,19 +118,22 @@ runtime·appendstr(SliceType *t, Slice x, String y, Slice ret)
if(m < x.len)
runtime·throw("append: slice overflow");
- if(raceenabled) {
- pc = runtime·getcallerpc(&t);
- for(i=0; i<x.len; i++)
- runtime·racereadpc(x.array + i*t->elem->size, pc, runtime·appendstr);
- for(i=x.len; i<x.cap; i++)
- runtime·racewritepc(x.array + i*t->elem->size, pc, runtime·appendstr);
- }
-
if(m > x.cap)
growslice1(t, x, m, &ret);
else
ret = x;
+ if(raceenabled) {
+ // Don't mark read/writes on the newly allocated slice.
+ pc = runtime·getcallerpc(&t);
+ // read x[:len]
+ if(m > x.cap)
+ runtime·racereadrangepc(x.array, x.len, 1, pc, runtime·appendstr);
+ // write x[len(x):len(x)+len(y)]
+ if(m <= x.cap)
+ runtime·racewriterangepc(ret.array+ret.len, y.len, 1, pc, runtime·appendstr);
+ }
+
runtime·memmove(ret.array + ret.len, y.str, y.len);
ret.len += y.len;
FLUSH(&ret);
@@ -140,7 +146,6 @@ runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret)
{
int64 cap;
void *pc;
- int32 i;
if(n < 1)
runtime·panicstring("growslice: invalid n");
@@ -152,8 +157,7 @@ runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret)
if(raceenabled) {
pc = runtime·getcallerpc(&t);
- for(i=0; i<old.len; i++)
- runtime·racewritepc(old.array + i*t->elem->size, pc, runtime·growslice);
+ runtime·racereadrangepc(old.array, old.len*t->elem->size, t->elem->size, pc, runtime·growslice);
}
growslice1(t, old, cap, &ret);
@@ -199,7 +203,6 @@ void
runtime·copy(Slice to, Slice fm, uintptr width, intgo ret)
{
void *pc;
- int32 i;
if(fm.len == 0 || to.len == 0 || width == 0) {
ret = 0;
@@ -212,10 +215,8 @@ runtime·copy(Slice to, Slice fm, uintptr width, intgo ret)
if(raceenabled) {
pc = runtime·getcallerpc(&to);
- for(i=0; i<ret; i++) {
- runtime·racewritepc(to.array + i*width, pc, runtime·copy);
- runtime·racereadpc(fm.array + i*width, pc, runtime·copy);
- }
+ runtime·racewriterangepc(to.array, ret*width, width, pc, runtime·copy);
+ runtime·racereadrangepc(fm.array, ret*width, width, pc, runtime·copy);
}
if(ret == 1 && width == 1) { // common case worth about 2x to do here
@@ -245,7 +246,6 @@ void
runtime·slicestringcopy(Slice to, String fm, intgo ret)
{
void *pc;
- int32 i;
if(fm.len == 0 || to.len == 0) {
ret = 0;
@@ -258,9 +258,7 @@ runtime·slicestringcopy(Slice to, String fm, intgo ret)
if(raceenabled) {
pc = runtime·getcallerpc(&to);
- for(i=0; i<ret; i++) {
- runtime·racewritepc(to.array + i, pc, runtime·slicestringcopy);
- }
+ runtime·racewriterangepc(to.array, ret, 1, pc, runtime·slicestringcopy);
}
runtime·memmove(to.array, fm.str, ret);