From f5d494bbdf945f2662eb4da45cdb75de2b7d43d4 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 15 Jun 2015 12:30:23 -0400 Subject: runtime: ensure GC sees type-safe memory on weak machines Currently its possible for the garbage collector to observe uninitialized memory or stale heap bitmap bits on weakly ordered architectures such as ARM and PPC. On such architectures, the stores that zero newly allocated memory and initialize its heap bitmap may move after a store in user code that makes the allocated object observable by the garbage collector. To fix this, add a "publication barrier" (also known as an "export barrier") before returning from mallocgc. This is a store/store barrier that ensures any write done by user code that makes the returned object observable to the garbage collector will be ordered after the initialization performed by mallocgc. No barrier is necessary on the reading side because of the data dependency between loading the pointer and loading the contents of the object. Fixes one of the issues raised in #9984. Change-Id: Ia3d96ad9c5fc7f4d342f5e05ec0ceae700cd17c8 Reviewed-on: https://go-review.googlesource.com/11083 Reviewed-by: Rick Hudson Reviewed-by: Dmitry Vyukov Reviewed-by: Minux Ma Reviewed-by: Martin Capitanio Reviewed-by: Russ Cox --- src/runtime/sys_linux_arm.s | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/runtime/sys_linux_arm.s') diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s index 50f074a234..b68b81af3e 100644 --- a/src/runtime/sys_linux_arm.s +++ b/src/runtime/sys_linux_arm.s @@ -416,6 +416,22 @@ check: TEXT runtime·casp1(SB),NOSPLIT,$0 B runtime·cas(SB) +// As for cas, memory barriers are complicated on ARM, but the kernel +// provides a user helper. ARMv5 does not support SMP and has no +// memory barrier instruction at all. ARMv6 added SMP support and has +// a memory barrier, but it requires writing to a coprocessor +// register. ARMv7 introduced the DMB instruction, but it's expensive +// even on single-core devices. The kernel helper takes care of all of +// this for us. + +TEXT publicationBarrier<>(SB),NOSPLIT,$0 + // void __kuser_memory_barrier(void); + MOVW $0xffff0fa0, R15 // R15 is hardware PC. + +TEXT ·publicationBarrier(SB),NOSPLIT,$0 + BL publicationBarrier<>(SB) + RET + TEXT runtime·osyield(SB),NOSPLIT,$0 MOVW $SYS_sched_yield, R7 SWI $0 -- cgit v1.3