Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(251)

Delta Between Two Patch Sets: src/pkg/runtime/mgc0.c

Issue 8022044: code review 8022044: cmd/ld, runtime: restrict stack root scan to locals and... (Closed)
Left Patch Set: diff -r 1296263f017c https://code.google.com/p/go/ Created 11 years, 11 months ago
Right Patch Set: diff -r a933e165d2ff https://code.google.com/p/go/ Created 11 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/ld/lib.c ('k') | src/pkg/runtime/mprof.goc » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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"
11 #include "mgc0.h" 11 #include "mgc0.h"
12 #include "race.h" 12 #include "race.h"
13 #include "type.h" 13 #include "type.h"
14 #include "typekind.h" 14 #include "typekind.h"
15 #include "hashmap.h" 15 #include "hashmap.h"
16 16
17 enum { 17 enum {
18 Debug = 0, 18 Debug = 0,
19 DebugMark = 0, // run second pass to check mark 19 DebugMark = 0, // run second pass to check mark
20 CollectStats = 0, 20 CollectStats = 0,
21 ScanStackByFrames = 0,
21 22
22 // Four bits per word (see #defines below). 23 // Four bits per word (see #defines below).
23 wordsPerBitmapWord = sizeof(void*)*8/4, 24 wordsPerBitmapWord = sizeof(void*)*8/4,
24 bitShift = sizeof(void*)*8/4, 25 bitShift = sizeof(void*)*8/4,
25 26
26 handoffThreshold = 4, 27 handoffThreshold = 4,
27 IntermediateBufferCapacity = 64, 28 IntermediateBufferCapacity = 64,
28 29
29 // Bits in type information 30 // Bits in type information
30 PRECISE = 1, 31 PRECISE = 1,
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 runtime·SysFree(work.roots, work.rootcap*sizeof(Obj)); 1311 runtime·SysFree(work.roots, work.rootcap*sizeof(Obj));
1311 } 1312 }
1312 work.roots = new; 1313 work.roots = new;
1313 work.rootcap = cap; 1314 work.rootcap = cap;
1314 } 1315 }
1315 work.roots[work.nroot] = obj; 1316 work.roots[work.nroot] = obj;
1316 work.nroot++; 1317 work.nroot++;
1317 } 1318 }
1318 1319
1319 // Scan a stack frame. The doframe parameter is a signal that the previously 1320 // Scan a stack frame. The doframe parameter is a signal that the previously
1320 // scanned activation has an unknown argument size. When doframe is true the 1321 // scanned activation has an unknown argument size. When *doframe is true the
1321 // current activation must have its entire frame scanned. Otherwise, only the 1322 // current activation must have its entire frame scanned. Otherwise, only the
1322 // locals need to be scanned. 1323 // locals need to be scanned.
1323 static void 1324 static void
1324 addframeroots(Func *f, byte*, byte *sp, void *doframe) 1325 addframeroots(Func *f, byte*, byte *sp, void *doframe)
1325 { 1326 {
1326 uintptr outs; 1327 uintptr outs;
1327 1328
1328 if(thechar == '5') 1329 if(thechar == '5')
1329 sp += sizeof(uintptr); 1330 sp += sizeof(uintptr);
1330 if(f->locals == 0 || *(bool*)doframe == true) 1331 if(f->locals == 0 || *(bool*)doframe == true)
1331 addroot((Obj){sp, f->frame - sizeof(uintptr), 0}); 1332 addroot((Obj){sp, f->frame - sizeof(uintptr), 0});
1332 else if(f->locals > 0) { 1333 else if(f->locals > 0) {
1333 outs = f->frame - sizeof(uintptr) - f->locals; 1334 outs = f->frame - sizeof(uintptr) - f->locals;
1334 addroot((Obj){sp + outs, f->locals, 0}); 1335 addroot((Obj){sp + outs, f->locals, 0});
1335 } 1336 }
1336 if(f->args > 0) 1337 if(f->args > 0)
1337 addroot((Obj){sp + f->frame, f->args, 0}); 1338 addroot((Obj){sp + f->frame, f->args, 0});
1338 » *(bool*)doframe = (f->args < 0); 1339 » *(bool*)doframe = (f->args == ArgsSizeUnknown);
1339 } 1340 }
1340 1341
1341 static void 1342 static void
1342 addstackroots(G *gp) 1343 addstackroots(G *gp)
1343 { 1344 {
1344 M *mp; 1345 M *mp;
1346 int32 n;
1347 Stktop *stk;
1348 byte *sp, *guard, *pc;
1345 Func *f; 1349 Func *f;
1346 byte *sp, *pc;
1347 bool doframe; 1350 bool doframe;
1351
1352 stk = (Stktop*)gp->stackbase;
1353 guard = (byte*)gp->stackguard;
1348 1354
1349 if(gp == g) { 1355 if(gp == g) {
1350 // Scanning our own stack: start at &gp. 1356 // Scanning our own stack: start at &gp.
1351 sp = runtime·getcallersp(&gp); 1357 sp = runtime·getcallersp(&gp);
1352 pc = runtime·getcallerpc(&gp); 1358 pc = runtime·getcallerpc(&gp);
1353 } else if((mp = gp->m) != nil && mp->helpgc) { 1359 } else if((mp = gp->m) != nil && mp->helpgc) {
1354 // gchelper's stack is in active use and has no interesting poin ters. 1360 // gchelper's stack is in active use and has no interesting poin ters.
1355 return; 1361 return;
1356 } else if(gp->gcstack != (uintptr)nil) { 1362 } else if(gp->gcstack != (uintptr)nil) {
1357 // Scanning another goroutine that is about to enter or might 1363 // Scanning another goroutine that is about to enter or might
1358 // have just exited a system call. It may be executing code such 1364 // have just exited a system call. It may be executing code such
1359 // as schedlock and may have needed to start a new stack segment . 1365 // as schedlock and may have needed to start a new stack segment .
1360 // Use the stack segment and stack pointer at the time of 1366 // Use the stack segment and stack pointer at the time of
1361 // the system call instead, since that won't change underfoot. 1367 // the system call instead, since that won't change underfoot.
1362 sp = (byte*)gp->gcsp; 1368 sp = (byte*)gp->gcsp;
1363 pc = gp->gcpc; 1369 pc = gp->gcpc;
1370 stk = (Stktop*)gp->gcstack;
1371 guard = (byte*)gp->gcguard;
1364 } else { 1372 } else {
1365 // Scanning another goroutine's stack. 1373 // Scanning another goroutine's stack.
1366 // The goroutine is usually asleep (the world is stopped). 1374 // The goroutine is usually asleep (the world is stopped).
1367 sp = (byte*)gp->sched.sp; 1375 sp = (byte*)gp->sched.sp;
1368 pc = gp->sched.pc; 1376 pc = gp->sched.pc;
1369 » » if(pc == (byte*)runtime·goexit && gp->fnstart != nil) { 1377 » » if(ScanStackByFrames && pc == (byte*)runtime·goexit && gp->fnsta rt != nil) {
1370 // The goroutine has not started. However, its incoming 1378 // The goroutine has not started. However, its incoming
1371 // arguments are live at the top of the stack and must 1379 // arguments are live at the top of the stack and must
1372 // be scanned. No other live values should be on the 1380 // be scanned. No other live values should be on the
1373 // stack. 1381 // stack.
1374 f = runtime·findfunc((uintptr)gp->fnstart->fn); 1382 f = runtime·findfunc((uintptr)gp->fnstart->fn);
1375 if(f->args > 0) { 1383 if(f->args > 0) {
1376 if(thechar == '5') 1384 if(thechar == '5')
1377 sp += sizeof(uintptr); 1385 sp += sizeof(uintptr);
1378 addroot((Obj){sp, f->args, 0}); 1386 addroot((Obj){sp, f->args, 0});
1379 } 1387 }
1380 return; 1388 return;
1381 } 1389 }
1382 } 1390 }
1383 » doframe = false; 1391 » if (ScanStackByFrames) {
1384 » runtime·gentraceback(pc, sp, nil, gp, 0, nil, 0x7fffffff, addframeroots, &doframe); 1392 » » doframe = false;
1393 » » runtime·gentraceback(pc, sp, nil, gp, 0, nil, 0x7fffffff, addfra meroots, &doframe);
1394 » } else {
1395 » » USED(pc);
1396 » » n = 0;
1397 » » while(stk) {
1398 » » » if(sp < guard-StackGuard || (byte*)stk < sp) {
1399 » » » » runtime·printf("scanstack inconsistent: g%D#%d s p=%p not in [%p,%p]\n", gp->goid, n, sp, guard-StackGuard, stk);
1400 » » » » runtime·throw("scanstack");
1401 » » » }
1402 » » » addroot((Obj){sp, (byte*)stk - sp, (uintptr)defaultProg | PRECISE | LOOP});
1403 » » » sp = (byte*)stk->gobuf.sp;
1404 » » » guard = stk->stackguard;
1405 » » » stk = (Stktop*)stk->stackbase;
1406 » » » n++;
1407 » » }
1408 » }
1385 } 1409 }
1386 1410
1387 static void 1411 static void
1388 addfinroots(void *v) 1412 addfinroots(void *v)
1389 { 1413 {
1390 uintptr size; 1414 uintptr size;
1391 void *base; 1415 void *base;
1392 1416
1393 size = 0; 1417 size = 0;
1394 if(!runtime·mlookup(v, &base, &size, nil) || !runtime·blockspecial(base) ) 1418 if(!runtime·mlookup(v, &base, &size, nil) || !runtime·blockspecial(base) )
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 uintptr n; 2332 uintptr n;
2309 2333
2310 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; 2334 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord;
2311 n = (n+bitmapChunk-1) & ~(bitmapChunk-1); 2335 n = (n+bitmapChunk-1) & ~(bitmapChunk-1);
2312 if(h->bitmap_mapped >= n) 2336 if(h->bitmap_mapped >= n)
2313 return; 2337 return;
2314 2338
2315 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); 2339 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped);
2316 h->bitmap_mapped = n; 2340 h->bitmap_mapped = n;
2317 } 2341 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b