]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: minor refactoring in preparation for parallel GC
authorDmitriy Vyukov <dvyukov@google.com>
Thu, 5 Apr 2012 17:02:20 +0000 (21:02 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Thu, 5 Apr 2012 17:02:20 +0000 (21:02 +0400)
factor sweepspan() out of sweep(), no logical changes

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5991047

src/pkg/runtime/mgc0.c

index be8eb883585b7431b6846d739ce7df50bc716be7..7c7178a596331ea6ff125b16265591939c495aa2 100644 (file)
@@ -719,22 +719,17 @@ handlespecial(byte *p, uintptr size)
        return true;
 }
 
+static void sweepspan(MSpan *s);
+
 // Sweep frees or collects finalizers for blocks not marked in the mark phase.
 // It clears the mark bits in preparation for the next GC round.
 static void
 sweep(void)
 {
        MSpan *s;
-       int32 cl, n, npages;
-       uintptr size;
-       byte *p;
-       MCache *c;
-       byte *arena_start;
        int64 now;
 
-       arena_start = runtime·mheap.arena_start;
        now = runtime·nanotime();
-
        for(;;) {
                s = work.spans;
                if(s == nil)
@@ -750,69 +745,82 @@ sweep(void)
                if(s->state != MSpanInUse)
                        continue;
 
-               p = (byte*)(s->start << PageShift);
-               cl = s->sizeclass;
-               if(cl == 0) {
-                       size = s->npages<<PageShift;
-                       n = 1;
-               } else {
-                       // Chunk full of small blocks.
-                       size = runtime·class_to_size[cl];
-                       npages = runtime·class_to_allocnpages[cl];
-                       n = (npages << PageShift) / size;
-               }
+               sweepspan(s);
+       }
+}
 
-               // Sweep through n objects of given size starting at p.
-               // This thread owns the span now, so it can manipulate
-               // the block bitmap without atomic operations.
-               for(; n > 0; n--, p += size) {
-                       uintptr off, *bitp, shift, bits;
+static void
+sweepspan(MSpan *s)
+{
+       int32 cl, n, npages;
+       uintptr size;
+       byte *p;
+       MCache *c;
+       byte *arena_start;
 
-                       off = (uintptr*)p - (uintptr*)arena_start;
-                       bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
-                       shift = off % wordsPerBitmapWord;
-                       bits = *bitp>>shift;
+       arena_start = runtime·mheap.arena_start;
+       p = (byte*)(s->start << PageShift);
+       cl = s->sizeclass;
+       if(cl == 0) {
+               size = s->npages<<PageShift;
+               n = 1;
+       } else {
+               // Chunk full of small blocks.
+               size = runtime·class_to_size[cl];
+               npages = runtime·class_to_allocnpages[cl];
+               n = (npages << PageShift) / size;
+       }
 
-                       if((bits & bitAllocated) == 0)
-                               continue;
+       // Sweep through n objects of given size starting at p.
+       // This thread owns the span now, so it can manipulate
+       // the block bitmap without atomic operations.
+       for(; n > 0; n--, p += size) {
+               uintptr off, *bitp, shift, bits;
 
-                       if((bits & bitMarked) != 0) {
-                               if(DebugMark) {
-                                       if(!(bits & bitSpecial))
-                                               runtime·printf("found spurious mark on %p\n", p);
-                                       *bitp &= ~(bitSpecial<<shift);
-                               }
-                               *bitp &= ~(bitMarked<<shift);
-                               continue;
-                       }
+               off = (uintptr*)p - (uintptr*)arena_start;
+               bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
+               shift = off % wordsPerBitmapWord;
+               bits = *bitp>>shift;
 
-                       // Special means it has a finalizer or is being profiled.
-                       // In DebugMark mode, the bit has been coopted so
-                       // we have to assume all blocks are special.
-                       if(DebugMark || (bits & bitSpecial) != 0) {
-                               if(handlespecial(p, size))
-                                       continue;
+               if((bits & bitAllocated) == 0)
+                       continue;
+
+               if((bits & bitMarked) != 0) {
+                       if(DebugMark) {
+                               if(!(bits & bitSpecial))
+                                       runtime·printf("found spurious mark on %p\n", p);
+                               *bitp &= ~(bitSpecial<<shift);
                        }
+                       *bitp &= ~(bitMarked<<shift);
+                       continue;
+               }
 
-                       // Mark freed; restore block boundary bit.
-                       *bitp = (*bitp & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
+               // Special means it has a finalizer or is being profiled.
+               // In DebugMark mode, the bit has been coopted so
+               // we have to assume all blocks are special.
+               if(DebugMark || (bits & bitSpecial) != 0) {
+                       if(handlespecial(p, size))
+                               continue;
+               }
 
-                       c = m->mcache;
-                       if(s->sizeclass == 0) {
-                               // Free large span.
-                               runtime·unmarkspan(p, 1<<PageShift);
-                               *(uintptr*)p = 1;       // needs zeroing
-                               runtime·MHeap_Free(&runtime·mheap, s, 1);
-                       } else {
-                               // Free small object.
-                               if(size > sizeof(uintptr))
-                                       ((uintptr*)p)[1] = 1;   // mark as "needs to be zeroed"
-                               c->local_by_size[s->sizeclass].nfree++;
-                               runtime·MCache_Free(c, p, s->sizeclass, size);
-                       }
-                       c->local_alloc -= size;
-                       c->local_nfree++;
+               // Mark freed; restore block boundary bit.
+               *bitp = (*bitp & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
+
+               c = m->mcache;
+               if(s->sizeclass == 0) {
+                       // Free large span.
+                       runtime·unmarkspan(p, 1<<PageShift);
+                       *(uintptr*)p = 1;       // needs zeroing
+                       runtime·MHeap_Free(&runtime·mheap, s, 1);
+               } else {
+                       // Free small object.
+                       if(size > sizeof(uintptr))
+                               ((uintptr*)p)[1] = 1;   // mark as "needs to be zeroed"
+                       c->local_by_size[s->sizeclass].nfree++;
+                       runtime·MCache_Free(c, p, s->sizeclass, size);
                }
+               c->local_alloc -= size;
+               c->local_nfree++;
        }
 }