[dev.garbage] runtime: Add write barriers to c code

Also improve missing GC mark diagnostics.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/169450043
This commit is contained in:
Rick Hudson 2014-11-12 14:20:53 -05:00
parent 9eded54fa3
commit 18ed947ee1
11 changed files with 51 additions and 2 deletions

View File

@ -29,8 +29,7 @@
// Preempted goroutines are scanned before P schedules next goroutine.
// 3. Set phase = GCmark.
// 4. Wait for all P's to acknowledge phase change.
// 5. Now write barrier marks and enqueues black or grey to white pointers. If a pointer is
// stored into a white slot, such pointer is not marked.
// 5. Now write barrier marks and enqueues black, grey, or white to white pointers.
// Malloc still allocates white (non-marked) objects.
// 6. Meanwhile GC transitively walks the heap marking reachable objects.
// 7. When GC finishes marking heap, it preempts P's one-by-one and
@ -446,7 +445,25 @@ greyobject(byte *obj, Markbits *mbits, Workbuf *wbuf)
if(checkmark) {
if(!ismarked(mbits)) {
MSpan *s;
pageID k;
uintptr x, i;
runtime·printf("runtime:greyobject: checkmarks finds unexpected unmarked object obj=%p, mbits->bits=%x, *mbits->bitp=%x\n", obj, mbits->bits, *mbits->bitp);
k = (uintptr)obj>>PageShift;
x = k;
x -= (uintptr)runtime·mheap.arena_start>>PageShift;
s = runtime·mheap.spans[x];
runtime·printf("runtime:greyobject Span: obj=%p, k=%p", obj, k);
if (s == nil) {
runtime·printf(" s=nil\n");
} else {
runtime·printf(" s->start=%p s->limit=%p, s->state=%d, s->sizeclass=%d, s->elemsize=%D \n", s->start*PageSize, s->limit, s->state, s->sizeclass, s->elemsize);
for(i=0; i<s->sizeclass; i++) {
runtime·printf(" ((uintptr*)obj)[%D]=%p\n", i, ((uintptr*)obj)[i]);
}
}
runtime·throw("checkmark found unmarked object");
}
if(ischeckmarked(mbits))

View File

@ -135,7 +135,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -195,7 +195,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024);
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -203,7 +203,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024);
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -233,7 +233,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -20,7 +20,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -271,7 +271,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024);
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -217,7 +217,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024);
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -20,12 +20,18 @@ runtime·mpreinit(M *mp)
{
// Initialize stack and goroutine for note handling.
mp->gsignal = runtime·malg(32*1024);
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
mp->notesig = (int8*)runtime·mallocgc(ERRMAX*sizeof(int8), nil, FlagNoScan);
runtime·writebarrierptr_nostore(&mp->notesig, mp->notesig);
// Initialize stack for handling strings from the
// errstr system call, as used in package syscall.
mp->errstr = (byte*)runtime·mallocgc(ERRMAX*sizeof(byte), nil, FlagNoScan);
runtime·writebarrierptr_nostore(&mp->errstr, mp->errstr);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -176,7 +176,10 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024);
runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
mp->gsignal->m = mp;
runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
}
// Called to initialize a new m (including the bootstrap m).

View File

@ -876,7 +876,9 @@ runtime·allocm(P *p)
mp->g0 = runtime·malg(-1);
else
mp->g0 = runtime·malg(8192);
runtime·writebarrierptr_nostore(&mp->g0, mp->g0);
mp->g0->m = mp;
runtime·writebarrierptr_nostore(&mp->g0->m, mp->g0->m);
if(p == g->m->p)
releasep();