aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-10-14 23:24:32 -0400
committerRuss Cox <rsc@golang.org>2014-10-14 23:24:32 -0400
commitff6d0a4df44b24b71df1cfbd29534f54a4b2de17 (patch)
tree6461474d72a76944e2cb07aefd41b67c483ebd8c
parentae250ab227311aab7fd8dff22ae05592abd13bde (diff)
downloadgo-ff6d0a4df44b24b71df1cfbd29534f54a4b2de17.tar.xz
cmd/gc, runtime: fix race, nacl for writebarrier changes
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
-rw-r--r--src/cmd/gc/builtin.c6
-rw-r--r--src/cmd/gc/racewalk.c7
-rw-r--r--src/cmd/gc/runtime.go10
-rw-r--r--src/cmd/gc/walk.c6
-rw-r--r--src/runtime/mgc0.go6
5 files changed, 17 insertions, 18 deletions
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
index 17f80ebba4..5fbb4f0cf3 100644
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -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"
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index cb98ca2471..c9e27fe560 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -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) {
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index 6ee5e2e364..86afe67f17 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -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
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 5b5385d50c..241d7d74ad 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -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)
diff --git a/src/runtime/mgc0.go b/src/runtime/mgc0.go
index 3152b1fe1a..3a7204b54f 100644
--- a/src/runtime/mgc0.go
+++ b/src/runtime/mgc0.go
@@ -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]