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.