OSDN Git Service

runtime: Multiplex goroutines onto OS threads.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / mgc0.c
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Garbage collector.
6
7 #include "runtime.h"
8 #include "arch.h"
9 #include "malloc.h"
10
11 #ifdef USING_SPLIT_STACK
12
13 extern void * __splitstack_find (void *, void *, size_t *, void **, void **,
14                                  void **);
15
16 extern void * __splitstack_find_context (void *context[10], size_t *, void **,
17                                          void **, void **);
18
19 #endif
20
21 enum {
22         Debug = 0,
23         PtrSize = sizeof(void*),
24         DebugMark = 0,  // run second pass to check mark
25
26         // Four bits per word (see #defines below).
27         wordsPerBitmapWord = sizeof(void*)*8/4,
28         bitShift = sizeof(void*)*8/4,
29 };
30
31 // Bits in per-word bitmap.
32 // #defines because enum might not be able to hold the values.
33 //
34 // Each word in the bitmap describes wordsPerBitmapWord words
35 // of heap memory.  There are 4 bitmap bits dedicated to each heap word,
36 // so on a 64-bit system there is one bitmap word per 16 heap words.
37 // The bits in the word are packed together by type first, then by
38 // heap location, so each 64-bit bitmap word consists of, from top to bottom,
39 // the 16 bitSpecial bits for the corresponding heap words, then the 16 bitMarked bits,
40 // then the 16 bitNoPointers/bitBlockBoundary bits, then the 16 bitAllocated bits.
41 // This layout makes it easier to iterate over the bits of a given type.
42 //
43 // The bitmap starts at mheap.arena_start and extends *backward* from
44 // there.  On a 64-bit system the off'th word in the arena is tracked by
45 // the off/16+1'th word before mheap.arena_start.  (On a 32-bit system,
46 // the only difference is that the divisor is 8.)
47 //
48 // To pull out the bits corresponding to a given pointer p, we use:
49 //
50 //      off = p - (uintptr*)mheap.arena_start;  // word offset
51 //      b = (uintptr*)mheap.arena_start - off/wordsPerBitmapWord - 1;
52 //      shift = off % wordsPerBitmapWord
53 //      bits = *b >> shift;
54 //      /* then test bits & bitAllocated, bits & bitMarked, etc. */
55 //
56 #define bitAllocated            ((uintptr)1<<(bitShift*0))
57 #define bitNoPointers           ((uintptr)1<<(bitShift*1))      /* when bitAllocated is set */
58 #define bitMarked               ((uintptr)1<<(bitShift*2))      /* when bitAllocated is set */
59 #define bitSpecial              ((uintptr)1<<(bitShift*3))      /* when bitAllocated is set - has finalizer or being profiled */
60 #define bitBlockBoundary        ((uintptr)1<<(bitShift*1))      /* when bitAllocated is NOT set */
61
62 #define bitMask (bitBlockBoundary | bitAllocated | bitMarked | bitSpecial)
63
64 // TODO: Make these per-M.
65 static uint64 nlookup;
66 static uint64 nsizelookup;
67 static uint64 naddrlookup;
68 static uint64 nhandoff;
69
70 static int32 gctrace;
71
72 typedef struct Workbuf Workbuf;
73 struct Workbuf
74 {
75         Workbuf *next;
76         uintptr nobj;
77         byte *obj[512-2];
78 };
79
80 typedef struct Finalizer Finalizer;
81 struct Finalizer
82 {
83         void (*fn)(void*);
84         void *arg;
85         const struct __go_func_type *ft;
86 };
87
88 typedef struct FinBlock FinBlock;
89 struct FinBlock
90 {
91         FinBlock *alllink;
92         FinBlock *next;
93         int32 cnt;
94         int32 cap;
95         Finalizer fin[1];
96 };
97
98
99 static G *fing;
100 static FinBlock *finq; // list of finalizers that are to be executed
101 static FinBlock *finc; // cache of free blocks
102 static FinBlock *allfin; // list of all blocks
103 static Lock finlock;
104 static int32 fingwait;
105
106 static void runfinq(void*);
107 static Workbuf* getempty(Workbuf*);
108 static Workbuf* getfull(Workbuf*);
109 static void     putempty(Workbuf*);
110 static Workbuf* handoff(Workbuf*);
111
112 static struct {
113         Lock fmu;
114         Workbuf *full;
115         Lock emu;
116         Workbuf *empty;
117         uint32  nproc;
118         volatile uint32 nwait;
119         volatile uint32 ndone;
120         Note    alldone;
121         Lock    markgate;
122         Lock    sweepgate;
123         MSpan   *spans;
124
125         Lock;
126         byte    *chunk;
127         uintptr nchunk;
128 } work;
129
130 // scanblock scans a block of n bytes starting at pointer b for references
131 // to other objects, scanning any it finds recursively until there are no
132 // unscanned objects left.  Instead of using an explicit recursion, it keeps
133 // a work list in the Workbuf* structures and loops in the main function
134 // body.  Keeping an explicit work list is easier on the stack allocator and
135 // more efficient.
136 static void
137 scanblock(byte *b, int64 n)
138 {
139         byte *obj, *arena_start, *arena_used, *p;
140         void **vp;
141         uintptr size, *bitp, bits, shift, i, j, x, xbits, off, nobj, nproc;
142         MSpan *s;
143         PageID k;
144         void **wp;
145         Workbuf *wbuf;
146         bool keepworking;
147
148         if((int64)(uintptr)n != n || n < 0) {
149                 // runtime_printf("scanblock %p %lld\n", b, (long long)n);
150                 runtime_throw("scanblock");
151         }
152
153         // Memory arena parameters.
154         arena_start = runtime_mheap.arena_start;
155         arena_used = runtime_mheap.arena_used;
156         nproc = work.nproc;
157
158         wbuf = nil;  // current work buffer
159         wp = nil;  // storage for next queued pointer (write pointer)
160         nobj = 0;  // number of queued objects
161
162         // Scanblock helpers pass b==nil.
163         // The main proc needs to return to make more
164         // calls to scanblock.  But if work.nproc==1 then
165         // might as well process blocks as soon as we
166         // have them.
167         keepworking = b == nil || work.nproc == 1;
168
169         // Align b to a word boundary.
170         off = (uintptr)b & (PtrSize-1);
171         if(off != 0) {
172                 b += PtrSize - off;
173                 n -= PtrSize - off;
174         }
175
176         for(;;) {
177                 // Each iteration scans the block b of length n, queueing pointers in
178                 // the work buffer.
179                 if(Debug > 1)
180                         runtime_printf("scanblock %p %lld\n", b, (long long) n);
181
182                 vp = (void**)b;
183                 n >>= (2+PtrSize/8);  /* n /= PtrSize (4 or 8) */
184                 for(i=0; i<(uintptr)n; i++) {
185                         obj = (byte*)vp[i];
186
187                         // Words outside the arena cannot be pointers.
188                         if((byte*)obj < arena_start || (byte*)obj >= arena_used)
189                                 continue;
190
191                         // obj may be a pointer to a live object.
192                         // Try to find the beginning of the object.
193
194                         // Round down to word boundary.
195                         obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
196
197                         // Find bits for this word.
198                         off = (uintptr*)obj - (uintptr*)arena_start;
199                         bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
200                         shift = off % wordsPerBitmapWord;
201                         xbits = *bitp;
202                         bits = xbits >> shift;
203
204                         // Pointing at the beginning of a block?
205                         if((bits & (bitAllocated|bitBlockBoundary)) != 0)
206                                 goto found;
207
208                         // Pointing just past the beginning?
209                         // Scan backward a little to find a block boundary.
210                         for(j=shift; j-->0; ) {
211                                 if(((xbits>>j) & (bitAllocated|bitBlockBoundary)) != 0) {
212                                         obj = (byte*)obj - (shift-j)*PtrSize;
213                                         shift = j;
214                                         bits = xbits>>shift;
215                                         goto found;
216                                 }
217                         }
218
219                         // Otherwise consult span table to find beginning.
220                         // (Manually inlined copy of MHeap_LookupMaybe.)
221                         nlookup++;
222                         naddrlookup++;
223                         k = (uintptr)obj>>PageShift;
224                         x = k;
225                         if(sizeof(void*) == 8)
226                                 x -= (uintptr)arena_start>>PageShift;
227                         s = runtime_mheap.map[x];
228                         if(s == nil || k < s->start || k - s->start >= s->npages || s->state != MSpanInUse)
229                                 continue;
230                         p =  (byte*)((uintptr)s->start<<PageShift);
231                         if(s->sizeclass == 0) {
232                                 obj = p;
233                         } else {
234                                 if((byte*)obj >= (byte*)s->limit)
235                                         continue;
236                                 size = runtime_class_to_size[s->sizeclass];
237                                 int32 i = ((byte*)obj - p)/size;
238                                 obj = p+i*size;
239                         }
240
241                         // Now that we know the object header, reload bits.
242                         off = (uintptr*)obj - (uintptr*)arena_start;
243                         bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
244                         shift = off % wordsPerBitmapWord;
245                         xbits = *bitp;
246                         bits = xbits >> shift;
247
248                 found:
249                         // Now we have bits, bitp, and shift correct for
250                         // obj pointing at the base of the object.
251                         // Only care about allocated and not marked.
252                         if((bits & (bitAllocated|bitMarked)) != bitAllocated)
253                                 continue;
254                         if(nproc == 1)
255                                 *bitp |= bitMarked<<shift;
256                         else {
257                                 for(;;) {
258                                         x = *bitp;
259                                         if(x & (bitMarked<<shift))
260                                                 goto continue_obj;
261                                         if(runtime_casp((void**)bitp, (void*)x, (void*)(x|(bitMarked<<shift))))
262                                                 break;
263                                 }
264                         }
265
266                         // If object has no pointers, don't need to scan further.
267                         if((bits & bitNoPointers) != 0)
268                                 continue;
269
270                         // If another proc wants a pointer, give it some.
271                         if(nobj > 4 && work.nwait > 0 && work.full == nil) {
272                                 wbuf->nobj = nobj;
273                                 wbuf = handoff(wbuf);
274                                 nobj = wbuf->nobj;
275                                 wp = (void**)(wbuf->obj + nobj);
276                         }
277
278                         // If buffer is full, get a new one.
279                         if(wbuf == nil || nobj >= nelem(wbuf->obj)) {
280                                 if(wbuf != nil)
281                                         wbuf->nobj = nobj;
282                                 wbuf = getempty(wbuf);
283                                 wp = (void**)(wbuf->obj);
284                                 nobj = 0;
285                         }
286                         *wp++ = obj;
287                         nobj++;
288                 continue_obj:;
289                 }
290
291                 // Done scanning [b, b+n).  Prepare for the next iteration of
292                 // the loop by setting b and n to the parameters for the next block.
293
294                 // Fetch b from the work buffer.
295                 if(nobj == 0) {
296                         if(!keepworking) {
297                                 putempty(wbuf);
298                                 return;
299                         }
300                         // Emptied our buffer: refill.
301                         wbuf = getfull(wbuf);
302                         if(wbuf == nil)
303                                 return;
304                         nobj = wbuf->nobj;
305                         wp = (void**)(wbuf->obj + wbuf->nobj);
306                 }
307                 b = *--wp;
308                 nobj--;
309
310                 // Figure out n = size of b.  Start by loading bits for b.
311                 off = (uintptr*)b - (uintptr*)arena_start;
312                 bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
313                 shift = off % wordsPerBitmapWord;
314                 xbits = *bitp;
315                 bits = xbits >> shift;
316
317                 // Might be small; look for nearby block boundary.
318                 // A block boundary is marked by either bitBlockBoundary
319                 // or bitAllocated being set (see notes near their definition).
320                 enum {
321                         boundary = bitBlockBoundary|bitAllocated
322                 };
323                 // Look for a block boundary both after and before b
324                 // in the same bitmap word.
325                 //
326                 // A block boundary j words after b is indicated by
327                 //      bits>>j & boundary
328                 // assuming shift+j < bitShift.  (If shift+j >= bitShift then
329                 // we'll be bleeding other bit types like bitMarked into our test.)
330                 // Instead of inserting the conditional shift+j < bitShift into the loop,
331                 // we can let j range from 1 to bitShift as long as we first
332                 // apply a mask to keep only the bits corresponding
333                 // to shift+j < bitShift aka j < bitShift-shift.
334                 bits &= (boundary<<(bitShift-shift)) - boundary;
335
336                 // A block boundary j words before b is indicated by
337                 //      xbits>>(shift-j) & boundary
338                 // (assuming shift >= j).  There is no cleverness here
339                 // avoid the test, because when j gets too large the shift
340                 // turns negative, which is undefined in C.
341
342                 for(j=1; j<bitShift; j++) {
343                         if(((bits>>j)&boundary) != 0 || (shift>=j && ((xbits>>(shift-j))&boundary) != 0)) {
344                                 n = j*PtrSize;
345                                 goto scan;
346                         }
347                 }
348
349                 // Fall back to asking span about size class.
350                 // (Manually inlined copy of MHeap_Lookup.)
351                 nlookup++;
352                 nsizelookup++;
353                 x = (uintptr)b>>PageShift;
354                 if(sizeof(void*) == 8)
355                         x -= (uintptr)arena_start>>PageShift;
356                 s = runtime_mheap.map[x];
357                 if(s->sizeclass == 0)
358                         n = s->npages<<PageShift;
359                 else
360                         n = runtime_class_to_size[s->sizeclass];
361         scan:;
362         }
363 }
364
365 // debug_scanblock is the debug copy of scanblock.
366 // it is simpler, slower, single-threaded, recursive,
367 // and uses bitSpecial as the mark bit.
368 static void
369 debug_scanblock(byte *b, int64 n)
370 {
371         byte *obj, *p;
372         void **vp;
373         uintptr size, *bitp, bits, shift, i, xbits, off;
374         MSpan *s;
375
376         if(!DebugMark)
377                 runtime_throw("debug_scanblock without DebugMark");
378
379         if((int64)(uintptr)n != n || n < 0) {
380                 //runtime_printf("debug_scanblock %p %D\n", b, n);
381                 runtime_throw("debug_scanblock");
382         }
383
384         // Align b to a word boundary.
385         off = (uintptr)b & (PtrSize-1);
386         if(off != 0) {
387                 b += PtrSize - off;
388                 n -= PtrSize - off;
389         }
390
391         vp = (void**)b;
392         n /= PtrSize;
393         for(i=0; i<(uintptr)n; i++) {
394                 obj = (byte*)vp[i];
395
396                 // Words outside the arena cannot be pointers.
397                 if((byte*)obj < runtime_mheap.arena_start || (byte*)obj >= runtime_mheap.arena_used)
398                         continue;
399
400                 // Round down to word boundary.
401                 obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
402
403                 // Consult span table to find beginning.
404                 s = runtime_MHeap_LookupMaybe(&runtime_mheap, obj);
405                 if(s == nil)
406                         continue;
407
408
409                 p =  (byte*)((uintptr)s->start<<PageShift);
410                 if(s->sizeclass == 0) {
411                         obj = p;
412                         size = (uintptr)s->npages<<PageShift;
413                 } else {
414                         if((byte*)obj >= (byte*)s->limit)
415                                 continue;
416                         size = runtime_class_to_size[s->sizeclass];
417                         int32 i = ((byte*)obj - p)/size;
418                         obj = p+i*size;
419                 }
420
421                 // Now that we know the object header, reload bits.
422                 off = (uintptr*)obj - (uintptr*)runtime_mheap.arena_start;
423                 bitp = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
424                 shift = off % wordsPerBitmapWord;
425                 xbits = *bitp;
426                 bits = xbits >> shift;
427
428                 // Now we have bits, bitp, and shift correct for
429                 // obj pointing at the base of the object.
430                 // If not allocated or already marked, done.
431                 if((bits & bitAllocated) == 0 || (bits & bitSpecial) != 0)  // NOTE: bitSpecial not bitMarked
432                         continue;
433                 *bitp |= bitSpecial<<shift;
434                 if(!(bits & bitMarked))
435                         runtime_printf("found unmarked block %p in %p\n", obj, vp+i);
436
437                 // If object has no pointers, don't need to scan further.
438                 if((bits & bitNoPointers) != 0)
439                         continue;
440
441                 debug_scanblock(obj, size);
442         }
443 }
444
445 // Get an empty work buffer off the work.empty list,
446 // allocating new buffers as needed.
447 static Workbuf*
448 getempty(Workbuf *b)
449 {
450         if(work.nproc == 1) {
451                 // Put b on full list.
452                 if(b != nil) {
453                         b->next = work.full;
454                         work.full = b;
455                 }
456                 // Grab from empty list if possible.
457                 b = work.empty;
458                 if(b != nil) {
459                         work.empty = b->next;
460                         goto haveb;
461                 }
462         } else {
463                 // Put b on full list.
464                 if(b != nil) {
465                         runtime_lock(&work.fmu);
466                         b->next = work.full;
467                         work.full = b;
468                         runtime_unlock(&work.fmu);
469                 }
470                 // Grab from empty list if possible.
471                 runtime_lock(&work.emu);
472                 b = work.empty;
473                 if(b != nil)
474                         work.empty = b->next;
475                 runtime_unlock(&work.emu);
476                 if(b != nil)
477                         goto haveb;
478         }
479
480         // Need to allocate.
481         runtime_lock(&work);
482         if(work.nchunk < sizeof *b) {
483                 work.nchunk = 1<<20;
484                 work.chunk = runtime_SysAlloc(work.nchunk);
485         }
486         b = (Workbuf*)work.chunk;
487         work.chunk += sizeof *b;
488         work.nchunk -= sizeof *b;
489         runtime_unlock(&work);
490
491 haveb:
492         b->nobj = 0;
493         return b;
494 }
495
496 static void
497 putempty(Workbuf *b)
498 {
499         if(b == nil)
500                 return;
501
502         if(work.nproc == 1) {
503                 b->next = work.empty;
504                 work.empty = b;
505                 return;
506         }
507
508         runtime_lock(&work.emu);
509         b->next = work.empty;
510         work.empty = b;
511         runtime_unlock(&work.emu);
512 }
513
514 // Get a full work buffer off the work.full list, or return nil.
515 static Workbuf*
516 getfull(Workbuf *b)
517 {
518         int32 i;
519         Workbuf *b1;
520
521         if(work.nproc == 1) {
522                 // Put b on empty list.
523                 if(b != nil) {
524                         b->next = work.empty;
525                         work.empty = b;
526                 }
527                 // Grab from full list if possible.
528                 // Since work.nproc==1, no one else is
529                 // going to give us work.
530                 b = work.full;
531                 if(b != nil)
532                         work.full = b->next;
533                 return b;
534         }
535
536         putempty(b);
537
538         // Grab buffer from full list if possible.
539         for(;;) {
540                 b1 = work.full;
541                 if(b1 == nil)
542                         break;
543                 runtime_lock(&work.fmu);
544                 if(work.full != nil) {
545                         b1 = work.full;
546                         work.full = b1->next;
547                         runtime_unlock(&work.fmu);
548                         return b1;
549                 }
550                 runtime_unlock(&work.fmu);
551         }
552
553         runtime_xadd(&work.nwait, +1);
554         for(i=0;; i++) {
555                 b1 = work.full;
556                 if(b1 != nil) {
557                         runtime_lock(&work.fmu);
558                         if(work.full != nil) {
559                                 runtime_xadd(&work.nwait, -1);
560                                 b1 = work.full;
561                                 work.full = b1->next;
562                                 runtime_unlock(&work.fmu);
563                                 return b1;
564                         }
565                         runtime_unlock(&work.fmu);
566                         continue;
567                 }
568                 if(work.nwait == work.nproc)
569                         return nil;
570                 if(i < 10)
571                         runtime_procyield(20);
572                 else if(i < 20)
573                         runtime_osyield();
574                 else
575                         runtime_usleep(100);
576         }
577 }
578
579 static Workbuf*
580 handoff(Workbuf *b)
581 {
582         int32 n;
583         Workbuf *b1;
584
585         // Make new buffer with half of b's pointers.
586         b1 = getempty(nil);
587         n = b->nobj/2;
588         b->nobj -= n;
589         b1->nobj = n;
590         runtime_memmove(b1->obj, b->obj+b->nobj, n*sizeof b1->obj[0]);
591         nhandoff += n;
592
593         // Put b on full list - let first half of b get stolen.
594         runtime_lock(&work.fmu);
595         b->next = work.full;
596         work.full = b;
597         runtime_unlock(&work.fmu);
598
599         return b1;
600 }
601
602 // Scanstack calls scanblock on each of gp's stack segments.
603 static void
604 scanstack(void (*scanblock)(byte*, int64), G *gp)
605 {
606 #ifdef USING_SPLIT_STACK
607         M *mp;
608         void* sp;
609         size_t spsize;
610         void* next_segment;
611         void* next_sp;
612         void* initial_sp;
613
614         if(gp == runtime_g()) {
615                 // Scanning our own stack.
616                 sp = __splitstack_find(nil, nil, &spsize, &next_segment,
617                                        &next_sp, &initial_sp);
618         } else if((mp = gp->m) != nil && mp->helpgc) {
619                 // gchelper's stack is in active use and has no interesting pointers.
620                 return;
621         } else {
622                 // Scanning another goroutine's stack.
623                 // The goroutine is usually asleep (the world is stopped).
624
625                 // The exception is that if the goroutine is about to enter or might
626                 // have just exited a system call, it may be executing code such
627                 // as schedlock and may have needed to start a new stack segment.
628                 // Use the stack segment and stack pointer at the time of
629                 // the system call instead, since that won't change underfoot.
630                 if(gp->gcstack != nil) {
631                         sp = gp->gcstack;
632                         spsize = gp->gcstack_size;
633                         next_segment = gp->gcnext_segment;
634                         next_sp = gp->gcnext_sp;
635                         initial_sp = gp->gcinitial_sp;
636                 } else {
637                         sp = __splitstack_find_context(&gp->stack_context[0],
638                                                        &spsize, &next_segment,
639                                                        &next_sp, &initial_sp);
640                 }
641         }
642         if(sp != nil) {
643                 scanblock(sp, spsize);
644                 while((sp = __splitstack_find(next_segment, next_sp,
645                                               &spsize, &next_segment,
646                                               &next_sp, &initial_sp)) != nil)
647                         scanblock(sp, spsize);
648         }
649 #else
650         M *mp;
651         byte* bottom;
652         byte* top;
653
654         if(gp == runtime_g()) {
655                 // Scanning our own stack.
656                 bottom = (byte*)&gp;
657         } else if((mp = gp->m) != nil && mp->helpgc) {
658                 // gchelper's stack is in active use and has no interesting pointers.
659                 return;
660         } else {
661                 // Scanning another goroutine's stack.
662                 // The goroutine is usually asleep (the world is stopped).
663                 bottom = (byte*)gp->gcnext_sp;
664                 if(bottom == nil)
665                         return;
666         }
667         top = (byte*)gp->gcinitial_sp + gp->gcstack_size;
668         if(top > bottom)
669                 scanblock(bottom, top - bottom);
670         else
671                 scanblock(top, bottom - top);
672 #endif
673 }
674
675 // Markfin calls scanblock on the blocks that have finalizers:
676 // the things pointed at cannot be freed until the finalizers have run.
677 static void
678 markfin(void *v)
679 {
680         uintptr size;
681
682         size = 0;
683         if(!runtime_mlookup(v, (byte**)&v, &size, nil) || !runtime_blockspecial(v))
684                 runtime_throw("mark - finalizer inconsistency");
685
686         // do not mark the finalizer block itself.  just mark the things it points at.
687         scanblock(v, size);
688 }
689
690 struct root_list {
691         struct root_list *next;
692         struct root {
693                 void *decl;
694                 size_t size;
695         } roots[];
696 };
697
698 static struct root_list* roots;
699
700 void
701 __go_register_gc_roots (struct root_list* r)
702 {
703         // FIXME: This needs locking if multiple goroutines can call
704         // dlopen simultaneously.
705         r->next = roots;
706         roots = r;
707 }
708
709 static void
710 debug_markfin(void *v)
711 {
712         uintptr size;
713
714         if(!runtime_mlookup(v, (byte**)&v, &size, nil))
715                 runtime_throw("debug_mark - finalizer inconsistency");
716         debug_scanblock(v, size);
717 }
718
719 // Mark
720 static void
721 mark(void (*scan)(byte*, int64))
722 {
723         struct root_list *pl;
724         G *gp;
725         FinBlock *fb;
726
727         // mark data+bss.
728         for(pl = roots; pl != nil; pl = pl->next) {
729                 struct root* pr = &pl->roots[0];
730                 while(1) {
731                         void *decl = pr->decl;
732                         if(decl == nil)
733                                 break;
734                         scanblock(decl, pr->size);
735                         pr++;
736                 }
737         }
738
739         scan((byte*)&runtime_m0, sizeof runtime_m0);
740         scan((byte*)&runtime_g0, sizeof runtime_g0);
741         scan((byte*)&runtime_allg, sizeof runtime_allg);
742         scan((byte*)&runtime_allm, sizeof runtime_allm);
743         runtime_MProf_Mark(scan);
744
745         // mark stacks
746         for(gp=runtime_allg; gp!=nil; gp=gp->alllink) {
747                 switch(gp->status){
748                 default:
749                         runtime_printf("unexpected G.status %d\n", gp->status);
750                         runtime_throw("mark - bad status");
751                 case Gdead:
752                         break;
753                 case Grunning:
754                         if(gp != runtime_g())
755                                 runtime_throw("mark - world not stopped");
756                         scanstack(scan, gp);
757                         break;
758                 case Grunnable:
759                 case Gsyscall:
760                 case Gwaiting:
761                         scanstack(scan, gp);
762                         break;
763                 }
764         }
765
766         // mark things pointed at by objects with finalizers
767         if(scan == debug_scanblock)
768                 runtime_walkfintab(debug_markfin, scan);
769         else
770                 runtime_walkfintab(markfin, scan);
771
772         for(fb=allfin; fb; fb=fb->alllink)
773                 scanblock((byte*)fb->fin, fb->cnt*sizeof(fb->fin[0]));
774
775         // in multiproc mode, join in the queued work.
776         scan(nil, 0);
777 }
778
779 static bool
780 handlespecial(byte *p, uintptr size)
781 {
782         void (*fn)(void*);
783         const struct __go_func_type *ft;
784         FinBlock *block;
785         Finalizer *f;
786         
787         if(!runtime_getfinalizer(p, true, &fn, &ft)) {
788                 runtime_setblockspecial(p, false);
789                 runtime_MProf_Free(p, size);
790                 return false;
791         }
792
793         runtime_lock(&finlock);
794         if(finq == nil || finq->cnt == finq->cap) {
795                 if(finc == nil) {
796                         finc = runtime_SysAlloc(PageSize);
797                         finc->cap = (PageSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
798                         finc->alllink = allfin;
799                         allfin = finc;
800                 }
801                 block = finc;
802                 finc = block->next;
803                 block->next = finq;
804                 finq = block;
805         }
806         f = &finq->fin[finq->cnt];
807         finq->cnt++;
808         f->fn = fn;
809         f->ft = ft;
810         f->arg = p;
811         runtime_unlock(&finlock); 
812         return true;
813 }
814
815 // Sweep frees or collects finalizers for blocks not marked in the mark phase.
816 // It clears the mark bits in preparation for the next GC round.
817 static void
818 sweep(void)
819 {
820         M *m;
821         MSpan *s;
822         int32 cl, n, npages;
823         uintptr size;
824         byte *p;
825         MCache *c;
826         byte *arena_start;
827
828         m = runtime_m();
829         arena_start = runtime_mheap.arena_start;
830
831         for(;;) {
832                 s = work.spans;
833                 if(s == nil)
834                         break;
835                 if(!runtime_casp(&work.spans, s, s->allnext))
836                         continue;
837
838                 if(s->state != MSpanInUse)
839                         continue;
840
841                 p = (byte*)(s->start << PageShift);
842                 cl = s->sizeclass;
843                 if(cl == 0) {
844                         size = s->npages<<PageShift;
845                         n = 1;
846                 } else {
847                         // Chunk full of small blocks.
848                         size = runtime_class_to_size[cl];
849                         npages = runtime_class_to_allocnpages[cl];
850                         n = (npages << PageShift) / size;
851                 }
852
853                 // Sweep through n objects of given size starting at p.
854                 // This thread owns the span now, so it can manipulate
855                 // the block bitmap without atomic operations.
856                 for(; n > 0; n--, p += size) {
857                         uintptr off, *bitp, shift, bits;
858
859                         off = (uintptr*)p - (uintptr*)arena_start;
860                         bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
861                         shift = off % wordsPerBitmapWord;
862                         bits = *bitp>>shift;
863
864                         if((bits & bitAllocated) == 0)
865                                 continue;
866
867                         if((bits & bitMarked) != 0) {
868                                 if(DebugMark) {
869                                         if(!(bits & bitSpecial))
870                                                 runtime_printf("found spurious mark on %p\n", p);
871                                         *bitp &= ~(bitSpecial<<shift);
872                                 }
873                                 *bitp &= ~(bitMarked<<shift);
874                                 continue;
875                         }
876
877                         // Special means it has a finalizer or is being profiled.
878                         // In DebugMark mode, the bit has been coopted so
879                         // we have to assume all blocks are special.
880                         if(DebugMark || (bits & bitSpecial) != 0) {
881                                 if(handlespecial(p, size))
882                                         continue;
883                         }
884
885                         // Mark freed; restore block boundary bit.
886                         *bitp = (*bitp & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
887
888                         c = m->mcache;
889                         if(s->sizeclass == 0) {
890                                 // Free large span.
891                                 runtime_unmarkspan(p, 1<<PageShift);
892                                 *(uintptr*)p = 1;       // needs zeroing
893                                 runtime_MHeap_Free(&runtime_mheap, s, 1);
894                         } else {
895                                 // Free small object.
896                                 if(size > sizeof(uintptr))
897                                         ((uintptr*)p)[1] = 1;   // mark as "needs to be zeroed"
898                                 c->local_by_size[s->sizeclass].nfree++;
899                                 runtime_MCache_Free(c, p, s->sizeclass, size);
900                         }
901                         c->local_alloc -= size;
902                         c->local_nfree++;
903                 }
904         }
905 }
906
907 void
908 runtime_gchelper(void)
909 {
910         // Wait until main proc is ready for mark help.
911         runtime_lock(&work.markgate);
912         runtime_unlock(&work.markgate);
913         scanblock(nil, 0);
914
915         // Wait until main proc is ready for sweep help.
916         runtime_lock(&work.sweepgate);
917         runtime_unlock(&work.sweepgate);
918         sweep();
919
920         if(runtime_xadd(&work.ndone, +1) == work.nproc-1)
921                 runtime_notewakeup(&work.alldone);
922 }
923
924 // Semaphore, not Lock, so that the goroutine
925 // reschedules when there is contention rather
926 // than spinning.
927 static uint32 gcsema = 1;
928
929 // Initialized from $GOGC.  GOGC=off means no gc.
930 //
931 // Next gc is after we've allocated an extra amount of
932 // memory proportional to the amount already in use.
933 // If gcpercent=100 and we're using 4M, we'll gc again
934 // when we get to 8M.  This keeps the gc cost in linear
935 // proportion to the allocation cost.  Adjusting gcpercent
936 // just changes the linear constant (and also the amount of
937 // extra memory used).
938 static int32 gcpercent = -2;
939
940 static void
941 stealcache(void)
942 {
943         M *m;
944
945         for(m=runtime_allm; m; m=m->alllink)
946                 runtime_MCache_ReleaseAll(m->mcache);
947 }
948
949 static void
950 cachestats(void)
951 {
952         M *m;
953         MCache *c;
954         uint32 i;
955         uint64 stacks_inuse;
956         uint64 stacks_sys;
957
958         stacks_inuse = 0;
959         stacks_sys = 0;
960         for(m=runtime_allm; m; m=m->alllink) {
961                 runtime_purgecachedstats(m);
962                 // stacks_inuse += m->stackalloc->inuse;
963                 // stacks_sys += m->stackalloc->sys;
964                 c = m->mcache;
965                 for(i=0; i<nelem(c->local_by_size); i++) {
966                         mstats.by_size[i].nmalloc += c->local_by_size[i].nmalloc;
967                         c->local_by_size[i].nmalloc = 0;
968                         mstats.by_size[i].nfree += c->local_by_size[i].nfree;
969                         c->local_by_size[i].nfree = 0;
970                 }
971         }
972         mstats.stacks_inuse = stacks_inuse;
973         mstats.stacks_sys = stacks_sys;
974 }
975
976 void
977 runtime_gc(int32 force)
978 {
979         M *m;
980         int64 t0, t1, t2, t3;
981         uint64 heap0, heap1, obj0, obj1;
982         const byte *p;
983         bool extra;
984
985         // The gc is turned off (via enablegc) until
986         // the bootstrap has completed.
987         // Also, malloc gets called in the guts
988         // of a number of libraries that might be
989         // holding locks.  To avoid priority inversion
990         // problems, don't bother trying to run gc
991         // while holding a lock.  The next mallocgc
992         // without a lock will do the gc instead.
993         m = runtime_m();
994         if(!mstats.enablegc || m->locks > 0 || runtime_panicking)
995                 return;
996
997         if(gcpercent == -2) {   // first time through
998                 p = runtime_getenv("GOGC");
999                 if(p == nil || p[0] == '\0')
1000                         gcpercent = 100;
1001                 else if(runtime_strcmp((const char*)p, "off") == 0)
1002                         gcpercent = -1;
1003                 else
1004                         gcpercent = runtime_atoi(p);
1005
1006                 p = runtime_getenv("GOGCTRACE");
1007                 if(p != nil)
1008                         gctrace = runtime_atoi(p);
1009         }
1010         if(gcpercent < 0)
1011                 return;
1012
1013         runtime_semacquire(&gcsema);
1014         if(!force && mstats.heap_alloc < mstats.next_gc) {
1015                 runtime_semrelease(&gcsema);
1016                 return;
1017         }
1018
1019         t0 = runtime_nanotime();
1020         nlookup = 0;
1021         nsizelookup = 0;
1022         naddrlookup = 0;
1023         nhandoff = 0;
1024
1025         m->gcing = 1;
1026         runtime_stoptheworld();
1027
1028         cachestats();
1029         heap0 = mstats.heap_alloc;
1030         obj0 = mstats.nmalloc - mstats.nfree;
1031
1032         runtime_lock(&work.markgate);
1033         runtime_lock(&work.sweepgate);
1034
1035         extra = false;
1036         work.nproc = 1;
1037         if(runtime_gomaxprocs > 1 && runtime_ncpu > 1) {
1038                 runtime_noteclear(&work.alldone);
1039                 work.nproc += runtime_helpgc(&extra);
1040         }
1041         work.nwait = 0;
1042         work.ndone = 0;
1043
1044         runtime_unlock(&work.markgate);  // let the helpers in
1045         mark(scanblock);
1046         if(DebugMark)
1047                 mark(debug_scanblock);
1048         t1 = runtime_nanotime();
1049
1050         work.spans = runtime_mheap.allspans;
1051         runtime_unlock(&work.sweepgate);  // let the helpers in
1052         sweep();
1053         if(work.nproc > 1)
1054                 runtime_notesleep(&work.alldone);
1055         t2 = runtime_nanotime();
1056
1057         stealcache();
1058         cachestats();
1059
1060         mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100;
1061         m->gcing = 0;
1062
1063         m->locks++;     // disable gc during the mallocs in newproc
1064         if(finq != nil) {
1065                 // kick off or wake up goroutine to run queued finalizers
1066                 if(fing == nil)
1067                         fing = __go_go(runfinq, nil);
1068                 else if(fingwait) {
1069                         fingwait = 0;
1070                         runtime_ready(fing);
1071                 }
1072         }
1073         m->locks--;
1074
1075         cachestats();
1076         heap1 = mstats.heap_alloc;
1077         obj1 = mstats.nmalloc - mstats.nfree;
1078
1079         t3 = runtime_nanotime();
1080         mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t3 - t0;
1081         mstats.pause_total_ns += t3 - t0;
1082         mstats.numgc++;
1083         if(mstats.debuggc)
1084                 runtime_printf("pause %llu\n", (unsigned long long)t3-t0);
1085
1086         if(gctrace) {
1087                 runtime_printf("gc%d: %llu+%llu+%llu ms %llu -> %llu MB %llu -> %llu (%llu-%llu) objects %llu pointer lookups (%llu size, %llu addr) %llu handoff\n",
1088                         mstats.numgc, (unsigned long long)(t1-t0)/1000000, (unsigned long long)(t2-t1)/1000000, (unsigned long long)(t3-t2)/1000000,
1089                         (unsigned long long)heap0>>20, (unsigned long long)heap1>>20, (unsigned long long)obj0, (unsigned long long)obj1,
1090                         (unsigned long long)mstats.nmalloc, (unsigned long long)mstats.nfree,
1091                         (unsigned long long)nlookup, (unsigned long long)nsizelookup, (unsigned long long)naddrlookup, (unsigned long long) nhandoff);
1092         }
1093
1094         runtime_semrelease(&gcsema);
1095
1096         // If we could have used another helper proc, start one now,
1097         // in the hope that it will be available next time.
1098         // It would have been even better to start it before the collection,
1099         // but doing so requires allocating memory, so it's tricky to
1100         // coordinate.  This lazy approach works out in practice:
1101         // we don't mind if the first couple gc rounds don't have quite
1102         // the maximum number of procs.
1103         runtime_starttheworld(extra);
1104
1105         // give the queued finalizers, if any, a chance to run  
1106         if(finq != nil) 
1107                 runtime_gosched();
1108
1109         if(gctrace > 1 && !force)
1110                 runtime_gc(1);
1111 }
1112
1113 void runtime_UpdateMemStats(void)
1114   __asm__("libgo_runtime.runtime.UpdateMemStats");
1115
1116 void
1117 runtime_UpdateMemStats(void)
1118 {
1119         M *m;
1120
1121         // Have to acquire gcsema to stop the world,
1122         // because stoptheworld can only be used by
1123         // one goroutine at a time, and there might be
1124         // a pending garbage collection already calling it.
1125         runtime_semacquire(&gcsema);
1126         m = runtime_m();
1127         m->gcing = 1;
1128         runtime_stoptheworld();
1129         cachestats();
1130         m->gcing = 0;
1131         runtime_semrelease(&gcsema);
1132         runtime_starttheworld(false);
1133 }
1134
1135 static void
1136 runfinq(void* dummy __attribute__ ((unused)))
1137 {
1138         G* gp;
1139         Finalizer *f;
1140         FinBlock *fb, *next;
1141         uint32 i;
1142
1143         gp = runtime_g();
1144         for(;;) {
1145                 // There's no need for a lock in this section
1146                 // because it only conflicts with the garbage
1147                 // collector, and the garbage collector only
1148                 // runs when everyone else is stopped, and
1149                 // runfinq only stops at the gosched() or
1150                 // during the calls in the for loop.
1151                 fb = finq;
1152                 finq = nil;
1153                 if(fb == nil) {
1154                         fingwait = 1;
1155                         gp->status = Gwaiting;
1156                         gp->waitreason = "finalizer wait";
1157                         runtime_gosched();
1158                         continue;
1159                 }
1160                 for(; fb; fb=next) {
1161                         next = fb->next;
1162                         for(i=0; i<(uint32)fb->cnt; i++) {
1163                                 void *params[1];
1164
1165                                 f = &fb->fin[i];
1166                                 params[0] = &f->arg;
1167                                 runtime_setblockspecial(f->arg, false);
1168                                 reflect_call(f->ft, (void*)f->fn, 0, 0, params, nil);
1169                                 f->fn = nil;
1170                                 f->arg = nil;
1171                         }
1172                         fb->cnt = 0;
1173                         fb->next = finc;
1174                         finc = fb;
1175                 }
1176                 runtime_gc(1);  // trigger another gc to clean up the finalized objects, if possible
1177         }
1178 }
1179
1180 // mark the block at v of size n as allocated.
1181 // If noptr is true, mark it as having no pointers.
1182 void
1183 runtime_markallocated(void *v, uintptr n, bool noptr)
1184 {
1185         uintptr *b, obits, bits, off, shift;
1186
1187         // if(0)
1188                 // runtime_printf("markallocated %p+%p\n", v, n);
1189
1190         if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
1191                 runtime_throw("markallocated: bad pointer");
1192
1193         off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;  // word offset
1194         b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1195         shift = off % wordsPerBitmapWord;
1196
1197         for(;;) {
1198                 obits = *b;
1199                 bits = (obits & ~(bitMask<<shift)) | (bitAllocated<<shift);
1200                 if(noptr)
1201                         bits |= bitNoPointers<<shift;
1202                 if(runtime_singleproc) {
1203                         *b = bits;
1204                         break;
1205                 } else {
1206                         // more than one goroutine is potentially running: use atomic op
1207                         if(runtime_casp((void**)b, (void*)obits, (void*)bits))
1208                                 break;
1209                 }
1210         }
1211 }
1212
1213 // mark the block at v of size n as freed.
1214 void
1215 runtime_markfreed(void *v, uintptr n)
1216 {
1217         uintptr *b, obits, bits, off, shift;
1218
1219         // if(0)
1220                 // runtime_printf("markallocated %p+%p\n", v, n);
1221
1222         if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
1223                 runtime_throw("markallocated: bad pointer");
1224
1225         off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;  // word offset
1226         b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1227         shift = off % wordsPerBitmapWord;
1228
1229         for(;;) {
1230                 obits = *b;
1231                 bits = (obits & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
1232                 if(runtime_singleproc) {
1233                         *b = bits;
1234                         break;
1235                 } else {
1236                         // more than one goroutine is potentially running: use atomic op
1237                         if(runtime_casp((void**)b, (void*)obits, (void*)bits))
1238                                 break;
1239                 }
1240         }
1241 }
1242
1243 // check that the block at v of size n is marked freed.
1244 void
1245 runtime_checkfreed(void *v, uintptr n)
1246 {
1247         uintptr *b, bits, off, shift;
1248
1249         if(!runtime_checking)
1250                 return;
1251
1252         if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
1253                 return; // not allocated, so okay
1254
1255         off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;  // word offset
1256         b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1257         shift = off % wordsPerBitmapWord;
1258
1259         bits = *b>>shift;
1260         if((bits & bitAllocated) != 0) {
1261                 runtime_printf("checkfreed %p+%p: off=%p have=%p\n",
1262                         v, (void*)n, (void*)off, (void*)(bits & bitMask));
1263                 runtime_throw("checkfreed: not freed");
1264         }
1265 }
1266
1267 // mark the span of memory at v as having n blocks of the given size.
1268 // if leftover is true, there is left over space at the end of the span.
1269 void
1270 runtime_markspan(void *v, uintptr size, uintptr n, bool leftover)
1271 {
1272         uintptr *b, off, shift;
1273         byte *p;
1274
1275         if((byte*)v+size*n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
1276                 runtime_throw("markspan: bad pointer");
1277
1278         p = v;
1279         if(leftover)    // mark a boundary just past end of last block too
1280                 n++;
1281         for(; n-- > 0; p += size) {
1282                 // Okay to use non-atomic ops here, because we control
1283                 // the entire span, and each bitmap word has bits for only
1284                 // one span, so no other goroutines are changing these
1285                 // bitmap words.
1286                 off = (uintptr*)p - (uintptr*)runtime_mheap.arena_start;  // word offset
1287                 b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1288                 shift = off % wordsPerBitmapWord;
1289                 *b = (*b & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
1290         }
1291 }
1292
1293 // unmark the span of memory at v of length n bytes.
1294 void
1295 runtime_unmarkspan(void *v, uintptr n)
1296 {
1297         uintptr *p, *b, off;
1298
1299         if((byte*)v+n > (byte*)runtime_mheap.arena_used || (byte*)v < runtime_mheap.arena_start)
1300                 runtime_throw("markspan: bad pointer");
1301
1302         p = v;
1303         off = p - (uintptr*)runtime_mheap.arena_start;  // word offset
1304         if(off % wordsPerBitmapWord != 0)
1305                 runtime_throw("markspan: unaligned pointer");
1306         b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1307         n /= PtrSize;
1308         if(n%wordsPerBitmapWord != 0)
1309                 runtime_throw("unmarkspan: unaligned length");
1310         // Okay to use non-atomic ops here, because we control
1311         // the entire span, and each bitmap word has bits for only
1312         // one span, so no other goroutines are changing these
1313         // bitmap words.
1314         n /= wordsPerBitmapWord;
1315         while(n-- > 0)
1316                 *b-- = 0;
1317 }
1318
1319 bool
1320 runtime_blockspecial(void *v)
1321 {
1322         uintptr *b, off, shift;
1323
1324         if(DebugMark)
1325                 return true;
1326
1327         off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;
1328         b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1329         shift = off % wordsPerBitmapWord;
1330
1331         return (*b & (bitSpecial<<shift)) != 0;
1332 }
1333
1334 void
1335 runtime_setblockspecial(void *v, bool s)
1336 {
1337         uintptr *b, off, shift, bits, obits;
1338
1339         if(DebugMark)
1340                 return;
1341
1342         off = (uintptr*)v - (uintptr*)runtime_mheap.arena_start;
1343         b = (uintptr*)runtime_mheap.arena_start - off/wordsPerBitmapWord - 1;
1344         shift = off % wordsPerBitmapWord;
1345
1346         for(;;) {
1347                 obits = *b;
1348                 if(s)
1349                         bits = obits | (bitSpecial<<shift);
1350                 else
1351                         bits = obits & ~(bitSpecial<<shift);
1352                 if(runtime_singleproc) {
1353                         *b = bits;
1354                         break;
1355                 } else {
1356                         // more than one goroutine is potentially running: use atomic op
1357                         if(runtime_casp((void**)b, (void*)obits, (void*)bits))
1358                                 break;
1359                 }
1360         }
1361 }
1362
1363 void
1364 runtime_MHeap_MapBits(MHeap *h)
1365 {
1366         // Caller has added extra mappings to the arena.
1367         // Add extra mappings of bitmap words as needed.
1368         // We allocate extra bitmap pieces in chunks of bitmapChunk.
1369         enum {
1370                 bitmapChunk = 8192
1371         };
1372         uintptr n;
1373
1374         n = (h->arena_used - h->arena_start) / wordsPerBitmapWord;
1375         n = (n+bitmapChunk-1) & ~(bitmapChunk-1);
1376         if(h->bitmap_mapped >= n)
1377                 return;
1378
1379         runtime_SysMap(h->arena_start - n, n - h->bitmap_mapped);
1380         h->bitmap_mapped = n;
1381 }