]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.garbage] runtime: Add write barriers to c code
authorRick Hudson <rlh@golang.org>
Wed, 12 Nov 2014 19:20:53 +0000 (14:20 -0500)
committerRick Hudson <rlh@golang.org>
Wed, 12 Nov 2014 19:20:53 +0000 (14:20 -0500)
Also improve missing GC mark diagnostics.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/169450043

src/runtime/mgc0.c
src/runtime/os_darwin.c
src/runtime/os_dragonfly.c
src/runtime/os_freebsd.c
src/runtime/os_linux.c
src/runtime/os_nacl.c
src/runtime/os_netbsd.c
src/runtime/os_openbsd.c
src/runtime/os_plan9.c
src/runtime/os_solaris.c
src/runtime/proc.c

index 3c4d1afa56ca63fde06f33acb11d6245ba6bbad9..214b9ebc2412368b5eece24d3af163dc241109ad 100644 (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))
index bbd29282b0b2d450308e10a4a918eab2c573cfbb..b866863d09871fb1889af7ad45edb8f8f2ed62ad 100644 (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).
index e372205ec8a0e894f8d9607ac7e41f0591a1aacc..051192ad31115fbe9e75a0472d924da75d7c36c8 100644 (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).
index a513cb6044e954a96346f4b7de8d567021c9f6c1..1c126547a71b38e346c42de104a7702e1e0fa40a 100644 (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).
index 9bd123d597b28a431b4f3f2808754e134734f493..cc23774e3b46498e824a5d6c818d102ba9c7b425 100644 (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).
index 14b5583033acf301400a36c44550cf3b50e444a2..ad72cc7c684a352854e54043b5ead1ed531ee79e 100644 (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).
index 58e5bedf2f7634b3b97ea8110059f4bad7d2b513..28929ea574d9b59abf227768a30227580282f044 100644 (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).
index eebaa13eea8638843ebf321a32292e1a50f74234..960aaffffa830297c317fb1d644321383b25fde3 100644 (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).
index f8c543f6f6ad0bbc2c1e375cda5afc4b110700a1..18460fc12e65465856afd78df18091a4b5afd117 100644 (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).
index e16b8e637009e6443de49563be9a201918c351d8..bee91d8e6031e7a98092e57f604fc1f159bb9a29 100644 (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).
index e5e2df2e422dc8e879bb8a9a1b1654b1ae908449..c1df40d02ff741490f8fe338a474839dae2c476b 100644 (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();