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
"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"
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) {
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
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)
}
//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]