runtime: check for no preemption during write barrier #12069
Changes the torture test in #12068 from failing about 1/10 times to not failing in almost 2,000 runs. This was only happening in -race mode because functions are bigger in -race mode, so a few of the helpers for heapBitsBulkBarrier were not being inlined, and they were not marked nosplit, so (only in -race mode) the write barrier was being preempted by GC, causing missed pointer updates. Filed issue #12069 for diagnosis of any other similar errors. Fixes #12068. Change-Id: Ic174d9b050ba278b18b08ab0d85a73c33bd5b175 Reviewed-on: https://go-review.googlesource.com/13364 Reviewed-by: Austin Clements <email@example.com>
To be clear, this is about things like
It seems like the way to do this is to add a new "go:nopreempt" annotation that's like a recursive nosplit and replace nosplits with nopreempts where that's what we really mean. One sticking point may be functions that increment mp.locks or set mp.preemptoff that must not be preempted before this point, but can grow the stack once they've dynamically disallowed preemption. Maybe for these we just keep using nosplit.