]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix race instrumentation of append
authorDmitry Vyukov <dvyukov@google.com>
Tue, 10 Feb 2015 12:26:07 +0000 (15:26 +0300)
committerDmitry Vyukov <dvyukov@google.com>
Thu, 12 Feb 2015 08:51:49 +0000 (08:51 +0000)
typedslicecopy is another write barrier that is not
understood by racewalk. It seems quite complex to handle it
in the compiler, so instead just instrument it in runtime.

Update #9796

Change-Id: I0eb6abf3a2cd2491a338fab5f7da22f01bf7e89b
Reviewed-on: https://go-review.googlesource.com/4370
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/gc/racewalk.c
src/runtime/mbarrier.go
src/runtime/race/testdata/slice_test.go

index 757b02cb122f5622af603c34449828bbc927c405..3aa7e3638682dbbed26c01ce6c9a183d2f860597 100644 (file)
@@ -205,6 +205,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
        case OCALLFUNC:
                // Instrument dst argument of runtime.writebarrier* calls
                // as we do not instrument runtime code.
+               // typedslicecopy is instrumented in runtime.
                if(n->left->sym != S && n->left->sym->pkg == runtimepkg && 
                (strncmp(n->left->sym->name, "writebarrier", 12) == 0 || strcmp(n->left->sym->name, "typedmemmove") == 0)) {
                        // Find the dst argument.
index 33d67c49761ffc857fba5b823c6df1a298cd0657..f6e92698580ed5e8aa03b1afdef252c4857f2afd 100644 (file)
@@ -328,6 +328,13 @@ func typedslicecopy(typ *_type, dst, src slice) int {
        dstp := unsafe.Pointer(dst.array)
        srcp := unsafe.Pointer(src.array)
 
+       if raceenabled {
+               callerpc := getcallerpc(unsafe.Pointer(&typ))
+               pc := funcPC(slicecopy)
+               racewriterangepc(dstp, uintptr(n)*typ.size, callerpc, pc)
+               racereadrangepc(srcp, uintptr(n)*typ.size, callerpc, pc)
+       }
+
        if !needwb() {
                memmove(dstp, srcp, uintptr(n)*typ.size)
                return int(n)
index 5702d1ac85859e7176414cfc9c135b6393facf15..32ae87897008a6c3aeefac794a623db85a473d54 100644 (file)
@@ -144,6 +144,54 @@ func TestNoRaceSliceCopyRead(t *testing.T) {
        <-ch
 }
 
+func TestRacePointerSliceCopyRead(t *testing.T) {
+       ch := make(chan bool, 1)
+       a := make([]*int, 10)
+       b := make([]*int, 10)
+       go func() {
+               _ = a[5]
+               ch <- true
+       }()
+       copy(a, b)
+       <-ch
+}
+
+func TestNoRacePointerSliceWriteCopy(t *testing.T) {
+       ch := make(chan bool, 1)
+       a := make([]*int, 10)
+       b := make([]*int, 10)
+       go func() {
+               a[5] = new(int)
+               ch <- true
+       }()
+       copy(a[:5], b[:5])
+       <-ch
+}
+
+func TestRacePointerSliceCopyWrite2(t *testing.T) {
+       ch := make(chan bool, 1)
+       a := make([]*int, 10)
+       b := make([]*int, 10)
+       go func() {
+               b[5] = new(int)
+               ch <- true
+       }()
+       copy(a, b)
+       <-ch
+}
+
+func TestNoRacePointerSliceCopyRead(t *testing.T) {
+       ch := make(chan bool, 1)
+       a := make([]*int, 10)
+       b := make([]*int, 10)
+       go func() {
+               _ = b[5]
+               ch <- true
+       }()
+       copy(a, b)
+       <-ch
+}
+
 func TestNoRaceSliceWriteSlice2(t *testing.T) {
        ch := make(chan bool, 1)
        a := make([]float64, 10)
@@ -395,6 +443,53 @@ func TestRaceSliceAppendString(t *testing.T) {
        <-c
 }
 
+func TestRacePointerSliceAppend(t *testing.T) {
+       c := make(chan bool, 1)
+       s := make([]*int, 10, 20)
+       go func() {
+               _ = append(s, new(int))
+               c <- true
+       }()
+       _ = append(s, new(int))
+       <-c
+}
+
+func TestRacePointerSliceAppendWrite(t *testing.T) {
+       c := make(chan bool, 1)
+       s := make([]*int, 10)
+       go func() {
+               _ = append(s, new(int))
+               c <- true
+       }()
+       s[0] = new(int)
+       <-c
+}
+
+func TestRacePointerSliceAppendSlice(t *testing.T) {
+       c := make(chan bool, 1)
+       s := make([]*int, 10)
+       go func() {
+               s2 := make([]*int, 10)
+               _ = append(s, s2...)
+               c <- true
+       }()
+       s[0] = new(int)
+       <-c
+}
+
+func TestRacePointerSliceAppendSlice2(t *testing.T) {
+       c := make(chan bool, 1)
+       s := make([]*int, 10)
+       s2foobar := make([]*int, 10)
+       go func() {
+               _ = append(s, s2foobar...)
+               c <- true
+       }()
+       println("WRITE:", &s2foobar[5])
+       s2foobar[5] = nil
+       <-c
+}
+
 func TestNoRaceSliceIndexAccess(t *testing.T) {
        c := make(chan bool, 1)
        s := make([]int, 10)