]> Cypherpunks repositories - gostls13.git/commit
runtime: perform write barrier before pointer write
authorAustin Clements <austin@google.com>
Mon, 22 Aug 2016 20:02:54 +0000 (16:02 -0400)
committerAustin Clements <austin@google.com>
Fri, 28 Oct 2016 20:47:52 +0000 (20:47 +0000)
commit8f81dfe8b47e975b90bb4a2f8dd314d32c633176
tree68a6ba2f5e1e212ff4a6bcdb5d68848ee299cbab
parent0f06d0a051714d14b923b0a9164ab1b3f463aa74
runtime: perform write barrier before pointer write

Currently, we perform write barriers after performing pointer writes.
At the moment, it simply doesn't matter what order this happens in, as
long as they appear atomic to GC. But both the hybrid barrier and ROC
are going to require a pre-write write barrier.

For the hybrid barrier, this is important because the barrier needs to
observe both the current value of the slot and the value that will be
written to it. (Alternatively, the caller could do the write and pass
in the old value, but it seems easier and more useful to just swap the
order of the barrier and the write.)

For ROC, this is necessary because, if the pointer write is going to
make the pointer reachable to some goroutine that it currently is not
visible to, the garbage collector must take some special action before
that pointer becomes more broadly visible.

This commits swaps pointer writes around so the write barrier occurs
before the pointer write.

The main subtlety here is bulk memory writes. Currently, these copy to
the destination first and then use the pointer bitmap of the
destination to find the copied pointers and invoke the write barrier.
This is necessary because the source may not have a pointer bitmap. To
handle these, we pass both the source and the destination to the bulk
memory barrier, which uses the pointer bitmap of the destination, but
reads the pointer values from the source.

Updates #17503.

Change-Id: I78ecc0c5c94ee81c29019c305b3d232069294a55
Reviewed-on: https://go-review.googlesource.com/31763
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/atomic_pointer.go
src/runtime/chan.go
src/runtime/mbarrier.go
src/runtime/mbitmap.go
src/runtime/proc.go