You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The go:nowritebarrierrec annotation is supposed to recursively disallow write barriers. However, it doesn't know about the implicit morestack call in most function prologues. Unfortunately, newstack (called from morestack) has a write barrier on the gp.sched.ctxt = ctxt line (complete with a comment explaining why that write barrier is important!), which means we can get a write barrier under a function that statically disallows write barriers if it causes stack growth.
I can think of two solutions:
Make go:nowritebarrierrec require either go:systemstack or go:nosplitrec. This seems like an ugly constraint that would be hard to add to the runtime, and go:nosplitrec doesn't even exist right now.
Eliminate the write barrier from newstack. The only write barrier is when assigning ctxt and ctxt is a little weird: it's really just a saved register. We just bounce ctxt between this register and gp.sched. Hence, it should be safe to simply drop the write barrier when saving ctxt (and when restoring it, which eliminates some nasty assembly code) and to instead scan it in scanstack, viewing it as a live register that goes along with the stack.
I have solution 2 implemented on amd64 and it seems to be working.
The
go:nowritebarrierrec
annotation is supposed to recursively disallow write barriers. However, it doesn't know about the implicitmorestack
call in most function prologues. Unfortunately,newstack
(called frommorestack
) has a write barrier on thegp.sched.ctxt = ctxt
line (complete with a comment explaining why that write barrier is important!), which means we can get a write barrier under a function that statically disallows write barriers if it causes stack growth.I can think of two solutions:
go:nowritebarrierrec
require eithergo:systemstack
orgo:nosplitrec
. This seems like an ugly constraint that would be hard to add to the runtime, andgo:nosplitrec
doesn't even exist right now.newstack
. The only write barrier is when assigningctxt
andctxt
is a little weird: it's really just a saved register. We just bouncectxt
between this register andgp.sched
. Hence, it should be safe to simply drop the write barrier when savingctxt
(and when restoring it, which eliminates some nasty assembly code) and to instead scan it inscanstack
, viewing it as a live register that goes along with the stack.I have solution 2 implemented on amd64 and it seems to be working.
/cc @RLH
The text was updated successfully, but these errors were encountered: