diff options
author | Rick Hudson <rlh@golang.org> | 2014-11-10 14:32:02 -0500 |
---|---|---|
committer | Rick Hudson <rlh@golang.org> | 2014-11-10 14:32:02 -0500 |
commit | 11c9da27d8b3d09835a611edea424885af1ec650 (patch) | |
tree | c761631e9c9f788cf3684ebbf1f4a1c8533d5792 /src/runtime | |
parent | cb223591339d2e03283e21144057b30d5e9667dd (diff) | |
download | go-11c9da27d8b3d09835a611edea424885af1ec650.tar.gz |
[dev.garbage] runtime: Coarsen the write barrier to always grey the destination.
LGTM=rsc
R=rsc
CC=golang-codereviews
https://codereview.appspot.com/174820043
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/mgc0.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c index 5300f554b..3f6cce5c0 100644 --- a/src/runtime/mgc0.c +++ b/src/runtime/mgc0.c @@ -1056,13 +1056,41 @@ shade(byte *b) return; } -// This is the Dijkstra barrier coarsened to shade grey to white whereas -// the original Dijkstra barrier only shaded black to white. +// This is the Dijkstra barrier coarsened to always shade the ptr (dst) object. +// The original Dijkstra barrier only shaded ptrs being placed in black slots. // // Shade indicates that it has seen a white pointer by adding the referent -// to wbuf. +// to wbuf as well as marking it. +// // slot is the destination (dst) in go code // ptr is the value that goes into the slot (src) in the go code +// +// Dijkstra pointed out that maintaining the no black to white +// pointers means that white to white pointers not need +// to be noted by the write barrier. Furthermore if either +// white object dies before it is reached by the +// GC then the object can be collected during this GC cycle +// instead of waiting for the next cycle. Unfortunately the cost of +// ensure that the object holding the slot doesn't concurrently +// change to black without the mutator noticing seems prohibitive. +// +// Consider the following example where the mutator writes into +// a slot and then loads the slot's mark bit while the GC thread +// writes to the slot's mark bit and then as part of scanning reads +// the slot. +// +// Initially both [slot] and [slotmark] are 0 (nil) +// Mutator thread GC thread +// st [slot], ptr st [slotmark], 1 +// +// ld r1, [slotmark] ld r2, [slot] +// +// This is a classic example of independent reads of independent writes, +// aka IRIW. The question is if r1==r2==0 is allowed and for most HW the +// answer is yes without inserting a memory barriers between the st and the ld. +// These barriers are expensive so we have decided that we will +// always grey the ptr object regardless of the slot's color. +// void runtime·gcmarkwb_m() { @@ -1081,11 +1109,11 @@ runtime·gcmarkwb_m() case GCscan: break; case GCmark: - if(ptr != nil && inheap(ptr) && shaded((byte*)slot)) + if(ptr != nil && inheap(ptr)) shade(ptr); break; case GCmarktermination: - if(ptr != nil && inheap(ptr) && shaded((byte*)slot)) + if(ptr != nil && inheap(ptr)) shade(ptr); break; } |