* hppa-tdep.c (read_unwind_info): Use "text_offset" for linker
[binutils-gdb.git] / gprof / printgprof.c
1 /*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that: (1) source distributions retain this entire copyright
7 * notice and comment, and (2) distributions including binaries display
8 * the following acknowledgement: ``This product includes software
9 * developed by the University of California, Berkeley and its contributors''
10 * in the documentation or other materials provided with the distribution
11 * and in all advertising materials mentioning features or use of this
12 * software. Neither the name of the University nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20 #ifndef lint
21 static char sccsid[] = "@(#)printgprof.c 5.7 (Berkeley) 6/1/90";
22 #endif /* not lint */
23
24 #include "gprof.h"
25 #include <demangle.h>
26
27 printprof()
28 {
29 register nltype *np;
30 nltype **sortednlp;
31 int index, timecmp();
32
33 actime = 0.0;
34 if ( bsd_style_output ) {
35 printf( "\f\n" );
36 if ( bflag) {
37 printf( "\n\n\nflat profile:\n" );
38 flat_blurb(stdout);
39 }
40 }
41 else
42 printf ("Flat profile:\n");
43 flatprofheader();
44 /*
45 * Sort the symbol table in by time
46 */
47 sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
48 if ( sortednlp == (nltype **) 0 ) {
49 fprintf( stderr , "[printprof] ran out of memory for time sorting\n" );
50 }
51 for ( index = 0 ; index < nname ; index += 1 ) {
52 sortednlp[ index ] = &nl[ index ];
53 }
54 qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
55 for ( index = 0 ; index < nname ; index += 1 ) {
56 np = sortednlp[ index ];
57 flatprofline( np );
58 }
59 actime = 0.0;
60 free( sortednlp );
61 if ( bflag && !bsd_style_output ) {
62 flat_blurb(stdout);
63 }
64 }
65
66 timecmp( npp1 , npp2 )
67 nltype **npp1, **npp2;
68 {
69 double timediff;
70 long calldiff;
71
72 timediff = (*npp2) -> time - (*npp1) -> time;
73 if ( timediff > 0.0 )
74 return 1 ;
75 if ( timediff < 0.0 )
76 return -1;
77 calldiff = (*npp2) -> ncall - (*npp1) -> ncall;
78 if ( calldiff > 0 )
79 return 1;
80 if ( calldiff < 0 )
81 return -1;
82 return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
83 }
84
85 /*
86 * header for flatprofline
87 */
88 flatprofheader()
89 {
90
91 if (bsd_style_output) {
92 printf( "\ngranularity: each sample hit covers %d byte(s)" ,
93 (long) scale * sizeof(UNIT) );
94 if (totime > 0.0)
95 printf(" for %.2f%% of %.2f seconds\n\n", 100.0/totime, totime / hz);
96 }
97 else {
98 printf( "\nEach sample counts as %g seconds.\n",
99 1.0 / hz);
100 }
101 if (totime <= 0.0)
102 {
103 printf(" no time accumulated\n\n");
104 /* This doesn't hurt since all the numerators will be zero. */
105 totime = 1.0;
106 }
107 printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
108 "% " , "cumulative" , "self " , "" , "self " , "total " , "" );
109 printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
110 "time" , "seconds " , "seconds" , "calls" ,
111 "ms/call" , "ms/call" , "name" );
112 }
113
114 flatprofline( np )
115 register nltype *np;
116 {
117
118 if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
119 return;
120 }
121 actime += np -> time;
122 if (bsd_style_output)
123 printf( "%5.1f %10.2f %8.2f" ,
124 100 * np -> time / totime , actime / hz , np -> time / hz );
125 else
126 printf( "%6.2f %9.2f %8.2f" ,
127 100 * np -> time / totime , actime / hz , np -> time / hz );
128 if ( np -> ncall != 0 ) {
129 printf( " %8d %8.2f %8.2f " , np -> ncall ,
130 1000 * np -> time / hz / np -> ncall ,
131 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall );
132 } else {
133 printf( " %8.8s %8.8s %8.8s " , "" , "" , "" );
134 }
135 if (bsd_style_output)
136 printname( np );
137 else
138 printnameonly( np );
139 printf( "\n" );
140 }
141
142 gprofheader()
143 {
144
145 if (!bsd_style_output)
146 if (bflag)
147 printf ("\t\t Call graph (explanation follows)\n\n");
148 else
149 printf ("\t\t\tCall graph\n\n");
150 printf( "\ngranularity: each sample hit covers %d byte(s)" ,
151 (long) scale * sizeof(UNIT) );
152 if ( printtime > 0.0 ) {
153 printf( " for %.2f%% of %.2f seconds\n\n" ,
154 100.0/printtime , printtime / hz );
155 } else {
156 printf( " no time propagated\n\n" );
157 /*
158 * this doesn't hurt, since all the numerators will be 0.0
159 */
160 printtime = 1.0;
161 }
162 if (bsd_style_output) {
163 printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
164 "" , "" , "" , "" , "called" , "total" , "parents");
165 printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
166 "index" , "%time" , "self" , "descendents" ,
167 "called" , "self" , "name" , "index" );
168 printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
169 "" , "" , "" , "" , "called" , "total" , "children");
170 printf( "\n" );
171 } else {
172 printf( "index %% time self children called name\n" );
173 }
174 }
175
176 gprofline( np )
177 register nltype *np;
178 {
179 char kirkbuffer[ BUFSIZ ];
180
181 sprintf( kirkbuffer , "[%d]" , np -> index );
182 printf(bsd_style_output
183 ? "%-6.6s %5.1f %7.2f %11.2f"
184 : "%-6.6s %5.1f %7.2f %7.2f" ,
185 kirkbuffer ,
186 100 * ( np -> propself + np -> propchild ) / printtime ,
187 np -> propself / hz ,
188 np -> propchild / hz );
189 if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
190 printf( " %7d" , np -> ncall );
191 if ( np -> selfcalls != 0 ) {
192 printf( "+%-7d " , np -> selfcalls );
193 } else {
194 printf( " %7.7s " , "" );
195 }
196 } else {
197 printf( " %7.7s %7.7s " , "" , "" );
198 }
199 printname( np );
200 printf( "\n" );
201 }
202
203 printgprof(timesortnlp)
204 nltype **timesortnlp;
205 {
206 int index;
207 nltype *parentp;
208
209 /*
210 * Print out the structured profiling list
211 */
212 if ( bflag && bsd_style_output ) {
213 bsd_callg_blurb(stdout);
214 }
215 gprofheader();
216 for ( index = 0 ; index < nname + ncycle ; index ++ ) {
217 parentp = timesortnlp[ index ];
218 if ( zflag == 0 &&
219 parentp -> ncall == 0 &&
220 parentp -> selfcalls == 0 &&
221 parentp -> propself == 0 &&
222 parentp -> propchild == 0 ) {
223 continue;
224 }
225 if ( ! parentp -> printflag ) {
226 continue;
227 }
228 if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
229 /*
230 * cycle header
231 */
232 printcycle( parentp );
233 printmembers( parentp );
234 } else {
235 printparents( parentp );
236 gprofline( parentp );
237 printchildren( parentp );
238 }
239 if (bsd_style_output)
240 printf( "\n" );
241 printf( "-----------------------------------------------\n" );
242 if (bsd_style_output)
243 printf( "\n" );
244 }
245 free( timesortnlp );
246 if ( bflag && !bsd_style_output) {
247 fsf_callg_blurb(stdout);
248 }
249 }
250
251 /*
252 * sort by decreasing propagated time
253 * if times are equal, but one is a cycle header,
254 * say that's first (e.g. less, i.e. -1).
255 * if one's name doesn't have an underscore and the other does,
256 * say the one is first.
257 * all else being equal, sort by names.
258 */
259 int
260 totalcmp( npp1 , npp2 )
261 nltype **npp1;
262 nltype **npp2;
263 {
264 register nltype *np1 = *npp1;
265 register nltype *np2 = *npp2;
266 double diff;
267
268 diff = ( np1 -> propself + np1 -> propchild )
269 - ( np2 -> propself + np2 -> propchild );
270 if ( diff < 0.0 )
271 return 1;
272 if ( diff > 0.0 )
273 return -1;
274 if ( np1 -> name == 0 && np1 -> cycleno != 0 )
275 return -1;
276 if ( np2 -> name == 0 && np2 -> cycleno != 0 )
277 return 1;
278 if ( np1 -> name == 0 )
279 return -1;
280 if ( np2 -> name == 0 )
281 return 1;
282 if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' )
283 return -1;
284 if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' )
285 return 1;
286 if ( np1 -> ncall > np2 -> ncall )
287 return -1;
288 if ( np1 -> ncall < np2 -> ncall )
289 return 1;
290 return strcmp( np1 -> name , np2 -> name );
291 }
292
293 printparents( childp )
294 nltype *childp;
295 {
296 nltype *parentp;
297 arctype *arcp;
298 nltype *cycleheadp;
299
300 if ( childp -> cyclehead != 0 ) {
301 cycleheadp = childp -> cyclehead;
302 } else {
303 cycleheadp = childp;
304 }
305 if ( childp -> parents == 0 ) {
306 printf(bsd_style_output
307 ? "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n"
308 : "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" ,
309 "" , "" , "" , "" , "" , "" );
310 return;
311 }
312 sortparents( childp );
313 for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
314 parentp = arcp -> arc_parentp;
315 if ( childp == parentp ||
316 ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
317 /*
318 * selfcall or call among siblings
319 */
320 printf(bsd_style_output
321 ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s "
322 : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s " ,
323 "" , "" , "" , "" ,
324 arcp -> arc_count , "" );
325 printname( parentp );
326 printf( "\n" );
327 } else {
328 /*
329 * regular parent of child
330 */
331 printf(bsd_style_output
332 ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d "
333 : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d ",
334 "" , "" ,
335 arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
336 arcp -> arc_count , cycleheadp -> ncall );
337 printname( parentp );
338 printf( "\n" );
339 }
340 }
341 }
342
343 printchildren( parentp )
344 nltype *parentp;
345 {
346 nltype *childp;
347 arctype *arcp;
348
349 sortchildren( parentp );
350 arcp = parentp -> children;
351 for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
352 childp = arcp -> arc_childp;
353 if ( childp == parentp ||
354 ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
355 /*
356 * self call or call to sibling
357 */
358 printf(bsd_style_output
359 ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s "
360 : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s " ,
361 "" , "" , "" , "" , arcp -> arc_count , "" );
362 printname( childp );
363 printf( "\n" );
364 } else {
365 /*
366 * regular child of parent
367 */
368 printf(bsd_style_output
369 ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d "
370 : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d " ,
371 "" , "" ,
372 arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
373 arcp -> arc_count , childp -> cyclehead -> ncall );
374 printname( childp );
375 printf( "\n" );
376 }
377 }
378 }
379
380 /* Print name of symbol. Return number of characters printed. */
381
382 int
383 printnameonly ( selfp )
384 nltype *selfp;
385 {
386 int size = 0;
387 CONST char *name = selfp->name;
388 if (name != NULL) {
389 char *demangled = NULL;
390 if (!bsd_style_output) {
391 if (name[0] == '_' && name[1] && discard_underscores)
392 name++;
393 demangled = cplus_demangle (name, DMGL_ANSI|DMGL_PARAMS);
394 if (demangled)
395 name = demangled;
396 }
397 printf( "%s" , name );
398 size = strlen (name);
399 if (demangled)
400 free (demangled);
401 #ifdef DEBUG
402 if ( debug & DFNDEBUG ) {
403 printf( "{%d} " , selfp -> toporder );
404 }
405 if ( debug & PROPDEBUG ) {
406 printf( "%5.2f%% " , selfp -> propfraction );
407 }
408 #endif DEBUG
409 }
410 return size;
411 }
412
413 printname( selfp )
414 nltype *selfp;
415 {
416 printnameonly (selfp);
417
418 if ( selfp -> cycleno != 0 ) {
419 printf( " <cycle %d>" , selfp -> cycleno );
420 }
421 if ( selfp -> index != 0 ) {
422 if ( selfp -> printflag ) {
423 printf( " [%d]" , selfp -> index );
424 } else {
425 printf( " (%d)" , selfp -> index );
426 }
427 }
428 }
429
430 sortchildren( parentp )
431 nltype *parentp;
432 {
433 arctype *arcp;
434 arctype *detachedp;
435 arctype sorted;
436 arctype *prevp;
437
438 /*
439 * unlink children from parent,
440 * then insertion sort back on to sorted's children.
441 * *arcp the arc you have detached and are inserting.
442 * *detachedp the rest of the arcs to be sorted.
443 * sorted arc list onto which you insertion sort.
444 * *prevp arc before the arc you are comparing.
445 */
446 sorted.arc_childlist = 0;
447 for ( (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist);
448 arcp ;
449 (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) {
450 /*
451 * consider *arcp as disconnected
452 * insert it into sorted
453 */
454 for ( prevp = &sorted ;
455 prevp -> arc_childlist ;
456 prevp = prevp -> arc_childlist ) {
457 if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
458 break;
459 }
460 }
461 arcp -> arc_childlist = prevp -> arc_childlist;
462 prevp -> arc_childlist = arcp;
463 }
464 /*
465 * reattach sorted children to parent
466 */
467 parentp -> children = sorted.arc_childlist;
468 }
469
470 sortparents( childp )
471 nltype *childp;
472 {
473 arctype *arcp;
474 arctype *detachedp;
475 arctype sorted;
476 arctype *prevp;
477
478 /*
479 * unlink parents from child,
480 * then insertion sort back on to sorted's parents.
481 * *arcp the arc you have detached and are inserting.
482 * *detachedp the rest of the arcs to be sorted.
483 * sorted arc list onto which you insertion sort.
484 * *prevp arc before the arc you are comparing.
485 */
486 sorted.arc_parentlist = 0;
487 for ( (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist);
488 arcp ;
489 (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) {
490 /*
491 * consider *arcp as disconnected
492 * insert it into sorted
493 */
494 for ( prevp = &sorted ;
495 prevp -> arc_parentlist ;
496 prevp = prevp -> arc_parentlist ) {
497 if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
498 break;
499 }
500 }
501 arcp -> arc_parentlist = prevp -> arc_parentlist;
502 prevp -> arc_parentlist = arcp;
503 }
504 /*
505 * reattach sorted arcs to child
506 */
507 childp -> parents = sorted.arc_parentlist;
508 }
509
510 /*
511 * print a cycle header
512 */
513 printcycle( cyclep )
514 nltype *cyclep;
515 {
516 char kirkbuffer[ BUFSIZ ];
517
518 sprintf( kirkbuffer , "[%d]" , cyclep -> index );
519 printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
520 kirkbuffer ,
521 100 * ( cyclep -> propself + cyclep -> propchild ) / printtime ,
522 cyclep -> propself / hz ,
523 cyclep -> propchild / hz ,
524 cyclep -> ncall );
525 if ( cyclep -> selfcalls != 0 ) {
526 printf( "+%-7d" , cyclep -> selfcalls );
527 } else {
528 printf( " %7.7s" , "" );
529 }
530 printf( " <cycle %d as a whole>\t[%d]\n" ,
531 cyclep -> cycleno , cyclep -> index );
532 }
533
534 /*
535 * print the members of a cycle
536 */
537 printmembers( cyclep )
538 nltype *cyclep;
539 {
540 nltype *memberp;
541
542 sortmembers( cyclep );
543 for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
544 printf( "%6.6s %5.5s %7.2f %11.2f %7d" ,
545 "" , "" , memberp -> propself / hz , memberp -> propchild / hz ,
546 memberp -> ncall );
547 if ( memberp -> selfcalls != 0 ) {
548 printf( "+%-7d" , memberp -> selfcalls );
549 } else {
550 printf( " %7.7s" , "" );
551 }
552 printf( " " );
553 printname( memberp );
554 printf( "\n" );
555 }
556 }
557
558 /*
559 * sort members of a cycle
560 */
561 sortmembers( cyclep )
562 nltype *cyclep;
563 {
564 nltype *todo;
565 nltype *doing;
566 nltype *prev;
567
568 /*
569 * detach cycle members from cyclehead,
570 * and insertion sort them back on.
571 */
572 todo = cyclep -> cnext;
573 cyclep -> cnext = 0;
574 for ( (doing = todo)&&(todo = doing -> cnext);
575 doing ;
576 (doing = todo )&&(todo = doing -> cnext )){
577 for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) {
578 if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) {
579 break;
580 }
581 }
582 doing -> cnext = prev -> cnext;
583 prev -> cnext = doing;
584 }
585 }
586
587 /*
588 * major sort is on propself + propchild,
589 * next is sort on ncalls + selfcalls.
590 */
591 int
592 membercmp( this , that )
593 nltype *this;
594 nltype *that;
595 {
596 double thistime = this -> propself + this -> propchild;
597 double thattime = that -> propself + that -> propchild;
598 long thiscalls = this -> ncall + this -> selfcalls;
599 long thatcalls = that -> ncall + that -> selfcalls;
600
601 if ( thistime > thattime ) {
602 return GREATERTHAN;
603 }
604 if ( thistime < thattime ) {
605 return LESSTHAN;
606 }
607 if ( thiscalls > thatcalls ) {
608 return GREATERTHAN;
609 }
610 if ( thiscalls < thatcalls ) {
611 return LESSTHAN;
612 }
613 return EQUALTO;
614 }
615 /*
616 * compare two arcs to/from the same child/parent.
617 * - if one arc is a self arc, it's least.
618 * - if one arc is within a cycle, it's less than.
619 * - if both arcs are within a cycle, compare arc counts.
620 * - if neither arc is within a cycle, compare with
621 * arc_time + arc_childtime as major key
622 * arc count as minor key
623 */
624 int
625 arccmp( thisp , thatp )
626 arctype *thisp;
627 arctype *thatp;
628 {
629 nltype *thisparentp = thisp -> arc_parentp;
630 nltype *thischildp = thisp -> arc_childp;
631 nltype *thatparentp = thatp -> arc_parentp;
632 nltype *thatchildp = thatp -> arc_childp;
633 double thistime;
634 double thattime;
635
636 # ifdef DEBUG
637 if ( debug & TIMEDEBUG ) {
638 printf( "[arccmp] " );
639 printname( thisparentp );
640 printf( " calls " );
641 printname ( thischildp );
642 printf( " %f + %f %d/%d\n" ,
643 thisp -> arc_time , thisp -> arc_childtime ,
644 thisp -> arc_count , thischildp -> ncall );
645 printf( "[arccmp] " );
646 printname( thatparentp );
647 printf( " calls " );
648 printname( thatchildp );
649 printf( " %f + %f %d/%d\n" ,
650 thatp -> arc_time , thatp -> arc_childtime ,
651 thatp -> arc_count , thatchildp -> ncall );
652 printf( "\n" );
653 }
654 # endif DEBUG
655 if ( thisparentp == thischildp ) {
656 /* this is a self call */
657 return LESSTHAN;
658 }
659 if ( thatparentp == thatchildp ) {
660 /* that is a self call */
661 return GREATERTHAN;
662 }
663 if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
664 thisparentp -> cycleno == thischildp -> cycleno ) {
665 /* this is a call within a cycle */
666 if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
667 thatparentp -> cycleno == thatchildp -> cycleno ) {
668 /* that is a call within the cycle, too */
669 if ( thisp -> arc_count < thatp -> arc_count ) {
670 return LESSTHAN;
671 }
672 if ( thisp -> arc_count > thatp -> arc_count ) {
673 return GREATERTHAN;
674 }
675 return EQUALTO;
676 } else {
677 /* that isn't a call within the cycle */
678 return LESSTHAN;
679 }
680 } else {
681 /* this isn't a call within a cycle */
682 if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
683 thatparentp -> cycleno == thatchildp -> cycleno ) {
684 /* that is a call within a cycle */
685 return GREATERTHAN;
686 } else {
687 /* neither is a call within a cycle */
688 thistime = thisp -> arc_time + thisp -> arc_childtime;
689 thattime = thatp -> arc_time + thatp -> arc_childtime;
690 if ( thistime < thattime )
691 return LESSTHAN;
692 if ( thistime > thattime )
693 return GREATERTHAN;
694 if ( thisp -> arc_count < thatp -> arc_count )
695 return LESSTHAN;
696 if ( thisp -> arc_count > thatp -> arc_count )
697 return GREATERTHAN;
698 return EQUALTO;
699 }
700 }
701 }
702
703 int
704 namecmp( npp1 , npp2 )
705 nltype **npp1, **npp2;
706 {
707 return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
708 }
709
710 printindex()
711 {
712 nltype **namesortnlp;
713 register nltype *nlp;
714 int index, nnames, todo, i, j;
715 char peterbuffer[20];
716
717 /*
718 * Now, sort regular function name alphbetically
719 * to create an index.
720 */
721 namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
722 if ( namesortnlp == (nltype **) 0 ) {
723 fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
724 }
725 for ( index = 0 , nnames = 0 ; index < nname ; index++ ) {
726 if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 )
727 continue;
728 namesortnlp[nnames++] = &nl[index];
729 }
730 qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp );
731 for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) {
732 namesortnlp[todo++] = &cyclenl[index];
733 }
734 printf( "\f\nIndex by function name\n\n" );
735 index = ( todo + 2 ) / 3;
736 for ( i = 0; i < index ; i++ ) {
737 for ( j = i; j < todo ; j += index ) {
738 nlp = namesortnlp[ j ];
739 if ( nlp -> printflag ) {
740 sprintf( peterbuffer , "[%d]" , nlp -> index );
741 } else {
742 sprintf( peterbuffer , "(%d)" , nlp -> index );
743 }
744 if ( j < nnames ) {
745 printf( "%6.6s " , peterbuffer );
746 if (bsd_style_output)
747 printf ("%-19.19s" , nlp->name);
748 else {
749 int size = printnameonly(nlp);
750 for ( ; size < 19; size++) putchar(' ');
751 }
752 } else {
753 printf( "%6.6s " , peterbuffer );
754 sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
755 printf( "%-19.19s" , peterbuffer );
756 }
757 }
758 printf( "\n" );
759 }
760 free( namesortnlp );
761 }
762
763 PTR
764 xmalloc (size)
765 long size;
766 {
767 PTR val = (PTR) malloc (size);
768 if (val == NULL) {
769 fprintf (stderr, "virtual memory exhaused\n");
770 exit (1);
771 }
772 return val;
773 }
774
775 PTR
776 xrealloc (oldval, size)
777 PTR oldval;
778 long size;
779 {
780 PTR val = (PTR) realloc (oldval, size);
781 if (val == NULL) {
782 fprintf (stderr, "virtual memory exhaused\n");
783 exit (1);
784 }
785 return val;
786 }
787