]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc, runtime: fix race, nacl for writebarrier changes
authorRuss Cox <rsc@golang.org>
Wed, 15 Oct 2014 03:24:32 +0000 (23:24 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 15 Oct 2014 03:24:32 +0000 (23:24 -0400)
The racewalk code was not updated for the new write barriers.
Make it more future-proof.

The new write barrier code assumed that +1 pointer would
be aligned properly for any type that might follow, but that's
not true on 32-bit systems where some types are 64-bit aligned.
The only system like that today is nacl/amd64p32.
Insert a dummy pointer so that the ambiguously typed
value is at +2 pointers, which is always max-aligned.

LGTM=r
R=r
CC=golang-codereviews, iant, khr
https://golang.org/cl/158890046

src/cmd/gc/builtin.c
src/cmd/gc/racewalk.c
src/cmd/gc/runtime.go
src/cmd/gc/walk.c
src/runtime/mgc0.go

index 17f80ebba46e5f9850a9eed3ba8eaaf6e18f72ef..5fbb4f0cf364d2e5b8d7faf4ba765fa870812f82 100644 (file)
@@ -87,9 +87,9 @@ char *runtimeimport =
        "func @\"\".writebarrierstring (@\"\".dst·1 *any, @\"\".src·2 any)\n"
        "func @\"\".writebarrierslice (@\"\".dst·1 *any, @\"\".src·2 any)\n"
        "func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n"
-       "func @\"\".writebarrierfat2 (@\"\".dst·1 *any, @\"\".src·2 any)\n"
-       "func @\"\".writebarrierfat3 (@\"\".dst·1 *any, @\"\".src·2 any)\n"
-       "func @\"\".writebarrierfat4 (@\"\".dst·1 *any, @\"\".src·2 any)\n"
+       "func @\"\".writebarrierfat2 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+       "func @\"\".writebarrierfat3 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+       "func @\"\".writebarrierfat4 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
        "func @\"\".writebarrierfat (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n"
        "func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n"
        "func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n"
index cb98ca2471efaeaa57ef03b68f8632627be4de4d..c9e27fe5604a88ae45016c3ff343861fb2e8bdf7 100644 (file)
@@ -210,12 +210,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.
-               if(n->left->sym != S && n->left->sym->pkg == runtimepkg &&
-                       (strcmp(n->left->sym->name, "writebarrierptr") == 0 ||
-                       strcmp(n->left->sym->name, "writebarrierstring") == 0 ||
-                       strcmp(n->left->sym->name, "writebarrierslice") == 0 ||
-                       strcmp(n->left->sym->name, "writebarrieriface") == 0 ||
-                       strcmp(n->left->sym->name, "writebarrierfat") == 0)) {
+               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) {
index 6ee5e2e364e6ec1b9ffd2d748435337f978fe4eb..86afe67f1700dfb767e2881452d91d83542648af 100644 (file)
@@ -112,9 +112,13 @@ func writebarrierptr(dst *any, src any)
 func writebarrierstring(dst *any, src any)
 func writebarrierslice(dst *any, src any)
 func writebarrieriface(dst *any, src any)
-func writebarrierfat2(dst *any, src any)
-func writebarrierfat3(dst *any, src any)
-func writebarrierfat4(dst *any, src any)
+
+// The unused *byte argument makes sure that src is 2-pointer-aligned,
+// which is the maximum alignment on NaCl amd64p32
+// (and possibly on 32-bit systems if we start 64-bit aligning uint64s).
+func writebarrierfat2(dst *any, _ *byte, src any)
+func writebarrierfat3(dst *any, _ *byte, src any)
+func writebarrierfat4(dst *any, _ *byte, src any)
 func writebarrierfat(typ *byte, dst *any, src *any)
 
 func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool
index 5b5385d50c6569c5fe3c7da9fa914d38433932d9..241d7d74adbc9029c12a02c12de63e0c0fbbd628 100644 (file)
@@ -2060,13 +2060,13 @@ applywritebarrier(Node *n, NodeList **init)
                                l, n->right);
                } else if(t->width == 2*widthptr) {
                        n = mkcall1(writebarrierfn("writebarrierfat2", t, n->right->type), T, init,
-                               l, n->right);
+                               l, nodnil(), n->right);
                } else if(t->width == 3*widthptr) {
                        n = mkcall1(writebarrierfn("writebarrierfat3", t, n->right->type), T, init,
-                               l, n->right);
+                               l, nodnil(), n->right);
                } else if(t->width == 4*widthptr) {
                        n = mkcall1(writebarrierfn("writebarrierfat4", t, n->right->type), T, init,
-                               l, n->right);
+                               l, nodnil(), n->right);
                } else {
                        r = n->right;
                        while(r->op == OCONVNOP)
index 3152b1fe1aa34615f33ed7e9c4ca73c7354afb87..3a7204b54f27c116b999615d360405cd181749fd 100644 (file)
@@ -110,20 +110,20 @@ func writebarrieriface(dst *[2]uintptr, src [2]uintptr) {
 }
 
 //go:nosplit
-func writebarrierfat2(dst *[2]uintptr, src [2]uintptr) {
+func writebarrierfat2(dst *[2]uintptr, _ *byte, src [2]uintptr) {
        dst[0] = src[0]
        dst[1] = src[1]
 }
 
 //go:nosplit
-func writebarrierfat3(dst *[3]uintptr, src [3]uintptr) {
+func writebarrierfat3(dst *[3]uintptr, _ *byte, src [3]uintptr) {
        dst[0] = src[0]
        dst[1] = src[1]
        dst[2] = src[2]
 }
 
 //go:nosplit
-func writebarrierfat4(dst *[4]uintptr, src [4]uintptr) {
+func writebarrierfat4(dst *[4]uintptr, _ *byte, src [4]uintptr) {
        dst[0] = src[0]
        dst[1] = src[1]
        dst[2] = src[2]