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

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

Issue 7413049: code review 7413049: runtime: add garbage collector statistics (Closed)
Left Patch Set: Created 12 years ago
Right Patch Set: diff -r 8a08842f7978 https://code.google.com/p/go/ Created 12 years 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 | « no previous file | no next file » | 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"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 164
165 enum { 165 enum {
166 GC_DEFAULT_PTR = GC_NUM_INSTR, 166 GC_DEFAULT_PTR = GC_NUM_INSTR,
167 GC_MAP_NEXT, 167 GC_MAP_NEXT,
168 GC_CHAN, 168 GC_CHAN,
169 169
170 GC_NUM_INSTR2 170 GC_NUM_INSTR2
171 }; 171 };
172 172
173 static struct { 173 static struct {
174 » uint64 ptr_sum; 174 » struct {
175 » uint64 ptr_cnt; 175 » » uint64 sum;
176 » » uint64 cnt;
177 » } ptr;
176 uint64 nbytes; 178 uint64 nbytes;
177 » uint64 nobj_sum; 179 » struct {
178 » uint64 nobj_cnt; 180 » » uint64 sum;
179 » uint64 nobj_notype; 181 » » uint64 cnt;
180 » uint64 nobj_typelookups_ok; 182 » » uint64 notype;
181 » uint64 rescans; 183 » » uint64 typelookup;
182 » uint64 rescan_nbytes; 184 » } obj;
185 » uint64 rescan;
186 » uint64 rescanbytes;
183 uint64 instr[GC_NUM_INSTR2]; 187 uint64 instr[GC_NUM_INSTR2];
184 uint64 putempty; 188 uint64 putempty;
185 uint64 getfull; 189 uint64 getfull;
186 } gcstats; 190 } gcstats;
187 191
188 // markonly marks an object. It returns true if the object 192 // markonly marks an object. It returns true if the object
189 // has been marked by this function, false otherwise. 193 // has been marked by this function, false otherwise.
190 // This function isn't thread-safe and doesn't append the object to any buffer. 194 // This function isn't thread-safe and doesn't append the object to any buffer.
191 static bool 195 static bool
192 markonly(void *obj) 196 markonly(void *obj)
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 331
328 wp = *_wp; 332 wp = *_wp;
329 wbuf = *_wbuf; 333 wbuf = *_wbuf;
330 nobj = *_nobj; 334 nobj = *_nobj;
331 335
332 ptrbuf_end = *ptrbufpos; 336 ptrbuf_end = *ptrbufpos;
333 n = ptrbuf_end - ptrbuf; 337 n = ptrbuf_end - ptrbuf;
334 *ptrbufpos = ptrbuf; 338 *ptrbufpos = ptrbuf;
335 339
336 if(CollectStats) { 340 if(CollectStats) {
337 » » runtime·xadd64(&gcstats.ptr_sum, n); 341 » » runtime·xadd64(&gcstats.ptr.sum, n);
338 » » runtime·xadd64(&gcstats.ptr_cnt, 1); 342 » » runtime·xadd64(&gcstats.ptr.cnt, 1);
339 } 343 }
340 344
341 // If buffer is nearly full, get a new one. 345 // If buffer is nearly full, get a new one.
342 if(wbuf == nil || nobj+n >= nelem(wbuf->obj)) { 346 if(wbuf == nil || nobj+n >= nelem(wbuf->obj)) {
343 if(wbuf != nil) 347 if(wbuf != nil)
344 wbuf->nobj = nobj; 348 wbuf->nobj = nobj;
345 wbuf = getempty(wbuf); 349 wbuf = getempty(wbuf);
346 wp = wbuf->obj; 350 wp = wbuf->obj;
347 nobj = 0; 351 nobj = 0;
348 352
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 643
640 for(;;) { 644 for(;;) {
641 // Each iteration scans the block b of length n, queueing pointe rs in 645 // Each iteration scans the block b of length n, queueing pointe rs in
642 // the work buffer. 646 // the work buffer.
643 if(Debug > 1) { 647 if(Debug > 1) {
644 runtime·printf("scanblock %p %D\n", b, (int64)n); 648 runtime·printf("scanblock %p %D\n", b, (int64)n);
645 } 649 }
646 650
647 if(CollectStats) { 651 if(CollectStats) {
648 runtime·xadd64(&gcstats.nbytes, n); 652 runtime·xadd64(&gcstats.nbytes, n);
649 » » » runtime·xadd64(&gcstats.nobj_sum, nobj); 653 » » » runtime·xadd64(&gcstats.obj.sum, nobj);
650 » » » runtime·xadd64(&gcstats.nobj_cnt, 1); 654 » » » runtime·xadd64(&gcstats.obj.cnt, 1);
651 } 655 }
652 656
653 if(ti != 0) { 657 if(ti != 0) {
654 pc = (uintptr*)(ti & ~(uintptr)PC_BITS); 658 pc = (uintptr*)(ti & ~(uintptr)PC_BITS);
655 precise_type = (ti & PRECISE); 659 precise_type = (ti & PRECISE);
656 stack_top.elemsize = pc[0]; 660 stack_top.elemsize = pc[0];
657 if(!precise_type) 661 if(!precise_type)
658 nominal_size = pc[0]; 662 nominal_size = pc[0];
659 if(ti & LOOP) { 663 if(ti & LOOP) {
660 stack_top.count = 0; // 0 means an infinite n umber of iterations 664 stack_top.count = 0; // 0 means an infinite n umber of iterations
661 stack_top.loop_or_ret = pc+1; 665 stack_top.loop_or_ret = pc+1;
662 } else { 666 } else {
663 stack_top.count = 1; 667 stack_top.count = 1;
664 } 668 }
665 } else if(UseSpanType) { 669 } else if(UseSpanType) {
666 if(CollectStats) 670 if(CollectStats)
667 » » » » runtime·xadd64(&gcstats.nobj_notype, 1); 671 » » » » runtime·xadd64(&gcstats.obj.notype, 1);
668 672
669 type = runtime·gettype(b); 673 type = runtime·gettype(b);
670 if(type != 0) { 674 if(type != 0) {
671 if(CollectStats) 675 if(CollectStats)
672 » » » » » runtime·xadd64(&gcstats.nobj_typelookups _ok, 1); 676 » » » » » runtime·xadd64(&gcstats.obj.typelookup, 1);
673 677
674 t = (Type*)(type & ~(uintptr)(PtrSize-1)); 678 t = (Type*)(type & ~(uintptr)(PtrSize-1));
675 switch(type & (PtrSize-1)) { 679 switch(type & (PtrSize-1)) {
676 case TypeInfo_SingleObject: 680 case TypeInfo_SingleObject:
677 pc = (uintptr*)t->gc; 681 pc = (uintptr*)t->gc;
678 precise_type = true; // type informatio n about 'b' is precise 682 precise_type = true; // type informatio n about 'b' is precise
679 stack_top.count = 1; 683 stack_top.count = 1;
680 stack_top.elemsize = pc[0]; 684 stack_top.elemsize = pc[0];
681 break; 685 break;
682 case TypeInfo_Array: 686 case TypeInfo_Array:
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 } 842 }
839 i = (uintptr)b + nominal_size; 843 i = (uintptr)b + nominal_size;
840 } 844 }
841 if(!precise_type) { 845 if(!precise_type) {
842 // Quickly scan [b+i,b+n) for possible pointers. 846 // Quickly scan [b+i,b+n) for possible pointers.
843 for(; i<=end_b; i+=PtrSize) { 847 for(; i<=end_b; i+=PtrSize) {
844 if(*(byte**)i != nil) { 848 if(*(byte**)i != nil) {
845 // Found a value that may be a p ointer. 849 // Found a value that may be a p ointer.
846 // Do a rescan of the entire blo ck. 850 // Do a rescan of the entire blo ck.
847 enqueue((Obj){b, n, 0}, &wbuf, & wp, &nobj); 851 enqueue((Obj){b, n, 0}, &wbuf, & wp, &nobj);
852 if(CollectStats) {
853 runtime·xadd64(&gcstats. rescan, 1);
854 runtime·xadd64(&gcstats. rescanbytes, n);
855 }
848 break; 856 break;
849 } 857 }
850 } 858 }
851 } 859 }
852 goto next_block; 860 goto next_block;
853 861
854 case GC_ARRAY_START: 862 case GC_ARRAY_START:
855 i = stack_top.b + pc[1]; 863 i = stack_top.b + pc[1];
856 count = pc[2]; 864 count = pc[2];
857 elemsize = pc[3]; 865 elemsize = pc[3];
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 runtime·printf("gc%d(%d): %D+%D+%D ms, %D -> %D MB %D -> %D (%D- %D) objects," 1909 runtime·printf("gc%d(%d): %D+%D+%D ms, %D -> %D MB %D -> %D (%D- %D) objects,"
1902 " %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\ n", 1910 " %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\ n",
1903 mstats.numgc, work.nproc, (t2-t1)/1000000, (t3-t2)/10000 00, (t1-t0+t4-t3)/1000000, 1911 mstats.numgc, work.nproc, (t2-t1)/1000000, (t3-t2)/10000 00, (t1-t0+t4-t3)/1000000,
1904 heap0>>20, heap1>>20, obj0, obj1, 1912 heap0>>20, heap1>>20, obj0, obj1,
1905 mstats.nmalloc, mstats.nfree, 1913 mstats.nmalloc, mstats.nfree,
1906 stats.nhandoff, stats.nhandoffcnt, 1914 stats.nhandoff, stats.nhandoffcnt,
1907 work.sweepfor->nsteal, work.sweepfor->nstealcnt, 1915 work.sweepfor->nsteal, work.sweepfor->nstealcnt,
1908 stats.nprocyield, stats.nosyield, stats.nsleep); 1916 stats.nprocyield, stats.nosyield, stats.nsleep);
1909 if(CollectStats) { 1917 if(CollectStats) {
1910 runtime·printf("scan: %D bytes, %D objects, %D untyped, %D types from MSpan\n", 1918 runtime·printf("scan: %D bytes, %D objects, %D untyped, %D types from MSpan\n",
1911 » » » » gcstats.nbytes, gcstats.nobj_cnt, gcstats.nobj_n otype, gcstats.nobj_typelookups_ok); 1919 » » » » gcstats.nbytes, gcstats.obj.cnt, gcstats.obj.not ype, gcstats.obj.typelookup);
1912 » » » if(gcstats.ptr_cnt != 0) 1920 » » » if(gcstats.ptr.cnt != 0)
1913 runtime·printf("avg ptrbufsize: %D (%D/%D)\n", 1921 runtime·printf("avg ptrbufsize: %D (%D/%D)\n",
1914 » » » » » gcstats.ptr_sum/gcstats.ptr_cnt, gcstats .ptr_sum, gcstats.ptr_cnt); 1922 » » » » » gcstats.ptr.sum/gcstats.ptr.cnt, gcstats .ptr.sum, gcstats.ptr.cnt);
1915 » » » if(gcstats.nobj_cnt != 0) 1923 » » » if(gcstats.obj.cnt != 0)
1916 runtime·printf("avg nobj: %D (%D/%D)\n", 1924 runtime·printf("avg nobj: %D (%D/%D)\n",
1917 » » » » » gcstats.nobj_sum/gcstats.nobj_cnt, gcsta ts.nobj_sum, gcstats.nobj_cnt); 1925 » » » » » gcstats.obj.sum/gcstats.obj.cnt, gcstats .obj.sum, gcstats.obj.cnt);
1918 » » » runtime·printf("rescans: %D, %D bytes\n", gcstats.rescan s, gcstats.rescan_nbytes); 1926 » » » runtime·printf("rescans: %D, %D bytes\n", gcstats.rescan , gcstats.rescanbytes);
1919 1927
1920 runtime·printf("instruction counts:\n"); 1928 runtime·printf("instruction counts:\n");
1921 ninstr = 0; 1929 ninstr = 0;
1922 for(i=0; i<nelem(gcstats.instr); i++) { 1930 for(i=0; i<nelem(gcstats.instr); i++) {
1923 runtime·printf("\t%d:\t%D\n", i, gcstats.instr[i ]); 1931 runtime·printf("\t%d:\t%D\n", i, gcstats.instr[i ]);
1924 ninstr += gcstats.instr[i]; 1932 ninstr += gcstats.instr[i];
1925 } 1933 }
1926 runtime·printf("\ttotal:\t%D\n", ninstr); 1934 runtime·printf("\ttotal:\t%D\n", ninstr);
1927 1935
1928 runtime·printf("putempty: %D, getfull: %D\n", gcstats.pu tempty, gcstats.getfull); 1936 runtime·printf("putempty: %D, getfull: %D\n", gcstats.pu tempty, gcstats.getfull);
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 uintptr n; 2252 uintptr n;
2245 2253
2246 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord; 2254 n = (h->arena_used - h->arena_start) / wordsPerBitmapWord;
2247 n = (n+bitmapChunk-1) & ~(bitmapChunk-1); 2255 n = (n+bitmapChunk-1) & ~(bitmapChunk-1);
2248 if(h->bitmap_mapped >= n) 2256 if(h->bitmap_mapped >= n)
2249 return; 2257 return;
2250 2258
2251 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped); 2259 runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped);
2252 h->bitmap_mapped = n; 2260 h->bitmap_mapped = n;
2253 } 2261 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

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