mirror of
https://github.com/golang/go
synced 2024-11-23 10:20:03 -07:00
[dev.garbage] runtime: Coarsen the write barrier to always grey the destination.
LGTM=rsc R=rsc CC=golang-codereviews https://golang.org/cl/174820043
This commit is contained in:
parent
d3d60975b4
commit
28c5385965
@ -1056,13 +1056,41 @@ shade(byte *b)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the Dijkstra barrier coarsened to shade grey to white whereas
|
// This is the Dijkstra barrier coarsened to always shade the ptr (dst) object.
|
||||||
// the original Dijkstra barrier only shaded black to white.
|
// 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
|
// 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
|
// slot is the destination (dst) in go code
|
||||||
// ptr is the value that goes into the slot (src) in the 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
|
void
|
||||||
runtime·gcmarkwb_m()
|
runtime·gcmarkwb_m()
|
||||||
{
|
{
|
||||||
@ -1081,11 +1109,11 @@ runtime·gcmarkwb_m()
|
|||||||
case GCscan:
|
case GCscan:
|
||||||
break;
|
break;
|
||||||
case GCmark:
|
case GCmark:
|
||||||
if(ptr != nil && inheap(ptr) && shaded((byte*)slot))
|
if(ptr != nil && inheap(ptr))
|
||||||
shade(ptr);
|
shade(ptr);
|
||||||
break;
|
break;
|
||||||
case GCmarktermination:
|
case GCmarktermination:
|
||||||
if(ptr != nil && inheap(ptr) && shaded((byte*)slot))
|
if(ptr != nil && inheap(ptr))
|
||||||
shade(ptr);
|
shade(ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user