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 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 runtime·memmove(new, work.roots, work.rootcap*sizeof(Obj
)); | 1384 runtime·memmove(new, work.roots, work.rootcap*sizeof(Obj
)); |
1385 runtime·SysFree(work.roots, work.rootcap*sizeof(Obj)); | 1385 runtime·SysFree(work.roots, work.rootcap*sizeof(Obj)); |
1386 } | 1386 } |
1387 work.roots = new; | 1387 work.roots = new; |
1388 work.rootcap = cap; | 1388 work.rootcap = cap; |
1389 } | 1389 } |
1390 work.roots[work.nroot] = obj; | 1390 work.roots[work.nroot] = obj; |
1391 work.nroot++; | 1391 work.nroot++; |
1392 } | 1392 } |
1393 | 1393 |
1394 // Scan a stack frame. The doframe parameter is a signal that the previously | 1394 // Scan a stack frame. Normally, this scans the locals area, |
1395 // scanned activation has an unknown argument size. When *doframe is true the | 1395 // belonging to the current frame, and the arguments area, belonging |
1396 // current activation must have its entire frame scanned. Otherwise, only the | 1396 // to the calling frame. When the arguments area size is unknown, the |
1397 // locals need to be scanned. | 1397 // arguments area scanning is delayed and the doframe parameter |
| 1398 // signals that the previously scanned activation has an unknown |
| 1399 // argument size. When *doframe is true, the possible arguments area |
| 1400 // for the callee, located between the stack pointer and the bottom of |
| 1401 // the locals area, is additionally scanned. Otherwise, this area is |
| 1402 // ignored, as it must have been scanned when the callee was scanned. |
1398 static void | 1403 static void |
1399 addframeroots(Func *f, byte*, byte *sp, void *doframe) | 1404 addframeroots(Func *f, byte*, byte *sp, void *doframe) |
1400 { | 1405 { |
| 1406 byte *fp, *ap; |
1401 uintptr outs; | 1407 uintptr outs; |
| 1408 int32 i, j, rem; |
| 1409 uint32 w, b; |
1402 | 1410 |
1403 if(thechar == '5') | 1411 if(thechar == '5') |
1404 sp += sizeof(uintptr); | 1412 sp += sizeof(uintptr); |
| 1413 fp = sp + f->frame; |
1405 if(f->locals == 0 || *(bool*)doframe == true) | 1414 if(f->locals == 0 || *(bool*)doframe == true) |
| 1415 // Scan the entire stack frame. |
1406 addroot((Obj){sp, f->frame - sizeof(uintptr), 0}); | 1416 addroot((Obj){sp, f->frame - sizeof(uintptr), 0}); |
1407 else if(f->locals > 0) { | 1417 else if(f->locals > 0) { |
| 1418 // Scan the locals area. |
1408 outs = f->frame - sizeof(uintptr) - f->locals; | 1419 outs = f->frame - sizeof(uintptr) - f->locals; |
1409 addroot((Obj){sp + outs, f->locals, 0}); | 1420 addroot((Obj){sp + outs, f->locals, 0}); |
1410 } | 1421 } |
1411 » if(f->args > 0) | 1422 » if(f->args > 0) { |
1412 » » addroot((Obj){sp + f->frame, f->args, 0}); | 1423 » » // Scan the arguments area. |
| 1424 » » if(f->ptrs.array != nil) { |
| 1425 » » » ap = fp; |
| 1426 » » » rem = f->args / sizeof(uintptr); |
| 1427 » » » for(i = 0; i < f->ptrs.len; i++) { |
| 1428 » » » » w = ((uint32*)f->ptrs.array)[i]; |
| 1429 » » » » b = 1; |
| 1430 » » » » for((j = (rem < 32) ? rem : 32); j > 0; j--) { |
| 1431 » » » » » if(w & b) |
| 1432 » » » » » » addroot((Obj){ap, sizeof(uintptr
), 0}); |
| 1433 » » » » » b <<= 1; |
| 1434 » » » » » ap += sizeof(uintptr); |
| 1435 » » » » } |
| 1436 » » » » rem -= 32; |
| 1437 » » » } |
| 1438 » » } else |
| 1439 » » » addroot((Obj){fp, f->args, 0}); |
| 1440 » } |
1413 *(bool*)doframe = (f->args == ArgsSizeUnknown); | 1441 *(bool*)doframe = (f->args == ArgsSizeUnknown); |
1414 } | 1442 } |
1415 | 1443 |
1416 static void | 1444 static void |
1417 addstackroots(G *gp) | 1445 addstackroots(G *gp) |
1418 { | 1446 { |
1419 M *mp; | 1447 M *mp; |
1420 int32 n; | 1448 int32 n; |
1421 Stktop *stk; | 1449 Stktop *stk; |
1422 byte *sp, *guard, *pc; | 1450 byte *sp, *guard, *pc; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 // Otherwise, scan everything between the | 1490 // Otherwise, scan everything between the |
1463 // top and the bottom of the stack. | 1491 // top and the bottom of the stack. |
1464 if(f->args > 0) | 1492 if(f->args > 0) |
1465 addroot((Obj){sp, f->args, 0}); | 1493 addroot((Obj){sp, f->args, 0}); |
1466 else | 1494 else |
1467 addroot((Obj){sp, (byte*)stk - sp, 0});· | 1495 addroot((Obj){sp, (byte*)stk - sp, 0});· |
1468 }· | 1496 }· |
1469 return; | 1497 return; |
1470 } | 1498 } |
1471 } | 1499 } |
1472 » if (ScanStackByFrames) { | 1500 » if(ScanStackByFrames) { |
1473 USED(stk); | 1501 USED(stk); |
1474 USED(guard); | 1502 USED(guard); |
1475 doframe = false; | 1503 doframe = false; |
1476 runtime·gentraceback(pc, sp, nil, gp, 0, nil, 0x7fffffff, addfra
meroots, &doframe); | 1504 runtime·gentraceback(pc, sp, nil, gp, 0, nil, 0x7fffffff, addfra
meroots, &doframe); |
1477 } else { | 1505 } else { |
1478 USED(pc); | 1506 USED(pc); |
1479 n = 0; | 1507 n = 0; |
1480 while(stk) { | 1508 while(stk) { |
1481 if(sp < guard-StackGuard || (byte*)stk < sp) { | 1509 if(sp < guard-StackGuard || (byte*)stk < sp) { |
1482 runtime·printf("scanstack inconsistent: g%D#%d s
p=%p not in [%p,%p]\n", gp->goid, n, sp, guard-StackGuard, stk); | 1510 runtime·printf("scanstack inconsistent: g%D#%d s
p=%p not in [%p,%p]\n", gp->goid, n, sp, guard-StackGuard, stk); |
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2403 uintptr n; | 2431 uintptr n; |
2404 | 2432 |
2405 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; | 2433 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; |
2406 n = ROUND(n, bitmapChunk); | 2434 n = ROUND(n, bitmapChunk); |
2407 if(h->bitmap_mapped >= n) | 2435 if(h->bitmap_mapped >= n) |
2408 return; | 2436 return; |
2409 | 2437 |
2410 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); | 2438 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); |
2411 h->bitmap_mapped = n; | 2439 h->bitmap_mapped = n; |
2412 } | 2440 } |
LEFT | RIGHT |