OLD | NEW |
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 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 } | 1380 } |
1381 work.roots = new; | 1381 work.roots = new; |
1382 work.rootcap = cap; | 1382 work.rootcap = cap; |
1383 } | 1383 } |
1384 work.roots[work.nroot] = obj; | 1384 work.roots[work.nroot] = obj; |
1385 work.nroot++; | 1385 work.nroot++; |
1386 } | 1386 } |
1387 | 1387 |
1388 extern byte pclntab[]; // base for f->ptrsoff | 1388 extern byte pclntab[]; // base for f->ptrsoff |
1389 | 1389 |
1390 typedef struct GCFunc GCFunc; | 1390 typedef struct BitVector BitVector; |
1391 struct GCFunc | 1391 struct BitVector |
1392 { | 1392 { |
1393 » uint32» locals; // size of local variables in bytes | 1393 » int32 n; |
1394 » uint32» nptrs; // number of words that follow | 1394 » uint32 data[]; |
1395 » uint32» ptrs[1]; // bitmap of pointers in arguments | |
1396 }; | 1395 }; |
1397 | 1396 |
| 1397 // Starting from scanp, scans words corresponding to set bits. |
| 1398 static void |
| 1399 scanbitvector(byte *scanp, BitVector *bv) |
| 1400 { |
| 1401 uint32 *wp; |
| 1402 uint32 w; |
| 1403 int32 i, remptrs; |
| 1404 |
| 1405 wp = bv->data; |
| 1406 for(remptrs = bv->n; remptrs > 0; remptrs -= 32) { |
| 1407 w = *wp++; |
| 1408 if(remptrs < 32) |
| 1409 i = remptrs; |
| 1410 else |
| 1411 i = 32; |
| 1412 for(; i > 0; i--) { |
| 1413 if(w & 1) |
| 1414 addroot((Obj){scanp, PtrSize, 0}); |
| 1415 w >>= 1; |
| 1416 scanp += PtrSize; |
| 1417 } |
| 1418 } |
| 1419 } |
| 1420 |
1398 // Scan a stack frame: local variables and function arguments/results. | 1421 // Scan a stack frame: local variables and function arguments/results. |
1399 static void | 1422 static void |
1400 addframeroots(Stkframe *frame, void*) | 1423 addframeroots(Stkframe *frame, void*) |
1401 { | 1424 { |
1402 Func *f; | 1425 Func *f; |
1403 » byte *ap; | 1426 » BitVector *args, *locals; |
1404 » int32 i, j, nuintptr; | 1427 » uintptr size; |
1405 » uint32 w, b; | |
1406 » GCFunc *gcf; | |
1407 | 1428 |
1408 f = frame->fn; | 1429 f = frame->fn; |
1409 » gcf = runtime·funcdata(f, FUNCDATA_GC); | 1430 |
1410 »······· | |
1411 // Scan local variables if stack frame has been allocated. | 1431 // Scan local variables if stack frame has been allocated. |
1412 » i = frame->varp - (byte*)frame->sp; | 1432 » // Use pointer information if known. |
1413 » if(i > 0) { | 1433 » if(frame->varp > (byte*)frame->sp) { |
1414 » » if(gcf == nil) | 1434 » » locals = runtime·funcdata(f, FUNCDATA_GCLocals); |
1415 » » » addroot((Obj){frame->varp - i, i, 0}); | 1435 » » if(locals == nil) { |
1416 » » else if(i >= gcf->locals) | 1436 » » » // No locals information, scan everything. |
1417 » » » addroot((Obj){frame->varp - gcf->locals, gcf->locals, 0}
); | 1437 » » » size = frame->varp - (byte*)frame->sp; |
| 1438 » » » addroot((Obj){frame->varp - size, size, 0}); |
| 1439 » » } else if(locals->n < 0) { |
| 1440 » » » // Locals size information, scan just the |
| 1441 » » » // locals. |
| 1442 » » » size = -locals->n; |
| 1443 » » » addroot((Obj){frame->varp - size, size, 0}); |
| 1444 » » } else if(locals->n > 0) { |
| 1445 » » » // Locals bitmap information, scan just the |
| 1446 » » » // pointers in locals. |
| 1447 » » » size = locals->n*PtrSize; |
| 1448 » » » scanbitvector(frame->varp - size, locals); |
| 1449 » » } |
1418 } | 1450 } |
1419 | 1451 |
1420 // Scan arguments. | 1452 // Scan arguments. |
1421 // Use pointer information if known. | 1453 // Use pointer information if known. |
1422 » if(f->args > 0 && gcf != nil && gcf->nptrs > 0) { | 1454 » args = runtime·funcdata(f, FUNCDATA_GCArgs); |
1423 » » ap = frame->argp; | 1455 » if(args != nil && args->n > 0) |
1424 » » nuintptr = f->args / sizeof(uintptr); | 1456 » » scanbitvector(frame->argp, args); |
1425 » » for(i = 0; i < gcf->nptrs; i++) { | 1457 » else |
1426 » » » w = gcf->ptrs[i]; | |
1427 » » » b = 1; | |
1428 » » » j = nuintptr; | |
1429 » » » if(j > 32) | |
1430 » » » » j = 32; | |
1431 » » » for(; j > 0; j--) { | |
1432 » » » » if(w & b) | |
1433 » » » » » addroot((Obj){ap, sizeof(uintptr), 0}); | |
1434 » » » » b <<= 1; | |
1435 » » » » ap += sizeof(uintptr); | |
1436 » » » } | |
1437 » » » nuintptr -= 32; | |
1438 » » } | |
1439 » } else | |
1440 addroot((Obj){frame->argp, frame->arglen, 0}); | 1458 addroot((Obj){frame->argp, frame->arglen, 0}); |
1441 } | 1459 } |
1442 | 1460 |
1443 static void | 1461 static void |
1444 addstackroots(G *gp) | 1462 addstackroots(G *gp) |
1445 { | 1463 { |
1446 M *mp; | 1464 M *mp; |
1447 int32 n; | 1465 int32 n; |
1448 Stktop *stk; | 1466 Stktop *stk; |
1449 uintptr sp, guard, pc, lr; | 1467 uintptr sp, guard, pc, lr; |
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2520 uintptr n; | 2538 uintptr n; |
2521 | 2539 |
2522 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; | 2540 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; |
2523 n = ROUND(n, bitmapChunk); | 2541 n = ROUND(n, bitmapChunk); |
2524 if(h->bitmap_mapped >= n) | 2542 if(h->bitmap_mapped >= n) |
2525 return; | 2543 return; |
2526 | 2544 |
2527 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); | 2545 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); |
2528 h->bitmap_mapped = n; | 2546 h->bitmap_mapped = n; |
2529 } | 2547 } |
OLD | NEW |