aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mwbbuf.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2018-12-17 13:45:14 -0500
committerAustin Clements <austin@google.com>2018-12-17 19:35:11 +0000
commitfe2feb978e0c4324047f749c3fcfb9cecaafcfdc (patch)
tree4e89bbd551da5869cb8068697e563b2ea53dde1f /src/runtime/mwbbuf.go
parentbed88f4e81013433ff47fb2661a329530b57ede6 (diff)
downloadgo-fe2feb978e0c4324047f749c3fcfb9cecaafcfdc.tar.gz
go-fe2feb978e0c4324047f749c3fcfb9cecaafcfdc.zip
runtime: poison the write barrier buffer during flushing
Currently we reset the write barrier buffer before processing the pointers in it. As a result, if there were any write barriers in the code that processes the buffer, it would corrupt the write barrier buffer and cause us to mark objects without later scanning them. As far as I can tell, this shouldn't be happening, but rather than relying on hope (and incomplete static analysis), this CL changes wbBufFlush1 to poison the write barrier buffer while processing it, and only reset it once it's done. Updates #27993. (Unlike many of the other changes for this issue, there's no need to roll back this CL. It's a good change in its own right.) Change-Id: I6d2d9f1b69b89438438b9ee624f3fff9f009e29d Reviewed-on: https://go-review.googlesource.com/c/154537 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/mwbbuf.go')
-rw-r--r--src/runtime/mwbbuf.go8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/runtime/mwbbuf.go b/src/runtime/mwbbuf.go
index a698493a0a..6f01bf68fd 100644
--- a/src/runtime/mwbbuf.go
+++ b/src/runtime/mwbbuf.go
@@ -217,14 +217,16 @@ func wbBufFlush1(_p_ *p) {
n := (_p_.wbBuf.next - start) / unsafe.Sizeof(_p_.wbBuf.buf[0])
ptrs := _p_.wbBuf.buf[:n]
- // Reset the buffer.
- _p_.wbBuf.reset()
+ // Poison the buffer to make extra sure nothing is enqueued
+ // while we're processing the buffer.
+ _p_.wbBuf.next = 0
if useCheckmark {
// Slow path for checkmark mode.
for _, ptr := range ptrs {
shade(ptr)
}
+ _p_.wbBuf.reset()
return
}
@@ -275,4 +277,6 @@ func wbBufFlush1(_p_ *p) {
// Enqueue the greyed objects.
gcw.putBatch(ptrs[:pos])
+
+ _p_.wbBuf.reset()
}