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 (GC). | 5 // Garbage collector (GC). |
6 // | 6 // |
7 // GC is: | 7 // GC is: |
8 // - mark&sweep | 8 // - mark&sweep |
9 // - mostly precise (with the exception of some C-allocated objects, assembly fr
ames/arguments, etc) | 9 // - mostly precise (with the exception of some C-allocated objects, assembly fr
ames/arguments, etc) |
10 // - parallel (up to MaxGcproc threads) | 10 // - parallel (up to MaxGcproc threads) |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 // clear sync.Pool's | 100 // clear sync.Pool's |
101 if(poolcleanup != nil) | 101 if(poolcleanup != nil) |
102 reflect·call(poolcleanup, nil, 0, 0); | 102 reflect·call(poolcleanup, nil, 0, 0); |
103 | 103 |
104 for(pp=runtime·allp; p=*pp; pp++) { | 104 for(pp=runtime·allp; p=*pp; pp++) { |
105 // clear tinyalloc pool | 105 // clear tinyalloc pool |
106 c = p->mcache; | 106 c = p->mcache; |
107 if(c != nil) { | 107 if(c != nil) { |
108 c->tiny = nil; | 108 c->tiny = nil; |
109 c->tinysize = 0; | 109 c->tinysize = 0; |
| 110 c->sudogcache = nil; |
110 } | 111 } |
111 // clear defer pools | 112 // clear defer pools |
112 for(i=0; i<nelem(p->deferpool); i++) | 113 for(i=0; i<nelem(p->deferpool); i++) |
113 p->deferpool[i] = nil; | 114 p->deferpool[i] = nil; |
114 } | 115 } |
115 } | 116 } |
116 | 117 |
117 // Holding worldsema grants an M the right to try to stop the world. | 118 // Holding worldsema grants an M the right to try to stop the world. |
118 // The procedure is: | 119 // The procedure is: |
119 // | 120 // |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 } | 1104 } |
1104 runtime·lock(&gclock); | 1105 runtime·lock(&gclock); |
1105 if(!runtime·mheap.sweepdone) { | 1106 if(!runtime·mheap.sweepdone) { |
1106 // It's possible if GC has happened between sweepone has | 1107 // It's possible if GC has happened between sweepone has |
1107 // returned -1 and gclock lock. | 1108 // returned -1 and gclock lock. |
1108 runtime·unlock(&gclock); | 1109 runtime·unlock(&gclock); |
1109 continue; | 1110 continue; |
1110 } | 1111 } |
1111 sweep.parked = true; | 1112 sweep.parked = true; |
1112 g->isbackground = true; | 1113 g->isbackground = true; |
1113 » » runtime·parkunlock(&gclock, "GC sweep wait"); | 1114 » » runtime·parkunlock(&gclock, runtime·gostringnocopy((byte*)"GC sw
eep wait")); |
1114 g->isbackground = false; | 1115 g->isbackground = false; |
1115 } | 1116 } |
1116 } | 1117 } |
1117 | 1118 |
1118 // sweeps one span | 1119 // sweeps one span |
1119 // returns number of pages returned to heap, or -1 if there is nothing to sweep | 1120 // returns number of pages returned to heap, or -1 if there is nothing to sweep |
1120 uintptr | 1121 uintptr |
1121 runtime·sweepone(void) | 1122 runtime·sweepone(void) |
1122 { | 1123 { |
1123 MSpan *s; | 1124 MSpan *s; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 // we're currently running on will no longer change. Cuts | 1368 // we're currently running on will no longer change. Cuts |
1368 // the root set down a bit (g0 stacks are not scanned, and | 1369 // the root set down a bit (g0 stacks are not scanned, and |
1369 // we don't need to scan gc's internal state). Also an | 1370 // we don't need to scan gc's internal state). Also an |
1370 // enabler for copyable stacks. | 1371 // enabler for copyable stacks. |
1371 for(i = 0; i < (runtime·debug.gctrace > 1 ? 2 : 1); i++) { | 1372 for(i = 0; i < (runtime·debug.gctrace > 1 ? 2 : 1); i++) { |
1372 if(i > 0) | 1373 if(i > 0) |
1373 a.start_time = runtime·nanotime(); | 1374 a.start_time = runtime·nanotime(); |
1374 // switch to g0, call gc(&a), then switch back | 1375 // switch to g0, call gc(&a), then switch back |
1375 g->param = &a; | 1376 g->param = &a; |
1376 g->status = Gwaiting; | 1377 g->status = Gwaiting; |
1377 » » g->waitreason = "garbage collection"; | 1378 » » g->waitreason = runtime·gostringnocopy((byte*)"garbage collectio
n"); |
1378 runtime·mcall(mgc); | 1379 runtime·mcall(mgc); |
1379 } | 1380 } |
1380 | 1381 |
1381 // all done | 1382 // all done |
1382 g->m->gcing = 0; | 1383 g->m->gcing = 0; |
1383 g->m->locks++; | 1384 g->m->locks++; |
1384 runtime·semrelease(&runtime·worldsema); | 1385 runtime·semrelease(&runtime·worldsema); |
1385 runtime·starttheworld(); | 1386 runtime·starttheworld(); |
1386 g->m->locks--; | 1387 g->m->locks--; |
1387 | 1388 |
(...skipping 14 matching lines...) Expand all Loading... |
1402 } | 1403 } |
1403 | 1404 |
1404 void | 1405 void |
1405 runtime·gc_m(void) | 1406 runtime·gc_m(void) |
1406 { | 1407 { |
1407 struct gc_args a; | 1408 struct gc_args a; |
1408 G *gp; | 1409 G *gp; |
1409 | 1410 |
1410 gp = g->m->curg; | 1411 gp = g->m->curg; |
1411 gp->status = Gwaiting; | 1412 gp->status = Gwaiting; |
1412 » gp->waitreason = "garbage collection"; | 1413 » gp->waitreason = runtime·gostringnocopy((byte*)"garbage collection"); |
1413 | 1414 |
1414 a.start_time = (uint64)(g->m->scalararg[0]) | ((uint64)(g->m->scalararg[
1]) << 32); | 1415 a.start_time = (uint64)(g->m->scalararg[0]) | ((uint64)(g->m->scalararg[
1]) << 32); |
1415 a.eagersweep = g->m->scalararg[2]; | 1416 a.eagersweep = g->m->scalararg[2]; |
1416 gc(&a); | 1417 gc(&a); |
1417 | 1418 |
1418 gp->status = Grunning; | 1419 gp->status = Grunning; |
1419 } | 1420 } |
1420 | 1421 |
1421 static void | 1422 static void |
1422 gc(struct gc_args *args) | 1423 gc(struct gc_args *args) |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 USED(&ef); | 1657 USED(&ef); |
1657 USED(&ef1); | 1658 USED(&ef1); |
1658 | 1659 |
1659 for(;;) { | 1660 for(;;) { |
1660 runtime·lock(&finlock); | 1661 runtime·lock(&finlock); |
1661 fb = finq; | 1662 fb = finq; |
1662 finq = nil; | 1663 finq = nil; |
1663 if(fb == nil) { | 1664 if(fb == nil) { |
1664 runtime·fingwait = true; | 1665 runtime·fingwait = true; |
1665 g->isbackground = true; | 1666 g->isbackground = true; |
1666 » » » runtime·parkunlock(&finlock, "finalizer wait"); | 1667 » » » runtime·parkunlock(&finlock, runtime·gostringnocopy((byt
e*)"finalizer wait")); |
1667 g->isbackground = false; | 1668 g->isbackground = false; |
1668 continue; | 1669 continue; |
1669 } | 1670 } |
1670 runtime·unlock(&finlock); | 1671 runtime·unlock(&finlock); |
1671 if(raceenabled) | 1672 if(raceenabled) |
1672 runtime·racefingo(); | 1673 runtime·racefingo(); |
1673 for(; fb; fb=next) { | 1674 for(; fb; fb=next) { |
1674 next = fb->next; | 1675 next = fb->next; |
1675 for(i=0; i<fb->cnt; i++) { | 1676 for(i=0; i<fb->cnt; i++) { |
1676 f = &fb->fin[i]; | 1677 f = &fb->fin[i]; |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 n = ((PtrType*)t)->elem->size; | 2101 n = ((PtrType*)t)->elem->size; |
2101 *len = n/PtrSize; | 2102 *len = n/PtrSize; |
2102 *mask = runtime·mallocgc(*len, nil, 0); | 2103 *mask = runtime·mallocgc(*len, nil, 0); |
2103 for(i = 0; i < n; i += PtrSize) { | 2104 for(i = 0; i < n; i += PtrSize) { |
2104 off = (p+i-frame.varp+size)/PtrSize; | 2105 off = (p+i-frame.varp+size)/PtrSize; |
2105 bits = (bv.data[off*BitsPerPointer/32] >> ((off*BitsPerP
ointer)%32))&BitsMask; | 2106 bits = (bv.data[off*BitsPerPointer/32] >> ((off*BitsPerP
ointer)%32))&BitsMask; |
2106 (*mask)[i/PtrSize] = bits; | 2107 (*mask)[i/PtrSize] = bits; |
2107 } | 2108 } |
2108 } | 2109 } |
2109 } | 2110 } |
LEFT | RIGHT |