if first function in file was dead code, it was being
discarded along with the file name information for that file.
leave the functions in the master function list longer:
let xfol take the dead code out of the code list,
and let span skip the unreachable functions during output.
before
throw: sys·mapaccess1: key not in map
panic PC=0x2e7b20
throw+0x33 /Users/rsc/go/src/pkg/runtime/runtime.c:65
throw(0x5834f, 0x0)
sys·mapaccess1+0x73 /Users/rsc/go/src/pkg/runtime/hashmap.c:769
sys·mapaccess1(0x2b9bd0, 0x0)
gob·*Encoder·Encode+0x16b /Users/rsc/go/src/pkg/fmt/print.go:2926
gob·*Encoder·Encode(0x2bb440, 0x0, 0x558b0, 0x0, 0x2e4be0, ...)
main·walk+0x331 :1603
main·walk(0x33a480, 0x0)
main·walk+0x271 :1596
main·walk(0x300640, 0x0)
main·walk+0x271 :1596
main·walk(0x300520, 0x0)
main·walk+0x271 :1596
main·walk(0x300240, 0x0)
main·walk+0x271 :1596
main·walk(0x678f8, 0x0)
main·main+0x22 :1610
main·main()
after
throw: sys·mapaccess1: key not in map
panic PC=0x2e7b20
throw+0x33 /Users/rsc/go/src/pkg/runtime/runtime.c:65
throw(0x5834f, 0x0)
sys·mapaccess1+0x73 /Users/rsc/go/src/pkg/runtime/hashmap.c:769
sys·mapaccess1(0x2b9bd0, 0x0)
gob·*Encoder·Encode+0x16b /Users/rsc/go/src/pkg/gob/encoder.go:319
gob·*Encoder·Encode(0x2bb3c0, 0x0, 0x558b0, 0x0, 0x2e4be0, ...)
main·walk+0x331 /Users/rsc/dir.go:121
main·walk(0x2f6ab0, 0x0)
main·walk+0x271 /Users/rsc/dir.go:114
main·walk(0x301640, 0x0)
main·walk+0x271 /Users/rsc/dir.go:114
main·walk(0x301520, 0x0)
main·walk+0x271 /Users/rsc/dir.go:114
main·walk(0x301240, 0x0)
main·walk+0x271 /Users/rsc/dir.go:114
main·walk(0x678f8, 0x0)
main·main+0x22 /Users/rsc/dir.go:128
main·main()
mainstart+0xe /Users/rsc/go/src/pkg/runtime/amd64/asm.s:55
mainstart()
goexit /Users/rsc/go/src/pkg/runtime/proc.c:133
goexit()
R=r
DELTA=46 (20 added, 25 deleted, 1 changed)
OCL=34094
CL=34103
if(a->type == D_FILE1)
putsymb(a->asym->name, 'Z', a->aoffset, 0);
+ if(!s->reachable)
+ continue;
+
if(s->type == STEXT)
putsymb(s->name, 'T', s->value, s->version);
else
a = p->as;
if(a == ATEXT)
curtext = p;
+ if(!curtext->from.sym->reachable) {
+ p = p->cond;
+ goto loop;
+ }
if(a == AB) {
q = p->cond;
if(q != P) {
return;
if(p->as == ATEXT)
curtext = p;
+ if(!curtext->from.sym->reachable) {
+ p = p->pcond;
+ goto loop;
+ }
if(p->as == AJMP)
if((q = p->pcond) != P && q->as != ATEXT) {
p->mark = 1;
for(p = textp; p != P; p = p->pcond) {
s = p->from.sym;
+ if(s->type != STEXT)
+ continue;
/* filenames first */
for(a=p->to.autom; a; a=a->link)
if(a->type == D_FILE1)
putsymb(a->asym->name, 'Z', a->aoffset, 0, 0);
- if(s->type != STEXT)
+ if(!s->reachable)
continue;
putsymb(s->name, 'T', s->value, s->version, s->gotype);
return;
if(p->as == ATEXT)
curtext = p;
+ if(!curtext->from.sym->reachable) {
+ p = p->pcond;
+ goto loop;
+ }
if(p->as == AJMP)
if((q = p->pcond) != P && q->as != ATEXT) {
p->mark = 1;
if(a->type == D_FILE1)
putsymb(a->asym->name, 'Z', a->aoffset, 0, 0);
+ if(!s->reachable)
+ continue;
+
putsymb(s->name, 'T', s->value, s->version, s->gotype);
/* frame, auto and param after */
case ADATA:
case AGLOBL:
reachable = p->from.sym->reachable;
- if(!reachable) {
- if(debug['v'] > 1)
- Bprint(&bso, "discard %s\n", p->from.sym->name);
- p->from.sym->type = Sxxx;
- break;
- }
- if(p->as == ATEXT) {
- // keeping this function; link into textp list
- if(etextp == P)
- textp = p;
- else
- etextp->pcond = p;
- etextp = p;
- etextp->pcond = P;
- }
- break;
}
if(reachable) {
if(q == P)
for(i=0; i<nelem(morename); i++)
mark(lookup(morename[i], 0));
- // remove dead code.
- // sweeplist will rebuild the list of functions at textp
- textp = P;
- etextp = P;
-
- // follow is going to redo the firstp, lastp list
- // but update it anyway just to keep things consistent.
- sweeplist(&firstp, &lastp);
-
// remove dead data
sweeplist(&datap, &edatap);
}