1*37da2899SCharles.Forsythimplement Profile; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsythinclude "draw.m"; 6*37da2899SCharles.Forsythinclude "bufio.m"; 7*37da2899SCharles.Forsyth bufio: Bufio; 8*37da2899SCharles.Forsyth Iobuf: import bufio; 9*37da2899SCharles.Forsythinclude "workdir.m"; 10*37da2899SCharles.Forsyth workdir: Workdir; 11*37da2899SCharles.Forsythinclude "debug.m"; 12*37da2899SCharles.Forsyth debug: Debug; 13*37da2899SCharles.Forsyth Sym: import debug; 14*37da2899SCharles.Forsythinclude "dis.m"; 15*37da2899SCharles.Forsyth dism: Dis; 16*37da2899SCharles.Forsythinclude "profile.m"; 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth# merge common code 19*37da2899SCharles.Forsyth 20*37da2899SCharles.ForsythPROF: con "/prof"; 21*37da2899SCharles.ForsythCTL: con "ctl"; 22*37da2899SCharles.ForsythNAME: con "name"; 23*37da2899SCharles.ForsythMPATH: con "path"; 24*37da2899SCharles.ForsythHISTOGRAM: con "histogram"; 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsythinited: int; 27*37da2899SCharles.Forsythmodl: string; 28*37da2899SCharles.Forsythlasterr: string; 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsythbspath := array[] of 31*37da2899SCharles.Forsyth{ 32*37da2899SCharles.Forsyth ("/dis/", "/appl/cmd/"), 33*37da2899SCharles.Forsyth ("/dis/", "/appl/"), 34*37da2899SCharles.Forsyth}; 35*37da2899SCharles.Forsyth 36*37da2899SCharles.Forsytherror(s: string) 37*37da2899SCharles.Forsyth{ 38*37da2899SCharles.Forsyth lasterr = sys->sprint("%s: %r", s); 39*37da2899SCharles.Forsyth} 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsytherror0(s: string) 42*37da2899SCharles.Forsyth{ 43*37da2899SCharles.Forsyth lasterr = s; 44*37da2899SCharles.Forsyth} 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsythcleare() 47*37da2899SCharles.Forsyth{ 48*37da2899SCharles.Forsyth lasterr = nil; 49*37da2899SCharles.Forsyth} 50*37da2899SCharles.Forsyth 51*37da2899SCharles.Forsythlasterror(): string 52*37da2899SCharles.Forsyth{ 53*37da2899SCharles.Forsyth return lasterr; 54*37da2899SCharles.Forsyth} 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsythinit(): int 57*37da2899SCharles.Forsyth{ 58*37da2899SCharles.Forsyth cleare(); 59*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 60*37da2899SCharles.Forsyth bufio = load Bufio Bufio->PATH; 61*37da2899SCharles.Forsyth debug = load Debug Debug->PATH; 62*37da2899SCharles.Forsyth if(debug == nil){ 63*37da2899SCharles.Forsyth error("cannot load Debug module"); 64*37da2899SCharles.Forsyth return -1; 65*37da2899SCharles.Forsyth } 66*37da2899SCharles.Forsyth debug->init(); 67*37da2899SCharles.Forsyth (ok, nil) := sys->stat(PROF + "/ctl"); 68*37da2899SCharles.Forsyth if (ok == -1) { 69*37da2899SCharles.Forsyth if(sys->bind("#P", PROF, Sys->MREPL|Sys->MCREATE) < 0){ 70*37da2899SCharles.Forsyth error(sys->sprint("cannot bind prof device to /prof")); 71*37da2899SCharles.Forsyth return -1; 72*37da2899SCharles.Forsyth } 73*37da2899SCharles.Forsyth } 74*37da2899SCharles.Forsyth inited = 1; 75*37da2899SCharles.Forsyth return 0; 76*37da2899SCharles.Forsyth} 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsythend(): int 79*37da2899SCharles.Forsyth{ 80*37da2899SCharles.Forsyth cleare(); 81*37da2899SCharles.Forsyth inited = 0; 82*37da2899SCharles.Forsyth modl = nil; 83*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "end") < 0) 84*37da2899SCharles.Forsyth return -1; 85*37da2899SCharles.Forsyth return 0; 86*37da2899SCharles.Forsyth} 87*37da2899SCharles.Forsyth 88*37da2899SCharles.Forsythstart(): int 89*37da2899SCharles.Forsyth{ 90*37da2899SCharles.Forsyth cleare(); 91*37da2899SCharles.Forsyth if(!inited && init() < 0) 92*37da2899SCharles.Forsyth return -1; 93*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "module " + modl) < 0) 94*37da2899SCharles.Forsyth return -1; 95*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "start") < 0) 96*37da2899SCharles.Forsyth return -1; 97*37da2899SCharles.Forsyth return 0; 98*37da2899SCharles.Forsyth} 99*37da2899SCharles.Forsyth 100*37da2899SCharles.Forsythcpstart(pid: int): int 101*37da2899SCharles.Forsyth{ 102*37da2899SCharles.Forsyth cleare(); 103*37da2899SCharles.Forsyth if(!inited && init() < 0) 104*37da2899SCharles.Forsyth return -1; 105*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "module " + modl) < 0) 106*37da2899SCharles.Forsyth return -1; 107*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "startcp " + string pid) < 0) 108*37da2899SCharles.Forsyth return -1; 109*37da2899SCharles.Forsyth return 0; 110*37da2899SCharles.Forsyth} 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsythmemstart(m: int): int 113*37da2899SCharles.Forsyth{ 114*37da2899SCharles.Forsyth cleare(); 115*37da2899SCharles.Forsyth if(!inited && init() < 0) 116*37da2899SCharles.Forsyth return -1; 117*37da2899SCharles.Forsyth if(modl != nil && write(mkpath(PROF, CTL), "module " + modl) < 0) 118*37da2899SCharles.Forsyth return -1; 119*37da2899SCharles.Forsyth start := "startmp"; 120*37da2899SCharles.Forsyth if(m == 0) 121*37da2899SCharles.Forsyth m = MAIN|HEAP|IMAGE; 122*37da2899SCharles.Forsyth if(m&MAIN) 123*37da2899SCharles.Forsyth start += "1"; 124*37da2899SCharles.Forsyth if(m&HEAP) 125*37da2899SCharles.Forsyth start += "2"; 126*37da2899SCharles.Forsyth if(m&IMAGE) 127*37da2899SCharles.Forsyth start += "3"; 128*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), start) < 0) 129*37da2899SCharles.Forsyth return -1; 130*37da2899SCharles.Forsyth return 0; 131*37da2899SCharles.Forsyth} 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsythstop(): int 134*37da2899SCharles.Forsyth{ 135*37da2899SCharles.Forsyth cleare(); 136*37da2899SCharles.Forsyth if(!inited && init() < 0) 137*37da2899SCharles.Forsyth return -1; 138*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "stop") < 0) 139*37da2899SCharles.Forsyth return -1; 140*37da2899SCharles.Forsyth return 0; 141*37da2899SCharles.Forsyth} 142*37da2899SCharles.Forsyth 143*37da2899SCharles.Forsythsample(i: int): int 144*37da2899SCharles.Forsyth{ 145*37da2899SCharles.Forsyth cleare(); 146*37da2899SCharles.Forsyth if(i <= 0){ 147*37da2899SCharles.Forsyth error0(sys->sprint("bad sample rate %d", i)); 148*37da2899SCharles.Forsyth return -1; 149*37da2899SCharles.Forsyth } 150*37da2899SCharles.Forsyth if(write(mkpath(PROF, CTL), "interval " + string i) < 0) 151*37da2899SCharles.Forsyth return -1; 152*37da2899SCharles.Forsyth return 0; 153*37da2899SCharles.Forsyth} 154*37da2899SCharles.Forsyth 155*37da2899SCharles.Forsythprofile(m: string): int 156*37da2899SCharles.Forsyth{ 157*37da2899SCharles.Forsyth cleare(); 158*37da2899SCharles.Forsyth modl = m + " " + modl; 159*37da2899SCharles.Forsyth return 0; 160*37da2899SCharles.Forsyth} 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsythstats(): Prof 163*37da2899SCharles.Forsyth{ 164*37da2899SCharles.Forsyth mp: Modprof; 165*37da2899SCharles.Forsyth p: Prof; 166*37da2899SCharles.Forsyth mpl: list of Modprof; 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth cleare(); 169*37da2899SCharles.Forsyth fd := sys->open(PROF, Sys->OREAD); 170*37da2899SCharles.Forsyth if(fd == nil){ 171*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", PROF)); 172*37da2899SCharles.Forsyth return (nil, 0, nil); 173*37da2899SCharles.Forsyth } 174*37da2899SCharles.Forsyth total := 0; 175*37da2899SCharles.Forsyth for(;;){ 176*37da2899SCharles.Forsyth (nr, d) := sys->dirread(fd); 177*37da2899SCharles.Forsyth if(nr <= 0) 178*37da2899SCharles.Forsyth break; 179*37da2899SCharles.Forsyth for(i := 0; i < nr; i++){ 180*37da2899SCharles.Forsyth if(d[i].name == CTL) 181*37da2899SCharles.Forsyth continue; 182*37da2899SCharles.Forsyth dn := mkpath(PROF, d[i].name); 183*37da2899SCharles.Forsyth mp.name = read(mkpath(dn, NAME)); 184*37da2899SCharles.Forsyth mp.path = read(mkpath(dn, MPATH)); 185*37da2899SCharles.Forsyth fdh := sys->open(mkpath(dn, HISTOGRAM), Sys->OREAD); 186*37da2899SCharles.Forsyth if(fdh == nil) 187*37da2899SCharles.Forsyth continue; 188*37da2899SCharles.Forsyth (mp.srcpath, mp.linetab, mp.funtab, mp.total) = tprofile(fdh, mp.path); 189*37da2899SCharles.Forsyth if((sp := getb(mp.path)) != nil) 190*37da2899SCharles.Forsyth mp.srcpath = sp; 191*37da2899SCharles.Forsyth if(mp.total != 0){ 192*37da2899SCharles.Forsyth mpl = mp :: mpl; 193*37da2899SCharles.Forsyth total += mp.total; 194*37da2899SCharles.Forsyth } 195*37da2899SCharles.Forsyth } 196*37da2899SCharles.Forsyth } 197*37da2899SCharles.Forsyth p.mods = mpl; 198*37da2899SCharles.Forsyth p.total = total; 199*37da2899SCharles.Forsyth return p; 200*37da2899SCharles.Forsyth} 201*37da2899SCharles.Forsyth 202*37da2899SCharles.Forsythcpstats(rec: int, v: int): Prof 203*37da2899SCharles.Forsyth{ 204*37da2899SCharles.Forsyth m: string; 205*37da2899SCharles.Forsyth mp: Modprof; 206*37da2899SCharles.Forsyth p: Prof; 207*37da2899SCharles.Forsyth mpl: list of Modprof; 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsyth cleare(); 210*37da2899SCharles.Forsyth fd := sys->open(PROF, Sys->OREAD); 211*37da2899SCharles.Forsyth if(fd == nil){ 212*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", PROF)); 213*37da2899SCharles.Forsyth return (nil, 0, nil); 214*37da2899SCharles.Forsyth } 215*37da2899SCharles.Forsyth total := 0; 216*37da2899SCharles.Forsyth for(;;){ 217*37da2899SCharles.Forsyth (nr, d) := sys->dirread(fd); 218*37da2899SCharles.Forsyth if(nr <= 0) 219*37da2899SCharles.Forsyth break; 220*37da2899SCharles.Forsyth for(i:=0; i<nr; i++){ 221*37da2899SCharles.Forsyth if(d[i].name == CTL) 222*37da2899SCharles.Forsyth continue; 223*37da2899SCharles.Forsyth dn := mkpath(PROF, d[i].name); 224*37da2899SCharles.Forsyth mp.name = read(mkpath(dn, NAME)); 225*37da2899SCharles.Forsyth mp.path = read(mkpath(dn, MPATH)); 226*37da2899SCharles.Forsyth fdh := sys->open(mkpath(dn, HISTOGRAM), Sys->OREAD); 227*37da2899SCharles.Forsyth if(fdh == nil) 228*37da2899SCharles.Forsyth continue; 229*37da2899SCharles.Forsyth (m, mp.srcpath, mp.rawtab, mp.linetab, mp.rngtab, mp.total, mp.coverage) = cprofile(fdh, mp.path, rec, v); 230*37da2899SCharles.Forsyth if(mp.name == nil) 231*37da2899SCharles.Forsyth mp.name = m; 232*37da2899SCharles.Forsyth if((sp := getb(mp.path)) != nil) 233*37da2899SCharles.Forsyth mp.srcpath = sp; 234*37da2899SCharles.Forsyth if(len mp.rawtab > 0){ 235*37da2899SCharles.Forsyth mpl = mp :: mpl; 236*37da2899SCharles.Forsyth total += mp.total; 237*37da2899SCharles.Forsyth } 238*37da2899SCharles.Forsyth } 239*37da2899SCharles.Forsyth } 240*37da2899SCharles.Forsyth p.mods = mpl; 241*37da2899SCharles.Forsyth p.total = total; 242*37da2899SCharles.Forsyth return p; 243*37da2899SCharles.Forsyth} 244*37da2899SCharles.Forsyth 245*37da2899SCharles.Forsythcpfstats(v: int): Prof 246*37da2899SCharles.Forsyth{ 247*37da2899SCharles.Forsyth mp: Modprof; 248*37da2899SCharles.Forsyth p: Prof; 249*37da2899SCharles.Forsyth mpl: list of Modprof; 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth cleare(); 252*37da2899SCharles.Forsyth total := 0; 253*37da2899SCharles.Forsyth (nil, l) := sys->tokenize(modl, " "); 254*37da2899SCharles.Forsyth for( ; l != nil; l = tl l){ 255*37da2899SCharles.Forsyth s := hd l; 256*37da2899SCharles.Forsyth suf := suff(s); 257*37da2899SCharles.Forsyth if(suf == nil) 258*37da2899SCharles.Forsyth s += ".dis"; 259*37da2899SCharles.Forsyth else 260*37da2899SCharles.Forsyth s = repsuff(s, "."+suf, ".dis"); 261*37da2899SCharles.Forsyth if(!exists(s) && s[0] != '/' && s[0:2] != "./") 262*37da2899SCharles.Forsyth s = "/dis/"+s; 263*37da2899SCharles.Forsyth mp.path = s; 264*37da2899SCharles.Forsyth (mp.name, mp.srcpath, mp.rawtab, mp.linetab, mp.rngtab, mp.total, mp.coverage) = cprofile(nil, mp.path, 1, v); 265*37da2899SCharles.Forsyth if((sp := getb(mp.path)) != nil) 266*37da2899SCharles.Forsyth mp.srcpath = sp; 267*37da2899SCharles.Forsyth if(len mp.rawtab > 0){ 268*37da2899SCharles.Forsyth mpl = mp :: mpl; 269*37da2899SCharles.Forsyth total += mp.total; 270*37da2899SCharles.Forsyth } 271*37da2899SCharles.Forsyth } 272*37da2899SCharles.Forsyth p.mods = mpl; 273*37da2899SCharles.Forsyth p.total = total; 274*37da2899SCharles.Forsyth return p; 275*37da2899SCharles.Forsyth} 276*37da2899SCharles.Forsyth 277*37da2899SCharles.Forsythmemstats(): Prof 278*37da2899SCharles.Forsyth{ 279*37da2899SCharles.Forsyth mp: Modprof; 280*37da2899SCharles.Forsyth p: Prof; 281*37da2899SCharles.Forsyth mpl: list of Modprof; 282*37da2899SCharles.Forsyth 283*37da2899SCharles.Forsyth cleare(); 284*37da2899SCharles.Forsyth fd := sys->open(PROF, Sys->OREAD); 285*37da2899SCharles.Forsyth if(fd == nil){ 286*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", PROF)); 287*37da2899SCharles.Forsyth return (nil, 0, nil); 288*37da2899SCharles.Forsyth } 289*37da2899SCharles.Forsyth total := totale := 0; 290*37da2899SCharles.Forsyth for(;;){ 291*37da2899SCharles.Forsyth (nr, d) := sys->dirread(fd); 292*37da2899SCharles.Forsyth if(nr <= 0) 293*37da2899SCharles.Forsyth break; 294*37da2899SCharles.Forsyth for(i:=0; i<nr; i++){ 295*37da2899SCharles.Forsyth if(d[i].name == CTL) 296*37da2899SCharles.Forsyth continue; 297*37da2899SCharles.Forsyth dn := mkpath(PROF, d[i].name); 298*37da2899SCharles.Forsyth mp.name = read(mkpath(dn, NAME)); 299*37da2899SCharles.Forsyth mp.path = read(mkpath(dn, MPATH)); 300*37da2899SCharles.Forsyth fdh := sys->open(mkpath(dn, HISTOGRAM), Sys->OREAD); 301*37da2899SCharles.Forsyth if(fdh == nil) 302*37da2899SCharles.Forsyth continue; 303*37da2899SCharles.Forsyth mp.totals = array[1] of int; 304*37da2899SCharles.Forsyth (mp.srcpath, mp.linetab, mp.funtab, mp.total, mp.totals[0]) = mprofile(fdh, mp.path); 305*37da2899SCharles.Forsyth if((sp := getb(mp.path)) != nil) 306*37da2899SCharles.Forsyth mp.srcpath = sp; 307*37da2899SCharles.Forsyth if(mp.total != 0 || mp.totals[0] != 0){ 308*37da2899SCharles.Forsyth mpl = mp :: mpl; 309*37da2899SCharles.Forsyth total += mp.total; 310*37da2899SCharles.Forsyth totale += mp.totals[0]; 311*37da2899SCharles.Forsyth } 312*37da2899SCharles.Forsyth } 313*37da2899SCharles.Forsyth } 314*37da2899SCharles.Forsyth p.mods = mpl; 315*37da2899SCharles.Forsyth p.total = total; 316*37da2899SCharles.Forsyth p.totals = array[1] of int; 317*37da2899SCharles.Forsyth p.totals[0] = totale; 318*37da2899SCharles.Forsyth return p; 319*37da2899SCharles.Forsyth} 320*37da2899SCharles.Forsyth 321*37da2899SCharles.Forsythtprofile(fd: ref Sys->FD, dis: string): (string, array of int, array of Funprof, int) 322*37da2899SCharles.Forsyth{ 323*37da2899SCharles.Forsyth sbl := findsbl(dis); 324*37da2899SCharles.Forsyth if(sbl == nil){ 325*37da2899SCharles.Forsyth error0(sys->sprint("cannot locate symbol table file for %s", dis)); 326*37da2899SCharles.Forsyth return (nil, nil, nil, 0); 327*37da2899SCharles.Forsyth } 328*37da2899SCharles.Forsyth (sym, err) := debug->sym(sbl); 329*37da2899SCharles.Forsyth if(sym == nil){ 330*37da2899SCharles.Forsyth error0(sys->sprint("bad symbol table file: %s", err)); 331*37da2899SCharles.Forsyth return (nil, nil, nil, 0); 332*37da2899SCharles.Forsyth } 333*37da2899SCharles.Forsyth nlines := 0; 334*37da2899SCharles.Forsyth nl := len sym.src; 335*37da2899SCharles.Forsyth for(i := 0; i < nl; i++){ 336*37da2899SCharles.Forsyth if((l := sym.src[i].stop.line) > nlines) 337*37da2899SCharles.Forsyth nlines = l; 338*37da2899SCharles.Forsyth } 339*37da2899SCharles.Forsyth name := sym.src[0].start.file; 340*37da2899SCharles.Forsyth line := array[nlines+1] of int; 341*37da2899SCharles.Forsyth for(i = 0; i <= nlines; i++) 342*37da2899SCharles.Forsyth line[i] = 0; 343*37da2899SCharles.Forsyth nf := len sym.fns; 344*37da2899SCharles.Forsyth fun := array[nf] of Funprof; 345*37da2899SCharles.Forsyth for(i = 0; i < nf; i++){ 346*37da2899SCharles.Forsyth fun[i].name = sym.fns[i].name; 347*37da2899SCharles.Forsyth # src seems to be always nil 348*37da2899SCharles.Forsyth # fun[i].file = sym.fns[i].src.start.file; 349*37da2899SCharles.Forsyth # fun[i].line = (sym.fns[i].src.start.line+sym.fns[i].src.stop.line)/2; 350*37da2899SCharles.Forsyth src := sym.pctosrc(sym.fns[i].offset); 351*37da2899SCharles.Forsyth if(src != nil) 352*37da2899SCharles.Forsyth fun[i].line = src.start.line; 353*37da2899SCharles.Forsyth else 354*37da2899SCharles.Forsyth fun[i].line = 0; 355*37da2899SCharles.Forsyth fun[i].count = 0; 356*37da2899SCharles.Forsyth } 357*37da2899SCharles.Forsyth buf := array[32] of byte; 358*37da2899SCharles.Forsyth # pc := 0; 359*37da2899SCharles.Forsyth tot := 0; 360*37da2899SCharles.Forsyth fi := 0; 361*37da2899SCharles.Forsyth# for(i=0; i < nl; i++) sys->print("%d -> %d\n", i, sym.pctosrc(i).start.line); 362*37da2899SCharles.Forsyth while((m := sys->read(fd, buf, len buf)) > 0){ 363*37da2899SCharles.Forsyth (nw, lw) := sys->tokenize(string buf[0:m], " "); 364*37da2899SCharles.Forsyth if(nw != 2){ 365*37da2899SCharles.Forsyth error0("bad histogram data"); 366*37da2899SCharles.Forsyth return (nil, nil, nil, 0); 367*37da2899SCharles.Forsyth } 368*37da2899SCharles.Forsyth pc := int hd lw; 369*37da2899SCharles.Forsyth f := int hd tl lw; 370*37da2899SCharles.Forsyth rpc := pc-1; 371*37da2899SCharles.Forsyth src := sym.pctosrc(rpc); 372*37da2899SCharles.Forsyth if(src == nil) 373*37da2899SCharles.Forsyth continue; 374*37da2899SCharles.Forsyth l1 := src.start.line; 375*37da2899SCharles.Forsyth l2 := src.stop.line; 376*37da2899SCharles.Forsyth if(l1 == 0 || l2 == 0) 377*37da2899SCharles.Forsyth continue; 378*37da2899SCharles.Forsyth if((nl = l2-l1+1) == 1) 379*37da2899SCharles.Forsyth line[l1] += f; 380*37da2899SCharles.Forsyth else{ 381*37da2899SCharles.Forsyth q := f/nl; 382*37da2899SCharles.Forsyth r := f-q*nl; 383*37da2899SCharles.Forsyth for(i = l1; i <= l2; i++) 384*37da2899SCharles.Forsyth line[i] += q+(r-->0); 385*37da2899SCharles.Forsyth } 386*37da2899SCharles.Forsyth if(fi < nf){ 387*37da2899SCharles.Forsyth if(rpc >= sym.fns[fi].offset && rpc < sym.fns[fi].stoppc) 388*37da2899SCharles.Forsyth fun[fi].count += f; 389*37da2899SCharles.Forsyth else{ 390*37da2899SCharles.Forsyth while(fi < nf && rpc >= sym.fns[fi].stoppc) 391*37da2899SCharles.Forsyth fi++; 392*37da2899SCharles.Forsyth # fi++; 393*37da2899SCharles.Forsyth if(fi >= nf && f != 0) 394*37da2899SCharles.Forsyth error0(sys->sprint("bad fn index")); 395*37da2899SCharles.Forsyth if(fi < nf) 396*37da2899SCharles.Forsyth fun[fi].count += f; 397*37da2899SCharles.Forsyth } 398*37da2899SCharles.Forsyth } 399*37da2899SCharles.Forsyth tot += f; 400*37da2899SCharles.Forsyth# sys->print("pc %d count %d l1 %d l2 %d\n", rpc, f, l1, l2); 401*37da2899SCharles.Forsyth } 402*37da2899SCharles.Forsyth return (name, line, fun, tot); 403*37da2899SCharles.Forsyth} 404*37da2899SCharles.Forsyth 405*37da2899SCharles.Forsythcprofile(fd: ref Sys->FD, dis: string, rec: int, v: int): (string, string, array of (int, int), array of int, array of ref Range, int, int) 406*37da2899SCharles.Forsyth{ 407*37da2899SCharles.Forsyth freq := v&FREQUENCY; 408*37da2899SCharles.Forsyth sbl := findsbl(dis); 409*37da2899SCharles.Forsyth if(sbl == nil){ 410*37da2899SCharles.Forsyth error0(sys->sprint("cannot locate symbol table file for %s", dis)); 411*37da2899SCharles.Forsyth return (nil, nil, nil, nil, nil, 0, 0); 412*37da2899SCharles.Forsyth } 413*37da2899SCharles.Forsyth (sym, err) := debug->sym(sbl); 414*37da2899SCharles.Forsyth if(sym == nil){ 415*37da2899SCharles.Forsyth error0(sys->sprint("bad symbol table file: %s", err)); 416*37da2899SCharles.Forsyth return (nil, nil, nil, nil, nil, 0, 0); 417*37da2899SCharles.Forsyth } 418*37da2899SCharles.Forsyth nlines := 0; 419*37da2899SCharles.Forsyth nl := len sym.src; 420*37da2899SCharles.Forsyth for(i := 0; i < nl; i++){ 421*37da2899SCharles.Forsyth if((l := sym.src[i].start.line) > nlines) 422*37da2899SCharles.Forsyth nlines = l; 423*37da2899SCharles.Forsyth if((l = sym.src[i].stop.line) > nlines) 424*37da2899SCharles.Forsyth nlines = l; 425*37da2899SCharles.Forsyth } 426*37da2899SCharles.Forsyth name := sym.src[0].start.file; 427*37da2899SCharles.Forsyth line := array[nlines+1] of int; 428*37da2899SCharles.Forsyth for(i = 0; i <= nlines; i++){ 429*37da2899SCharles.Forsyth if(freq) 430*37da2899SCharles.Forsyth line[i] = -1; 431*37da2899SCharles.Forsyth else 432*37da2899SCharles.Forsyth line[i] = 0; 433*37da2899SCharles.Forsyth } 434*37da2899SCharles.Forsyth rng := array[nlines+1] of ref Range; 435*37da2899SCharles.Forsyth for(i = 0; i < nl; i++) 436*37da2899SCharles.Forsyth cover(i, -1, sym, line, rng, freq); 437*37da2899SCharles.Forsyth buf := array[32] of byte; 438*37da2899SCharles.Forsyth nr := 0; 439*37da2899SCharles.Forsyth r := array[1024] of (int, int); 440*37da2899SCharles.Forsyth while((m := sys->read(fd, buf, len buf)) > 0){ 441*37da2899SCharles.Forsyth (nw, lw) := sys->tokenize(string buf[0:m], " "); 442*37da2899SCharles.Forsyth if(nw != 2){ 443*37da2899SCharles.Forsyth error0("bad histogram data"); 444*37da2899SCharles.Forsyth return (nil, nil, nil, nil, nil, 0, 0); 445*37da2899SCharles.Forsyth } 446*37da2899SCharles.Forsyth (r, nr) = add(r, nr, int hd lw, int hd tl lw); 447*37da2899SCharles.Forsyth } 448*37da2899SCharles.Forsyth r = clip(r, nr); 449*37da2899SCharles.Forsyth if(rec){ 450*37da2899SCharles.Forsyth wt := nr > 0; 451*37da2899SCharles.Forsyth prf := repsuff(sbl, ".sbl", ".prf"); 452*37da2899SCharles.Forsyth if(exists(prf)){ 453*37da2899SCharles.Forsyth if(stamp(sbl) > stamp(prf)){ 454*37da2899SCharles.Forsyth error0(sys->sprint("%s later than %s", sbl, prf)); 455*37da2899SCharles.Forsyth return (nil, nil, nil, nil, nil, 0, 0); 456*37da2899SCharles.Forsyth } 457*37da2899SCharles.Forsyth r = mergeprof(r, readprof(prf)); 458*37da2899SCharles.Forsyth nr = len r; 459*37da2899SCharles.Forsyth } 460*37da2899SCharles.Forsyth if(wt && writeprof(prf, r) < 0){ 461*37da2899SCharles.Forsyth error0(sys->sprint("cannot write profile file %s", prf)); 462*37da2899SCharles.Forsyth return (nil, nil, nil, nil, nil, 0, 0); 463*37da2899SCharles.Forsyth } 464*37da2899SCharles.Forsyth } 465*37da2899SCharles.Forsyth tot := 0; 466*37da2899SCharles.Forsyth lpc := 0; 467*37da2899SCharles.Forsyth dise := dist := 0; 468*37da2899SCharles.Forsyth for(i = 0; i < nr; i++){ 469*37da2899SCharles.Forsyth (pc, f) := r[i]; 470*37da2899SCharles.Forsyth for( ; lpc < pc; lpc++){ 471*37da2899SCharles.Forsyth cover(lpc, 0, sym, line, rng, freq); 472*37da2899SCharles.Forsyth dist++; 473*37da2899SCharles.Forsyth } 474*37da2899SCharles.Forsyth cover(pc, f, sym, line, rng, freq); 475*37da2899SCharles.Forsyth dist++; 476*37da2899SCharles.Forsyth if(f != 0) 477*37da2899SCharles.Forsyth dise++; 478*37da2899SCharles.Forsyth tot += f; 479*37da2899SCharles.Forsyth lpc = pc+1; 480*37da2899SCharles.Forsyth } 481*37da2899SCharles.Forsyth for( ; lpc < nl; lpc++){ 482*37da2899SCharles.Forsyth cover(lpc, 0, sym, line, rng, freq); 483*37da2899SCharles.Forsyth dist++; 484*37da2899SCharles.Forsyth } 485*37da2899SCharles.Forsyth if(dist == 0) 486*37da2899SCharles.Forsyth dist = 1; 487*37da2899SCharles.Forsyth return (sym.name, name, r, line, rng, tot, (100*dise)/dist); 488*37da2899SCharles.Forsyth} 489*37da2899SCharles.Forsyth 490*37da2899SCharles.Forsythshow(p: Prof, v: int): int 491*37da2899SCharles.Forsyth{ 492*37da2899SCharles.Forsyth i: int; 493*37da2899SCharles.Forsyth 494*37da2899SCharles.Forsyth cleare(); 495*37da2899SCharles.Forsyth tot := p.total; 496*37da2899SCharles.Forsyth if(tot == 0) 497*37da2899SCharles.Forsyth return 0; 498*37da2899SCharles.Forsyth verbose := v&VERBOSE; 499*37da2899SCharles.Forsyth fullhdr := v&FULLHDR; 500*37da2899SCharles.Forsyth for(ml := p.mods; ml != nil; ml = tl ml){ 501*37da2899SCharles.Forsyth mp := hd ml; 502*37da2899SCharles.Forsyth if(mp.total == 0) 503*37da2899SCharles.Forsyth continue; 504*37da2899SCharles.Forsyth if((b := getb(mp.path)) == nil) 505*37da2899SCharles.Forsyth continue; 506*37da2899SCharles.Forsyth sys->print("\nModule: %s(%s)\n\n", mp.name, mp.path); 507*37da2899SCharles.Forsyth line := mp.linetab; 508*37da2899SCharles.Forsyth if(v&FUNCTION){ 509*37da2899SCharles.Forsyth fun := mp.funtab; 510*37da2899SCharles.Forsyth nf := len fun; 511*37da2899SCharles.Forsyth for(i = 0; i < nf; i++) 512*37da2899SCharles.Forsyth if(verbose || fun[i].count != 0){ 513*37da2899SCharles.Forsyth if(fullhdr) 514*37da2899SCharles.Forsyth sys->print("%s:", b); 515*37da2899SCharles.Forsyth sys->print("%d\t%.2f\t%s()\n", fun[i].line, 100.0*(real fun[i].count)/(real tot), fun[i].name); 516*37da2899SCharles.Forsyth } 517*37da2899SCharles.Forsyth sys->print("\n**** module sampling points %d ****\n\n", mp.total); 518*37da2899SCharles.Forsyth if(v&LINE) 519*37da2899SCharles.Forsyth sys->print("\n"); 520*37da2899SCharles.Forsyth } 521*37da2899SCharles.Forsyth if(v&LINE){ 522*37da2899SCharles.Forsyth bio := bufio->open(b, Bufio->OREAD); 523*37da2899SCharles.Forsyth if(bio == nil){ 524*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", b)); 525*37da2899SCharles.Forsyth continue; 526*37da2899SCharles.Forsyth } 527*37da2899SCharles.Forsyth i = 1; 528*37da2899SCharles.Forsyth ll := len line; 529*37da2899SCharles.Forsyth while((s := bio.gets('\n')) != nil){ 530*37da2899SCharles.Forsyth f := 0; 531*37da2899SCharles.Forsyth if(i < ll) 532*37da2899SCharles.Forsyth f = line[i]; 533*37da2899SCharles.Forsyth if(verbose || f != 0){ 534*37da2899SCharles.Forsyth if(fullhdr) 535*37da2899SCharles.Forsyth sys->print("%s:", b); 536*37da2899SCharles.Forsyth sys->print("%d\t%.2f\t%s", i, 100.0*(real f)/(real tot), s); 537*37da2899SCharles.Forsyth } 538*37da2899SCharles.Forsyth i++; 539*37da2899SCharles.Forsyth } 540*37da2899SCharles.Forsyth sys->print("\n**** module sampling points %d ****\n\n", mp.total); 541*37da2899SCharles.Forsyth } 542*37da2899SCharles.Forsyth } 543*37da2899SCharles.Forsyth if(p.mods != nil && tl p.mods != nil) 544*37da2899SCharles.Forsyth sys->print("\n**** total sampling points %d ****\n\n", p.total); 545*37da2899SCharles.Forsyth return 0; 546*37da2899SCharles.Forsyth} 547*37da2899SCharles.Forsyth 548*37da2899SCharles.Forsythcpshow(p: Prof, v: int): int 549*37da2899SCharles.Forsyth{ 550*37da2899SCharles.Forsyth i: int; 551*37da2899SCharles.Forsyth 552*37da2899SCharles.Forsyth cleare(); 553*37da2899SCharles.Forsyth tot := p.total; 554*37da2899SCharles.Forsyth fullhdr := v&FULLHDR; 555*37da2899SCharles.Forsyth freq := v&FREQUENCY; 556*37da2899SCharles.Forsyth for(ml := p.mods; ml != nil; ml = tl ml){ 557*37da2899SCharles.Forsyth mp := hd ml; 558*37da2899SCharles.Forsyth if((b := getb(mp.path)) == nil) 559*37da2899SCharles.Forsyth continue; 560*37da2899SCharles.Forsyth sys->print("\nModule: %s(%s)", mp.name, mp.path); 561*37da2899SCharles.Forsyth sys->print("\t%d%% coverage\n\n", mp.coverage); 562*37da2899SCharles.Forsyth if(mp.coverage == 100 && !freq) 563*37da2899SCharles.Forsyth continue; 564*37da2899SCharles.Forsyth line := mp.linetab; 565*37da2899SCharles.Forsyth rng := mp.rngtab; 566*37da2899SCharles.Forsyth bio := bufio->open(b, Bufio->OREAD); 567*37da2899SCharles.Forsyth if(bio == nil){ 568*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", b)); 569*37da2899SCharles.Forsyth continue; 570*37da2899SCharles.Forsyth } 571*37da2899SCharles.Forsyth i = 1; 572*37da2899SCharles.Forsyth ll := len line; 573*37da2899SCharles.Forsyth while((s := bio.gets('\n')) != nil){ 574*37da2899SCharles.Forsyth f := 0; 575*37da2899SCharles.Forsyth if(i < ll) 576*37da2899SCharles.Forsyth f = line[i]; 577*37da2899SCharles.Forsyth if(fullhdr) 578*37da2899SCharles.Forsyth sys->print("%s:", b); 579*37da2899SCharles.Forsyth sys->print("%d\t", i); 580*37da2899SCharles.Forsyth if(rng != nil && i < ll && (r := rng[i]) != nil && multirng(r)){ 581*37da2899SCharles.Forsyth for( ; r != nil; r = r.n){ 582*37da2899SCharles.Forsyth sys->print("%s", trans(r.f, freq)); 583*37da2899SCharles.Forsyth if(r.n != nil) 584*37da2899SCharles.Forsyth sys->print("|"); 585*37da2899SCharles.Forsyth } 586*37da2899SCharles.Forsyth } 587*37da2899SCharles.Forsyth else 588*37da2899SCharles.Forsyth sys->print("%s", trans(f, freq)); 589*37da2899SCharles.Forsyth sys->print("\t%s", s); 590*37da2899SCharles.Forsyth i++; 591*37da2899SCharles.Forsyth } 592*37da2899SCharles.Forsyth sys->print("\n**** module dis instructions %d ****\n\n", mp.total); 593*37da2899SCharles.Forsyth } 594*37da2899SCharles.Forsyth if(p.mods != nil && tl p.mods != nil) 595*37da2899SCharles.Forsyth sys->print("\n**** total number dis instructions %d ****\n\n", p.total); 596*37da2899SCharles.Forsyth return 0; 597*37da2899SCharles.Forsyth} 598*37da2899SCharles.Forsyth 599*37da2899SCharles.Forsythcoverage(p: Prof, v: int): Coverage 600*37da2899SCharles.Forsyth{ 601*37da2899SCharles.Forsyth i: int; 602*37da2899SCharles.Forsyth clist: Coverage; 603*37da2899SCharles.Forsyth 604*37da2899SCharles.Forsyth cleare(); 605*37da2899SCharles.Forsyth freq := v&FREQUENCY; 606*37da2899SCharles.Forsyth for(ml := p.mods; ml != nil; ml = tl ml){ 607*37da2899SCharles.Forsyth mp := hd ml; 608*37da2899SCharles.Forsyth if((b := getb(mp.path)) == nil) 609*37da2899SCharles.Forsyth continue; 610*37da2899SCharles.Forsyth line := mp.linetab; 611*37da2899SCharles.Forsyth rng := mp.rngtab; 612*37da2899SCharles.Forsyth bio := bufio->open(b, Bufio->OREAD); 613*37da2899SCharles.Forsyth if(bio == nil){ 614*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", b)); 615*37da2899SCharles.Forsyth continue; 616*37da2899SCharles.Forsyth } 617*37da2899SCharles.Forsyth i = 1; 618*37da2899SCharles.Forsyth ll := len line; 619*37da2899SCharles.Forsyth llist: list of (list of (int, int, int), string); 620*37da2899SCharles.Forsyth while((s := bio.gets('\n')) != nil){ 621*37da2899SCharles.Forsyth f := 0; 622*37da2899SCharles.Forsyth if(i < ll) 623*37da2899SCharles.Forsyth f = line[i]; 624*37da2899SCharles.Forsyth rlist: list of (int, int, int); 625*37da2899SCharles.Forsyth if(rng != nil && i < ll && (r := rng[i]) != nil){ 626*37da2899SCharles.Forsyth for( ; r != nil; r = r.n){ 627*37da2899SCharles.Forsyth if(r.u == ∞) 628*37da2899SCharles.Forsyth r.u = len s - 1; 629*37da2899SCharles.Forsyth if(freq){ 630*37da2899SCharles.Forsyth if(r.f > 0) 631*37da2899SCharles.Forsyth rlist = (r.l, r.u, r.f) :: rlist; 632*37da2899SCharles.Forsyth } 633*37da2899SCharles.Forsyth else{ 634*37da2899SCharles.Forsyth if(r.f&NEX) 635*37da2899SCharles.Forsyth rlist = (r.l, r.u, (r.f&EXE)==EXE) :: rlist; 636*37da2899SCharles.Forsyth } 637*37da2899SCharles.Forsyth } 638*37da2899SCharles.Forsyth } 639*37da2899SCharles.Forsyth else{ 640*37da2899SCharles.Forsyth if(freq){ 641*37da2899SCharles.Forsyth if(f > 0) 642*37da2899SCharles.Forsyth rlist = (0, len s - 1, f) :: rlist; 643*37da2899SCharles.Forsyth } 644*37da2899SCharles.Forsyth else{ 645*37da2899SCharles.Forsyth if(f&NEX) 646*37da2899SCharles.Forsyth rlist = (0, len s - 1, (f&EXE)==EXE) :: nil; 647*37da2899SCharles.Forsyth } 648*37da2899SCharles.Forsyth } 649*37da2899SCharles.Forsyth llist = (rlist, s) :: llist; 650*37da2899SCharles.Forsyth i++; 651*37da2899SCharles.Forsyth } 652*37da2899SCharles.Forsyth if(freq) 653*37da2899SCharles.Forsyth n := mp.total; 654*37da2899SCharles.Forsyth else 655*37da2899SCharles.Forsyth n = mp.coverage; 656*37da2899SCharles.Forsyth clist = (b, n, rev(llist)) :: clist; 657*37da2899SCharles.Forsyth } 658*37da2899SCharles.Forsyth return clist; 659*37da2899SCharles.Forsyth} 660*37da2899SCharles.Forsyth 661*37da2899SCharles.Forsyth∞: con 1<<30; 662*37da2899SCharles.Forsyth 663*37da2899SCharles.ForsythDIS: con 1; 664*37da2899SCharles.ForsythEXE: con 2; 665*37da2899SCharles.ForsythNEX: con 4; 666*37da2899SCharles.Forsyth 667*37da2899SCharles.Forsythcover(pc: int, f: int, sym: ref Debug->Sym, line: array of int, rng: array of ref Range, freq: int) 668*37da2899SCharles.Forsyth{ 669*37da2899SCharles.Forsyth v: int; 670*37da2899SCharles.Forsyth 671*37da2899SCharles.Forsyth src := sym.pctosrc(pc); 672*37da2899SCharles.Forsyth if(src == nil) 673*37da2899SCharles.Forsyth return; 674*37da2899SCharles.Forsyth l1 := src.start.line; 675*37da2899SCharles.Forsyth l2 := src.stop.line; 676*37da2899SCharles.Forsyth if(l1 == 0 || l2 == 0) 677*37da2899SCharles.Forsyth return; 678*37da2899SCharles.Forsyth c1 := src.start.pos; 679*37da2899SCharles.Forsyth c2 := src.stop.pos; 680*37da2899SCharles.Forsyth if(freq){ 681*37da2899SCharles.Forsyth v = 0; 682*37da2899SCharles.Forsyth if(f > 0) 683*37da2899SCharles.Forsyth v = f; 684*37da2899SCharles.Forsyth } 685*37da2899SCharles.Forsyth else{ 686*37da2899SCharles.Forsyth v = DIS; 687*37da2899SCharles.Forsyth if(f > 0) 688*37da2899SCharles.Forsyth v = EXE; 689*37da2899SCharles.Forsyth else if(f == 0) 690*37da2899SCharles.Forsyth v = NEX; 691*37da2899SCharles.Forsyth } 692*37da2899SCharles.Forsyth for(i := l1; i <= l2; i++){ 693*37da2899SCharles.Forsyth r1 := 0; 694*37da2899SCharles.Forsyth r2 := ∞; 695*37da2899SCharles.Forsyth if(i == l1) 696*37da2899SCharles.Forsyth r1 = c1; 697*37da2899SCharles.Forsyth if(i == l2) 698*37da2899SCharles.Forsyth r2 = c2; 699*37da2899SCharles.Forsyth if(rng != nil) 700*37da2899SCharles.Forsyth rng[i] = mrgrng(addrng(rng[i], r1, r2, v, freq)); 701*37da2899SCharles.Forsyth if(freq){ 702*37da2899SCharles.Forsyth if(v > line[i]) 703*37da2899SCharles.Forsyth line[i] = v; 704*37da2899SCharles.Forsyth } 705*37da2899SCharles.Forsyth else 706*37da2899SCharles.Forsyth line[i] |= v; 707*37da2899SCharles.Forsyth # if(i==123) sys->print("%d %d-%d %d %d\n", i, r1, r2, v, pc); 708*37da2899SCharles.Forsyth } 709*37da2899SCharles.Forsyth} 710*37da2899SCharles.Forsyth 711*37da2899SCharles.Forsytharng(c1: int, c2: int, f: int, tr: ref Range, lr: ref Range, r: ref Range): ref Range 712*37da2899SCharles.Forsyth{ 713*37da2899SCharles.Forsyth nr := ref Range(c1, c2, f, tr); 714*37da2899SCharles.Forsyth if(lr == nil) 715*37da2899SCharles.Forsyth r = nr; 716*37da2899SCharles.Forsyth else 717*37da2899SCharles.Forsyth lr.n = nr; 718*37da2899SCharles.Forsyth return r; 719*37da2899SCharles.Forsyth} 720*37da2899SCharles.Forsyth 721*37da2899SCharles.Forsythaddrng(r: ref Range, c1: int, c2: int, f: int, freq: int): ref Range 722*37da2899SCharles.Forsyth{ 723*37da2899SCharles.Forsyth lr: ref Range; 724*37da2899SCharles.Forsyth 725*37da2899SCharles.Forsyth if(c1 > c2) 726*37da2899SCharles.Forsyth return r; 727*37da2899SCharles.Forsyth for(tr := r; tr != nil; tr = tr.n){ 728*37da2899SCharles.Forsyth r1 := tr.l; 729*37da2899SCharles.Forsyth r2 := tr.u; 730*37da2899SCharles.Forsyth if(c1 < r1){ 731*37da2899SCharles.Forsyth if(c2 < r1) 732*37da2899SCharles.Forsyth return arng(c1, c2, f, tr, lr, r); 733*37da2899SCharles.Forsyth else if(c2 <= r2){ 734*37da2899SCharles.Forsyth r = addrng(r, c1, r1-1, f, freq); 735*37da2899SCharles.Forsyth return addrng(r, r1, c2, f, freq); 736*37da2899SCharles.Forsyth } 737*37da2899SCharles.Forsyth else{ 738*37da2899SCharles.Forsyth r = addrng(r, c1, r1-1, f, freq); 739*37da2899SCharles.Forsyth r = addrng(r, r1, r2, f, freq); 740*37da2899SCharles.Forsyth return addrng(r, r2+1, c2, f, freq); 741*37da2899SCharles.Forsyth } 742*37da2899SCharles.Forsyth } 743*37da2899SCharles.Forsyth else if(c1 <= r2){ 744*37da2899SCharles.Forsyth if(c2 <= r2){ 745*37da2899SCharles.Forsyth v := tr.f; 746*37da2899SCharles.Forsyth tr.l = c1; 747*37da2899SCharles.Forsyth tr.u = c2; 748*37da2899SCharles.Forsyth if(freq){ 749*37da2899SCharles.Forsyth if(f > tr.f) 750*37da2899SCharles.Forsyth tr.f = f; 751*37da2899SCharles.Forsyth } 752*37da2899SCharles.Forsyth else 753*37da2899SCharles.Forsyth tr.f |= f; 754*37da2899SCharles.Forsyth r = addrng(r, r1, c1-1, v, freq); 755*37da2899SCharles.Forsyth return addrng(r, c2+1, r2, v, freq); 756*37da2899SCharles.Forsyth } 757*37da2899SCharles.Forsyth else{ 758*37da2899SCharles.Forsyth r = addrng(r, c1, r2, f, freq); 759*37da2899SCharles.Forsyth return addrng(r, r2+1, c2, f, freq); 760*37da2899SCharles.Forsyth } 761*37da2899SCharles.Forsyth } 762*37da2899SCharles.Forsyth lr = tr; 763*37da2899SCharles.Forsyth } 764*37da2899SCharles.Forsyth return arng(c1, c2, f, nil, lr, r); 765*37da2899SCharles.Forsyth} 766*37da2899SCharles.Forsyth 767*37da2899SCharles.Forsythmrgrng(r: ref Range): ref Range 768*37da2899SCharles.Forsyth{ 769*37da2899SCharles.Forsyth lr: ref Range; 770*37da2899SCharles.Forsyth 771*37da2899SCharles.Forsyth for(tr := r; tr != nil; tr = tr.n){ 772*37da2899SCharles.Forsyth if(lr != nil && lr.u >= tr.l) 773*37da2899SCharles.Forsyth sys->print("ERROR %d %d\n", lr.u, tr.l); 774*37da2899SCharles.Forsyth if(lr != nil && lr.f == tr.f && lr.u+1 == tr.l){ 775*37da2899SCharles.Forsyth lr.u = tr.u; 776*37da2899SCharles.Forsyth lr.n = tr.n; 777*37da2899SCharles.Forsyth } 778*37da2899SCharles.Forsyth else 779*37da2899SCharles.Forsyth lr = tr; 780*37da2899SCharles.Forsyth } 781*37da2899SCharles.Forsyth return r; 782*37da2899SCharles.Forsyth} 783*37da2899SCharles.Forsyth 784*37da2899SCharles.Forsythmultirng(r: ref Range): int 785*37da2899SCharles.Forsyth{ 786*37da2899SCharles.Forsyth f := r.f; 787*37da2899SCharles.Forsyth for(tr := r; tr != nil; tr = tr.n) 788*37da2899SCharles.Forsyth if(tr.f != f) 789*37da2899SCharles.Forsyth return 1; 790*37da2899SCharles.Forsyth return 0; 791*37da2899SCharles.Forsyth} 792*37da2899SCharles.Forsyth 793*37da2899SCharles.Forsythadd(r: array of (int, int), nr: int, pc: int, f: int): (array of (int, int), int) 794*37da2899SCharles.Forsyth{ 795*37da2899SCharles.Forsyth l := len r; 796*37da2899SCharles.Forsyth if(nr == l){ 797*37da2899SCharles.Forsyth s := array[2*l] of (int, int); 798*37da2899SCharles.Forsyth s[0:] = r[0: nr]; 799*37da2899SCharles.Forsyth r = s; 800*37da2899SCharles.Forsyth } 801*37da2899SCharles.Forsyth r[nr++] = (pc, f); 802*37da2899SCharles.Forsyth return (r, nr); 803*37da2899SCharles.Forsyth} 804*37da2899SCharles.Forsyth 805*37da2899SCharles.Forsythclip(r: array of (int, int), nr: int): array of (int, int) 806*37da2899SCharles.Forsyth{ 807*37da2899SCharles.Forsyth l := len r; 808*37da2899SCharles.Forsyth if(nr < l){ 809*37da2899SCharles.Forsyth s := array[nr] of (int, int); 810*37da2899SCharles.Forsyth s[0:] = r[0: nr]; 811*37da2899SCharles.Forsyth r = s; 812*37da2899SCharles.Forsyth } 813*37da2899SCharles.Forsyth return r; 814*37da2899SCharles.Forsyth} 815*37da2899SCharles.Forsyth 816*37da2899SCharles.Forsythreadprof(f: string): array of (int, int) 817*37da2899SCharles.Forsyth{ 818*37da2899SCharles.Forsyth b := bufio->open(f, Bufio->OREAD); 819*37da2899SCharles.Forsyth if(b == nil) 820*37da2899SCharles.Forsyth return nil; 821*37da2899SCharles.Forsyth nr := 0; 822*37da2899SCharles.Forsyth r := array[1024] of (int, int); 823*37da2899SCharles.Forsyth while((buf := b.gets('\n')) != nil){ 824*37da2899SCharles.Forsyth (nw, lw) := sys->tokenize(buf, " "); 825*37da2899SCharles.Forsyth if(nw != 2){ 826*37da2899SCharles.Forsyth error0("bad raw data"); 827*37da2899SCharles.Forsyth return nil; 828*37da2899SCharles.Forsyth } 829*37da2899SCharles.Forsyth (r, nr) = add(r, nr, int hd lw, int hd tl lw); 830*37da2899SCharles.Forsyth } 831*37da2899SCharles.Forsyth r = clip(r, nr); 832*37da2899SCharles.Forsyth return r; 833*37da2899SCharles.Forsyth} 834*37da2899SCharles.Forsyth 835*37da2899SCharles.Forsythmergeprof(r1, r2: array of (int, int)): array of (int, int) 836*37da2899SCharles.Forsyth{ 837*37da2899SCharles.Forsyth nr := 0; 838*37da2899SCharles.Forsyth r := array[1024] of (int, int); 839*37da2899SCharles.Forsyth l1 := len r1; 840*37da2899SCharles.Forsyth l2 := len r2; 841*37da2899SCharles.Forsyth for((i, j) := (0, 0); i < l1 || j < l2; ){ 842*37da2899SCharles.Forsyth if(i < l1) 843*37da2899SCharles.Forsyth (pc1, f1) := r1[i]; 844*37da2899SCharles.Forsyth else 845*37da2899SCharles.Forsyth pc1 = ∞; 846*37da2899SCharles.Forsyth if(j < l2) 847*37da2899SCharles.Forsyth (pc2, f2) := r2[j]; 848*37da2899SCharles.Forsyth else 849*37da2899SCharles.Forsyth pc2 = ∞; 850*37da2899SCharles.Forsyth if(pc1 < pc2){ 851*37da2899SCharles.Forsyth (r, nr) = add(r, nr, pc1, f1); 852*37da2899SCharles.Forsyth i++; 853*37da2899SCharles.Forsyth } 854*37da2899SCharles.Forsyth else if(pc1 > pc2){ 855*37da2899SCharles.Forsyth (r, nr) = add(r, nr, pc2, f2); 856*37da2899SCharles.Forsyth j++; 857*37da2899SCharles.Forsyth } 858*37da2899SCharles.Forsyth else{ 859*37da2899SCharles.Forsyth (r, nr) = add(r, nr, pc1, f1+f2); 860*37da2899SCharles.Forsyth i++; 861*37da2899SCharles.Forsyth j++; 862*37da2899SCharles.Forsyth } 863*37da2899SCharles.Forsyth } 864*37da2899SCharles.Forsyth r = clip(r, nr); 865*37da2899SCharles.Forsyth return r; 866*37da2899SCharles.Forsyth} 867*37da2899SCharles.Forsyth 868*37da2899SCharles.Forsythwriteprof(f: string, r: array of (int, int)): int 869*37da2899SCharles.Forsyth{ 870*37da2899SCharles.Forsyth fd := sys->create(f, Sys->OWRITE, 8r664); 871*37da2899SCharles.Forsyth if(fd == nil) 872*37da2899SCharles.Forsyth return -1; 873*37da2899SCharles.Forsyth l := len r; 874*37da2899SCharles.Forsyth for(i := 0; i < l; i++){ 875*37da2899SCharles.Forsyth (pc, fr) := r[i]; 876*37da2899SCharles.Forsyth sys->fprint(fd, "%d %d\n", pc, fr); 877*37da2899SCharles.Forsyth } 878*37da2899SCharles.Forsyth return 0; 879*37da2899SCharles.Forsyth} 880*37da2899SCharles.Forsyth 881*37da2899SCharles.Forsythtrans(f: int, freq: int): string 882*37da2899SCharles.Forsyth{ 883*37da2899SCharles.Forsyth if(freq) 884*37da2899SCharles.Forsyth return transf(f); 885*37da2899SCharles.Forsyth else 886*37da2899SCharles.Forsyth return transc(f); 887*37da2899SCharles.Forsyth} 888*37da2899SCharles.Forsyth 889*37da2899SCharles.Forsythtransf(f: int): string 890*37da2899SCharles.Forsyth{ 891*37da2899SCharles.Forsyth if(f < 0) 892*37da2899SCharles.Forsyth return " "; 893*37da2899SCharles.Forsyth return string f; 894*37da2899SCharles.Forsyth} 895*37da2899SCharles.Forsyth 896*37da2899SCharles.Forsythtransc(f: int): string 897*37da2899SCharles.Forsyth{ 898*37da2899SCharles.Forsyth c := ""; 899*37da2899SCharles.Forsyth case(f){ 900*37da2899SCharles.Forsyth 0 => c = " "; 901*37da2899SCharles.Forsyth DIS|EXE => c = "+"; 902*37da2899SCharles.Forsyth DIS|NEX => c = "-"; 903*37da2899SCharles.Forsyth DIS|EXE|NEX => c = "?"; 904*37da2899SCharles.Forsyth * => 905*37da2899SCharles.Forsyth error(sys->sprint("bad code %d\n", f)); 906*37da2899SCharles.Forsyth } 907*37da2899SCharles.Forsyth return c; 908*37da2899SCharles.Forsyth} 909*37da2899SCharles.Forsyth 910*37da2899SCharles.Forsythgetb(dis: string): string 911*37da2899SCharles.Forsyth{ 912*37da2899SCharles.Forsyth b := findb(dis); 913*37da2899SCharles.Forsyth if(b == nil){ 914*37da2899SCharles.Forsyth error0(sys->sprint("cannot locate source file for %s\n", dis)); 915*37da2899SCharles.Forsyth return nil; 916*37da2899SCharles.Forsyth } 917*37da2899SCharles.Forsyth if(stamp(b) > stamp(dis)){ 918*37da2899SCharles.Forsyth error0(sys->sprint("%s later than %s", b, dis)); 919*37da2899SCharles.Forsyth return nil; 920*37da2899SCharles.Forsyth } 921*37da2899SCharles.Forsyth return b; 922*37da2899SCharles.Forsyth} 923*37da2899SCharles.Forsyth 924*37da2899SCharles.Forsythmkpath(d: string, f: string): string 925*37da2899SCharles.Forsyth{ 926*37da2899SCharles.Forsyth return d+"/"+f; 927*37da2899SCharles.Forsyth} 928*37da2899SCharles.Forsyth 929*37da2899SCharles.Forsythsuff(s: string): string 930*37da2899SCharles.Forsyth{ 931*37da2899SCharles.Forsyth (n, l) := sys->tokenize(s, "."); 932*37da2899SCharles.Forsyth if(n > 1){ 933*37da2899SCharles.Forsyth while(tl l != nil) 934*37da2899SCharles.Forsyth l = tl l; 935*37da2899SCharles.Forsyth return hd l; 936*37da2899SCharles.Forsyth } 937*37da2899SCharles.Forsyth return nil; 938*37da2899SCharles.Forsyth} 939*37da2899SCharles.Forsyth 940*37da2899SCharles.Forsythrepsuff(s: string, old: string, new: string): string 941*37da2899SCharles.Forsyth{ 942*37da2899SCharles.Forsyth lo := len old; 943*37da2899SCharles.Forsyth ls := len s; 944*37da2899SCharles.Forsyth if(lo <= ls && s[ls-lo:ls] == old) 945*37da2899SCharles.Forsyth return s[0:ls-lo]+new; 946*37da2899SCharles.Forsyth return s; 947*37da2899SCharles.Forsyth} 948*37da2899SCharles.Forsyth 949*37da2899SCharles.Forsythread(f: string): string 950*37da2899SCharles.Forsyth{ 951*37da2899SCharles.Forsyth if((fd := sys->open(f, Sys->OREAD)) == nil){ 952*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", f)); 953*37da2899SCharles.Forsyth return nil; 954*37da2899SCharles.Forsyth } 955*37da2899SCharles.Forsyth buf := array[128] of byte; 956*37da2899SCharles.Forsyth n := sys->read(fd, buf, len buf); 957*37da2899SCharles.Forsyth return string buf[0:n]; 958*37da2899SCharles.Forsyth} 959*37da2899SCharles.Forsyth 960*37da2899SCharles.Forsythwrite(f: string, s: string): int 961*37da2899SCharles.Forsyth{ 962*37da2899SCharles.Forsyth if((fd := sys->open(f, Sys->OWRITE)) == nil){ 963*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for writing", f)); 964*37da2899SCharles.Forsyth return -1; 965*37da2899SCharles.Forsyth } 966*37da2899SCharles.Forsyth b := array of byte s; 967*37da2899SCharles.Forsyth if((n := sys->write(fd, b, len b)) != len b){ 968*37da2899SCharles.Forsyth error(sys->sprint("cannot write %s to file %s", s, f)); 969*37da2899SCharles.Forsyth return -1; 970*37da2899SCharles.Forsyth } 971*37da2899SCharles.Forsyth return 0; 972*37da2899SCharles.Forsyth} 973*37da2899SCharles.Forsyth 974*37da2899SCharles.Forsythexists(f: string): int 975*37da2899SCharles.Forsyth{ 976*37da2899SCharles.Forsyth return sys->open(f, Sys->OREAD) != nil; 977*37da2899SCharles.Forsyth} 978*37da2899SCharles.Forsyth 979*37da2899SCharles.Forsythstamp(f: string): int 980*37da2899SCharles.Forsyth{ 981*37da2899SCharles.Forsyth (ok, d) := sys->stat(f); 982*37da2899SCharles.Forsyth if(ok < 0) 983*37da2899SCharles.Forsyth return 0; 984*37da2899SCharles.Forsyth return d.mtime; 985*37da2899SCharles.Forsyth} 986*37da2899SCharles.Forsyth 987*37da2899SCharles.Forsythfindb(dis: string): string 988*37da2899SCharles.Forsyth{ 989*37da2899SCharles.Forsyth if(dism == nil){ 990*37da2899SCharles.Forsyth dism = load Dis Dis->PATH; 991*37da2899SCharles.Forsyth if(dism != nil) 992*37da2899SCharles.Forsyth dism->init(); 993*37da2899SCharles.Forsyth } 994*37da2899SCharles.Forsyth if(dism != nil && (b := dism->src(dis)) != nil && exists(b)) 995*37da2899SCharles.Forsyth return b; 996*37da2899SCharles.Forsyth return findfile(repsuff(dis, ".dis", ".b")); 997*37da2899SCharles.Forsyth} 998*37da2899SCharles.Forsyth 999*37da2899SCharles.Forsythfindsbl(dis: string): string 1000*37da2899SCharles.Forsyth{ 1001*37da2899SCharles.Forsyth b := findb(dis); 1002*37da2899SCharles.Forsyth if(b != nil){ 1003*37da2899SCharles.Forsyth sbl := repsuff(b, ".b", ".sbl"); 1004*37da2899SCharles.Forsyth if(exists(sbl)) 1005*37da2899SCharles.Forsyth return sbl; 1006*37da2899SCharles.Forsyth return findfile(sbl); 1007*37da2899SCharles.Forsyth } 1008*37da2899SCharles.Forsyth return findfile(repsuff(dis, ".dis", ".sbl")); 1009*37da2899SCharles.Forsyth} 1010*37da2899SCharles.Forsyth 1011*37da2899SCharles.Forsythfindfile(s: string): string 1012*37da2899SCharles.Forsyth{ 1013*37da2899SCharles.Forsyth if(exists(s)) 1014*37da2899SCharles.Forsyth return s; 1015*37da2899SCharles.Forsyth if(s != nil && s[0] != '/'){ 1016*37da2899SCharles.Forsyth if(workdir == nil) 1017*37da2899SCharles.Forsyth workdir = load Workdir Workdir->PATH; 1018*37da2899SCharles.Forsyth if(workdir == nil){ 1019*37da2899SCharles.Forsyth error("cannot load Workdir module"); 1020*37da2899SCharles.Forsyth return nil; 1021*37da2899SCharles.Forsyth } 1022*37da2899SCharles.Forsyth s = workdir->init() + "/" + s; 1023*37da2899SCharles.Forsyth } 1024*37da2899SCharles.Forsyth (d, f) := split(s, '/'); 1025*37da2899SCharles.Forsyth (fp, nil) := split(f, '.'); 1026*37da2899SCharles.Forsyth if(fp != nil) 1027*37da2899SCharles.Forsyth fp = fp[0: len fp - 1]; 1028*37da2899SCharles.Forsyth for(k := 0; k < 2; k++){ 1029*37da2899SCharles.Forsyth if(k == 0) 1030*37da2899SCharles.Forsyth str := s; 1031*37da2899SCharles.Forsyth else 1032*37da2899SCharles.Forsyth str = d; 1033*37da2899SCharles.Forsyth ls := len str; 1034*37da2899SCharles.Forsyth for(i := 0; i < len bspath; i++){ 1035*37da2899SCharles.Forsyth (dis, src) := bspath[i]; 1036*37da2899SCharles.Forsyth ld := len dis; 1037*37da2899SCharles.Forsyth if(ls >= ld && str[:ld] == dis){ 1038*37da2899SCharles.Forsyth if(k == 0) 1039*37da2899SCharles.Forsyth ns := src + str[ld:]; 1040*37da2899SCharles.Forsyth else 1041*37da2899SCharles.Forsyth ns = src + str[ld:] + fp + "/" + f; 1042*37da2899SCharles.Forsyth if(exists(ns)) 1043*37da2899SCharles.Forsyth return ns; 1044*37da2899SCharles.Forsyth } 1045*37da2899SCharles.Forsyth } 1046*37da2899SCharles.Forsyth } 1047*37da2899SCharles.Forsyth return nil; 1048*37da2899SCharles.Forsyth} 1049*37da2899SCharles.Forsyth 1050*37da2899SCharles.Forsythsplit(s: string, c: int): (string, string) 1051*37da2899SCharles.Forsyth{ 1052*37da2899SCharles.Forsyth for(i := len s - 1; i >= 0; --i) 1053*37da2899SCharles.Forsyth if(s[i] == c) 1054*37da2899SCharles.Forsyth break; 1055*37da2899SCharles.Forsyth return (s[0:i+1], s[i+1:]); 1056*37da2899SCharles.Forsyth} 1057*37da2899SCharles.Forsyth 1058*37da2899SCharles.Forsythrev(llist: list of (list of (int, int, int), string)): list of (list of (int, int, int), string) 1059*37da2899SCharles.Forsyth{ 1060*37da2899SCharles.Forsyth r: list of (list of (int, int, int), string); 1061*37da2899SCharles.Forsyth 1062*37da2899SCharles.Forsyth for(l := llist; l != nil; l = tl l) 1063*37da2899SCharles.Forsyth r = hd l :: r; 1064*37da2899SCharles.Forsyth return r; 1065*37da2899SCharles.Forsyth} 1066*37da2899SCharles.Forsyth 1067*37da2899SCharles.Forsythmprofile(fd: ref Sys->FD, dis: string): (string, array of int, array of Funprof, int, int) 1068*37da2899SCharles.Forsyth{ 1069*37da2899SCharles.Forsyth sbl := findsbl(dis); 1070*37da2899SCharles.Forsyth if(sbl == nil){ 1071*37da2899SCharles.Forsyth error0(sys->sprint("cannot locate symbol table file for %s", dis)); 1072*37da2899SCharles.Forsyth return (nil, nil, nil, 0, 0); 1073*37da2899SCharles.Forsyth } 1074*37da2899SCharles.Forsyth (sym, err) := debug->sym(sbl); 1075*37da2899SCharles.Forsyth if(sym == nil){ 1076*37da2899SCharles.Forsyth error0(sys->sprint("bad symbol table file: %s", err)); 1077*37da2899SCharles.Forsyth return (nil, nil, nil, 0, 0); 1078*37da2899SCharles.Forsyth } 1079*37da2899SCharles.Forsyth nlines := 0; 1080*37da2899SCharles.Forsyth nl := len sym.src; 1081*37da2899SCharles.Forsyth for(i := 0; i < nl; i++){ 1082*37da2899SCharles.Forsyth if((l := sym.src[i].stop.line) > nlines) 1083*37da2899SCharles.Forsyth nlines = l; 1084*37da2899SCharles.Forsyth } 1085*37da2899SCharles.Forsyth name := sym.src[0].start.file; 1086*37da2899SCharles.Forsyth nl0 := 2*(nlines+1); 1087*37da2899SCharles.Forsyth line := array[nl0] of int; 1088*37da2899SCharles.Forsyth for(i = 0; i < nl0; i++) 1089*37da2899SCharles.Forsyth line[i] = 0; 1090*37da2899SCharles.Forsyth nf := len sym.fns; 1091*37da2899SCharles.Forsyth fun := array[nf] of Funprof; 1092*37da2899SCharles.Forsyth for(i = 0; i < nf; i++){ 1093*37da2899SCharles.Forsyth fun[i].name = sym.fns[i].name; 1094*37da2899SCharles.Forsyth # src seems to be always nil 1095*37da2899SCharles.Forsyth # fun[i].file = sym.fns[i].src.start.file; 1096*37da2899SCharles.Forsyth # fun[i].line = (sym.fns[i].src.start.line+sym.fns[i].src.stop.line)/2; 1097*37da2899SCharles.Forsyth src := sym.pctosrc(sym.fns[i].offset); 1098*37da2899SCharles.Forsyth if(src != nil) 1099*37da2899SCharles.Forsyth fun[i].line = src.start.line; 1100*37da2899SCharles.Forsyth else 1101*37da2899SCharles.Forsyth fun[i].line = 0; 1102*37da2899SCharles.Forsyth fun[i].count = fun[i].counte = 0; 1103*37da2899SCharles.Forsyth } 1104*37da2899SCharles.Forsyth buf := array[32] of byte; 1105*37da2899SCharles.Forsyth # pc := 0; 1106*37da2899SCharles.Forsyth ktot := ktot1 := 0; 1107*37da2899SCharles.Forsyth fi := 0; 1108*37da2899SCharles.Forsyth# for(i=0; i < nl; i++) sys->print("%d -> %d\n", i, sym.pctosrc(i).start.line); 1109*37da2899SCharles.Forsyth while((m := sys->read(fd, buf, len buf)) > 0){ 1110*37da2899SCharles.Forsyth (nw, lw) := sys->tokenize(string buf[0:m], " "); 1111*37da2899SCharles.Forsyth if(nw != 2){ 1112*37da2899SCharles.Forsyth error0("bad histogram data"); 1113*37da2899SCharles.Forsyth return (nil, nil, nil, 0, 0); 1114*37da2899SCharles.Forsyth } 1115*37da2899SCharles.Forsyth pc := int hd lw; 1116*37da2899SCharles.Forsyth f := int hd tl lw; 1117*37da2899SCharles.Forsyth if(pc == 0){ 1118*37da2899SCharles.Forsyth ktot = f; 1119*37da2899SCharles.Forsyth continue; 1120*37da2899SCharles.Forsyth } 1121*37da2899SCharles.Forsyth if(pc == 1){ 1122*37da2899SCharles.Forsyth ktot1 = f; 1123*37da2899SCharles.Forsyth continue; 1124*37da2899SCharles.Forsyth } 1125*37da2899SCharles.Forsyth pc -= 2; 1126*37da2899SCharles.Forsyth t := pc&1; 1127*37da2899SCharles.Forsyth pc /= 2; 1128*37da2899SCharles.Forsyth rpc := pc-1; 1129*37da2899SCharles.Forsyth src := sym.pctosrc(rpc); 1130*37da2899SCharles.Forsyth if(src == nil) 1131*37da2899SCharles.Forsyth continue; 1132*37da2899SCharles.Forsyth l1 := src.start.line; 1133*37da2899SCharles.Forsyth l2 := src.stop.line; 1134*37da2899SCharles.Forsyth if(l1 == 0 || l2 == 0) 1135*37da2899SCharles.Forsyth continue; 1136*37da2899SCharles.Forsyth if((nl = l2-l1+1) == 1) 1137*37da2899SCharles.Forsyth line[2*l1+t] += f; 1138*37da2899SCharles.Forsyth else{ 1139*37da2899SCharles.Forsyth q := f/nl; 1140*37da2899SCharles.Forsyth r := f-q*nl; 1141*37da2899SCharles.Forsyth for(i = l1; i <= l2; i++) 1142*37da2899SCharles.Forsyth line[2*i+t] += q+(r-->0); 1143*37da2899SCharles.Forsyth } 1144*37da2899SCharles.Forsyth if(fi < nf){ 1145*37da2899SCharles.Forsyth if(rpc >= sym.fns[fi].offset && rpc < sym.fns[fi].stoppc){ 1146*37da2899SCharles.Forsyth if(t) 1147*37da2899SCharles.Forsyth fun[fi].counte += f; 1148*37da2899SCharles.Forsyth else 1149*37da2899SCharles.Forsyth fun[fi].count += f; 1150*37da2899SCharles.Forsyth } 1151*37da2899SCharles.Forsyth else{ 1152*37da2899SCharles.Forsyth while(fi < nf && rpc >= sym.fns[fi].stoppc) 1153*37da2899SCharles.Forsyth fi++; 1154*37da2899SCharles.Forsyth # fi++; 1155*37da2899SCharles.Forsyth if(fi >= nf && f != 0) 1156*37da2899SCharles.Forsyth error0(sys->sprint("bad fn index")); 1157*37da2899SCharles.Forsyth if(fi < nf){ 1158*37da2899SCharles.Forsyth if(t) 1159*37da2899SCharles.Forsyth fun[fi].counte += f; 1160*37da2899SCharles.Forsyth else 1161*37da2899SCharles.Forsyth fun[fi].count += f; 1162*37da2899SCharles.Forsyth } 1163*37da2899SCharles.Forsyth } 1164*37da2899SCharles.Forsyth } 1165*37da2899SCharles.Forsyth# sys->print("pc %d count %d l1 %d l2 %d\n", rpc, f, l1, l2); 1166*37da2899SCharles.Forsyth } 1167*37da2899SCharles.Forsyth return (name, line, fun, ktot, ktot1); 1168*37da2899SCharles.Forsyth} 1169*37da2899SCharles.Forsyth 1170*37da2899SCharles.Forsythmemshow(p: Prof, v: int): int 1171*37da2899SCharles.Forsyth{ 1172*37da2899SCharles.Forsyth i: int; 1173*37da2899SCharles.Forsyth 1174*37da2899SCharles.Forsyth cleare(); 1175*37da2899SCharles.Forsyth tot := p.total; 1176*37da2899SCharles.Forsyth if(p.total == 0 && p.totals[0] == 0) 1177*37da2899SCharles.Forsyth return 0; 1178*37da2899SCharles.Forsyth verbose := v&VERBOSE; 1179*37da2899SCharles.Forsyth fullhdr := v&FULLHDR; 1180*37da2899SCharles.Forsyth for(ml := p.mods; ml != nil; ml = tl ml){ 1181*37da2899SCharles.Forsyth mp := hd ml; 1182*37da2899SCharles.Forsyth if(mp.total == 0 && mp.totals[0] == 0) 1183*37da2899SCharles.Forsyth continue; 1184*37da2899SCharles.Forsyth if((b := getb(mp.path)) == nil) 1185*37da2899SCharles.Forsyth continue; 1186*37da2899SCharles.Forsyth sys->print("\nModule: %s(%s)\n\n", mp.name, mp.path); 1187*37da2899SCharles.Forsyth line := mp.linetab; 1188*37da2899SCharles.Forsyth if(v&LINE){ 1189*37da2899SCharles.Forsyth bio := bufio->open(b, Bufio->OREAD); 1190*37da2899SCharles.Forsyth if(bio == nil){ 1191*37da2899SCharles.Forsyth error(sys->sprint("cannot open %s for reading", b)); 1192*37da2899SCharles.Forsyth continue; 1193*37da2899SCharles.Forsyth } 1194*37da2899SCharles.Forsyth i = 1; 1195*37da2899SCharles.Forsyth ll := len line/2; 1196*37da2899SCharles.Forsyth while((s := bio.gets('\n')) != nil){ 1197*37da2899SCharles.Forsyth f := g := 0; 1198*37da2899SCharles.Forsyth if(i < ll){ 1199*37da2899SCharles.Forsyth f = line[2*i]; 1200*37da2899SCharles.Forsyth g = line[2*i+1]; 1201*37da2899SCharles.Forsyth } 1202*37da2899SCharles.Forsyth if(verbose || f != 0 || g != 0){ 1203*37da2899SCharles.Forsyth if(fullhdr) 1204*37da2899SCharles.Forsyth sys->print("%s:", b); 1205*37da2899SCharles.Forsyth sys->print("%d\t%d\t%d\t%s", i, f, g, s); 1206*37da2899SCharles.Forsyth } 1207*37da2899SCharles.Forsyth i++; 1208*37da2899SCharles.Forsyth } 1209*37da2899SCharles.Forsyth if(v&(FUNCTION|MODULE)) 1210*37da2899SCharles.Forsyth sys->print("\n"); 1211*37da2899SCharles.Forsyth } 1212*37da2899SCharles.Forsyth if(v&FUNCTION){ 1213*37da2899SCharles.Forsyth fun := mp.funtab; 1214*37da2899SCharles.Forsyth nf := len fun; 1215*37da2899SCharles.Forsyth for(i = 0; i < nf; i++) 1216*37da2899SCharles.Forsyth if(verbose || fun[i].count != 0 || fun[i].counte != 0){ 1217*37da2899SCharles.Forsyth if(fullhdr) 1218*37da2899SCharles.Forsyth sys->print("%s:", b); 1219*37da2899SCharles.Forsyth sys->print("%d\t%d\t%d\t%s()\n", fun[i].line, fun[i].count, fun[i].counte, fun[i].name); 1220*37da2899SCharles.Forsyth } 1221*37da2899SCharles.Forsyth if(v&MODULE) 1222*37da2899SCharles.Forsyth sys->print("\n"); 1223*37da2899SCharles.Forsyth } 1224*37da2899SCharles.Forsyth if(v&MODULE) 1225*37da2899SCharles.Forsyth sys->print("Module totals\t%d\t%d\n\n", mp.total, mp.totals[0]); 1226*37da2899SCharles.Forsyth } 1227*37da2899SCharles.Forsyth if(p.mods != nil && tl p.mods != nil) 1228*37da2899SCharles.Forsyth sys->print("Grand totals\t%d\t%d\n\n", p.total, p.totals[0]); 1229*37da2899SCharles.Forsyth return 0; 1230*37da2899SCharles.Forsyth} 1231