]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/src/Print.cc
1 /* Copyright (C) 2021-2023 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
31 #include <sys/types.h>
36 #include "StringBuilder.h"
37 #include "DbeSession.h"
42 #include "Experiment.h"
43 #include "MetricList.h"
46 #include "DataSpace.h"
47 #include "DataObject.h"
48 #include "FilterExp.h"
49 #include "LoadObject.h"
53 #include "CallStack.h"
56 er_print_common_display::open (Print_params
*params
)
59 pr_params
.name
= dbe_strdup (params
->name
);
60 if (params
->dest
== DEST_PRINTER
)
62 tmp_file
= dbeSession
->get_tmp_file_name (NTXT ("print"), false);
63 dbeSession
->tmp_files
->append (strdup (tmp_file
));
64 out_file
= fopen (tmp_file
, NTXT ("w"));
66 else if (params
->dest
== DEST_OPEN_FILE
)
67 out_file
= pr_params
.openfile
;
69 out_file
= fopen (pr_params
.name
, NTXT ("w"));
78 er_print_common_display::print_output ()
82 if (pr_params
.dest
!= DEST_OPEN_FILE
)
85 if (pr_params
.dest
== DEST_PRINTER
)
87 if (streq ((char *) pr_params
.name
, NTXT ("")))
88 sys_call
= dbe_sprintf ("(/usr/bin/lp -c -n%d %s) 2>/dev/null 1>&2",
89 pr_params
.ncopies
, tmp_file
);
91 sys_call
= dbe_sprintf ("(/usr/bin/lp -c -d%s -n%d %s) 2>/dev/null 1>&2",
92 pr_params
.name
, pr_params
.ncopies
, tmp_file
);
93 if (system (sys_call
) != 0)
102 // Return the report. If the report size is greater than max, return truncated report
103 // Allocates memory, so the caller should free this memory.
106 er_print_common_display::get_output (int maxsize
)
108 off_t max
= (off_t
) maxsize
;
109 if (out_file
!= (FILE *) NULL
)
111 fclose (out_file
); // close tmp_file
112 out_file
= (FILE *) NULL
;
115 int st
= stat (tmp_file
, &sbuf
);
118 off_t sz
= sbuf
.st_size
;
120 return dbe_sprintf (GTXT ("Error: report is too long.\n"));
122 return dbe_sprintf (GTXT ("Error: empty temporary file: %s\n"),
127 FILE *f
= fopen (tmp_file
, "r");
129 return dbe_sprintf (GTXT ("Error: cannot open temporary file: %s\n"),
131 char *report
= (char *) malloc (max
);
134 if (1 != fread (report
, max
- 1, 1, f
))
138 return dbe_sprintf (GTXT ("Error: cannot read temporary file: %s\n"),
148 er_print_common_display::header_dump (int exp_idx
)
150 if (load
&& (exp_idx
== exp_idx1
))
153 print_load_object (out_file
);
155 print_header (dbeSession
->get_exp (exp_idx
), out_file
);
159 pr_load_objects (Vector
<LoadObject
*> *loadobjects
, char *lead
)
167 size
= loadobjects
->size ();
168 for (i
= 0; i
< size
; i
++)
170 lo
= loadobjects
->fetch (i
);
171 lo_name
= lo
->get_name ();
174 size_t len
= strlen (lo_name
);
175 if (len
> 7 && streq (lo_name
+ len
- 7, NTXT (".class>")))
179 // print the segment name
181 sb
.append (NTXT (" "));
182 sb
.append (lo
->get_name ());
183 sb
.append (NTXT (" ("));
184 sb
.append (lo
->get_pathname ());
185 sb
.append (NTXT (")\n"));
188 m
= lo
->fetch_warnings ();
191 msg
= pr_mesgs (m
, NULL
, NTXT (" "));
196 return sb
.toString ();
200 pr_mesgs (Emsg
*msg
, const char *null_str
, const char *lead
)
205 return dbe_strdup (null_str
);
206 for (m
= msg
; m
; m
= m
->next
)
209 sb
.append (m
->get_msg ());
210 sb
.append (NTXT ("\n"));
212 return sb
.toString ();
216 print_load_object (FILE *out_file
)
218 Vector
<LoadObject
*> *loadobjects
= dbeSession
->get_text_segments ();
219 char *msg
= pr_load_objects (loadobjects
, NTXT ("\t"));
220 fprintf (out_file
, GTXT ("Load Object Coverage:\n"));
221 fprintf (out_file
, NTXT ("%s"), msg
);
223 "----------------------------------------------------------------\n");
229 print_header (Experiment
*exp
, FILE *out_file
)
231 fprintf (out_file
, GTXT ("Experiment: %s\n"), exp
->get_expt_name ());
232 char *msg
= pr_mesgs (exp
->fetch_notes (), NTXT (""), NTXT (""));
233 fprintf (out_file
, NTXT ("%s"), msg
);
236 msg
= pr_mesgs (exp
->fetch_errors (), GTXT ("No errors\n"), NTXT (""));
237 fprintf (out_file
, NTXT ("%s"), msg
);
240 msg
= pr_mesgs (exp
->fetch_warnings (), GTXT ("No warnings\n"), NTXT (""));
241 fprintf (out_file
, NTXT ("%s"), msg
);
244 msg
= pr_mesgs (exp
->fetch_comments (), NTXT (""), NTXT (""));
245 fprintf (out_file
, NTXT ("%s"), msg
);
248 msg
= pr_mesgs (exp
->fetch_pprocq (), NTXT (""), NTXT (""));
249 fprintf (out_file
, NTXT ("%s"), msg
);
254 delTrailingBlanks (char *s
)
256 for (int i
= (int) strlen (s
) - 1; i
>= 0 && s
[i
] == ' '; i
--)
262 * Print the 3-line header with column heads for the metrics
263 * Return offset of "Name" column (this is needed to print Callers-Callees)
266 print_label (FILE *out_file
, MetricList
*metrics_list
,
267 Metric::HistMetric
*hist_metric
, int space
)
269 char line0
[2 * MAX_LEN
], line1
[2 * MAX_LEN
];
270 char line2
[2 * MAX_LEN
], line3
[2 * MAX_LEN
];
272 *line0
= *line1
= *line2
= *line3
= '\0';
273 Vector
<Metric
*> *mlist
= metrics_list
->get_items ();
274 for (int index
= 0, mlist_sz
= mlist
->size (); index
< mlist_sz
; index
++)
276 Metric
*mitem
= mlist
->fetch (index
);
277 if (mitem
->is_visible () || mitem
->is_tvisible () || mitem
->is_pvisible ())
279 Metric::HistMetric
*hitem
= hist_metric
+ index
;
281 if (index
> 0 && mitem
->get_type () == Metric::ONAME
)
284 name_offset
= strlen (line1
);
288 int width
= (int) hitem
->width
;
289 size_t len
= strlen (line1
);
290 snprintf (line1
+ len
, sizeof (line1
) - len
, "%s%-*s", s
, width
,
292 len
= strlen (line2
);
293 snprintf (line2
+ len
, sizeof (line2
) - len
, "%s%-*s", s
, width
,
295 len
= strlen (line3
);
296 snprintf (line3
+ len
, sizeof (line3
) - len
, "%s%-*s", s
, width
,
298 len
= strlen (line0
);
299 snprintf (line0
+ len
, sizeof (line0
) - len
, "%s%-*s", s
, width
,
300 mitem
->legend
? mitem
->legend
: NTXT (""));
303 char *s
= delTrailingBlanks (line0
);
305 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), s
);
306 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), delTrailingBlanks (line1
));
307 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), delTrailingBlanks (line2
));
308 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), delTrailingBlanks (line3
));
312 er_print_histogram::er_print_histogram (DbeView
*_dbev
, Hist_data
*data
,
313 MetricList
*metrics_list
,
314 Print_mode disp_type
, int limit
,
315 char *sort_name
, Histable
*sobj
,
316 bool show_load
, bool show_header
)
319 mlist
= metrics_list
;
321 number_entries
= limit
;
322 sort_metric
= sort_name
;
326 exp_idx2
= dbeSession
->nexps () - 1;
328 header
= show_header
;
332 er_print_histogram::dump_list (int limit
)
334 Histable::NameFormat nfmt
= dbev
->get_name_format ();
336 char *title
= NULL
; // No title for some formats
337 enum PrintMode pm
= dbev
->get_printmode ();
339 // create a header line, except for delimiter-separated list output
340 if (pm
!= PM_DELIM_SEP_LIST
)
342 if (hist_data
->type
== Histable::FUNCTION
)
343 sb
.append (GTXT ("Functions sorted by metric: "));
344 else if (hist_data
->type
== Histable::INSTR
)
345 sb
.append (GTXT ("PCs sorted by metric: "));
346 else if (hist_data
->type
== Histable::LINE
)
347 sb
.append (GTXT ("Lines sorted by metric: "));
348 else if (hist_data
->type
== Histable::DOBJECT
)
349 sb
.append (GTXT ("Dataobjects sorted by metric: "));
351 sb
.append (GTXT ("Objects sorted by metric: "));
352 sb
.append (sort_metric
);
353 title
= sb
.toString ();
360 Metric::HistMetric
*hist_metric
= hist_data
->get_histmetrics ();
361 fprintf (out_file
, NTXT ("%s\n\n"), title
); //print title
362 hist_data
->print_label (out_file
, hist_metric
, 0);
363 hist_data
->print_content (out_file
, hist_metric
, limit
);
364 fprintf (out_file
, nl
);
369 print_html_title (out_file
, title
);
370 print_html_label (out_file
, mlist
);
371 print_html_content (out_file
, hist_data
, mlist
, limit
, nfmt
);
372 print_html_trailer (out_file
);
375 case PM_DELIM_SEP_LIST
:
377 char delim
= dbev
->get_printdelimiter ();
378 print_delim_label (out_file
, mlist
, delim
);
379 print_delim_content (out_file
, hist_data
, mlist
, limit
, nfmt
, delim
);
380 print_delim_trailer (out_file
, delim
);
388 er_print_histogram::dump_annotated_dataobjects (Vector
<int> *marks
,
391 if (!dbeSession
->is_datamode_available ())
393 GTXT ("No dataspace information recorded in experiments\n\n"));
395 Hist_data
*layout_data
= dbev
->get_data_space ()->get_layout_data (hist_data
, marks
, ithreshold
);
396 Metric::HistMetric
*hist_metric
= layout_data
->get_histmetrics ();
398 // snprintf (hist_metric[name_index].legend2, MAX_LEN, GTXT ("* +offset .element"));
399 layout_data
->print_label (out_file
, hist_metric
, 3);
400 fprintf (out_file
, nl
);
403 for (long i
= 0; i
< layout_data
->size (); i
++)
406 if (marks
->find (i
) != -1)
410 layout_data
->print_row (&sb
, i
, hist_metric
, " ");
411 sb
.toFileLn (out_file
);
413 fprintf (out_file
, nl
);
418 max_length(size_t len
, size_t str_len
)
426 er_print_histogram::dump_detail (int limit
)
429 Hist_data
*current_data
;
430 Histable::Type htype
;
432 double dvalue
, percent
;
433 MetricList
*prop_mlist
= new MetricList (mlist
);
437 LoadObject
*loadobject
;
438 char *sname
, *oname
, *lname
, *alias
, *mangle
;
440 Histable::NameFormat nfmt
= dbev
->get_name_format ();
442 // Check max. length of metrics names
443 size_t len
= 0, slen
= 0;
444 Vec_loop (Metric
*, prop_mlist
->get_items (), index
, mitem
)
446 mitem
->set_vvisible (true);
447 if (mitem
->get_vtype () == VT_LABEL
)
450 if (mitem
->get_subtype () != Metric::STATIC
)
452 mitem
->set_pvisible (true);
453 len
= max_length (len
, hist_data
->value_maxlen (index
));
454 slen
= max_length (slen
, strlen (mitem
->get_name ()));
458 // now get the length of the other (non-performance-data) messages
459 if (hist_data
->type
== Histable::FUNCTION
)
461 slen
= max_length (slen
, strlen (GTXT ("Source File")));
462 slen
= max_length (slen
, strlen (GTXT ("Object File")));
463 slen
= max_length (slen
, strlen (GTXT ("Load Object")));
464 slen
= max_length (slen
, strlen (GTXT ("Mangled Name")));
465 slen
= max_length (slen
, strlen (GTXT ("Aliases")));
467 else if (hist_data
->type
== Histable::DOBJECT
)
469 slen
= max_length (slen
, strlen (GTXT ("Scope")));
470 slen
= max_length (slen
, strlen (GTXT ("Type")));
471 slen
= max_length (slen
, strlen (GTXT ("Member of")));
472 slen
= max_length (slen
, strlen (GTXT ("Offset (bytes)")));
473 slen
= max_length (slen
, strlen (GTXT ("Size (bytes)")));
474 slen
= max_length (slen
, strlen (GTXT ("Elements")));
476 int max_len
= (int) len
;
477 int smax_len
= (int) slen
;
479 #define PR_TITLE(t) fprintf (out_file, "\t%*s:", smax_len, t)
480 #define PR(title, nm) PR_TITLE(title); \
482 fprintf (out_file, " %s", nm); \
483 fprintf (out_file, "\n")
485 // now loop over the objects
486 int num_printed_items
= 0;
487 for (i
= 0; i
< hist_data
->size (); i
++)
489 if (hist_data
->type
== Histable::FUNCTION
)
491 if (num_printed_items
>= limit
)
493 obj
= sel_obj
? sel_obj
: hist_data
->fetch (i
)->obj
;
494 htype
= obj
->get_type ();
496 // ask the view for all the data for the object
497 // xxxxx may be expensive to rescan all packets via get_hist_data()
498 current_data
= dbev
->get_hist_data (prop_mlist
,
499 htype
, 0, Hist_data::SELF
, obj
);
500 if (current_data
->size () == 0)
502 values
= current_data
->fetch (0)->value
;
506 obj
= hist_data
->fetch (i
)->obj
;
507 DataObject
*dobj
= (DataObject
*) obj
;
510 // print selected item and its members
512 && (DataObject
*) sel_obj
!= dobj
->get_parent ())
513 // not a match, advance to next item
516 else if (num_printed_items
>= limit
)
518 htype
= obj
->get_type ();
519 values
= hist_data
->fetch (i
)->value
;
520 current_data
= hist_data
;
523 if (num_printed_items
)
524 // if this isn't the first one, add a blank line
525 fprintf (out_file
, NTXT ("\n"));
528 // Print full object name
529 if (htype
!= Histable::DOBJECT
)
530 fprintf (out_file
, NTXT ("%s\n"), obj
->get_name (nfmt
));
533 DataObject
*dobj
= (DataObject
*) obj
;
534 if (!dobj
->get_parent ())
535 fprintf (out_file
, NTXT ("%s\n"), obj
->get_name (nfmt
));
537 fprintf (out_file
, NTXT (" %s\n"), obj
->get_name (nfmt
));
540 Vec_loop (Metric
*, prop_mlist
->get_items (), index
, mitem
)
542 if (mitem
->get_vtype () == VT_LABEL
)
544 if (mitem
->get_subtype () == Metric::STATIC
545 && htype
== Histable::DOBJECT
)
547 PR_TITLE (mitem
->get_name ());
550 char *s
= values
[index
].to_str (buf
, sizeof (buf
));
551 if (mitem
->get_value_styles () & VAL_PERCENT
)
553 dvalue
= values
[index
].to_double ();
554 percent
= 100.0 * current_data
->get_percentage (dvalue
, index
);
555 if (!mitem
->is_time_val ())
557 fprintf (out_file
, " %*s", max_len
, s
);
559 fprintf (out_file
, " ( 0. %%)\n");
561 fprintf (out_file
, " (%5.1f%%)\n", percent
);
568 v
.d
= dvalue
/ (1.e
+6 * dbeSession
->get_clock (-1));
570 char *s1
= v
.to_str (buf1
, sizeof (buf1
));
571 fprintf (out_file
, " %*s", max_len
, s1
);
573 fprintf (out_file
, " ( 0. %%)\n");
575 fprintf (out_file
, " (%5.1f%%)\n", percent
);
576 PR_TITLE (GTXT ("Count"));
579 int max_len1
= max_len
;
580 for (int j
= (int) strlen (s
) - 1; j
>= 0 && s
[j
] == ' '; j
--)
585 fprintf (out_file
, " %*s\n", max_len1
, s
);
588 // now add the descriptive information about the object
589 if (htype
!= Histable::DOBJECT
)
591 Function
*func
= (Function
*) obj
->convertto (Histable::FUNCTION
);
592 if (func
&& func
->get_type () == Histable::FUNCTION
)
594 // Print the source/object/load-object files & aliases
595 oname
= lname
= alias
= NULL
;
596 sname
= func
->getDefSrcName ();
597 mangle
= func
->get_mangled_name ();
598 if (mangle
&& streq (func
->get_name (), mangle
))
600 module
= func
->module
;
603 oname
= module
->get_name ();
604 loadobject
= module
->loadobject
;
607 lname
= loadobject
->get_pathname ();
608 alias
= loadobject
->get_alias (func
);
612 if (htype
== Histable::INSTR
&& dbeSession
->is_datamode_available ())
613 alias
= ((DbeInstr
*) obj
)->get_descriptor ();
615 PR (GTXT ("Source File"), sname
);
616 PR (GTXT ("Object File"), oname
);
617 PR (GTXT ("Load Object"), lname
);
618 PR (GTXT ("Mangled Name"), mangle
);
619 PR (GTXT ("Aliases"), alias
);
624 // Print the dataobject information
625 DataObject
*dobj
= (DataObject
*) obj
;
626 Histable
*scope
= dobj
->get_scope ();
629 PR_TITLE (GTXT ("Scope"));
631 fprintf (out_file
, GTXT ("(Global)\n"));
632 else switch (scope
->get_type ())
634 case Histable::FUNCTION
:
635 fprintf (out_file
, NTXT ("%s(%s)\n"),
636 ((Function
*) scope
)->module
->get_name (),
639 case Histable::LOADOBJECT
:
640 case Histable::MODULE
:
642 fprintf (out_file
, NTXT ("%s\n"), scope
->get_name ());
645 // print the type name
646 PR_TITLE (GTXT ("Type"));
647 if (dobj
->get_typename ())
648 fprintf (out_file
, NTXT ("%s\n"), dobj
->get_typename ());
650 fprintf (out_file
, GTXT ("(Synthetic)\n"));
653 if (dobj
->get_offset () != -1)
655 if (dobj
->get_parent ())
657 PR_TITLE (GTXT ("Member of"));
658 fprintf (out_file
, NTXT ("%s\n"), dobj
->get_parent ()->get_name ());
660 PR_TITLE (GTXT ("Offset (bytes)"));
661 fprintf (out_file
, NTXT ("%lld\n"), (long long) dobj
->get_offset ());
664 if (dobj
->get_size ())
666 PR_TITLE (GTXT ("Size (bytes)"));
667 fprintf (out_file
, NTXT ("%lld\n"), (long long) dobj
->get_size ());
670 if (hist_data
->type
== Histable::FUNCTION
)
673 if (num_printed_items
== 0 && sel_obj
)
675 GTXT ("Error: Specified item `%s' had no recorded metrics.\n"),
676 sel_obj
->get_name ());
680 static Metric::HistMetric
*
681 allocateHistMetric (int no_metrics
)
683 Metric::HistMetric
*hist_metric
= new Metric::HistMetric
[no_metrics
];
684 for (int i
= 0; i
< no_metrics
; i
++)
686 Metric::HistMetric
*hm
= &hist_metric
[i
];
693 er_print_histogram::dump_gprof (int limit
)
701 int no_metrics
= mlist
->get_items ()->size ();
702 Metric::HistMetric
*hist_metric
= allocateHistMetric (no_metrics
);
703 for (int i
= 0; i
< limit
; i
++)
705 obj
= sel_obj
? sel_obj
: hist_data
->fetch (i
)->obj
;
706 callers
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
707 Hist_data::CALLERS
, obj
);
708 callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
709 Hist_data::CALLEES
, obj
);
710 center
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
711 Hist_data::SELF
, obj
);
712 callers
->update_max (hist_metric
);
713 callees
->update_max (hist_metric
);
714 center
->update_max (hist_metric
);
715 callers
->update_legend_width (hist_metric
);
716 callers
->print_label (out_file
, hist_metric
, 0);
717 callers
->print_content (out_file
, hist_metric
, callers
->size ());
719 if (center
->size () > 0)
721 center
->update_total (callers
->get_totals ());
723 center
->print_row (&sb
, 0, hist_metric
, NTXT ("*"));
724 sb
.toFileLn (out_file
);
726 callees
->print_content (out_file
, hist_metric
, callees
->size ());
727 fprintf (out_file
, nl
);
732 delete[] hist_metric
;
735 // dump an annotated file
737 dump_anno_file (FILE *fp
, Histable::Type type
, Module
*module
, DbeView
*dbev
,
738 MetricList
*mlist
, TValue
*ftotal
, const char *srcFile
,
739 Function
*func
, Vector
<int> *marks
, int threshold
, int vis_bits
,
740 int src_visible
, bool hex_visible
, bool src_only
)
742 int lspace
, mspace
, tspace
, remain
, mindex
, next_mark
, hidx
, index
;
745 Hist_data::HistItem
*item
;
747 SourceFile
*srcContext
= NULL
;
748 bool func_scope
= dbev
== NULL
? false : dbev
->get_func_scope ();
751 srcContext
= module
->findSource (srcFile
, false);
752 if (srcContext
== NULL
)
754 Vector
<SourceFile
*> *includes
= module
->includes
;
755 char *bname
= get_basename (srcFile
);
756 for (int i
= 0, sz
= includes
? includes
->size () : 0; i
< sz
; i
++)
758 SourceFile
*sf
= includes
->fetch (i
);
759 if (streq (get_basename (sf
->get_name ()), bname
))
770 srcContext
= func
->getDefSrc ();
772 Hist_data
*hdata
= module
->get_data (dbev
, mlist
, type
, ftotal
, srcContext
,
773 func
, marks
, threshold
, vis_bits
,
774 src_visible
, hex_visible
,
775 func_scope
, src_only
);
780 // force the name metric to be invisible
781 MetricList
*nmlist
= hdata
->get_metric_list ();
782 nmlist
->find_metric (GTXT ("name"), Metric::STATIC
)->clear_all_visbits ();
783 Metric::HistMetric
*hist_metric
= hdata
->get_histmetrics ();
785 // lspace is for max line number that's inserted; use to set width
787 Vec_loop (Hist_data::HistItem
*, hdata
, hidx
, item
)
791 if (item
->obj
->get_type () == Histable::LINE
792 && ((DbeLine
*) item
->obj
)->lineno
> max_lineno
)
793 max_lineno
= ((DbeLine
*) item
->obj
)->lineno
;
794 else if (item
->obj
->get_type () == Histable::INSTR
795 && ((DbeInstr
*) item
->obj
)->lineno
> max_lineno
)
796 max_lineno
= ((DbeInstr
*) item
->obj
)->lineno
;
799 lspace
= snprintf (buf
, sizeof (buf
), NTXT ("%d"), max_lineno
);
801 // mspace is the space needed for all metrics, and the mark, if any
803 if (nmlist
->get_items ()->size () > 0)
805 mspace
= 3; // mark "## "
806 Vec_loop (Metric
*, nmlist
->get_items (), index
, mitem
)
808 if (mitem
->is_visible () || mitem
->is_tvisible ()
809 || mitem
->is_pvisible ())
810 mspace
+= (int) hist_metric
[index
].width
;
814 remain
= (mspace
+ lspace
+ 3) % 8; // " " before, ". " after line#
821 next_mark
= (mindex
< marks
->size ()) ? marks
->fetch (mindex
) : -1;
823 // Print the header for this list
824 SourceFile
*sf
= srcContext
? srcContext
: module
->getMainSrc ();
825 char *src_name
= sf
->dbeFile
->get_location_info ();
826 DbeFile
*df
= module
->dbeFile
;
827 if (df
== NULL
|| (df
->filetype
& DbeFile::F_JAVACLASS
) == 0)
828 df
= module
->loadobject
->dbeFile
;
829 char *lo_name
= df
->get_location_info ();
830 char *dot_o_name
= lo_name
;
831 if (module
->dot_o_file
)
832 dot_o_name
= module
->dot_o_file
->dbeFile
->get_location_info ();
833 fprintf (fp
, GTXT ("Source file: %s\nObject file: %s\nLoad Object: %s\n\n"),
834 src_name
, dot_o_name
, lo_name
);
836 // Print metric labels
837 if (nmlist
->get_items ()->size () != 0)
838 print_label (fp
, nmlist
, hist_metric
, 3);
840 // determine the name metric (not printed as a metric, though)
841 int lind
= nmlist
->get_listorder (GTXT ("name"), Metric::STATIC
);
843 // now loop over the data rows -- the lines in the annotated source/disasm,
844 // including index lines, compiler commentary, etc.
846 Vec_loop (Hist_data::HistItem
*, hdata
, hidx
, item
)
849 if (item
->type
== Module::AT_DIS
|| item
->type
== Module::AT_QUOTE
850 || item
->type
== Module::AT_SRC
)
852 // does this line get a high-metric mark?
853 if (hidx
== next_mark
)
855 sb
.append (NTXT ("## "));
857 next_mark
= (mindex
< marks
->size ()) ? marks
->fetch (mindex
) : -1;
860 sb
.append (NTXT (" "));
862 hdata
->print_row (&sb
, hidx
, hist_metric
, NTXT (" "));
864 for (int i
= sb
.length (); i
< mspace
; i
++)
870 // this line does not get any metrics; insert blanks in lieu of them
871 for (int i
= 0; i
< mspace
; i
++)
876 case Module::AT_SRC_ONLY
:
877 if (item
->obj
== NULL
)
878 fprintf (fp
, NTXT ("%*s. "), lspace
+ 1, "?");
880 fprintf (fp
, "%*d. ", lspace
+ 1, ((DbeLine
*) item
->obj
)->lineno
);
884 fprintf (fp
, "%*d. ", lspace
+ 1, ((DbeLine
*) item
->obj
)->lineno
);
886 case Module::AT_FUNC
:
887 case Module::AT_QUOTE
:
888 fprintf (fp
, NTXT ("%*c"), lspace
+ 3, ' ');
891 case Module::AT_DIS_ONLY
:
892 if (item
->obj
== NULL
|| ((DbeInstr
*) item
->obj
)->lineno
== -1)
893 fprintf (fp
, "%*c[%*s] ", lspace
+ 3, ' ', lspace
, "?");
895 fprintf (fp
, "%*c[%*d] ", lspace
+ 3, ' ', lspace
,
896 ((DbeInstr
*) item
->obj
)->lineno
);
899 case Module::AT_EMPTY
:
903 if (item
->value
[lind
].l
== NULL
)
904 item
->value
[lind
].l
= dbe_strdup (GTXT ("INTERNAL ERROR: missing line text"));
905 fprintf (fp
, NTXT ("%s\n"), item
->value
[lind
].l
);
911 er_print_histogram::dump_annotated ()
913 Vector
<int> *marks
= new Vector
<int>;
914 Function
*anno_func
= (Function
*) sel_obj
;
915 Module
*module
= anno_func
? anno_func
->module
: NULL
;
917 if (hist_data
->type
== Histable::DOBJECT
)
918 dump_annotated_dataobjects (marks
, number_entries
); // threshold
919 else if (number_entries
== 0)
921 dump_anno_file (out_file
, Histable::LINE
, module
, dbev
, mlist
,
922 hist_data
->get_totals ()->value
, NULL
, anno_func
, marks
,
923 dbev
->get_thresh_src (), dbev
->get_src_compcom (),
924 dbev
->get_src_visible (), dbev
->get_hex_visible (), true);
926 // Annotated disassembly
927 dump_anno_file (out_file
, Histable::INSTR
, module
, dbev
, mlist
,
928 hist_data
->get_totals ()->value
, NULL
, anno_func
, marks
,
929 dbev
->get_thresh_dis (), dbev
->get_dis_compcom (),
930 dbev
->get_src_visible (), dbev
->get_hex_visible (), true);
934 er_print_histogram::data_dump ()
937 if (hist_data
->get_status () == Hist_data::SUCCESS
)
939 if (sort_metric
[0] == '\n')
940 { // csingle Callers-Callees entry
942 fprintf (out_file
, NTXT ("%s\n\n"), sort_metric
);
944 else if (!sel_obj
&& type
!= MODE_LIST
)
946 if (hist_data
->type
== Histable::FUNCTION
)
948 GTXT ("Functions sorted by metric: %s\n\n"), sort_metric
);
949 else if (hist_data
->type
== Histable::DOBJECT
)
950 fprintf (out_file
, GTXT ("Dataobjects sorted by metric: %s\n\n"),
954 GTXT ("Objects sorted by metric: %s\n\n"), sort_metric
);
956 limit
= hist_data
->size ();
957 if ((number_entries
> 0) && (number_entries
< limit
))
958 limit
= number_entries
;
977 fprintf (out_file
, GTXT ("Get_Hist_data call failed %d\n"),
978 (int) hist_data
->get_status ());
982 * Class er_print_ctree to print functions call tree
984 er_print_ctree::er_print_ctree (DbeView
*_dbev
, Vector
<Histable
*> *_cstack
,
985 Histable
*_sobj
, int _limit
)
993 exp_idx2
= dbeSession
->nexps () - 1;
999 er_print_ctree::data_dump ()
1002 Hist_data::HistItem
*total
;
1003 sb
.append (GTXT ("Functions Call Tree. Metric: "));
1004 char *s
= dbev
->getSort (MET_CALL_AGR
);
1007 sb
.toFileLn (out_file
);
1008 fprintf (out_file
, NTXT ("\n"));
1009 mlist
= dbev
->get_metric_list (MET_CALL_AGR
);
1011 // Change cstack: add sobj to the end of cstack
1012 cstack
->append (sobj
);
1013 Hist_data
*center
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1014 Hist_data::SELF
, cstack
);
1015 Hist_data
*callers
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1016 Hist_data::CALLERS
, cstack
);
1017 Hist_data
*callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1018 Hist_data::CALLEES
, cstack
);
1021 int last
= cstack
->size () - 1;
1022 cstack
->remove (last
);
1025 int no_metrics
= mlist
->size ();
1027 // calculate max. width using data from callers, callees, center
1028 hist_metric
= allocateHistMetric (no_metrics
);
1029 callers
->update_max (hist_metric
);
1030 callees
->update_max (hist_metric
);
1031 center
->update_max (hist_metric
);
1032 callers
->update_legend_width (hist_metric
);
1033 callers
->print_label (out_file
, hist_metric
, 0); // returns Name column offset
1036 // Pass real total to print_children()
1037 total
= center
->get_totals ();
1038 print_children (center
, 0, sobj
, NTXT (" "), total
);
1045 delete[] hist_metric
;
1049 * Recursive method print_children prints Call Tree elements.
1052 er_print_ctree::print_children (Hist_data
*data
, int index
, Histable
*my_obj
,
1053 char * prefix
, Hist_data::HistItem
*total
)
1056 const char *P0
= "+-";
1057 const char *P2
= " |";
1058 const char *P1
= " ";
1060 // If limit exceeded - return
1062 if (limit
> 0 && print_row
> limit
)
1066 return; // should never happen
1069 buf
.append (prefix
);
1070 if (buf
.endsWith (P2
))
1072 int len
= buf
.length () - 1;
1073 buf
.setLength (len
);
1077 // Change cstack: add my_obj to the end of cstack
1078 cstack
->append (my_obj
);
1080 // Print current node info
1081 char * my_prefix
= buf
.toString ();
1083 // Replace parent's total values with real total values
1084 data
->update_total (total
); // Needed to to calculate percentage only
1086 data
->print_row (&buf
, index
, hist_metric
, my_prefix
);
1087 buf
.toFileLn (out_file
);
1091 Hist_data
*callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1092 Hist_data::CALLEES
, cstack
);
1093 int nc
= callees
->size ();
1097 Hist_data::HistItem
*item
;
1101 buf
.append (prefix
);
1103 ch_prefix
= buf
.toString ();
1104 for (int i
= 0; i
< nc
- 1; i
++)
1106 item
= callees
->fetch (i
);
1108 print_children (callees
, i
, ch_obj
, ch_prefix
, total
);
1112 buf
.append (prefix
);
1114 ch_prefix
= buf
.toString ();
1115 item
= callees
->fetch (nc
- 1);
1117 print_children (callees
, nc
- 1, ch_obj
, ch_prefix
, total
);
1122 int last
= cstack
->size () - 1;
1123 cstack
->remove (last
);
1128 er_print_gprof::er_print_gprof (DbeView
*_dbev
, Vector
<Histable
*> *_cstack
)
1133 exp_idx2
= dbeSession
->nexps () - 1;
1139 er_print_gprof::data_dump ()
1142 sb
.append (GTXT ("Callers and callees sorted by metric: "));
1143 char *s
= dbev
->getSort (MET_CALL
);
1146 sb
.toFileLn (out_file
);
1147 fprintf (out_file
, NTXT ("\n"));
1149 MetricList
*mlist
= dbev
->get_metric_list (MET_CALL
);
1150 Hist_data
*center
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1151 Hist_data::SELF
, cstack
);
1152 Hist_data
*callers
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1153 Hist_data::CALLERS
, cstack
);
1154 Hist_data
*callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1155 Hist_data::CALLEES
, cstack
);
1157 mlist
= center
->get_metric_list ();
1158 int no_metrics
= mlist
->get_items ()->size ();
1160 // update max. width for callers/callees/center function item
1161 Metric::HistMetric
*hist_metric
= allocateHistMetric (no_metrics
);
1162 callers
->update_max (hist_metric
);
1163 callees
->update_max (hist_metric
);
1164 center
->update_max (hist_metric
);
1166 callers
->update_legend_width (hist_metric
);
1167 int name_offset
= callers
->print_label (out_file
, hist_metric
, 0); // returns Name column offset
1170 for (int i
= 0; i
< name_offset
; i
++)
1171 sb
.append (NTXT ("="));
1172 if (name_offset
> 0)
1173 sb
.append (NTXT (" "));
1174 char *line1
= sb
.toString ();
1176 if (callers
->size () > 0)
1177 line2
= GTXT ("Callers");
1179 line2
= GTXT ("No Callers");
1180 fprintf (out_file
, NTXT ("%s%s\n"), line1
, line2
);
1181 callers
->print_content (out_file
, hist_metric
, callers
->size ());
1183 // Print Stack Fragment
1184 line2
= GTXT ("Stack Fragment");
1185 fprintf (out_file
, NTXT ("\n%s%s\n"), line1
, line2
);
1187 for (long i
= 0, last
= cstack
->size () - 1; i
<= last
; ++i
)
1190 if (i
== last
&& center
->size () > 0)
1192 center
->update_total (callers
->get_totals ()); // Needed to to calculate percentage only
1193 center
->print_row (&sb
, center
->size () - 1, hist_metric
, NTXT (" "));
1197 for (int n
= name_offset
; n
> 0; n
--)
1198 sb
.append (NTXT (" "));
1199 if (name_offset
> 0)
1200 sb
.append (NTXT (" "));
1201 sb
.append (cstack
->get (i
)->get_name ());
1203 sb
.toFileLn (out_file
);
1207 if (callees
->size () > 0)
1208 line2
= GTXT ("Callees");
1210 line2
= GTXT ("No Callees");
1211 fprintf (out_file
, NTXT ("\n%s%s\n"), line1
, line2
);
1212 callees
->print_content (out_file
, hist_metric
, callees
->size ());
1213 fprintf (out_file
, nl
);
1218 delete[] hist_metric
;
1221 er_print_leaklist::er_print_leaklist (DbeView
*_dbev
, bool show_leak
,
1222 bool show_alloca
, int _limit
)
1226 alloca
= show_alloca
;
1230 // Output routine for leak list only
1232 er_print_leaklist::data_dump ()
1235 CStack_data::CStack_item
*lae
;
1237 if (!dbeSession
->is_leaklist_available ())
1238 fprintf (out_file
, GTXT ("No leak or allocation information recorded in experiments\n\n"));
1240 MetricList
*origmlist
= dbev
->get_metric_list (MET_NORMAL
);
1243 // make a copy of the metric list, and set metrics for leaks
1244 MetricList
*nmlist
= new MetricList (origmlist
);
1245 nmlist
->set_metrics ("e.heapleakbytes:e.heapleakcnt:name", true,
1246 dbev
->get_derived_metrics ());
1248 // now make a compacted version of it to get the right indices
1249 MetricList
*mlist
= new MetricList (nmlist
);
1252 // fetch the callstack data
1253 lam
= dbev
->get_cstack_data (mlist
);
1256 if (lam
&& lam
->size () != 0)
1258 fprintf (out_file
, GTXT ("Summary Results: Distinct Leaks = %d, Total Instances = %lld, Total Bytes Leaked = %lld\n\n"),
1259 (int) lam
->size (), lam
->total
->value
[1].ll
,
1260 lam
->total
->value
[0].ll
);
1262 Vec_loop (CStack_data::CStack_item
*, lam
->cstack_items
, index
, lae
)
1265 GTXT ("Leak #%d, Instances = %lld, Bytes Leaked = %lld\n"),
1266 index
+ 1, lae
->value
[1].ll
, lae
->value
[0].ll
);
1267 if (lae
->stack
!= NULL
)
1268 for (int i
= lae
->stack
->size () - 1; i
>= 0; i
--)
1270 DbeInstr
*instr
= lae
->stack
->fetch (i
);
1271 fprintf (out_file
, NTXT (" %s\n"), instr
->get_name ());
1273 fprintf (out_file
, NTXT ("\n"));
1274 if (index
+ 1 == limit
) break;
1278 fprintf (out_file
, GTXT ("No leak information\n\n"));
1285 // make a copy of the metric list, and set metrics for leaks
1286 MetricList
*nmlist
= new MetricList (origmlist
);
1287 nmlist
->set_metrics ("e.heapallocbytes:e.heapalloccnt:name",
1288 true, dbev
->get_derived_metrics ());
1290 // now make a compacted version of it to get the right indices
1291 MetricList
*mlist
= new MetricList (nmlist
);
1294 // fetch the callstack data
1295 lam
= dbev
->get_cstack_data (mlist
);
1298 if (lam
&& lam
->size () != 0)
1300 fprintf (out_file
, GTXT ("Summary Results: Distinct Allocations = %d, Total Instances = %lld, Total Bytes Allocated = %lld\n\n"),
1301 (int) lam
->size (), lam
->total
->value
[1].ll
,
1302 lam
->total
->value
[0].ll
);
1303 Vec_loop (CStack_data::CStack_item
*, lam
->cstack_items
, index
, lae
)
1305 fprintf (out_file
, GTXT ("Allocation #%d, Instances = %lld, Bytes Allocated = %lld\n"),
1306 index
+ 1, lae
->value
[1].ll
, lae
->value
[0].ll
);
1307 if (lae
->stack
!= NULL
)
1308 for (int i
= lae
->stack
->size () - 1; i
>= 0; i
--)
1310 DbeInstr
*instr
= lae
->stack
->fetch (i
);
1311 fprintf (out_file
, NTXT (" %s\n"), instr
->get_name ());
1313 fprintf (out_file
, NTXT ("\n"));
1314 if (index
+ 1 == limit
) break;
1318 fprintf (out_file
, GTXT ("No allocation information\n\n"));
1324 er_print_heapactivity::er_print_heapactivity (DbeView
*_dbev
,
1325 Histable::Type _type
,
1326 bool _printStat
, int _limit
)
1330 printStat
= _printStat
;
1335 er_print_heapactivity::printCallStacks (Hist_data
*hist_data
)
1337 Hist_data::HistItem
*hi
;
1340 int size
= hist_data
->size ();
1341 if (limit
> 0 && limit
< size
)
1344 Histable::NameFormat fmt
= dbev
->get_name_format ();
1345 for (int i
= 0; i
< size
; i
++)
1347 hi
= hist_data
->fetch (i
);
1348 hData
= (HeapData
*) hi
->obj
;
1349 stackId
= hData
->id
;
1351 fprintf (out_file
, NTXT ("\n"));
1353 fprintf (out_file
, NTXT ("%s\n"), hData
->get_name (fmt
));
1354 if (hData
->getAllocCnt () > 0)
1356 fprintf (out_file
, GTXT ("Instances = %d "),
1357 (int) (hData
->getAllocCnt ()));
1358 fprintf (out_file
, GTXT ("Bytes Allocated = %lld\n"),
1359 (long long) hData
->getAllocBytes ());
1362 if (hData
->getLeakCnt () > 0)
1364 fprintf (out_file
, GTXT ("Instances = %d "),
1365 (int) (hData
->getLeakCnt ()));
1366 fprintf (out_file
, GTXT ("Bytes Leaked = %lld\n"),
1367 (long long) hData
->getLeakBytes ());
1370 // There is no stack trace for <Total>
1374 // LIBRARY VISIBILITY pass extra argument if necessary to get hide stack
1375 Vector
<Histable
*> *instrs
= CallStack::getStackPCs ((void *) stackId
);
1378 int stSize
= instrs
->size ();
1379 for (int j
= 0; j
< stSize
; j
++)
1381 Histable
*instr
= instrs
->fetch (j
);
1383 fprintf (out_file
, NTXT (" %s\n"), instr
->get_name ());
1391 er_print_heapactivity::printStatistics (Hist_data
*hist_data
)
1393 Hist_data::HistItem
*hi
;
1394 HeapData
*hDataTotal
;
1395 hi
= hist_data
->fetch (0);
1396 hDataTotal
= (HeapData
*) hi
->obj
;
1397 Vector
<hrtime_t
> *pTimestamps
;
1398 if (hDataTotal
->getPeakMemUsage () > 0)
1400 fprintf (out_file
, GTXT ("\nProcess With Highest Peak Memory Usage\n"));
1402 "-------------------------------------------------------\n");
1403 fprintf (out_file
, GTXT ("Heap size bytes %lld\n"),
1404 (long long) hDataTotal
->getPeakMemUsage ());
1405 fprintf (out_file
, GTXT ("Experiment Id %d\n"),
1406 (int) (hDataTotal
->getUserExpId ()));
1407 fprintf (out_file
, GTXT ("Process Id %d\n"),
1408 (int) (hDataTotal
->getPid ()));
1409 pTimestamps
= hDataTotal
->getPeakTimestamps ();
1410 if (pTimestamps
!= NULL
)
1411 for (int i
= 0; i
< pTimestamps
->size (); i
++)
1413 GTXT ("Time of peak %.3f (secs.)\n"),
1414 (double) (pTimestamps
->fetch (i
) / (double) NANOSEC
));
1417 if (hDataTotal
->getAllocCnt () > 0)
1419 fprintf (out_file
, GTXT ("\nMemory Allocations Statistics\n"));
1421 GTXT ("Allocation Size Range Allocations \n"));
1423 "-------------------------------------------------------\n");
1424 if (hDataTotal
->getA0KB1KBCnt () > 0)
1425 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
1426 hDataTotal
->getA0KB1KBCnt ());
1427 if (hDataTotal
->getA1KB8KBCnt () > 0)
1428 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
1429 hDataTotal
->getA1KB8KBCnt ());
1430 if (hDataTotal
->getA8KB32KBCnt () > 0)
1431 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
1432 hDataTotal
->getA8KB32KBCnt ());
1433 if (hDataTotal
->getA32KB128KBCnt () > 0)
1434 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
1435 hDataTotal
->getA32KB128KBCnt ());
1436 if (hDataTotal
->getA128KB256KBCnt () > 0)
1437 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
1438 hDataTotal
->getA128KB256KBCnt ());
1439 if (hDataTotal
->getA256KB512KBCnt () > 0)
1440 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
1441 hDataTotal
->getA256KB512KBCnt ());
1442 if (hDataTotal
->getA512KB1000KBCnt () > 0)
1443 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
1444 hDataTotal
->getA512KB1000KBCnt ());
1445 if (hDataTotal
->getA1000KB10MBCnt () > 0)
1446 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
1447 hDataTotal
->getA1000KB10MBCnt ());
1448 if (hDataTotal
->getA10MB100MBCnt () > 0)
1449 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
1450 hDataTotal
->getA10MB100MBCnt ());
1451 if (hDataTotal
->getA100MB1GBCnt () > 0)
1452 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
1453 hDataTotal
->getA100MB1GBCnt ());
1454 if (hDataTotal
->getA1GB10GBCnt () > 0)
1455 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
1456 hDataTotal
->getA1GB10GBCnt ());
1457 if (hDataTotal
->getA10GB100GBCnt () > 0)
1458 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
1459 hDataTotal
->getA10GB100GBCnt ());
1460 if (hDataTotal
->getA100GB1TBCnt () > 0)
1461 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
1462 hDataTotal
->getA100GB1TBCnt ());
1463 if (hDataTotal
->getA1TB10TBCnt () > 0)
1464 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
1465 hDataTotal
->getA1TB10TBCnt ());
1466 fprintf (out_file
, GTXT ("\nSmallest allocation bytes %lld\n"),
1467 (long long) hDataTotal
->getASmallestBytes ());
1468 fprintf (out_file
, GTXT ("Largest allocation bytes %lld\n"),
1469 (long long) hDataTotal
->getALargestBytes ());
1470 fprintf (out_file
, GTXT ("Total allocations %d\n"),
1471 hDataTotal
->getAllocCnt ());
1472 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
1473 (long long) hDataTotal
->getAllocBytes ());
1476 if (hDataTotal
->getLeakCnt () > 0)
1478 fprintf (out_file
, GTXT ("\nMemory Leaks Statistics\n"));
1480 GTXT ("Leak Size Range Leaks \n"));
1482 "-------------------------------------------------------\n");
1483 if (hDataTotal
->getL0KB1KBCnt () > 0)
1484 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
1485 hDataTotal
->getL0KB1KBCnt ());
1486 if (hDataTotal
->getL1KB8KBCnt () > 0)
1487 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
1488 hDataTotal
->getL1KB8KBCnt ());
1489 if (hDataTotal
->getL8KB32KBCnt () > 0)
1490 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
1491 hDataTotal
->getL8KB32KBCnt ());
1492 if (hDataTotal
->getL32KB128KBCnt () > 0)
1493 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
1494 hDataTotal
->getL32KB128KBCnt ());
1495 if (hDataTotal
->getL128KB256KBCnt () > 0)
1496 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
1497 hDataTotal
->getL128KB256KBCnt ());
1498 if (hDataTotal
->getL256KB512KBCnt () > 0)
1499 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
1500 hDataTotal
->getL256KB512KBCnt ());
1501 if (hDataTotal
->getL512KB1000KBCnt () > 0)
1502 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
1503 hDataTotal
->getL512KB1000KBCnt ());
1504 if (hDataTotal
->getL1000KB10MBCnt () > 0)
1505 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
1506 hDataTotal
->getL1000KB10MBCnt ());
1507 if (hDataTotal
->getL10MB100MBCnt () > 0)
1508 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
1509 hDataTotal
->getL10MB100MBCnt ());
1510 if (hDataTotal
->getL100MB1GBCnt () > 0)
1511 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
1512 hDataTotal
->getL100MB1GBCnt ());
1513 if (hDataTotal
->getL1GB10GBCnt () > 0)
1514 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
1515 hDataTotal
->getL1GB10GBCnt ());
1516 if (hDataTotal
->getL10GB100GBCnt () > 0)
1517 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
1518 hDataTotal
->getL10GB100GBCnt ());
1519 if (hDataTotal
->getL100GB1TBCnt () > 0)
1520 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
1521 hDataTotal
->getL100GB1TBCnt ());
1522 if (hDataTotal
->getL1TB10TBCnt () > 0)
1523 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
1524 hDataTotal
->getL1TB10TBCnt ());
1525 fprintf (out_file
, GTXT ("\nSmallest leaked bytes %lld\n"),
1526 (long long) hDataTotal
->getLSmallestBytes ());
1527 fprintf (out_file
, GTXT ("Largest leaked bytes %lld\n"),
1528 (long long) hDataTotal
->getLLargestBytes ());
1529 fprintf (out_file
, GTXT ("Total leaked %d \n"),
1530 hDataTotal
->getLeakCnt ());
1531 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
1532 (long long) hDataTotal
->getLeakBytes ());
1534 fprintf (out_file
, NTXT ("\n"));
1538 er_print_heapactivity::data_dump ()
1540 // get the list of heap events from DbeView
1541 int numExps
= dbeSession
->nexps ();
1545 GTXT ("There is no heap event information in the experiments\n"));
1548 MetricList
*mlist
= dbev
->get_metric_list (MET_HEAP
);
1549 Hist_data
*hist_data
;
1550 hist_data
= dbev
->get_hist_data (mlist
, type
, 0, Hist_data::ALL
);
1552 printStatistics (hist_data
);
1554 printCallStacks (hist_data
);
1557 er_print_ioactivity::er_print_ioactivity (DbeView
*_dbev
, Histable::Type _type
,
1558 bool _printStat
, int _limit
)
1562 printStat
= _printStat
;
1567 er_print_ioactivity::printCallStacks (Hist_data
*hist_data
)
1569 Hist_data::HistItem
*hi
;
1572 int size
= hist_data
->size ();
1573 if (limit
> 0 && limit
< size
)
1576 for (int i
= 0; i
< size
; i
++)
1578 hi
= hist_data
->fetch (i
);
1579 fData
= (FileData
*) hi
->obj
;
1580 stackId
= fData
->id
;
1582 fprintf (out_file
, NTXT ("\n"));
1583 fprintf (out_file
, NTXT ("%s\n"), fData
->getFileName ());
1584 if (fData
->getWriteCnt () > 0)
1586 fprintf (out_file
, GTXT ("Write Time=%.6f (secs.) "),
1587 (double) (fData
->getWriteTime () / (double) NANOSEC
));
1588 fprintf (out_file
, GTXT ("Write Bytes=%lld "),
1589 (long long) fData
->getWriteBytes ());
1590 fprintf (out_file
, GTXT ("Write Count=%d\n"),
1591 (int) (fData
->getWriteCnt ()));
1593 if (fData
->getReadCnt () > 0)
1595 fprintf (out_file
, GTXT ("Read Time=%.6f (secs.) "),
1596 (double) (fData
->getReadTime () / (double) NANOSEC
));
1597 fprintf (out_file
, GTXT ("Read Bytes=%lld "),
1598 (long long) fData
->getReadBytes ());
1599 fprintf (out_file
, GTXT ("Read Count=%d\n"),
1600 (int) fData
->getReadCnt ());
1602 if (fData
->getOtherCnt () > 0)
1604 fprintf (out_file
, GTXT ("Other I/O Time=%.6f (secs.) "),
1605 (double) (fData
->getOtherTime () / (double) NANOSEC
));
1606 fprintf (out_file
, GTXT ("Other I/O Count=%d\n"),
1607 (int) (fData
->getOtherCnt ()));
1609 if (fData
->getErrorCnt () > 0)
1611 fprintf (out_file
, GTXT ("I/O Error Time=%.6f (secs.) "),
1612 (double) (fData
->getErrorTime () / (double) NANOSEC
));
1613 fprintf (out_file
, GTXT ("I/O Error Count=%d\n"),
1614 (int) (fData
->getErrorCnt ()));
1617 // There is no stack trace for <Total>
1621 // LIBRARY VISIBILITY pass extra argument if necessary to get hide stack
1622 Vector
<Histable
*> *instrs
= CallStack::getStackPCs ((void *) stackId
);
1625 int stSize
= instrs
->size ();
1626 for (int j
= 0; j
< stSize
; j
++)
1628 Histable
*instr
= instrs
->fetch (j
);
1630 fprintf (out_file
, " %s\n", instr
->get_name ());
1638 er_print_ioactivity::printStatistics (Hist_data
*hist_data
)
1640 Hist_data::HistItem
*hi
;
1641 FileData
*fDataTotal
;
1643 hi
= hist_data
->fetch (0);
1644 fDataTotal
= (FileData
*) hi
->obj
;
1646 if (fDataTotal
->getWriteCnt () > 0)
1649 GTXT ("\nWrite Statistics\n"));
1651 GTXT ("I/O Size Range Write Calls \n"));
1653 "-------------------------------------------------------\n");
1654 if (fDataTotal
->getW0KB1KBCnt () > 0)
1655 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
1656 fDataTotal
->getW0KB1KBCnt ());
1657 if (fDataTotal
->getW1KB8KBCnt () > 0)
1658 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
1659 fDataTotal
->getW1KB8KBCnt ());
1660 if (fDataTotal
->getW8KB32KBCnt () > 0)
1661 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
1662 fDataTotal
->getW8KB32KBCnt ());
1663 if (fDataTotal
->getW32KB128KBCnt () > 0)
1664 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
1665 fDataTotal
->getW32KB128KBCnt ());
1666 if (fDataTotal
->getW128KB256KBCnt () > 0)
1667 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
1668 fDataTotal
->getW128KB256KBCnt ());
1669 if (fDataTotal
->getW256KB512KBCnt () > 0)
1670 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
1671 fDataTotal
->getW256KB512KBCnt ());
1672 if (fDataTotal
->getW512KB1000KBCnt () > 0)
1673 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
1674 fDataTotal
->getW512KB1000KBCnt ());
1675 if (fDataTotal
->getW1000KB10MBCnt () > 0)
1676 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
1677 fDataTotal
->getW1000KB10MBCnt ());
1678 if (fDataTotal
->getW10MB100MBCnt () > 0)
1679 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
1680 fDataTotal
->getW10MB100MBCnt ());
1681 if (fDataTotal
->getW100MB1GBCnt () > 0)
1682 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
1683 fDataTotal
->getW100MB1GBCnt ());
1684 if (fDataTotal
->getW1GB10GBCnt () > 0)
1685 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
1686 fDataTotal
->getW1GB10GBCnt ());
1687 if (fDataTotal
->getW10GB100GBCnt () > 0)
1688 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
1689 fDataTotal
->getW10GB100GBCnt ());
1690 if (fDataTotal
->getW100GB1TBCnt () > 0)
1691 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
1692 fDataTotal
->getW100GB1TBCnt ());
1693 if (fDataTotal
->getW1TB10TBCnt () > 0)
1694 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
1695 fDataTotal
->getW1TB10TBCnt ());
1697 GTXT ("\nLongest write %.6f (secs.)\n"),
1698 (double) (fDataTotal
->getWSlowestBytes () / (double) NANOSEC
));
1699 fprintf (out_file
, GTXT ("Smallest write bytes %lld\n"),
1700 (long long) fDataTotal
->getWSmallestBytes ());
1701 fprintf (out_file
, GTXT ("Largest write bytes %lld\n"),
1702 (long long) fDataTotal
->getWLargestBytes ());
1704 GTXT ("Total time %.6f (secs.)\n"),
1705 (double) (fDataTotal
->getWriteTime () / (double) NANOSEC
));
1706 fprintf (out_file
, GTXT ("Total calls %d\n"),
1707 fDataTotal
->getWriteCnt ());
1708 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
1709 (long long) fDataTotal
->getWriteBytes ());
1712 if (fDataTotal
->getReadCnt () > 0)
1715 GTXT ("\nRead Statistics\n"));
1717 GTXT ("I/O Size Range Read Calls \n"));
1719 "------------------------------------------------------\n");
1720 if (fDataTotal
->getR0KB1KBCnt () > 0)
1721 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
1722 fDataTotal
->getR0KB1KBCnt ());
1723 if (fDataTotal
->getR1KB8KBCnt () > 0)
1724 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
1725 fDataTotal
->getR1KB8KBCnt ());
1726 if (fDataTotal
->getR8KB32KBCnt () > 0)
1727 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
1728 fDataTotal
->getR8KB32KBCnt ());
1729 if (fDataTotal
->getR32KB128KBCnt () > 0)
1730 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
1731 fDataTotal
->getR32KB128KBCnt ());
1732 if (fDataTotal
->getR128KB256KBCnt () > 0)
1733 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
1734 fDataTotal
->getR128KB256KBCnt ());
1735 if (fDataTotal
->getR256KB512KBCnt () > 0)
1736 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
1737 fDataTotal
->getR256KB512KBCnt ());
1738 if (fDataTotal
->getR512KB1000KBCnt () > 0)
1739 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
1740 fDataTotal
->getR512KB1000KBCnt ());
1741 if (fDataTotal
->getR1000KB10MBCnt () > 0)
1742 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
1743 fDataTotal
->getR1000KB10MBCnt ());
1744 if (fDataTotal
->getR10MB100MBCnt () > 0)
1745 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
1746 fDataTotal
->getR10MB100MBCnt ());
1747 if (fDataTotal
->getR100MB1GBCnt () > 0)
1748 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
1749 fDataTotal
->getR100MB1GBCnt ());
1750 if (fDataTotal
->getR1GB10GBCnt () > 0)
1751 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
1752 fDataTotal
->getR1GB10GBCnt ());
1753 if (fDataTotal
->getR10GB100GBCnt () > 0)
1754 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
1755 fDataTotal
->getR10GB100GBCnt ());
1756 if (fDataTotal
->getR100GB1TBCnt () > 0)
1757 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
1758 fDataTotal
->getR100GB1TBCnt ());
1759 if (fDataTotal
->getR1TB10TBCnt () > 0)
1760 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
1761 fDataTotal
->getR1TB10TBCnt ());
1763 GTXT ("\nLongest time %.6f (secs.)\n"),
1764 (double) (fDataTotal
->getRSlowestBytes () / (double) NANOSEC
));
1765 fprintf (out_file
, GTXT ("Smallest read bytes %lld\n"),
1766 (long long) fDataTotal
->getRSmallestBytes ());
1767 fprintf (out_file
, GTXT ("Largest read bytes %lld\n"),
1768 (long long) fDataTotal
->getRLargestBytes ());
1770 GTXT ("Total time %.6f (secs.)\n"),
1771 (double) (fDataTotal
->getReadTime () / (double) NANOSEC
));
1772 fprintf (out_file
, GTXT ("Total calls %d\n"),
1773 fDataTotal
->getReadCnt ());
1774 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
1775 (long long) fDataTotal
->getReadBytes ());
1778 if (fDataTotal
->getOtherCnt () > 0)
1780 fprintf (out_file
, GTXT ("\nOther I/O Statistics\n"));
1782 "-----------------------------------------------------\n");
1784 GTXT ("Total time %.6f (secs.)\n"),
1785 (double) (fDataTotal
->getOtherTime () / (double) NANOSEC
));
1786 fprintf (out_file
, GTXT ("Total calls %d \n"),
1787 fDataTotal
->getOtherCnt ());
1789 if (fDataTotal
->getErrorCnt () > 0)
1791 fprintf (out_file
, GTXT ("\nI/O Error Statistics\n"));
1793 "-----------------------------------------------------\n");
1795 GTXT ("Total time %.6f (secs.)\n"),
1796 (double) (fDataTotal
->getErrorTime () / (double) NANOSEC
));
1797 fprintf (out_file
, GTXT ("Total calls %d \n"),
1798 fDataTotal
->getErrorCnt ());
1800 fprintf (out_file
, NTXT ("\n"));
1804 er_print_ioactivity::data_dump ()
1806 // get the list of io events from DbeView
1807 int numExps
= dbeSession
->nexps ();
1811 GTXT ("There is no IO event information in the experiments\n"));
1815 MetricList
*mlist
= dbev
->get_metric_list (MET_IO
);
1816 Hist_data
*hist_data
= dbev
->get_hist_data (mlist
, type
, 0, Hist_data::ALL
);
1817 if (type
== Histable::IOCALLSTACK
)
1818 printCallStacks (hist_data
);
1820 printStatistics (hist_data
);
1823 Metric::HistMetric
*hist_metric
= hist_data
->get_histmetrics ();
1824 hist_data
->print_label (out_file
, hist_metric
, 0);
1825 hist_data
->print_content (out_file
, hist_metric
, limit
);
1826 fprintf (out_file
, nl
);
1830 er_print_experiment::er_print_experiment (DbeView
*_dbev
, int bgn_idx
,
1831 int end_idx
, bool show_load
,
1832 bool show_header
, bool show_stat
,
1833 bool show_over
, bool show_odetail
)
1839 header
= show_header
;
1842 odetail
= show_odetail
;
1846 er_print_experiment::data_dump ()
1855 if (exp_idx2
> exp_idx1
)
1857 statistics_sum (maxlen
);
1858 fprintf (out_file
, nl
);
1861 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
1862 statistics_dump (index
, maxlen
);
1867 if (exp_idx2
> exp_idx1
)
1869 overview_sum (maxlen
);
1870 fprintf (out_file
, nl
);
1873 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
1874 overview_dump (index
, maxlen
);
1877 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
1879 if (index
!= exp_idx1
)
1881 "----------------------------------------------------------------\n");
1882 header_dump (index
);
1887 er_print_experiment::overview_sum (int &maxlen
)
1890 Ovw_data
*sum_data
= new Ovw_data ();
1891 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
1893 Ovw_data
*ovw_data
= dbev
->get_ovw_data (index
);
1894 if (ovw_data
== NULL
)
1896 sum_data
->sum (ovw_data
);
1900 fprintf (out_file
, GTXT ("<Sum across selected experiments>"));
1901 fprintf (out_file
, nl
);
1902 overview_summary (sum_data
, maxlen
);
1903 fprintf (out_file
, nl
);
1908 er_print_experiment::overview_dump (int exp_idx
, int &maxlen
)
1911 Ovw_data::Ovw_item ovw_item_labels
;
1912 Ovw_data::Ovw_item ovw_item
;
1916 ovw_data
= dbev
->get_ovw_data (exp_idx
);
1917 if (ovw_data
== NULL
)
1919 if (pr_params
.header
)
1920 header_dump (exp_idx
);
1922 fprintf (out_file
, GTXT ("Experiment: %s\n"),
1923 dbeSession
->get_exp (exp_idx
)->get_expt_name ());
1925 overview_summary (ovw_data
, maxlen
);
1932 //Get the collection params for the sample selection and display them.
1933 fprintf (out_file
, "\n\n%*s\n\n", max_len1
, GTXT ("Individual samples"));
1935 size
= ovw_data
->size ();
1936 ovw_item_labels
= ovw_data
->get_labels ();
1938 for (index
= 0; index
< size
; index
++)
1940 ovw_item
= ovw_data
->fetch (index
);
1941 fprintf (out_file
, "%*s: %d\n\n", max_len1
, GTXT ("Sample Number"),
1943 overview_item (&ovw_item
, &ovw_item_labels
);
1944 fprintf (out_file
, nl
);
1951 er_print_experiment::overview_summary (Ovw_data
*ovw_data
, int &maxlen
)
1955 Ovw_data::Ovw_item totals
;
1956 Ovw_data::Ovw_item ovw_item_labels
;
1957 totals
= ovw_data
->get_totals ();
1958 len
= snprintf (buf
, sizeof (buf
), "%.3lf", tstodouble (totals
.total
.t
));
1963 fprintf (out_file
, "%*s\n\n", max_len1
,
1964 GTXT ("Aggregated statistics for selected samples"));
1966 ovw_item_labels
= ovw_data
->get_labels ();
1967 overview_item (&totals
, &ovw_item_labels
);
1971 er_print_experiment::overview_item (Ovw_data::Ovw_item
*ovw_item
,
1972 Ovw_data::Ovw_item
*ovw_item_labels
)
1974 double start
, end
, total_value
;
1976 timestruc_t total_time
= {0, 0};
1978 start
= tstodouble (ovw_item
->start
);
1979 end
= tstodouble (ovw_item
->end
);
1981 fprintf (out_file
, "%*s: %s\n", max_len1
, GTXT ("Start Label"),
1982 ovw_item
->start_label
);
1983 fprintf (out_file
, "%*s: %s\n", max_len1
, GTXT ("End Label"),
1984 ovw_item
->end_label
);
1986 fprintf (out_file
, "%*s: ", max_len1
, GTXT ("Start Time (sec.)"));
1988 fprintf (out_file
, GTXT ("N/A"));
1990 fprintf (out_file
, "%*.3f", max_len2
, start
);
1991 fprintf (out_file
, nl
);
1992 fprintf (out_file
, "%*s: ", max_len1
, GTXT ("End Time (sec.)"));
1994 fprintf (out_file
, GTXT ("N/A"));
1996 fprintf (out_file
, "%*.3f", max_len2
, end
);
1997 fprintf (out_file
, nl
);
1998 fprintf (out_file
, "%*s: ", max_len1
, GTXT ("Duration (sec.)"));
1999 fprintf (out_file
, "%*.3f", max_len2
, tstodouble (ovw_item
->duration
));
2000 fprintf (out_file
, NTXT ("\n"));
2002 size
= ovw_item
->size
;
2003 for (index
= 0; index
< size
; index
++)
2004 tsadd (&total_time
, &ovw_item
->values
[index
].t
);
2006 total_value
= tstodouble (total_time
);
2007 fprintf (out_file
, "%*s: %*.3f", max_len1
, GTXT ("Total Thread Time (sec.)"),
2008 max_len2
, tstodouble (ovw_item
->tlwp
));
2009 fprintf (out_file
, NTXT ("\n"));
2010 fprintf (out_file
, "%*s: ", max_len1
, GTXT ("Average number of Threads"));
2011 if (tstodouble (ovw_item
->duration
) != 0)
2012 fprintf (out_file
, "%*.3f", max_len2
, ovw_item
->nlwp
);
2014 fprintf (out_file
, GTXT ("N/A"));
2015 fprintf (out_file
, NTXT ("\n\n"));
2016 fprintf (out_file
, "%*s:\n", max_len1
, GTXT ("Process Times (sec.)"));
2017 for (index
= 1; index
< size
; index
++)
2019 overview_value (&ovw_item_labels
->values
[index
], ovw_item_labels
->type
,
2021 overview_value (&ovw_item
->values
[index
], ovw_item
->type
,
2023 fprintf (out_file
, NTXT ("\n"));
2028 er_print_experiment::overview_value (Value
*value
, ValueTag value_tag
,
2035 fprintf (out_file
, "%*s: ", max_len1
, value
->l
);
2038 dvalue
= tstodouble (value
->t
);
2040 fprintf (out_file
, "%*s ( 0. %%)", max_len3
, "0. ");
2042 fprintf (out_file
, "%*.3f (%5.1f%%)", max_len3
, dvalue
,
2043 100.0 * dvalue
/ total_value
);
2046 fprintf (out_file
, NTXT ("%d"), value
->i
);
2049 fprintf (out_file
, "%*.3f", max_len3
, total_value
);
2054 er_print_experiment::statistics_sum (int &maxlen
)
2058 Stats_data
*sum_data
= new Stats_data ();
2059 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
2061 Stats_data
*stats_data
= dbev
->get_stats_data (index
);
2062 if (stats_data
== NULL
)
2064 sum_data
->sum (stats_data
);
2068 // get the maximum width of values
2069 size
= sum_data
->size ();
2070 for (index
= 0; index
< size
; index
++)
2072 len
= (int) sum_data
->fetch (index
).value
.get_len ();
2077 // print overview average
2078 overview_sum (maxlen
);
2080 // print statistics data
2082 statistics_item (sum_data
);
2087 er_print_experiment::statistics_dump (int exp_idx
, int &maxlen
)
2089 Stats_data
*stats_data
;
2092 stats_data
= dbev
->get_stats_data (exp_idx
);
2093 if (stats_data
== NULL
)
2095 if (pr_params
.header
)
2097 header_dump (exp_idx
);
2098 fprintf (out_file
, nl
);
2101 fprintf (out_file
, GTXT ("Experiment: %s\n"),
2102 dbeSession
->get_exp (exp_idx
)->get_expt_name ());
2104 // get the maximum width of values
2105 size
= stats_data
->size ();
2106 for (index
= 0; index
< size
; index
++)
2108 len
= (int) stats_data
->fetch (index
).value
.get_len ();
2113 // print overview average
2114 overview_dump (exp_idx
, maxlen
);
2115 fprintf (out_file
, nl
);
2117 // print statistics data
2119 statistics_item (stats_data
);
2124 er_print_experiment::statistics_item (Stats_data
*stats_data
)
2127 Stats_data::Stats_item stats_item
;
2129 size
= stats_data
->size ();
2130 for (index
= 0; index
< size
; index
++)
2132 stats_item
= stats_data
->fetch (index
);
2133 fprintf (out_file
, "%*s: %*s\n", max_len1
, stats_item
.label
,
2134 max_len2
, stats_item
.value
.to_str (buf
, sizeof (buf
)));
2136 fprintf (out_file
, nl
);
2139 // Print annotated source or disassembly -- called by er_print only
2141 print_anno_file (char *name
, const char *sel
, const char *srcFile
,
2142 bool isDisasm
, FILE *dis_file
, FILE *inp_file
, FILE *out_file
,
2143 DbeView
*dbev
, bool xdefault
)
2149 Hist_data
*hist_data
;
2157 bool srcmetrics_visible
;
2159 if ((name
== NULL
) || (strlen (name
) == 0))
2161 fprintf (stderr
, GTXT ("Error: No function or file has been specified.\n"));
2165 // find the function from the name
2166 if (!dbeSession
->find_obj (dis_file
, inp_file
, obj
, name
, sel
,
2167 Histable::FUNCTION
, xdefault
))
2172 // source or disassembly for <Total>, <Unknown>, or @plt
2173 if (obj
->get_type () != Histable::FUNCTION
)
2176 GTXT ("Error: %s is not a real function; no source or disassembly available.\n"),
2181 func
= (Function
*) obj
;
2182 if (func
->flags
& FUNC_FLAG_SIMULATED
)
2185 GTXT ("Error: %s is not a real function; no source or disassembly available.\n"),
2189 else if (dbev
!= NULL
&& isDisasm
)
2190 dbev
->set_func_scope (true);
2192 // function found, set module
2193 module
= func
->module
;
2194 int ix
= module
->loadobject
->seg_idx
;
2195 if (dbev
->get_lo_expand (ix
) == LIBEX_HIDE
)
2197 char *lo_name
= module
->loadobject
->get_name ();
2199 GTXT ("Error: No source or disassembly available for hidden object %s.\n"),
2206 Vector
<SourceFile
*> *sources
= func
->get_sources ();
2208 if (sources
== NULL
)
2210 fitem
= func
->getDefSrc ();
2211 found
= (func
->line_first
> 0)
2212 && strcmp (get_basename (srcFile
),
2213 get_basename (fitem
->get_name ())) == 0;
2217 Vec_loop (SourceFile
*, sources
, index
, fitem
)
2219 if (strcmp (get_basename (srcFile
), get_basename (fitem
->get_name ())) == 0)
2228 fprintf (stderr
, GTXT ("Error: Source file context %s does not contribute to function `%s'.\n"),
2236 // function not found
2237 if (sel
&& strrchr (sel
, ':'))
2239 // 'sel' was "@seg_num:address" or "file_name:address"
2241 GTXT ("Error: No function with given name `%s %s' found.\n"),
2245 // search for a file of that name
2246 if (!dbeSession
->find_obj (dis_file
, inp_file
, obj
, name
, sel
,
2247 Histable::MODULE
, xdefault
))
2251 { // neither function nor file found
2252 fprintf (stderr
, GTXT ("Error: No function or file with given name `%s' found.\n"),
2258 module
= (Module
*) obj
;
2259 int ix
= module
->loadobject
->seg_idx
;
2260 if (dbev
->get_lo_expand (ix
) == LIBEX_HIDE
)
2262 char *lo_name
= module
->loadobject
->get_name ();
2263 fprintf (stderr
, GTXT ("Error: No source or disassembly available for hidden object %s.\n"),
2271 if (module
== NULL
|| module
->get_name () == NULL
)
2273 fprintf (stderr
, GTXT ("Error: Object name not recorded in experiment\n"));
2276 module
->read_stabs ();
2278 if (!isDisasm
&& (module
->file_name
== NULL
2279 || (module
->flags
& MOD_FLAG_UNKNOWN
) != 0
2280 || *module
->file_name
== 0))
2282 fprintf (stderr
, GTXT ("Error: Source location not recorded in experiment\n"));
2286 MetricList
*metric_list
= dbev
->get_metric_list (MET_NORMAL
);
2287 int sort_ref_index
= metric_list
->get_sort_ref_index ();
2289 metric_list
->set_sort_ref_index (-1);
2291 // Ask DbeView to generate function-level data
2292 // MSI: I think this is used only to get totals to compute percentages
2293 hist_data
= dbev
->get_hist_data (metric_list
, Histable::FUNCTION
, 0,
2295 MetricList
*nmlist
= hist_data
->get_metric_list ();
2296 metric_list
->set_sort_ref_index (sort_ref_index
);
2297 if (nmlist
->get_items ()->size () != 0
2298 && hist_data
->get_status () != Hist_data::SUCCESS
)
2300 errstr
= DbeView::status_str (DbeView::DBEVIEW_NO_DATA
);
2303 fprintf (stderr
, GTXT ("Error: %s\n"), errstr
);
2309 marks
= new Vector
<int>;
2312 threshold
= dbev
->get_thresh_dis ();
2313 compcom_bits
= dbev
->get_dis_compcom ();
2314 src_visible
= dbev
->get_src_visible ();
2315 hex_visible
= dbev
->get_hex_visible ();
2316 srcmetrics_visible
= dbev
->get_srcmetric_visible ();
2320 threshold
= dbev
->get_thresh_src ();
2321 compcom_bits
= dbev
->get_src_compcom ();
2322 src_visible
= SRC_NA
;
2323 hex_visible
= false;
2324 srcmetrics_visible
= false;
2327 dump_anno_file (out_file
, isDisasm
? Histable::INSTR
: Histable::LINE
,
2328 module
, dbev
, nmlist
, hist_data
->get_totals ()->value
,
2329 srcFile
, func
, marks
, threshold
, compcom_bits
,
2330 src_visible
, hex_visible
, srcmetrics_visible
);
2334 errstr
= module
->anno_str ();
2337 fprintf (stderr
, GTXT ("Error: %s\n"), errstr
);
2344 print_html_title (FILE *out_file
, char *title
)
2346 // This will print a header row for the report
2347 fprintf (out_file
, "<html><title>%s</title>\n", title
);
2348 fprintf (out_file
, "<center><h3>%s</h3></center>\n", title
);
2352 print_html_label (FILE *out_file
, MetricList
*metrics_list
)
2356 // This will print a header row for the metrics
2357 Vector
<Metric
*> *mlist
= metrics_list
->get_items ();
2358 mlist_sz
= mlist
->size ();
2360 fprintf (out_file
, "<style type=\"text/css\">\n");
2361 fprintf (out_file
, "<!--\nBODY\n");
2362 fprintf (out_file
, ".th_C { text-align:center; background-color:lightgoldenrodyellow; }\n");
2363 fprintf (out_file
, ".th_CG { text-align:center; background-color:#ffff33; }\n");
2364 fprintf (out_file
, ".th_L { text-align:left; background-color:lightgoldenrodyellow; }\n");
2365 fprintf (out_file
, ".th_LG { text-align:left; background-color:#ffff33; }\n");
2366 fprintf (out_file
, ".td_R { text-align:right; }\n");
2367 fprintf (out_file
, ".td_RG { text-align:right; background-color:#ffff33; }\n");
2368 fprintf (out_file
, ".td_L { text-align:left; }\n");
2369 fprintf (out_file
, ".td_LG { text-align:left; background-color:#ffff33; }\n");
2370 fprintf (out_file
, "-->\n</style>");
2371 fprintf (out_file
, "<center><table border=1 cellspacing=2>\n<tr>");
2373 for (int index
= 0; index
< mlist_sz
; index
++)
2375 Metric
*mitem
= mlist
->fetch (index
);
2377 if (mitem
->is_visible ())
2379 if (mitem
->is_tvisible ())
2381 if (mitem
->is_pvisible ())
2385 char *name
= strdup (mitem
->get_name ());
2386 char *name2
= split_metric_name (name
);
2387 const char *style
= index
== metrics_list
->get_sort_ref_index () ? "G" : "";
2389 // start the column, with colspan setting, legend, and sort metric indicator
2392 if (mitem
->get_vtype () == VT_LABEL
)
2393 // left-adjust the name metric
2395 "<th class=\"th_L%s\">%s <br>%s %s <br>%s </th>",
2396 style
, mitem
->legend
== NULL
? " " : mitem
->legend
,
2397 (index
== metrics_list
->get_sort_ref_index ()) ? "∇" : " ",
2398 name
, name2
== NULL
? " " : name2
);
2400 // but center the others
2402 "<th class=\"th_C%s\">%s <br>%s %s <br>%s </th>",
2403 style
, mitem
->legend
== NULL
? " " : mitem
->legend
,
2404 (index
== metrics_list
->get_sort_ref_index ()) ?
2405 "∇" : " ",
2406 name
, name2
== NULL
? NTXT (" ") : name2
);
2409 // name metric can't span columns
2411 "<th colspan=%d class=\"th_C%s\">%s <br>%s %s <br>%s </th>",
2413 mitem
->legend
== NULL
? " " : mitem
->legend
,
2414 index
== metrics_list
->get_sort_ref_index () ?
2415 "∇" : " ",
2416 name
, name2
== NULL
? " " : name2
);
2421 // end this row, start the units row
2422 fprintf (out_file
, NTXT ("</tr>\n<tr>"));
2424 // now do the units row
2425 for (int index
= 0; index
< mlist_sz
; index
++)
2427 Metric
*mitem
= mlist
->fetch (index
);
2428 const char *style
= index
== metrics_list
->get_sort_ref_index () ? "G" : "";
2430 if (mitem
->is_tvisible ())
2431 fprintf (out_file
, "<th class=\"th_C%s\"> (%s)</th>", style
,
2433 if (mitem
->is_visible ())
2435 if (mitem
->get_abbr_unit () == NULL
)
2436 fprintf (out_file
, "<th class=\"th_C%s\"> </th>", style
);
2438 fprintf (out_file
, "<th class=\"th_C%s\">(%s)</th>", style
,
2439 mitem
->get_abbr_unit () == NULL
? " "
2440 : mitem
->get_abbr_unit ());
2442 if (mitem
->is_pvisible ())
2443 fprintf (out_file
, "<th class=\"th_C%s\"> (%%)</th>", style
);
2445 fprintf (out_file
, NTXT ("</tr>\n"));
2449 print_html_content (FILE *out_file
, Hist_data
*data
, MetricList
*metrics_list
,
2450 int limit
, Histable::NameFormat nfmt
)
2452 Hist_data::HistItem
*item
;
2454 // printing contents.
2455 for (int i
= 0; i
< limit
; i
++)
2457 item
= data
->fetch (i
);
2458 print_html_one (out_file
, data
, item
, metrics_list
, nfmt
);
2463 print_html_one (FILE *out_file
, Hist_data
*data
, Hist_data::HistItem
*item
,
2464 MetricList
*metrics_list
, Histable::NameFormat nfmt
)
2468 int visible
, tvisible
, pvisible
;
2472 fprintf (out_file
, NTXT ("<tr>"));
2473 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
2475 visible
= mitem
->is_visible ();
2476 tvisible
= mitem
->is_tvisible ();
2477 pvisible
= mitem
->is_pvisible ();
2478 const char *style
= index
== metrics_list
->get_sort_ref_index () ? "G" : "";
2482 value
= &(item
->value
[index
]);
2483 if (value
->ll
== 0LL)
2485 "<td class=\"td_R%s\"><tt>0. </tt></td>",
2488 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%4.3lf</tt></td>",
2489 style
, 1.e
-6 * value
->ll
/ dbeSession
->get_clock (-1));
2494 if (mitem
->get_vtype () == VT_LABEL
)
2496 value
= &(item
->value
[index
]);
2498 if (value
->tag
== VT_OFFSET
)
2499 r
= ((DataObject
*) (item
->obj
))->get_offset_name ();
2501 r
= item
->obj
->get_name (nfmt
);
2502 char *n
= html_ize_name (r
);
2503 fprintf (out_file
, NTXT ("<td class=\"td_L%s\">%s</td>"), style
, n
);
2508 value
= &(item
->value
[index
]);
2512 if (value
->d
== 0.0)
2514 "<td class=\"td_R%s\"><tt>0. </tt></td>",
2518 "<td class=\"td_R%s\"><tt>%4.3lf</tt></td>", style
,
2522 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%d</tt></td>",
2526 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%lld</td></tt>",
2530 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%llu</td></tt>",
2535 "<td class=\"td_R%s\"><tt>%u:0x%08x</tt></td>", style
,
2536 ADDRESS_SEG (value
->ll
), ADDRESS_OFF (value
->ll
));
2539 if (value
->f
== 0.0)
2541 "<td class=\"td_R%s\"><tt>0. </tt></td>",
2545 "<td class=\"td_R%s\"><tt>%4.3f</tt></td>",
2549 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%d</tt></td>",
2552 // ignoring the following cases (why?)
2563 percent
= data
->get_percentage (item
->value
[index
].to_double (), index
);
2565 // adjust to change format from xx.yy%
2566 fprintf (out_file
, "<td class=\"td_R%s\">0. </td>",
2569 // adjust format below to change format from xx.yy%
2570 fprintf (out_file
, "<td class=\"td_R%s\">%3.2f</td>", style
,
2574 fprintf (out_file
, NTXT ("</tr>\n"));
2578 print_html_trailer (FILE *out_file
)
2580 fprintf (out_file
, NTXT ("</table></center></html>\n"));
2586 size_t len
= strlen (s
);
2593 print_delim_label (FILE *out_file
, MetricList
*metrics_list
, char delim
)
2595 char line0
[2 * MAX_LEN
], line1
[2 * MAX_LEN
];
2596 char line2
[2 * MAX_LEN
], line3
[2 * MAX_LEN
];
2599 // This will print four header rows for the metrics
2604 Vector
<Metric
*> *mlist
= metrics_list
->get_items ();
2605 for (int index
= 0, mlist_sz
= mlist
->size (); index
< mlist_sz
; index
++)
2607 Metric
*mitem
= mlist
->fetch (index
);
2608 if (!(mitem
->is_visible () || mitem
->is_tvisible ()
2609 || mitem
->is_pvisible ()))
2611 char *name
= strdup (mitem
->get_name ());
2612 char *name2
= split_metric_name (name
);
2614 if (mitem
->is_tvisible ())
2616 len
= strlen (line0
);
2617 snprintf (line0
+ len
, sizeof (line0
) - len
, NTXT ("\"%s\"%c"),
2618 mitem
->legend
== NULL
? NTXT ("") : mitem
->legend
, delim
);
2619 len
= strlen (line1
);
2620 snprintf (line1
+ len
, sizeof (line1
) - len
, NTXT ("\"%s\"%c"),
2622 len
= strlen (line2
);
2623 snprintf (line2
+ len
, sizeof (line2
) - len
, NTXT ("\"%s\"%c"),
2624 name2
== NULL
? NTXT ("") : name2
, delim
);
2625 len
= strlen (line3
);
2626 if (index
== metrics_list
->get_sort_ref_index ())
2627 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\"V %s\"%c"),
2628 GTXT ("(sec.)"), delim
);
2630 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\" %s\"%c"),
2631 GTXT ("(sec.)"), delim
);
2633 if (mitem
->is_visible ())
2635 len
= strlen (line0
);
2636 snprintf (line0
+ len
, sizeof (line0
) - len
, "\"%s\"%c",
2637 mitem
->legend
== NULL
? "" : mitem
->legend
, delim
);
2639 len
= strlen (line1
);
2640 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%s\"%c",
2643 len
= strlen (line2
);
2644 snprintf (line2
+ len
, sizeof (line2
) - len
, "\"%s\"%c",
2645 name2
== NULL
? NTXT ("") : name2
, delim
);
2647 len
= strlen (line3
);
2648 char *au
= mitem
->get_abbr_unit ();
2650 if (index
== metrics_list
->get_sort_ref_index ())
2653 snprintf (line3
+ len
, sizeof (line3
) - len
, "\"V \"%c", delim
);
2655 snprintf (line3
+ len
, sizeof (line3
) - len
, "\"V (%s)\"%c",
2661 snprintf (line3
+ len
, sizeof (line3
) - len
, "\" \"%c",
2664 snprintf (line3
+ len
, sizeof (line3
) - len
, "\" (%s)\"%c",
2668 if (mitem
->is_pvisible ())
2670 len
= strlen (line0
);
2671 snprintf (line0
+ len
, sizeof (line0
) - len
, NTXT ("\"%s\"%c"),
2672 mitem
->legend
== NULL
? NTXT ("") : mitem
->legend
, delim
);
2674 len
= strlen (line1
);
2675 snprintf (line1
+ len
, sizeof (line1
) - len
, NTXT ("\"%s\"%c"),
2678 len
= strlen (line2
);
2679 snprintf (line2
+ len
, sizeof (line2
) - len
, NTXT ("\"%s\"%c"),
2680 name2
== NULL
? NTXT ("") : name2
, delim
);
2682 len
= strlen (line3
);
2683 if (index
== metrics_list
->get_sort_ref_index ())
2684 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\"V %s\"%c"),
2685 NTXT ("%%"), delim
);
2687 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\" %s\"%c"),
2688 NTXT ("%%"), delim
);
2692 // now remove the trailing delimiter, and print the four lines
2693 fprintf (out_file
, NTXT ("%s\n"), del_delim (line0
));
2694 fprintf (out_file
, NTXT ("%s\n"), del_delim (line1
));
2695 fprintf (out_file
, NTXT ("%s\n"), del_delim (line2
));
2696 fprintf (out_file
, NTXT ("%s\n"), del_delim (line3
));
2700 print_delim_content (FILE *out_file
, Hist_data
*data
, MetricList
*metrics_list
,
2701 int limit
, Histable::NameFormat nfmt
, char delim
)
2703 Hist_data::HistItem
*item
;
2706 // printing contents.
2707 for (i
= 0; i
< limit
; i
++)
2709 item
= data
->fetch (i
);
2710 print_delim_one (out_file
, data
, item
, metrics_list
, nfmt
, delim
);
2715 print_delim_trailer (FILE */
*out_file*/
, char /*delim*/) { }
2717 // EUGENE does this function work properly when "-compare ratio" is used?
2718 // how about when the ratio is nonzero-divided-by-zero?
2719 // EUGENE actually, review this entire file
2722 print_delim_one (FILE *out_file
, Hist_data
*data
, Hist_data::HistItem
*item
,
2723 MetricList
*metrics_list
, Histable::NameFormat nfmt
,
2728 int visible
, tvisible
, pvisible
;
2733 char line1
[2 * MAX_LEN
];
2735 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
2737 visible
= mitem
->is_visible ();
2738 tvisible
= mitem
->is_tvisible ();
2739 pvisible
= mitem
->is_pvisible ();
2742 value
= &(item
->value
[index
]);
2743 len
= strlen (line1
);
2744 if (value
->ll
== 0LL)
2745 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c", delim
);
2747 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%4.3lf\"%c",
2748 1.e
-6 * value
->ll
/ dbeSession
->get_clock (-1),
2754 len
= strlen (line1
);
2755 if (mitem
->get_vtype () == VT_LABEL
)
2757 value
= &(item
->value
[index
]);
2759 if (value
->tag
== VT_OFFSET
)
2760 r
= ((DataObject
*) (item
->obj
))->get_offset_name ();
2762 r
= item
->obj
->get_name (nfmt
);
2763 char *p
= csv_ize_name (r
, delim
);
2764 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%s\"%c", p
, delim
);
2769 value
= &(item
->value
[index
]);
2773 if (value
->d
== 0.0)
2774 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c",
2777 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%4.3lf\"%c",
2781 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%d\"%c",
2785 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%lld\"%c",
2789 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%llu\"%c",
2793 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%u:0x%08x\"%c",
2794 ADDRESS_SEG (value
->ll
),
2795 ADDRESS_OFF (value
->ll
), delim
);
2798 if (value
->f
== 0.0)
2799 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c",
2802 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%4.3f\"%c",
2806 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%d\"%c",
2809 // ignoring the following cases (why?)
2820 len
= strlen (line1
);
2821 percent
= data
->get_percentage (item
->value
[index
].to_double (), index
);
2823 // adjust to change format from xx.yy%
2824 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c", delim
);
2826 // adjust format below to change format from xx.yy%
2827 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%3.2f\"%c",
2828 (100.0 * percent
), delim
);
2831 fprintf (out_file
, NTXT ("%s\n"), del_delim (line1
));
2835 html_ize_name (char *name
)
2838 for (size_t i
= 0; i
< strlen (name
); i
++)
2842 case ' ': sb
.append (NTXT (" "));
2844 case '"': sb
.append (NTXT ("""));
2846 case '&': sb
.append (NTXT ("&"));
2848 case '<': sb
.append (NTXT ("<"));
2850 case '>': sb
.append (NTXT (">"));
2852 default: sb
.append (name
[i
]);
2856 char *ret
= sb
.toString ();
2861 csv_ize_name (char *name
, char /*delim*/)
2864 for (size_t i
= 0; i
< strlen (name
); i
++)
2865 sb
.append (name
[i
]);
2866 char *ret
= sb
.toString ();
2870 // Split a metric name into two parts, replacing a blank with
2871 // a zero and returning pointer to the rest of the string, or
2872 // leaving the string unchanged, and returning NULL;
2875 split_metric_name (char *name
)
2877 // figure out the most even split of the name
2878 size_t len
= strlen (name
);
2879 char *middle
= &name
[len
/ 2];
2881 // find the first blank
2882 char *first
= strchr (name
, (int) ' ');
2883 if (first
== NULL
) // no blanks
2889 p
= strchr (p
+ 1, (int) ' ');
2903 // pick the better of the two
2905 int f
= (int) (middle
- first
);
2906 int l
= (int) (last
- middle
);
2907 if ((first
== last
) || (f
<= l
))