LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2014 The Go Authors. All rights reserved. | 1 // Copyright 2014 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 // Implementation of runtime/debug.WriteHeapDump. Writes all | 5 // Implementation of runtime/debug.WriteHeapDump. Writes all |
6 // objects in the heap plus additional info (roots, threads, | 6 // objects in the heap plus additional info (roots, threads, |
7 // finalizers, etc.) to a file. | 7 // finalizers, etc.) to a file. |
8 | 8 |
9 // The format of the dumped file is described at | 9 // The format of the dumped file is described at |
10 // http://code.google.com/p/go-wiki/wiki/heapdump13 | 10 // http://code.google.com/p/go-wiki/wiki/heapdump13 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 switch(bv->data[i/32] >> i%32 & 3) { | 253 switch(bv->data[i/32] >> i%32 & 3) { |
254 case BitsDead: | 254 case BitsDead: |
255 case BitsScalar: | 255 case BitsScalar: |
256 break; | 256 break; |
257 case BitsPointer: | 257 case BitsPointer: |
258 dumpint(FieldKindPtr); | 258 dumpint(FieldKindPtr); |
259 dumpint(offset + i / BitsPerPointer * PtrSize); | 259 dumpint(offset + i / BitsPerPointer * PtrSize); |
260 break; | 260 break; |
261 case BitsMultiWord: | 261 case BitsMultiWord: |
262 switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPoin
ter)%32 & 3) { | 262 switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPoin
ter)%32 & 3) { |
263 » » » case BitsString: | 263 » » » default: |
264 » » » » dumpint(FieldKindString); | 264 » » » » runtime·throw("unexpected garbage collection bit
s"); |
265 » » » » dumpint(offset + i / BitsPerPointer * PtrSize); | |
266 » » » » i += BitsPerPointer; | |
267 » » » » break; | |
268 » » » case BitsSlice: | |
269 » » » » dumpint(FieldKindSlice); | |
270 » » » » dumpint(offset + i / BitsPerPointer * PtrSize); | |
271 » » » » i += 2 * BitsPerPointer; | |
272 » » » » break; | |
273 case BitsIface: | 265 case BitsIface: |
274 dumpint(FieldKindIface); | 266 dumpint(FieldKindIface); |
275 dumpint(offset + i / BitsPerPointer * PtrSize); | 267 dumpint(offset + i / BitsPerPointer * PtrSize); |
276 i += BitsPerPointer; | 268 i += BitsPerPointer; |
277 break; | 269 break; |
278 case BitsEface: | 270 case BitsEface: |
279 dumpint(FieldKindEface); | 271 dumpint(FieldKindEface); |
280 dumpint(offset + i / BitsPerPointer * PtrSize); | 272 dumpint(offset + i / BitsPerPointer * PtrSize); |
281 i += BitsPerPointer; | 273 i += BitsPerPointer; |
282 break; | 274 break; |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 MSpan *s, **allspans; | 480 MSpan *s, **allspans; |
489 uint32 spanidx; | 481 uint32 spanidx; |
490 Special *sp; | 482 Special *sp; |
491 SpecialFinalizer *spf; | 483 SpecialFinalizer *spf; |
492 byte *p; | 484 byte *p; |
493 | 485 |
494 // data segment | 486 // data segment |
495 dumpint(TagData); | 487 dumpint(TagData); |
496 dumpint((uintptr)data); | 488 dumpint((uintptr)data); |
497 dumpmemrange(data, edata - data); | 489 dumpmemrange(data, edata - data); |
498 » dumpfields((BitVector){(edata - data)*8, (uint32*)runtime·gcdatamask}); | 490 » dumpfields(runtime·gcdatamask); |
499 | 491 |
500 // bss segment | 492 // bss segment |
501 dumpint(TagBss); | 493 dumpint(TagBss); |
502 dumpint((uintptr)bss); | 494 dumpint((uintptr)bss); |
503 dumpmemrange(bss, ebss - bss); | 495 dumpmemrange(bss, ebss - bss); |
504 » dumpfields((BitVector){(ebss - bss)*8, (uint32*)runtime·gcbssmask}); | 496 » dumpfields(runtime·gcdatamask); |
505 | 497 |
506 // MSpan.types | 498 // MSpan.types |
507 allspans = runtime·mheap.allspans; | 499 allspans = runtime·mheap.allspans; |
508 for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) { | 500 for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) { |
509 s = allspans[spanidx]; | 501 s = allspans[spanidx]; |
510 if(s->state == MSpanInUse) { | 502 if(s->state == MSpanInUse) { |
511 // Finalizers | 503 // Finalizers |
512 for(sp = s->specials; sp != nil; sp = sp->next) { | 504 for(sp = s->specials; sp != nil; sp = sp->next) { |
513 if(sp->kind != KindSpecialFinalizer) | 505 if(sp->kind != KindSpecialFinalizer) |
514 continue; | 506 continue; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 // any Eface described by this bit vector. | 787 // any Eface described by this bit vector. |
796 static void | 788 static void |
797 dumpbvtypes(BitVector *bv, byte *base) | 789 dumpbvtypes(BitVector *bv, byte *base) |
798 { | 790 { |
799 uintptr i; | 791 uintptr i; |
800 | 792 |
801 for(i = 0; i < bv->n; i += BitsPerPointer) { | 793 for(i = 0; i < bv->n; i += BitsPerPointer) { |
802 if((bv->data[i/32] >> i%32 & 3) != BitsMultiWord) | 794 if((bv->data[i/32] >> i%32 & 3) != BitsMultiWord) |
803 continue; | 795 continue; |
804 switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32
& 3) { | 796 switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32
& 3) { |
805 » » case BitsString: | 797 » » default: |
| 798 » » » runtime·throw("unexpected garbage collection bits"); |
806 case BitsIface: | 799 case BitsIface: |
807 i += BitsPerPointer; | 800 i += BitsPerPointer; |
808 break; | |
809 case BitsSlice: | |
810 i += 2 * BitsPerPointer; | |
811 break; | 801 break; |
812 case BitsEface: | 802 case BitsEface: |
813 dumptype(*(Type**)(base + i / BitsPerPointer * PtrSize))
; | 803 dumptype(*(Type**)(base + i / BitsPerPointer * PtrSize))
; |
814 i += BitsPerPointer; | 804 i += BitsPerPointer; |
815 break; | 805 break; |
816 } | 806 } |
817 } | 807 } |
818 } | 808 } |
819 | 809 |
820 static BitVector | 810 static BitVector |
(...skipping 22 matching lines...) Expand all Loading... |
843 shift = (off % wordsPerBitmapByte) * gcBits; | 833 shift = (off % wordsPerBitmapByte) * gcBits; |
844 bits = (*bitp >> (shift + 2)) & BitsMask; | 834 bits = (*bitp >> (shift + 2)) & BitsMask; |
845 if(!mw && bits == BitsDead) | 835 if(!mw && bits == BitsDead) |
846 break; // end of heap object | 836 break; // end of heap object |
847 mw = !mw && bits == BitsMultiWord; | 837 mw = !mw && bits == BitsMultiWord; |
848 tmpbuf[i*BitsPerPointer/8] &= ~(BitsMask<<((i*BitsPerPointer)%8)
); | 838 tmpbuf[i*BitsPerPointer/8] &= ~(BitsMask<<((i*BitsPerPointer)%8)
); |
849 tmpbuf[i*BitsPerPointer/8] |= bits<<((i*BitsPerPointer)%8); | 839 tmpbuf[i*BitsPerPointer/8] |= bits<<((i*BitsPerPointer)%8); |
850 } | 840 } |
851 return (BitVector){i*BitsPerPointer, (uint32*)tmpbuf}; | 841 return (BitVector){i*BitsPerPointer, (uint32*)tmpbuf}; |
852 } | 842 } |
LEFT | RIGHT |