mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
[dev.garbage] runtime: Code to implement write barriers
To turn concurrent gc on alter the if false in func gogc currently at line 489 in malloc.go LGTM=rsc R=rsc CC=golang-codereviews, rlh https://golang.org/cl/172190043
This commit is contained in:
parent
d8ee1c5a2c
commit
d3d60975b4
5 changed files with 66 additions and 16 deletions
|
@ -486,16 +486,17 @@ func gogc(force int32) {
|
|||
|
||||
onM(stoptheworld)
|
||||
onM(finishsweep_m) // finish sweep before we start concurrent scan.
|
||||
onM(starttheworld)
|
||||
|
||||
// Do a concurrent heap scan before we stop the world.
|
||||
onM(gcscan_m)
|
||||
onM(gcinstallmarkwb_m)
|
||||
onM(stoptheworld)
|
||||
// onM(starttheworld)
|
||||
// mark from roots scanned in gcscan_m. startthework when write barrier works
|
||||
onM(gcmark_m)
|
||||
// onM(stoptheworld)
|
||||
if false { // To turn on concurrent scan and mark set to true...
|
||||
onM(starttheworld)
|
||||
// Do a concurrent heap scan before we stop the world.
|
||||
onM(gcscan_m)
|
||||
onM(stoptheworld)
|
||||
onM(gcinstallmarkwb_m)
|
||||
onM(starttheworld)
|
||||
onM(gcmark_m)
|
||||
onM(stoptheworld)
|
||||
onM(gcinstalloffwb_m)
|
||||
}
|
||||
if mp != acquirem() {
|
||||
gothrow("gogc: rescheduled")
|
||||
}
|
||||
|
|
|
@ -1061,13 +1061,34 @@ shade(byte *b)
|
|||
//
|
||||
// Shade indicates that it has seen a white pointer by adding the referent
|
||||
// to wbuf.
|
||||
// slot is the destination (dst) in go code
|
||||
// ptr is the value that goes into the slot (src) in the go code
|
||||
void
|
||||
runtime·markwb(void **slot, void *ptr)
|
||||
runtime·gcmarkwb_m()
|
||||
{
|
||||
// initial nil check avoids some needlesss loads
|
||||
if(ptr != nil && inheap(ptr) && shaded((void*)slot))
|
||||
shade(ptr);
|
||||
byte **slot, *ptr;
|
||||
slot = (byte**)g->m->scalararg[0];
|
||||
ptr = (byte*)g->m->scalararg[1];
|
||||
|
||||
*slot = ptr;
|
||||
switch(runtime·gcphase) {
|
||||
default:
|
||||
runtime·throw("gcphasework in bad gcphase");
|
||||
case GCoff:
|
||||
case GCquiesce:
|
||||
case GCstw:
|
||||
case GCsweep:
|
||||
case GCscan:
|
||||
break;
|
||||
case GCmark:
|
||||
if(ptr != nil && inheap(ptr) && shaded((byte*)slot))
|
||||
shade(ptr);
|
||||
break;
|
||||
case GCmarktermination:
|
||||
if(ptr != nil && inheap(ptr) && shaded((byte*)slot))
|
||||
shade(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The gp has been moved to a GC safepoint. GC phase specific
|
||||
|
@ -1945,7 +1966,7 @@ runtime·gcmark_m(void)
|
|||
scanblock(nil, 0, nil);
|
||||
}
|
||||
|
||||
// For now this must be followed by a stoptheworld and a starttheworld to ensure
|
||||
// For now this must be bracketed with a stoptheworld and a starttheworld to ensure
|
||||
// all go routines see the new barrier.
|
||||
void
|
||||
runtime·gcinstallmarkwb_m(void)
|
||||
|
@ -1953,6 +1974,14 @@ runtime·gcinstallmarkwb_m(void)
|
|||
runtime·gcphase = GCmark;
|
||||
}
|
||||
|
||||
// For now this must be bracketed with a stoptheworld and a starttheworld to ensure
|
||||
// all go routines see the new barrier.
|
||||
void
|
||||
runtime·gcinstalloffwb_m(void)
|
||||
{
|
||||
runtime·gcphase = GCoff;
|
||||
}
|
||||
|
||||
static void
|
||||
gc(struct gc_args *args)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,24 @@ func writebarrierptr(dst *uintptr, src uintptr) {
|
|||
if src != 0 && (src < _PageSize || src == _PoisonGC || src == _PoisonStack) {
|
||||
onM(func() { gothrow("bad pointer in write barrier") })
|
||||
}
|
||||
*dst = src
|
||||
|
||||
mp := acquirem()
|
||||
if mp.inwb {
|
||||
*dst = src
|
||||
releasem(mp)
|
||||
return
|
||||
}
|
||||
mp.inwb = true
|
||||
oldscalar0 := mp.scalararg[0]
|
||||
oldscalar1 := mp.scalararg[1]
|
||||
mp.scalararg[0] = uintptr(unsafe.Pointer(dst))
|
||||
mp.scalararg[1] = src
|
||||
onM_signalok(gcmarkwb_m)
|
||||
mp.scalararg[0] = oldscalar0
|
||||
mp.scalararg[1] = oldscalar1
|
||||
mp.inwb = false
|
||||
releasem(mp)
|
||||
// *dst = src is done inside of the write barrier.
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
|
|
@ -345,6 +345,7 @@ struct M
|
|||
int32 helpgc;
|
||||
bool spinning; // M is out of work and is actively looking for work
|
||||
bool blocked; // M is blocked on a Note
|
||||
bool inwb; // M is executing a write barrier
|
||||
int8 printlock;
|
||||
uint32 fastrand;
|
||||
uint64 ncgocall; // number of cgo calls in total
|
||||
|
|
|
@ -112,7 +112,9 @@ func gccheckmark_m()
|
|||
func gccheckmarkenable_m()
|
||||
func gccheckmarkdisable_m()
|
||||
func gcinstallmarkwb_m()
|
||||
func gcinstalloffwb_m()
|
||||
func gcmarknewobject_m()
|
||||
func gcmarkwb_m()
|
||||
func finishsweep_m()
|
||||
func scavenge_m()
|
||||
func setFinalizer_m()
|
||||
|
|
Loading…
Reference in a new issue