runtime: scan write barrier buffer conservatively
authorIan Lance Taylor <ian@gcc.gnu.org>
Sat, 17 Aug 2019 04:35:37 +0000 (04:35 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 17 Aug 2019 04:35:37 +0000 (04:35 +0000)
    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
    sacnning 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.

    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/190599

From-SVN: r274598

gcc/go/gofrontend/MERGE
libgo/go/runtime/mwbbuf.go

index 48b42496965bb9028035ba2c79353e5d36fb3a55..78597da64177f6c0fb78ada1b504a0ebec2e1a29 100644 (file)
@@ -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 4c875ff2d15daf73db1b2b34574a564aa7b3db33..a27406e298761a4c8beaf0e6555a1d4947082399 100644 (file)
@@ -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)