LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Garbage collector. | 5 // Garbage collector. |
6 | 6 |
7 #include "runtime.h" | 7 #include "runtime.h" |
8 #include "arch_GOARCH.h" | 8 #include "arch_GOARCH.h" |
9 #include "malloc.h" | 9 #include "malloc.h" |
10 #include "stack.h" | 10 #include "stack.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 Lock fmu; | 116 Lock fmu; |
117 Workbuf *full; | 117 Workbuf *full; |
118 Lock emu; | 118 Lock emu; |
119 Workbuf *empty; | 119 Workbuf *empty; |
120 uint32 nproc; | 120 uint32 nproc; |
121 volatile uint32 nwait; | 121 volatile uint32 nwait; |
122 volatile uint32 ndone; | 122 volatile uint32 ndone; |
123 Note alldone; | 123 Note alldone; |
124 Lock markgate; | 124 Lock markgate; |
125 Lock sweepgate; | 125 Lock sweepgate; |
126 » MSpan» *spans; | 126 » uint32» spanidx; |
127 | 127 |
128 Lock; | 128 Lock; |
129 byte *chunk; | 129 byte *chunk; |
130 uintptr nchunk; | 130 uintptr nchunk; |
131 } work; | 131 } work; |
132 | 132 |
133 // scanblock scans a block of n bytes starting at pointer b for references | 133 // scanblock scans a block of n bytes starting at pointer b for references |
134 // to other objects, scanning any it finds recursively until there are no | 134 // to other objects, scanning any it finds recursively until there are no |
135 // unscanned objects left. Instead of using an explicit recursion, it keeps | 135 // unscanned objects left. Instead of using an explicit recursion, it keeps |
136 // a work list in the Workbuf* structures and loops in the main function | 136 // a work list in the Workbuf* structures and loops in the main function |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 return true; | 721 return true; |
722 } | 722 } |
723 | 723 |
724 static void sweepspan(MSpan *s); | 724 static void sweepspan(MSpan *s); |
725 | 725 |
726 // Sweep frees or collects finalizers for blocks not marked in the mark phase. | 726 // Sweep frees or collects finalizers for blocks not marked in the mark phase. |
727 // It clears the mark bits in preparation for the next GC round. | 727 // It clears the mark bits in preparation for the next GC round. |
728 static void | 728 static void |
729 sweep(void) | 729 sweep(void) |
730 { | 730 { |
731 » MSpan *s; | 731 » MSpan *s, **allspans; |
732 int64 now; | 732 int64 now; |
| 733 uint32 spanidx, nspan; |
733 | 734 |
734 now = runtime·nanotime(); | 735 now = runtime·nanotime(); |
| 736 nspan = runtime·mheap.nspan; |
| 737 allspans = runtime·mheap.allspans; |
735 for(;;) { | 738 for(;;) { |
736 » » s = work.spans; | 739 » » spanidx = runtime·xadd(&work.spanidx, 1) - 1; |
737 » » if(s == nil) | 740 » » if(spanidx >= nspan) |
738 break; | 741 break; |
739 » » if(!runtime·casp(&work.spans, s, s->allnext)) | 742 » » s = allspans[spanidx]; |
740 » » » continue; | |
741 | 743 |
742 // Stamp newly unused spans. The scavenger will use that | 744 // Stamp newly unused spans. The scavenger will use that |
743 // info to potentially give back some pages to the OS. | 745 // info to potentially give back some pages to the OS. |
744 if(s->state == MSpanFree && s->unusedsince == 0) | 746 if(s->state == MSpanFree && s->unusedsince == 0) |
745 s->unusedsince = now; | 747 s->unusedsince = now; |
746 | 748 |
747 if(s->state != MSpanInUse) | 749 if(s->state != MSpanInUse) |
748 continue; | 750 continue; |
749 | 751 |
750 sweepspan(s); | 752 sweepspan(s); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 } | 964 } |
963 work.nwait = 0; | 965 work.nwait = 0; |
964 work.ndone = 0; | 966 work.ndone = 0; |
965 | 967 |
966 runtime·unlock(&work.markgate); // let the helpers in | 968 runtime·unlock(&work.markgate); // let the helpers in |
967 mark(scanblock); | 969 mark(scanblock); |
968 if(DebugMark) | 970 if(DebugMark) |
969 mark(debug_scanblock); | 971 mark(debug_scanblock); |
970 t1 = runtime·nanotime(); | 972 t1 = runtime·nanotime(); |
971 | 973 |
972 » work.spans = runtime·mheap.allspans; | 974 » work.spanidx = 0; |
973 runtime·unlock(&work.sweepgate); // let the helpers in | 975 runtime·unlock(&work.sweepgate); // let the helpers in |
974 sweep(); | 976 sweep(); |
975 if(work.nproc > 1) | 977 if(work.nproc > 1) |
976 runtime·notesleep(&work.alldone); | 978 runtime·notesleep(&work.alldone); |
977 t2 = runtime·nanotime(); | 979 t2 = runtime·nanotime(); |
978 | 980 |
979 stealcache(); | 981 stealcache(); |
980 cachestats(&stats); | 982 cachestats(&stats); |
981 | 983 |
982 mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100; | 984 mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 uintptr n; | 1299 uintptr n; |
1298 | 1300 |
1299 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; | 1301 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; |
1300 n = (n+bitmapChunk-1) & ~(bitmapChunk-1); | 1302 n = (n+bitmapChunk-1) & ~(bitmapChunk-1); |
1301 if(h->bitmap_mapped >= n) | 1303 if(h->bitmap_mapped >= n) |
1302 return; | 1304 return; |
1303 | 1305 |
1304 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); | 1306 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); |
1305 h->bitmap_mapped = n; | 1307 h->bitmap_mapped = n; |
1306 } | 1308 } |
LEFT | RIGHT |