On Friday, July 28, 2023 at 8:05:03 AM UTC-4 metronome wrote:

Hi,

I came across two questions regarding the hybrid barrier that I am hoping 
someone can help with.


1.

Chang https://go-review.googlesource.com/c/go/+/31765 says:

*"It's unconditional for now because barriers on channel operations require 
checking both the source and destination stacks and we don't have a way to 
funnel this information into the write barrier at the moment."*

Can anyone help in understanding the statement, say with a sample? Isn't 
"channel operations involving both stacks" already covered by 
runtime.sendDirect?

Here's my best guess: at the time this CL was written, sendDirect called 
typeBitsBulkBarrier which in turn called writebarrier_prewrite and then 
gcmarkwb_m (the generic non-assembly write barrier function). gcmarkwb_m, 
however, didn't have any knowledge of the context around the pointers being 
written and deleted, or the stack it would've been running on. Information 
about both the source and destination stacks would have had to be passed 
down through those other functions. It could be done, but it's a lot of 
context to pass around for just one corner case.

Though, honestly, I believe the true reason the write barrier was made 
unconditional was because the performance was good enough and it's more 
complex to make it conditional.

In fact, I suspect this is why the hybrid write barrier is still 
unconditional to this day. It also looks very different! The write barrier 
no longer directly marks objects and instead it enqueues the relevant 
pointers in the write barrier buffer system, so there's no write barrier 
routine to plumb this information down into. There may be some ways to make 
it conditional (this TODO f 
<https://cs.opensource.google/go/go/+/master:src/runtime/mwbbuf.go;l=221?q=mwbbuf&ss=go%2Fgo>or
 
instance) but I don't think anyone is planning to work on it. My gut 
feeling is that the complexity and cost of plumbing this information 
through (or acquiring and using it at the point of the write barrier) might 
not be worth whatever modest performance improvement we would get out of 
it. It would still be interesting to try and find out; I'm happy to be 
wrong. :)

2. comments in mbarrier.go says

// The insertion part of the barrier

// is necessary while the calling goroutine's stack is grey. In

// pseudocode, the barrier is:

//

// writePointer(slot, ptr):

// shade(*slot)

// if current stack is grey:

// shade(ptr)

// *slot = ptr

What does "grey stack" mean? Is a stack considered 'grey' right after its 
goroutine gets suspended, scanned and resumed to execution?

Thanks a lot.

A goroutine stack is a GC mark root, so I believe in this terminology it's 
implicitly grey at the start of the mark phase. It then transitions to 
black once it gets scanned.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/0ae11cc2-73eb-4467-9abe-5db1aee5b11an%40googlegroups.com.

Reply via email to