This libgo patch by Cherry Zhang scans the write barrier buffer
conservatively.  In gccgo, we insert the write barriers in the
frontend, and so we cannot completely prevent write barriers on stack
writes.  So it is possible for a bad pointer appearing in the write
barrier buffer.  When flushing the write barrier, treat it the same as
scanning the stack.  In particular, don't mark a pointer if it does
not point to an allocated object. We already have similar logic in
greyobject.  With this, hopefully, we can prevent an unallocated
object from being marked completely.  Bootstrapped and ran Go
testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 274591)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-0f6d673d5b1a3474c3424cb6994ae8ff9baed255
+838f926c93898767f0337122725a4f52a1335186
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/go/runtime/mwbbuf.go
===================================================================
--- libgo/go/runtime/mwbbuf.go  (revision 274169)
+++ libgo/go/runtime/mwbbuf.go  (working copy)
@@ -285,10 +285,17 @@ func wbBufFlush1(_p_ *p) {
                        // path to reduce the rate of flushes?
                        continue
                }
-               obj, span, objIndex := findObject(ptr, 0, 0, false)
+               obj, span, objIndex := findObject(ptr, 0, 0, !usestackmaps)
                if obj == 0 {
                        continue
                }
+               if span.isFree(objIndex) {
+                       // For gccgo, it is possible that we have a write 
barrier
+                       // writing to unintialized stack memory. So we could see
+                       // a bad pointer in the write barrier buffer. Don't mark
+                       // it in this case.
+                       continue
+               }
                // TODO: Consider making two passes where the first
                // just prefetches the mark bits.
                mbits := span.markBitsForIndex(objIndex)

Reply via email to