1 /* Copyright (C) 2021 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. */
32 #include <sys/types.h>
37 #include "StringBuilder.h"
38 #include "DbeSession.h"
43 #include "Experiment.h"
44 #include "MetricList.h"
47 #include "DataSpace.h"
48 #include "DataObject.h"
49 #include "FilterExp.h"
50 #include "LoadObject.h"
54 #include "CallStack.h"
57 er_print_common_display::open (Print_params
*params
)
60 pr_params
.name
= dbe_strdup (params
->name
);
61 if (params
->dest
== DEST_PRINTER
)
63 tmp_file
= dbeSession
->get_tmp_file_name (NTXT ("print"), false);
64 dbeSession
->tmp_files
->append (strdup (tmp_file
));
65 out_file
= fopen (tmp_file
, NTXT ("w"));
67 else if (params
->dest
== DEST_OPEN_FILE
)
68 out_file
= pr_params
.openfile
;
70 out_file
= fopen (pr_params
.name
, NTXT ("w"));
79 er_print_common_display::print_output ()
83 if (pr_params
.dest
!= DEST_OPEN_FILE
)
86 if (pr_params
.dest
== DEST_PRINTER
)
88 if (streq ((char *) pr_params
.name
, NTXT ("")))
89 sys_call
= dbe_sprintf ("(/usr/bin/lp -c -n%d %s) 2>/dev/null 1>&2",
90 pr_params
.ncopies
, tmp_file
);
92 sys_call
= dbe_sprintf ("(/usr/bin/lp -c -d%s -n%d %s) 2>/dev/null 1>&2",
93 pr_params
.name
, pr_params
.ncopies
, tmp_file
);
94 if (system (sys_call
) != 0)
103 // Return the report. If the report size is greater than max, return truncated report
104 // Allocates memory, so the caller should free this memory.
107 er_print_common_display::get_output (int maxsize
)
109 off_t max
= (off_t
) maxsize
;
110 if (out_file
!= (FILE *) NULL
)
112 fclose (out_file
); // close tmp_file
113 out_file
= (FILE *) NULL
;
116 int st
= stat (tmp_file
, &sbuf
);
119 off_t sz
= sbuf
.st_size
;
121 return dbe_sprintf (GTXT ("Error: report is too long.\n"));
123 return dbe_sprintf (GTXT ("Error: empty temporary file: %s\n"),
128 FILE *f
= fopen (tmp_file
, "r");
130 return dbe_sprintf (GTXT ("Error: cannot open temporary file: %s\n"),
132 char *report
= (char *) malloc (max
);
135 if (1 != fread (report
, max
- 1, 1, f
))
139 return dbe_sprintf (GTXT ("Error: cannot read temporary file: %s\n"),
149 er_print_common_display::header_dump (int exp_idx
)
151 if (load
&& (exp_idx
== exp_idx1
))
154 print_load_object (out_file
);
156 print_header (dbeSession
->get_exp (exp_idx
), out_file
);
160 pr_load_objects (Vector
<LoadObject
*> *loadobjects
, char *lead
)
168 size
= loadobjects
->size ();
169 for (i
= 0; i
< size
; i
++)
171 lo
= loadobjects
->fetch (i
);
172 lo_name
= lo
->get_name ();
175 size_t len
= strlen (lo_name
);
176 if (len
> 7 && streq (lo_name
+ len
- 7, NTXT (".class>")))
180 // print the segment name
182 sb
.append (NTXT (" "));
183 sb
.append (lo
->get_name ());
184 sb
.append (NTXT (" ("));
185 sb
.append (lo
->get_pathname ());
186 sb
.append (NTXT (")\n"));
189 m
= lo
->fetch_warnings ();
192 msg
= pr_mesgs (m
, NULL
, NTXT (" "));
197 return sb
.toString ();
201 pr_mesgs (Emsg
*msg
, const char *null_str
, const char *lead
)
206 return dbe_strdup (null_str
);
207 for (m
= msg
; m
; m
= m
->next
)
210 sb
.append (m
->get_msg ());
211 sb
.append (NTXT ("\n"));
213 return sb
.toString ();
217 print_load_object (FILE *out_file
)
219 Vector
<LoadObject
*> *loadobjects
= dbeSession
->get_text_segments ();
220 char *msg
= pr_load_objects (loadobjects
, NTXT ("\t"));
221 fprintf (out_file
, GTXT ("Load Object Coverage:\n"));
222 fprintf (out_file
, NTXT ("%s"), msg
);
224 "----------------------------------------------------------------\n");
230 print_header (Experiment
*exp
, FILE *out_file
)
232 fprintf (out_file
, GTXT ("Experiment: %s\n"), exp
->get_expt_name ());
233 char *msg
= pr_mesgs (exp
->fetch_notes (), NTXT (""), NTXT (""));
234 fprintf (out_file
, NTXT ("%s"), msg
);
237 msg
= pr_mesgs (exp
->fetch_errors (), GTXT ("No errors\n"), NTXT (""));
238 fprintf (out_file
, NTXT ("%s"), msg
);
241 msg
= pr_mesgs (exp
->fetch_warnings (), GTXT ("No warnings\n"), NTXT (""));
242 fprintf (out_file
, NTXT ("%s"), msg
);
245 msg
= pr_mesgs (exp
->fetch_comments (), NTXT (""), NTXT (""));
246 fprintf (out_file
, NTXT ("%s"), msg
);
249 msg
= pr_mesgs (exp
->fetch_pprocq (), NTXT (""), NTXT (""));
250 fprintf (out_file
, NTXT ("%s"), msg
);
255 get_width (Hist_data
*data
,
256 MetricList
*metrics_list
, Metric::HistMetric
*hist_metric
)
259 Metric::HistMetric
*hitem
;
263 // find the last visible column.
265 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
267 if (mitem
->is_visible () || mitem
->is_tvisible () || mitem
->is_pvisible ())
271 // find the width for each column.
273 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
275 hitem
= &hist_metric
[index
];
277 if (mitem
->is_visible ())
279 if (mitem
->get_vtype () == VT_LABEL
)
281 if (index
== last_column
)
282 hitem
->maxvalue_width
= 0;
284 hitem
->maxvalue_width
= data
->name_maxlen ();
285 // truncate names which will be too long
286 if (hitem
->maxvalue_width
> MAX_LEN
- 3)
287 hitem
->maxvalue_width
= MAX_LEN
- 3;
289 else if (mitem
->get_vtype () == VT_ADDRESS
)
291 hitem
->maxvalue_width
= data
->value_maxlen (index
);
292 if (hitem
->maxvalue_width
< 13)
293 hitem
->maxvalue_width
= 13;
296 hitem
->maxvalue_width
= data
->value_maxlen (index
);
299 hitem
->maxvalue_width
= 0;
301 if (mitem
->is_tvisible ())
303 if (mitem
->get_visbits () & VAL_RATIO
)
304 hitem
->maxtime_width
= data
->value_maxlen (index
);
306 hitem
->maxtime_width
= data
->time_maxlen (index
,
307 dbeSession
->get_clock (-1));
311 hitem
->maxtime_width
= 0;
317 get_format (char **fmt_int
, char **fmt_real0
, char **fmt_real1
,
318 MetricList
*metrics_list
, Metric::HistMetric
*hist_metric
,
322 Metric::HistMetric
*hitem
;
324 int visible
, tvisible
, pvisible
;
327 char numstr
[MAX_LEN
], pstr_int
[MAX_LEN
],
328 pstr_real0
[MAX_LEN
], pstr_real1
[MAX_LEN
];
330 // find the width for each column.
331 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
333 hitem
= &hist_metric
[index
];
334 visible
= mitem
->is_visible ();
335 tvisible
= mitem
->is_tvisible ();
336 pvisible
= mitem
->is_pvisible ();
337 *pstr_int
= *pstr_real0
= *pstr_real1
= '\0';
339 // Get 'Show Value' format
340 const char *sign
= (mitem
->get_visbits () & VAL_DELTA
) ? "+" : "";
343 maxlen
= hitem
->maxvalue_width
;
344 switch (mitem
->get_vtype2 ())
347 if (mitem
->get_visbits () & VAL_RATIO
)
349 snprintf (numstr
, sizeof (numstr
), "x %%#%d.0lf ",
351 snprintf (pstr_real0
, sizeof (pstr_real0
), numstr
, 0.0);
352 snprintf (pstr_real1
, sizeof (pstr_real1
), "x%%s%%%d.3lf ",
357 snprintf (numstr
, sizeof (numstr
), "%%#%s%d.0lf ", sign
,
359 snprintf (pstr_real0
, sizeof (pstr_real0
), numstr
, 0.0);
360 snprintf (pstr_real1
, sizeof (pstr_real1
), "%%s%%%s%d.3lf ",
365 snprintf (pstr_int
, sizeof (pstr_int
), "%%%s%dd ", sign
,
369 snprintf (pstr_int
, sizeof (pstr_int
), "%%%s%dlld ", sign
,
373 snprintf (pstr_int
, sizeof (pstr_int
), "%%%s%dllu ", sign
,
379 snprintf (pstr_int
, sizeof (pstr_int
), "%%%dd:0x%%08x", 2);
383 snprintf (pstr_int
, sizeof (pstr_int
), "%%%dd:0x%%08x",
384 (int) (maxlen
- 13));
388 snprintf (numstr
, sizeof (numstr
), "%%#%d.0f ",
390 snprintf (pstr_real0
, sizeof (pstr_real0
), numstr
, 0.0);
391 snprintf (pstr_real1
, sizeof (pstr_real1
), "%%%d.3f ",
395 snprintf (pstr_int
, sizeof (pstr_int
), "%%%dhu ", (int) maxlen
);
398 if (maxlen
== 0) // last column
399 snprintf (pstr_int
, sizeof (pstr_int
), NTXT ("%%s%%s"));
400 else if (maxlen
+ nspace
>= MAX_LEN
- 3)
401 snprintf (pstr_int
, sizeof (pstr_int
), NTXT ("%%s%%-%d.%ds "),
402 MAX_LEN
- 7, MAX_LEN
- 7);
404 snprintf (pstr_int
, sizeof (pstr_int
), NTXT ("%%s%%-%ds "),
405 (int) (maxlen
+ nspace
));
412 // Get 'Show Time' format
415 maxlen
= hitem
->maxtime_width
;
416 if (mitem
->get_visbits () & VAL_RATIO
)
418 snprintf (numstr
, sizeof (numstr
), " %%%s#%d.0lf ",
419 sign
, (int) (maxlen
- 3));
420 snprintf (pstr_real0
, sizeof (pstr_real0
), numstr
, 0.0);
421 snprintf (pstr_real1
, sizeof (pstr_real1
), "%%s%%%s%d.3lf ",
426 snprintf (numstr
, sizeof (numstr
), "%%%s#%d.0lf ",
427 sign
, (int) (maxlen
- 3));
428 snprintf (pstr_real0
, sizeof (pstr_real0
), numstr
, 0.0);
429 snprintf (pstr_real1
, sizeof (pstr_real1
), "%%s%%%s%d.3lf ",
436 fmt_int
[index
] = dbe_strdup (pstr_int
);
438 fmt_int
[index
] = NULL
;
441 fmt_real0
[index
] = dbe_strdup (pstr_real0
);
443 fmt_real0
[index
] = NULL
;
446 fmt_real1
[index
] = dbe_strdup (pstr_real1
);
448 fmt_real1
[index
] = NULL
;
452 if (hitem
->maxvalue_width
> 0)
454 hitem
->width
+= hitem
->maxvalue_width
;
460 if (hitem
->maxtime_width
> 0)
464 hitem
->width
+= hitem
->maxtime_width
;
472 hitem
->width
+= 6; // adjust to change format from xx.yy%
474 if (visible
|| tvisible
|| pvisible
)
475 mitem
->legend_width (hitem
, 2);
480 delTrailingBlanks (char *s
)
482 for (int i
= (int) strlen (s
) - 1; i
>= 0 && s
[i
] == ' '; i
--)
488 * Print the 3-line header with column heads for the metrics
489 * Return offset of "Name" column (this is needed to print Callers-Callees)
492 print_label (FILE *out_file
, MetricList
*metrics_list
,
493 Metric::HistMetric
*hist_metric
, int space
)
495 char line0
[2 * MAX_LEN
], line1
[2 * MAX_LEN
];
496 char line2
[2 * MAX_LEN
], line3
[2 * MAX_LEN
];
498 *line0
= *line1
= *line2
= *line3
= '\0';
499 Vector
<Metric
*> *mlist
= metrics_list
->get_items ();
500 for (int index
= 0, mlist_sz
= mlist
->size (); index
< mlist_sz
; index
++)
502 Metric
*mitem
= mlist
->fetch (index
);
503 if (mitem
->is_visible () || mitem
->is_tvisible () || mitem
->is_pvisible ())
505 Metric::HistMetric
*hitem
= hist_metric
+ index
;
507 if (index
> 0 && mitem
->get_type () == Metric::ONAME
)
509 fmt
= NTXT (" %-*s");
510 name_offset
= strlen (line1
);
514 int width
= (int) hitem
->width
;
515 size_t len
= strlen (line1
);
516 snprintf (line1
+ len
, sizeof (line1
) - len
, fmt
, width
,
518 len
= strlen (line2
);
519 snprintf (line2
+ len
, sizeof (line2
) - len
, fmt
, width
,
521 len
= strlen (line3
);
522 snprintf (line3
+ len
, sizeof (line3
) - len
, fmt
, width
,
524 len
= strlen (line0
);
525 snprintf (line0
+ len
, sizeof (line0
) - len
, fmt
, width
,
526 mitem
->legend
? mitem
->legend
: NTXT (""));
529 char *s
= delTrailingBlanks (line0
);
531 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), s
);
532 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), delTrailingBlanks (line1
));
533 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), delTrailingBlanks (line2
));
534 fprintf (out_file
, NTXT ("%*s%s\n"), space
, NTXT (""), delTrailingBlanks (line3
));
539 print_one_visible (FILE *out_file
, char *fmt_int
, char *fmt_real0
, char *fmt_real1
,
540 TValue
*value
, int visbits
)
547 nc
= fprintf (out_file
, fmt_real0
);
550 if (visbits
& VAL_RATIO
)
552 if (value
->d
> 99.999)
553 nc
= fprintf (out_file
, fmt_real1
, NTXT (">"), 99.999);
555 nc
= fprintf (out_file
, fmt_real1
, NTXT (" "), value
->d
);
558 nc
= fprintf (out_file
, fmt_real1
, NTXT (""), value
->d
);
562 nc
= fprintf (out_file
, fmt_int
, value
->i
);
566 nc
= fprintf (out_file
, fmt_int
, value
->ll
);
569 nc
= fprintf (out_file
, fmt_int
, ADDRESS_SEG (value
->ll
),
570 ADDRESS_OFF (value
->ll
));
574 nc
= fprintf (out_file
, fmt_real0
);
576 nc
= fprintf (out_file
, fmt_real1
, value
->f
);
579 nc
= fprintf (out_file
, fmt_int
, value
->s
);
581 // ignoring the following cases (why?)
591 print_one_tvisible (FILE *out_file
, char *fmt_real0
, char *fmt_real1
,
592 TValue
*value
, int visbits
, int clock
)
595 if (value
->ll
== 0LL)
596 nc
= fprintf (out_file
, fmt_real0
);
599 if (visbits
& VAL_RATIO
)
601 if (value
->d
> 99.999)
602 nc
= fprintf (out_file
, fmt_real1
, NTXT (">"), 99.999);
604 nc
= fprintf (out_file
, fmt_real1
, NTXT (" "), value
->d
);
607 nc
= fprintf (out_file
, fmt_real1
, "", 1.e
-6 * value
->ll
/ clock
);
613 print_one (FILE *out_file
, Hist_data
*data
, Hist_data::HistItem
*item
,
614 char **fmt_int
, char **fmt_real0
, char **fmt_real1
,
615 MetricList
*metrics_list
, Metric::HistMetric
*hist_metric
,
616 char *mark
, Histable::NameFormat nfmt
)
619 Metric::HistMetric
*hitem
;
620 int index
, nc
, np
, i
;
621 int visible
, tvisible
, pvisible
;
625 if (item
->type
== Module::AT_EMPTY
)
627 fprintf (out_file
, nl
);
632 int name_is_Total
= 0;
634 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
636 if (mitem
->get_type () != Metric::ONAME
)
638 name_is_Total
= strcmp (item
->obj
->get_name (), GTXT ("<Total>")) == 0;
643 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
645 visible
= mitem
->is_visible ();
646 tvisible
= mitem
->is_tvisible ();
647 pvisible
= mitem
->is_pvisible ();
650 for (i
= 0; i
< np
; i
++)
651 fputc (' ', out_file
);
653 hitem
= &hist_metric
[index
];
657 value
= &(item
->value
[index
]);
658 nc
= print_one_tvisible (out_file
, fmt_real0
[index
], fmt_real1
[index
],
659 value
, mitem
->get_visbits (),
660 dbeSession
->get_clock (-1));
667 if (mitem
->get_vtype () == VT_LABEL
)
669 value
= &(item
->value
[index
]);
670 if (value
->tag
== VT_OFFSET
)
671 nc
+= fprintf (out_file
, fmt_int
[index
], mark
,
672 ((DataObject
*) (item
->obj
))->get_offset_name ());
674 nc
+= fprintf (out_file
, fmt_int
[index
], mark
,
675 item
->obj
->get_name (nfmt
));
677 else if (name_is_Total
&&
678 (strcmp (mitem
->get_username (), "Block Covered %") == 0
679 || strcmp (mitem
->get_username (), "Instr Covered %") == 0))
682 snprintf (stmp
, sizeof (stmp
), fmt_int
[index
], 0);
684 /* and now blank that '0' out */
685 for (int ii
= 0; ii
< 128; ii
++)
692 nc
+= fprintf (out_file
, stmp
);
695 nc
+= print_one_visible (out_file
, fmt_int
[index
], fmt_real0
[index
],
696 fmt_real1
[index
], &(item
->value
[index
]),
697 mitem
->get_visbits ());
702 percent
= data
->get_percentage (item
->value
[index
].to_double (), index
);
704 // adjust to change format from xx.yy%
705 nc
+= fprintf (out_file
, NTXT ("%#4.0f "), 0.);
707 // adjust format below to change format from xx.yy%
708 nc
+= fprintf (out_file
, NTXT ("%6.2f "), (100.0 * percent
));
710 np
= (int) (hitem
->width
- nc
);
712 fprintf (out_file
, nl
);
716 print_content (FILE *out_file
, Hist_data
*data
,
717 char **fmt_int
, char **fmt_real0
, char **fmt_real1
,
718 MetricList
*metrics_list
, Metric::HistMetric
*hist_metric
,
719 int limit
, Histable::NameFormat nfmt
)
721 // printing contents.
722 for (int i
= 0; i
< limit
; i
++)
724 Hist_data::HistItem
*item
= data
->fetch (i
);
725 print_one (out_file
, data
, item
, fmt_int
, fmt_real0
, fmt_real1
,
726 metrics_list
, hist_metric
, NTXT (" "), nfmt
);
730 er_print_histogram::er_print_histogram (DbeView
*_dbev
, Hist_data
*data
,
731 MetricList
*metrics_list
,
732 Print_mode disp_type
, int limit
,
733 char *sort_name
, Histable
*sobj
,
734 bool show_load
, bool show_header
)
737 mlist
= metrics_list
;
739 number_entries
= limit
;
740 sort_metric
= sort_name
;
744 exp_idx2
= dbeSession
->nexps () - 1;
746 header
= show_header
;
750 er_print_histogram::dump_list (int limit
)
752 Histable::NameFormat nfmt
= dbev
->get_name_format ();
754 char *title
= NULL
; // No title for some formats
755 enum PrintMode pm
= dbev
->get_printmode ();
757 // create a header line, except for delimiter-separated list output
758 if (pm
!= PM_DELIM_SEP_LIST
)
760 if (hist_data
->type
== Histable::FUNCTION
)
761 sb
.append (GTXT ("Functions sorted by metric: "));
762 else if (hist_data
->type
== Histable::INSTR
)
763 sb
.append (GTXT ("PCs sorted by metric: "));
764 else if (hist_data
->type
== Histable::LINE
)
765 sb
.append (GTXT ("Lines sorted by metric: "));
766 else if (hist_data
->type
== Histable::DOBJECT
)
767 sb
.append (GTXT ("Dataobjects sorted by metric: "));
769 sb
.append (GTXT ("Objects sorted by metric: "));
770 sb
.append (sort_metric
);
771 title
= sb
.toString ();
778 Metric::HistMetric
*hist_metric
= hist_data
->get_histmetrics ();
779 fprintf (out_file
, NTXT ("%s\n\n"), title
); //print title
780 hist_data
->print_label (out_file
, hist_metric
, 0);
781 hist_data
->print_content (out_file
, hist_metric
, limit
);
782 fprintf (out_file
, nl
);
787 print_html_title (out_file
, title
);
788 print_html_label (out_file
, mlist
);
789 print_html_content (out_file
, hist_data
, mlist
, limit
, nfmt
);
790 print_html_trailer (out_file
);
793 case PM_DELIM_SEP_LIST
:
795 char delim
= dbev
->get_printdelimiter ();
796 print_delim_label (out_file
, mlist
, delim
);
797 print_delim_content (out_file
, hist_data
, mlist
, limit
, nfmt
, delim
);
798 print_delim_trailer (out_file
, delim
);
806 er_print_histogram::dump_annotated_dataobjects (Vector
<int> *marks
,
809 Metric::HistMetric
*hist_metric
;
810 char **fmt_int
, **fmt_real0
, **fmt_real1
;
811 int no_metrics
= mlist
->get_items ()->size ();
813 Histable::NameFormat nfmt
= dbev
->get_name_format ();
814 if (!dbeSession
->is_datamode_available ())
816 GTXT ("No dataspace information recorded in experiments\n\n"));
818 Hist_data
*layout_data
= dbev
->get_data_space ()->get_layout_data (hist_data
, marks
, ithreshold
);
820 for (int mind
= 0; mind
< no_metrics
; mind
++)
821 if (mlist
->get_items ()->fetch (mind
)->get_type () == Metric::ONAME
)
824 fmt_int
= new char*[no_metrics
];
825 fmt_real0
= new char*[no_metrics
];
826 fmt_real1
= new char*[no_metrics
];
827 hist_metric
= new Metric::HistMetric
[no_metrics
];
829 // use new layout_data to set metric format
830 get_width (hist_data
, mlist
, hist_metric
);
831 get_format (fmt_int
, fmt_real0
, fmt_real1
, mlist
, hist_metric
, 0);
832 snprintf (hist_metric
[name_index
].legend2
, MAX_LEN
, GTXT ("* +offset .element"));
833 print_label (out_file
, mlist
, hist_metric
, 3);
834 fprintf (out_file
, nl
);
835 for (long i
= 0; i
< layout_data
->size (); i
++)
837 Hist_data::HistItem
* item
= layout_data
->fetch (i
);
838 if (marks
->find (i
) != -1)
839 fprintf (out_file
, NTXT ("## "));
841 fprintf (out_file
, NTXT (" "));
842 print_one (out_file
, layout_data
, item
, fmt_int
, fmt_real0
, fmt_real1
,
843 mlist
, hist_metric
, NTXT (" "), nfmt
);
845 fprintf (out_file
, nl
);
847 // free format strings.
848 for (int i
= 0; i
< no_metrics
; i
++)
857 delete[] hist_metric
;
862 er_print_histogram::dump_detail (int limit
)
865 Hist_data
*current_data
;
866 Histable::Type htype
;
868 double dvalue
, percent
;
869 MetricList
*prop_mlist
= new MetricList (mlist
);
872 size_t max_len
, len
, smax_len
, slen
;
875 LoadObject
*loadobject
;
876 char *sname
, *oname
, *lname
, *alias
, *mangle
;
877 char fmt_name
[MAX_LEN
];
878 char fmt_elem
[MAX_LEN
];
879 char fmt_real1
[MAX_LEN
], fmt_real2
[MAX_LEN
];
880 char fmt_int1
[MAX_LEN
], fmt_int2
[MAX_LEN
];
881 char fmt_long1
[MAX_LEN
], fmt_long2
[MAX_LEN
], fmt_long3
[MAX_LEN
];
882 char fmt_int0
[MAX_LEN
], fmt_long0
[MAX_LEN
];
883 char numstr
[MAX_LEN
];
885 Histable::NameFormat nfmt
= dbev
->get_name_format ();
887 // Check max. length of metrics names
888 max_len
= smax_len
= 0;
890 Vec_loop (Metric
*, prop_mlist
->get_items (), index
, mitem
)
892 mitem
->set_vvisible (true);
893 if (mitem
->get_vtype () == VT_LABEL
)
896 if (mitem
->get_subtype () != Metric::STATIC
)
898 mitem
->set_pvisible (true);
899 len
= hist_data
->value_maxlen (index
);
902 slen
= strlen (mitem
->get_name ());
908 // now get the length of the other (non-performance-data) messages
909 if (hist_data
->type
== Histable::FUNCTION
)
911 slen
= strlen (GTXT ("Source File"));
914 slen
= strlen (GTXT ("Object File"));
917 slen
= strlen (GTXT ("Load Object"));
920 slen
= strlen (GTXT ("Mangled Name"));
923 slen
= strlen (GTXT ("Aliases"));
927 else if (hist_data
->type
== Histable::DOBJECT
)
929 slen
= strlen (GTXT ("Scope"));
932 slen
= strlen (GTXT ("Type"));
935 slen
= strlen (GTXT ("Member of"));
938 slen
= strlen (GTXT ("Offset (bytes)"));
941 slen
= strlen (GTXT ("Size (bytes)"));
944 slen
= strlen (GTXT ("Elements"));
948 snprintf (fmt_name
, sizeof (fmt_name
), NTXT ("\t%%%ds: "), (int) smax_len
);
949 snprintf (fmt_elem
, sizeof (fmt_elem
), NTXT ("\t%%%ds "), (int) smax_len
);
950 snprintf (numstr
, sizeof (numstr
), "%%#%d.0lf ( %#1.0f %%%%%%%%)\n",
951 (int) (max_len
- 3), 0.);
952 snprintf (fmt_real1
, sizeof (fmt_real1
), numstr
, 0.0);
953 snprintf (fmt_real2
, sizeof (fmt_real2
), NTXT ("%%%d.3lf (%%5.1f%%%%)\n"),
955 snprintf (fmt_int0
, sizeof (fmt_int0
), NTXT ("%%%dd\n"), (int) max_len
);
956 snprintf (numstr
, sizeof (numstr
), NTXT ("%%%dd ( %#1.0f %%%%%%%%)\n"),
958 snprintf (fmt_int1
, sizeof (fmt_int1
), numstr
, 0);
959 snprintf (fmt_int2
, sizeof (fmt_int2
), NTXT ("%%%dd (%%5.1f%%%%)\n"),
961 snprintf (fmt_long0
, sizeof (fmt_long0
), NTXT ("%%%dllu\n"), (int) max_len
);
962 snprintf (numstr
, sizeof (numstr
), NTXT ("%%%dd ( %#1.0f %%%%%%%%)\n"),
964 snprintf (fmt_long1
, sizeof (fmt_long1
), numstr
, 0);
965 snprintf (fmt_long2
, sizeof (fmt_long2
), "%%%dllu (%%5.1f%%%%)\n",
967 snprintf (numstr
, sizeof (numstr
), NTXT ("\t%%%ds %%%%%dllu\n"),
968 (int) (smax_len
+ 1), (int) max_len
);
969 snprintf (fmt_long3
, sizeof (fmt_long3
), numstr
, GTXT ("Count:"));
970 snprintf (numstr
, sizeof (numstr
), "%%%dd ( %#1.0f %%%%%%%%) %%#%d.0lf\n",
971 (int) max_len
, 0., (int) (max_len
- 6));
973 // now loop over the objects
974 int num_printed_items
= 0;
975 for (i
= 0; i
< hist_data
->size (); i
++)
977 if (hist_data
->type
== Histable::FUNCTION
)
979 if (num_printed_items
>= limit
)
981 obj
= sel_obj
? sel_obj
: hist_data
->fetch (i
)->obj
;
982 htype
= obj
->get_type ();
984 // ask the view for all the data for the object
985 // xxxxx may be expensive to rescan all packets via get_hist_data()
986 current_data
= dbev
->get_hist_data (prop_mlist
,
987 htype
, 0, Hist_data::SELF
, obj
);
988 if (current_data
->size () == 0)
990 values
= current_data
->fetch (0)->value
;
994 obj
= hist_data
->fetch (i
)->obj
;
995 DataObject
*dobj
= (DataObject
*) obj
;
998 // print selected item and its members
1000 && (DataObject
*) sel_obj
!= dobj
->get_parent ())
1001 // not a match, advance to next item
1004 else if (num_printed_items
>= limit
)
1006 htype
= obj
->get_type ();
1007 values
= hist_data
->fetch (i
)->value
;
1008 current_data
= hist_data
;
1011 if (num_printed_items
)
1012 // if this isn't the first one, add a blank line
1013 fprintf (out_file
, NTXT ("\n"));
1014 num_printed_items
++;
1016 // Print full object name
1017 if (htype
!= Histable::DOBJECT
)
1018 fprintf (out_file
, NTXT ("%s\n"), obj
->get_name (nfmt
));
1021 DataObject
*dobj
= (DataObject
*) obj
;
1022 if (!dobj
->get_parent ())
1023 fprintf (out_file
, NTXT ("%s\n"), obj
->get_name (nfmt
));
1025 fprintf (out_file
, NTXT (" %s\n"), obj
->get_name (nfmt
));
1028 Vec_loop (Metric
*, prop_mlist
->get_items (), index
, mitem
)
1030 if (mitem
->get_vtype () == VT_LABEL
)
1032 if (mitem
->get_subtype () == Metric::STATIC
1033 && htype
== Histable::DOBJECT
)
1035 fprintf (out_file
, fmt_name
, mitem
->get_name ());
1037 if (mitem
->get_value_styles () & VAL_PERCENT
)
1039 dvalue
= values
[index
].to_double ();
1040 switch (mitem
->get_vtype ())
1044 fprintf (out_file
, fmt_real1
);
1046 fprintf (out_file
, fmt_real2
, dvalue
, 100.0
1047 * current_data
->get_percentage (dvalue
, index
));
1051 fprintf (out_file
, fmt_int1
);
1053 fprintf (out_file
, fmt_int2
, (int) dvalue
, 100.0
1054 * current_data
->get_percentage (dvalue
, index
));
1058 if (values
[index
].ll
== 0LL)
1060 if (mitem
->is_time_val ())
1062 fprintf (out_file
, fmt_real1
);
1063 fprintf (out_file
, fmt_long3
, 0LL);
1066 fprintf (out_file
, fmt_long1
);
1071 current_data
->get_percentage (dvalue
, index
);
1072 if (mitem
->is_time_val ())
1074 dvalue
/= 1.e
+6 * dbeSession
->get_clock (-1);
1075 fprintf (out_file
, fmt_real2
, dvalue
, percent
);
1076 fprintf (out_file
, fmt_long3
, values
[index
].ll
);
1079 fprintf (out_file
, fmt_long2
, values
[index
].ll
,
1089 switch (mitem
->get_vtype ())
1092 fprintf (out_file
, fmt_int0
, values
[index
].i
);
1096 fprintf (out_file
, fmt_long0
, values
[index
].ll
);
1099 pc
= values
[index
].ll
;
1100 fprintf (out_file
, NTXT ("%u:0x%08x\n"), ADDRESS_SEG (pc
),
1104 if (values
[index
].d
== 0.0)
1105 fprintf (out_file
, fmt_real1
);
1107 fprintf (out_file
, "\t%*.3lf\n", (int) (max_len
- 5), values
[index
].d
);
1115 // now add the descriptive information about the object
1116 if (htype
!= Histable::DOBJECT
)
1118 Function
*func
= (Function
*) obj
->convertto (Histable::FUNCTION
);
1119 if (func
&& func
->get_type () == Histable::FUNCTION
)
1121 // Print the source/object/load-object files & aliases
1122 oname
= lname
= alias
= NULL
;
1123 sname
= func
->getDefSrcName ();
1124 mangle
= func
->get_mangled_name ();
1125 if (mangle
&& streq (func
->get_name (), mangle
))
1127 module
= func
->module
;
1130 oname
= module
->get_name ();
1131 loadobject
= module
->loadobject
;
1134 lname
= loadobject
->get_pathname ();
1135 alias
= loadobject
->get_alias (func
);
1139 if (htype
== Histable::INSTR
&& dbeSession
->is_datamode_available ())
1140 alias
= ((DbeInstr
*) obj
)->get_descriptor ();
1142 fprintf (out_file
, fmt_name
, GTXT ("Source File"));
1144 fprintf (out_file
, NTXT ("%s"), sname
);
1145 fprintf (out_file
, NTXT ("\n"));
1147 fprintf (out_file
, fmt_name
, GTXT ("Object File"));
1149 fprintf (out_file
, NTXT ("%s"), oname
);
1150 fprintf (out_file
, NTXT ("\n"));
1152 fprintf (out_file
, fmt_name
, GTXT ("Load Object"));
1154 fprintf (out_file
, NTXT ("%s"), lname
);
1155 fprintf (out_file
, NTXT ("\n"));
1157 fprintf (out_file
, fmt_name
, GTXT ("Mangled Name"));
1159 fprintf (out_file
, NTXT ("%s"), mangle
);
1160 fprintf (out_file
, NTXT ("\n"));
1161 fprintf (out_file
, fmt_name
, GTXT ("Aliases"));
1163 fprintf (out_file
, NTXT ("%s"), alias
);
1164 fprintf (out_file
, NTXT ("\n"));
1169 // Print the dataobject information
1170 DataObject
*dobj
= (DataObject
*) obj
;
1171 Histable
*scope
= dobj
->get_scope ();
1174 fprintf (out_file
, fmt_name
, GTXT ("Scope"));
1176 fprintf (out_file
, GTXT ("(Global)\n"));
1177 else switch (scope
->get_type ())
1179 case Histable::FUNCTION
:
1180 fprintf (out_file
, NTXT ("%s(%s)\n"),
1181 ((Function
*) scope
)->module
->get_name (),
1182 scope
->get_name ());
1184 case Histable::LOADOBJECT
:
1185 case Histable::MODULE
:
1187 fprintf (out_file
, NTXT ("%s\n"), scope
->get_name ());
1190 // print the type name
1191 fprintf (out_file
, fmt_name
, GTXT ("Type"));
1192 if (dobj
->get_typename ())
1193 fprintf (out_file
, NTXT ("%s\n"), dobj
->get_typename ());
1195 fprintf (out_file
, GTXT ("(Synthetic)\n"));
1198 if (dobj
->get_offset () != -1)
1200 if (dobj
->get_parent ())
1202 fprintf (out_file
, fmt_name
, GTXT ("Member of"));
1203 fprintf (out_file
, NTXT ("%s\n"), dobj
->get_parent ()->get_name ());
1205 fprintf (out_file
, fmt_name
, GTXT ("Offset (bytes)"));
1206 fprintf (out_file
, NTXT ("%lld\n"), (long long) dobj
->get_offset ());
1209 if (dobj
->get_size ())
1211 fprintf (out_file
, fmt_name
, GTXT ("Size (bytes)"));
1212 fprintf (out_file
, NTXT ("%lld\n"), (long long) dobj
->get_size ());
1215 if (hist_data
->type
== Histable::FUNCTION
)
1216 delete current_data
;
1218 if (num_printed_items
== 0 && sel_obj
)
1220 GTXT ("Error: Specified item `%s' had no recorded metrics.\n"),
1221 sel_obj
->get_name ());
1225 static Metric::HistMetric
*
1226 allocateHistMetric (int no_metrics
)
1228 Metric::HistMetric
*hist_metric
= new Metric::HistMetric
[no_metrics
];
1229 for (int i
= 0; i
< no_metrics
; i
++)
1231 Metric::HistMetric
*hm
= &hist_metric
[i
];
1238 er_print_histogram::dump_gprof (int limit
)
1246 int no_metrics
= mlist
->get_items ()->size ();
1247 Metric::HistMetric
*hist_metric
= allocateHistMetric (no_metrics
);
1248 for (int i
= 0; i
< limit
; i
++)
1250 obj
= sel_obj
? sel_obj
: hist_data
->fetch (i
)->obj
;
1251 callers
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1252 Hist_data::CALLERS
, obj
);
1253 callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1254 Hist_data::CALLEES
, obj
);
1255 center
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1256 Hist_data::SELF
, obj
);
1257 callers
->update_max (hist_metric
);
1258 callees
->update_max (hist_metric
);
1259 center
->update_max (hist_metric
);
1260 callers
->update_legend_width (hist_metric
);
1261 callers
->print_label (out_file
, hist_metric
, 0);
1262 callers
->print_content (out_file
, hist_metric
, callers
->size ());
1264 if (center
->size () > 0)
1266 center
->update_total (callers
->get_totals ());
1268 center
->print_row (&sb
, 0, hist_metric
, NTXT ("*"));
1269 sb
.toFileLn (out_file
);
1271 callees
->print_content (out_file
, hist_metric
, callees
->size ());
1272 fprintf (out_file
, nl
);
1277 delete[] hist_metric
;
1280 // dump an annotated file
1282 dump_anno_file (FILE *fp
, Histable::Type type
, Module
*module
, DbeView
*dbev
,
1283 MetricList
*mlist
, TValue
*ftotal
, const char *srcFile
,
1284 Function
*func
, Vector
<int> *marks
, int threshold
, int vis_bits
,
1285 int src_visible
, bool hex_visible
, bool src_only
)
1287 int no_metrics
, lspace
, mspace
, tspace
,
1288 remain
, mindex
, next_mark
, hidx
,
1291 char **fmt_int
, **fmt_real0
, **fmt_real1
, buf
[MAX_LEN
];
1292 Hist_data::HistItem
*item
;
1294 SourceFile
*srcContext
= NULL
;
1295 bool func_scope
= dbev
== NULL
? false : dbev
->get_func_scope ();
1298 srcContext
= module
->findSource (srcFile
, false);
1299 if (srcContext
== NULL
)
1301 Vector
<SourceFile
*> *includes
= module
->includes
;
1302 char *bname
= get_basename (srcFile
);
1303 for (int i
= 0, sz
= includes
? includes
->size () : 0; i
< sz
; i
++)
1305 SourceFile
*sf
= includes
->fetch (i
);
1306 if (streq (get_basename (sf
->get_name ()), bname
))
1317 srcContext
= func
->getDefSrc ();
1319 Hist_data
*hdata
= module
->get_data (dbev
, mlist
, type
, ftotal
, srcContext
,
1320 func
, marks
, threshold
, vis_bits
,
1321 src_visible
, hex_visible
,
1322 func_scope
, src_only
);
1327 // force the name metric to be invisible
1328 MetricList
*nmlist
= hdata
->get_metric_list ();
1329 nmlist
->find_metric (GTXT ("name"), Metric::STATIC
)->clear_all_visbits ();
1330 no_metrics
= nmlist
->get_items ()->size ();
1331 fmt_int
= new char*[no_metrics
];
1332 fmt_real0
= new char*[no_metrics
];
1333 fmt_real1
= new char*[no_metrics
];
1334 Metric::HistMetric
*hist_metric
= hdata
->get_histmetrics ();
1336 // lspace is for max line number that's inserted; use to set width
1338 Vec_loop (Hist_data::HistItem
*, hdata
, hidx
, item
)
1342 if (item
->obj
->get_type () == Histable::LINE
1343 && ((DbeLine
*) item
->obj
)->lineno
> max_lineno
)
1344 max_lineno
= ((DbeLine
*) item
->obj
)->lineno
;
1345 else if (item
->obj
->get_type () == Histable::INSTR
1346 && ((DbeInstr
*) item
->obj
)->lineno
> max_lineno
)
1347 max_lineno
= ((DbeInstr
*) item
->obj
)->lineno
;
1350 lspace
= snprintf (buf
, sizeof (buf
), NTXT ("%d"), max_lineno
);
1352 // mspace is the space needed for all metrics, and the mark, if any
1354 if (nmlist
->get_items ()->size () > 0)
1356 mspace
= 3; // mark "## "
1357 Vec_loop (Metric
*, nmlist
->get_items (), index
, mitem
)
1359 if (mitem
->is_visible () || mitem
->is_tvisible ()
1360 || mitem
->is_pvisible ())
1361 mspace
+= (int) hist_metric
[index
].width
;
1365 remain
= (mspace
+ lspace
+ 3) % 8; // " " before, ". " after line#
1368 tspace
= 8 - remain
;
1372 next_mark
= (mindex
< marks
->size ()) ? marks
->fetch (mindex
) : -1;
1374 // Print the header for this list
1375 SourceFile
*sf
= srcContext
? srcContext
: module
->getMainSrc ();
1376 char *src_name
= sf
->dbeFile
->get_location_info ();
1377 DbeFile
*df
= module
->dbeFile
;
1378 if (df
== NULL
|| (df
->filetype
& DbeFile::F_JAVACLASS
) == 0)
1379 df
= module
->loadobject
->dbeFile
;
1380 char *lo_name
= df
->get_location_info ();
1381 char *dot_o_name
= lo_name
;
1382 if (module
->dot_o_file
)
1383 dot_o_name
= module
->dot_o_file
->dbeFile
->get_location_info ();
1384 fprintf (fp
, GTXT ("Source file: %s\nObject file: %s\nLoad Object: %s\n\n"),
1385 src_name
, dot_o_name
, lo_name
);
1387 // Print metric labels
1388 if (nmlist
->get_items ()->size () != 0)
1389 print_label (fp
, nmlist
, hist_metric
, 3);
1391 // determine the name metric (not printed as a metric, though)
1392 int lind
= nmlist
->get_listorder (GTXT ("name"), Metric::STATIC
);
1394 // now loop over the data rows -- the lines in the annotated source/disasm,
1395 // including index lines, compiler commentary, etc.
1397 Vec_loop (Hist_data::HistItem
*, hdata
, hidx
, item
)
1400 if (item
->type
== Module::AT_DIS
|| item
->type
== Module::AT_QUOTE
1401 || item
->type
== Module::AT_SRC
)
1403 // does this line get a high-metric mark?
1404 if (hidx
== next_mark
)
1406 sb
.append (NTXT ("## "));
1408 next_mark
= (mindex
< marks
->size ()) ? marks
->fetch (mindex
) : -1;
1411 sb
.append (NTXT (" "));
1413 hdata
->print_row (&sb
, hidx
, hist_metric
, NTXT (" "));
1415 for (int i
= sb
.length (); i
< mspace
; i
++)
1421 // this line does not get any metrics; insert blanks in lieu of them
1422 for (int i
= 0; i
< mspace
; i
++)
1427 case Module::AT_SRC_ONLY
:
1428 if (item
->obj
== NULL
)
1429 fprintf (fp
, NTXT ("%*s. "), lspace
+ 1, "?");
1431 fprintf (fp
, "%*d. ", lspace
+ 1, ((DbeLine
*) item
->obj
)->lineno
);
1434 case Module::AT_SRC
:
1435 fprintf (fp
, "%*d. ", lspace
+ 1, ((DbeLine
*) item
->obj
)->lineno
);
1437 case Module::AT_FUNC
:
1438 case Module::AT_QUOTE
:
1439 fprintf (fp
, NTXT ("%*c"), lspace
+ 3, ' ');
1441 case Module::AT_DIS
:
1442 case Module::AT_DIS_ONLY
:
1443 if (item
->obj
== NULL
|| ((DbeInstr
*) item
->obj
)->lineno
== -1)
1444 fprintf (fp
, "%*c[%*s] ", lspace
+ 3, ' ', lspace
, "?");
1446 fprintf (fp
, "%*c[%*d] ", lspace
+ 3, ' ', lspace
,
1447 ((DbeInstr
*) item
->obj
)->lineno
);
1449 case Module::AT_COM
:
1450 case Module::AT_EMPTY
:
1454 if (item
->value
[lind
].l
== NULL
)
1455 item
->value
[lind
].l
= dbe_strdup (GTXT ("INTERNAL ERROR: missing line text"));
1456 fprintf (fp
, NTXT ("%s\n"), item
->value
[lind
].l
);
1465 er_print_histogram::dump_annotated ()
1467 Vector
<int> *marks
= new Vector
<int>;
1468 Function
*anno_func
= (Function
*) sel_obj
;
1469 Module
*module
= anno_func
? anno_func
->module
: NULL
;
1471 if (hist_data
->type
== Histable::DOBJECT
)
1472 dump_annotated_dataobjects (marks
, number_entries
); // threshold
1473 else if (number_entries
== 0)
1475 dump_anno_file (out_file
, Histable::LINE
, module
, dbev
, mlist
,
1476 hist_data
->get_totals ()->value
, NULL
, anno_func
, marks
,
1477 dbev
->get_thresh_src (), dbev
->get_src_compcom (),
1478 dbev
->get_src_visible (), dbev
->get_hex_visible (), true);
1480 // Annotated disassembly
1481 dump_anno_file (out_file
, Histable::INSTR
, module
, dbev
, mlist
,
1482 hist_data
->get_totals ()->value
, NULL
, anno_func
, marks
,
1483 dbev
->get_thresh_dis (), dbev
->get_dis_compcom (),
1484 dbev
->get_src_visible (), dbev
->get_hex_visible (), true);
1488 er_print_histogram::data_dump ()
1491 if (hist_data
->get_status () == Hist_data::SUCCESS
)
1493 if (sort_metric
[0] == '\n')
1494 { // csingle Callers-Callees entry
1496 fprintf (out_file
, NTXT ("%s\n\n"), sort_metric
);
1498 else if (!sel_obj
&& type
!= MODE_LIST
)
1500 if (hist_data
->type
== Histable::FUNCTION
)
1502 GTXT ("Functions sorted by metric: %s\n\n"), sort_metric
);
1503 else if (hist_data
->type
== Histable::DOBJECT
)
1504 fprintf (out_file
, GTXT ("Dataobjects sorted by metric: %s\n\n"),
1508 GTXT ("Objects sorted by metric: %s\n\n"), sort_metric
);
1510 limit
= hist_data
->size ();
1511 if ((number_entries
> 0) && (number_entries
< limit
))
1512 limit
= number_entries
;
1520 dump_detail (limit
);
1525 case MODE_ANNOTATED
:
1531 fprintf (out_file
, GTXT ("Get_Hist_data call failed %d\n"),
1532 (int) hist_data
->get_status ());
1536 * Class er_print_ctree to print functions call tree
1538 er_print_ctree::er_print_ctree (DbeView
*_dbev
, Vector
<Histable
*> *_cstack
,
1539 Histable
*_sobj
, int _limit
)
1547 exp_idx2
= dbeSession
->nexps () - 1;
1553 er_print_ctree::data_dump ()
1556 Hist_data::HistItem
*total
;
1557 sb
.append (GTXT ("Functions Call Tree. Metric: "));
1558 char *s
= dbev
->getSort (MET_CALL_AGR
);
1561 sb
.toFileLn (out_file
);
1562 fprintf (out_file
, NTXT ("\n"));
1563 mlist
= dbev
->get_metric_list (MET_CALL_AGR
);
1565 // Change cstack: add sobj to the end of cstack
1566 cstack
->append (sobj
);
1567 Hist_data
*center
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1568 Hist_data::SELF
, cstack
);
1569 Hist_data
*callers
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1570 Hist_data::CALLERS
, cstack
);
1571 Hist_data
*callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1572 Hist_data::CALLEES
, cstack
);
1575 int last
= cstack
->size () - 1;
1576 cstack
->remove (last
);
1579 int no_metrics
= mlist
->size ();
1581 // calculate max. width using data from callers, callees, center
1582 hist_metric
= allocateHistMetric (no_metrics
);
1583 callers
->update_max (hist_metric
);
1584 callees
->update_max (hist_metric
);
1585 center
->update_max (hist_metric
);
1586 callers
->update_legend_width (hist_metric
);
1587 callers
->print_label (out_file
, hist_metric
, 0); // returns Name column offset
1590 // Pass real total to print_children()
1591 total
= center
->get_totals ();
1592 print_children (center
, 0, sobj
, NTXT (" "), total
);
1599 delete[] hist_metric
;
1603 * Recursive method print_children prints Call Tree elements.
1606 er_print_ctree::print_children (Hist_data
*data
, int index
, Histable
*my_obj
,
1607 char * prefix
, Hist_data::HistItem
*total
)
1610 const char *P0
= "+-";
1611 const char *P2
= " |";
1612 const char *P1
= " ";
1614 // If limit exceeded - return
1616 if (limit
> 0 && print_row
> limit
)
1620 return; // should never happen
1623 buf
.append (prefix
);
1624 if (buf
.endsWith (P2
))
1626 int len
= buf
.length () - 1;
1627 buf
.setLength (len
);
1631 // Change cstack: add my_obj to the end of cstack
1632 cstack
->append (my_obj
);
1634 // Print current node info
1635 char * my_prefix
= buf
.toString ();
1637 // Replace parent's total values with real total values
1638 data
->update_total (total
); // Needed to to calculate percentage only
1640 data
->print_row (&buf
, index
, hist_metric
, my_prefix
);
1641 buf
.toFileLn (out_file
);
1645 Hist_data
*callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1646 Hist_data::CALLEES
, cstack
);
1647 int nc
= callees
->size ();
1651 Hist_data::HistItem
*item
;
1655 buf
.append (prefix
);
1657 ch_prefix
= buf
.toString ();
1658 for (int i
= 0; i
< nc
- 1; i
++)
1660 item
= callees
->fetch (i
);
1662 print_children (callees
, i
, ch_obj
, ch_prefix
, total
);
1666 buf
.append (prefix
);
1668 ch_prefix
= buf
.toString ();
1669 item
= callees
->fetch (nc
- 1);
1671 print_children (callees
, nc
- 1, ch_obj
, ch_prefix
, total
);
1676 int last
= cstack
->size () - 1;
1677 cstack
->remove (last
);
1682 er_print_gprof::er_print_gprof (DbeView
*_dbev
, Vector
<Histable
*> *_cstack
)
1687 exp_idx2
= dbeSession
->nexps () - 1;
1693 er_print_gprof::data_dump ()
1696 sb
.append (GTXT ("Callers and callees sorted by metric: "));
1697 char *s
= dbev
->getSort (MET_CALL
);
1700 sb
.toFileLn (out_file
);
1701 fprintf (out_file
, NTXT ("\n"));
1703 MetricList
*mlist
= dbev
->get_metric_list (MET_CALL
);
1704 Hist_data
*center
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1705 Hist_data::SELF
, cstack
);
1706 Hist_data
*callers
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1707 Hist_data::CALLERS
, cstack
);
1708 Hist_data
*callees
= dbev
->get_hist_data (mlist
, Histable::FUNCTION
, 0,
1709 Hist_data::CALLEES
, cstack
);
1711 mlist
= center
->get_metric_list ();
1712 int no_metrics
= mlist
->get_items ()->size ();
1714 // update max. width for callers/callees/center function item
1715 Metric::HistMetric
*hist_metric
= allocateHistMetric (no_metrics
);
1716 callers
->update_max (hist_metric
);
1717 callees
->update_max (hist_metric
);
1718 center
->update_max (hist_metric
);
1720 callers
->update_legend_width (hist_metric
);
1721 int name_offset
= callers
->print_label (out_file
, hist_metric
, 0); // returns Name column offset
1724 for (int i
= 0; i
< name_offset
; i
++)
1725 sb
.append (NTXT ("="));
1726 if (name_offset
> 0)
1727 sb
.append (NTXT (" "));
1728 char *line1
= sb
.toString ();
1730 if (callers
->size () > 0)
1731 line2
= GTXT ("Callers");
1733 line2
= GTXT ("No Callers");
1734 fprintf (out_file
, NTXT ("%s%s\n"), line1
, line2
);
1735 callers
->print_content (out_file
, hist_metric
, callers
->size ());
1737 // Print Stack Fragment
1738 line2
= GTXT ("Stack Fragment");
1739 fprintf (out_file
, NTXT ("\n%s%s\n"), line1
, line2
);
1741 for (long i
= 0, last
= cstack
->size () - 1; i
<= last
; ++i
)
1744 if (i
== last
&& center
->size () > 0)
1746 center
->update_total (callers
->get_totals ()); // Needed to to calculate percentage only
1747 center
->print_row (&sb
, center
->size () - 1, hist_metric
, NTXT (" "));
1751 for (int n
= name_offset
; n
> 0; n
--)
1752 sb
.append (NTXT (" "));
1753 if (name_offset
> 0)
1754 sb
.append (NTXT (" "));
1755 sb
.append (cstack
->get (i
)->get_name ());
1757 sb
.toFileLn (out_file
);
1761 if (callees
->size () > 0)
1762 line2
= GTXT ("Callees");
1764 line2
= GTXT ("No Callees");
1765 fprintf (out_file
, NTXT ("\n%s%s\n"), line1
, line2
);
1766 callees
->print_content (out_file
, hist_metric
, callees
->size ());
1767 fprintf (out_file
, nl
);
1772 delete[] hist_metric
;
1775 er_print_leaklist::er_print_leaklist (DbeView
*_dbev
, bool show_leak
,
1776 bool show_alloca
, int _limit
)
1780 alloca
= show_alloca
;
1784 // Output routine for leak list only
1786 er_print_leaklist::data_dump ()
1789 CStack_data::CStack_item
*lae
;
1791 if (!dbeSession
->is_leaklist_available ())
1792 fprintf (out_file
, GTXT ("No leak or allocation information recorded in experiments\n\n"));
1794 MetricList
*origmlist
= dbev
->get_metric_list (MET_NORMAL
);
1797 // make a copy of the metric list, and set metrics for leaks
1798 MetricList
*nmlist
= new MetricList (origmlist
);
1799 nmlist
->set_metrics ("e.heapleakbytes:e.heapleakcnt:name", true,
1800 dbev
->get_derived_metrics ());
1802 // now make a compacted version of it to get the right indices
1803 MetricList
*mlist
= new MetricList (nmlist
);
1806 // fetch the callstack data
1807 lam
= dbev
->get_cstack_data (mlist
);
1810 if (lam
&& lam
->size () != 0)
1812 fprintf (out_file
, GTXT ("Summary Results: Distinct Leaks = %d, Total Instances = %lld, Total Bytes Leaked = %lld\n\n"),
1813 (int) lam
->size (), lam
->total
->value
[1].ll
,
1814 lam
->total
->value
[0].ll
);
1816 Vec_loop (CStack_data::CStack_item
*, lam
->cstack_items
, index
, lae
)
1819 GTXT ("Leak #%d, Instances = %lld, Bytes Leaked = %lld\n"),
1820 index
+ 1, lae
->value
[1].ll
, lae
->value
[0].ll
);
1821 if (lae
->stack
!= NULL
)
1822 for (int i
= lae
->stack
->size () - 1; i
>= 0; i
--)
1824 DbeInstr
*instr
= lae
->stack
->fetch (i
);
1825 fprintf (out_file
, NTXT (" %s\n"), instr
->get_name ());
1827 fprintf (out_file
, NTXT ("\n"));
1828 if (index
+ 1 == limit
) break;
1832 fprintf (out_file
, GTXT ("No leak information\n\n"));
1839 // make a copy of the metric list, and set metrics for leaks
1840 MetricList
*nmlist
= new MetricList (origmlist
);
1841 nmlist
->set_metrics ("e.heapallocbytes:e.heapalloccnt:name",
1842 true, dbev
->get_derived_metrics ());
1844 // now make a compacted version of it to get the right indices
1845 MetricList
*mlist
= new MetricList (nmlist
);
1848 // fetch the callstack data
1849 lam
= dbev
->get_cstack_data (mlist
);
1852 if (lam
&& lam
->size () != 0)
1854 fprintf (out_file
, GTXT ("Summary Results: Distinct Allocations = %d, Total Instances = %lld, Total Bytes Allocated = %lld\n\n"),
1855 (int) lam
->size (), lam
->total
->value
[1].ll
,
1856 lam
->total
->value
[0].ll
);
1857 Vec_loop (CStack_data::CStack_item
*, lam
->cstack_items
, index
, lae
)
1859 fprintf (out_file
, GTXT ("Allocation #%d, Instances = %lld, Bytes Allocated = %lld\n"),
1860 index
+ 1, lae
->value
[1].ll
, lae
->value
[0].ll
);
1861 if (lae
->stack
!= NULL
)
1862 for (int i
= lae
->stack
->size () - 1; i
>= 0; i
--)
1864 DbeInstr
*instr
= lae
->stack
->fetch (i
);
1865 fprintf (out_file
, NTXT (" %s\n"), instr
->get_name ());
1867 fprintf (out_file
, NTXT ("\n"));
1868 if (index
+ 1 == limit
) break;
1872 fprintf (out_file
, GTXT ("No allocation information\n\n"));
1878 er_print_heapactivity::er_print_heapactivity (DbeView
*_dbev
,
1879 Histable::Type _type
,
1880 bool _printStat
, int _limit
)
1884 printStat
= _printStat
;
1889 er_print_heapactivity::printCallStacks (Hist_data
*hist_data
)
1891 Hist_data::HistItem
*hi
;
1894 int size
= hist_data
->size ();
1895 if (limit
> 0 && limit
< size
)
1898 Histable::NameFormat fmt
= dbev
->get_name_format ();
1899 for (int i
= 0; i
< size
; i
++)
1901 hi
= hist_data
->fetch (i
);
1902 hData
= (HeapData
*) hi
->obj
;
1903 stackId
= hData
->id
;
1905 fprintf (out_file
, NTXT ("\n"));
1907 fprintf (out_file
, NTXT ("%s\n"), hData
->get_name (fmt
));
1908 if (hData
->getAllocCnt () > 0)
1910 fprintf (out_file
, GTXT ("Instances = %d "),
1911 (int) (hData
->getAllocCnt ()));
1912 fprintf (out_file
, GTXT ("Bytes Allocated = %lld\n"),
1913 (long long) hData
->getAllocBytes ());
1916 if (hData
->getLeakCnt () > 0)
1918 fprintf (out_file
, GTXT ("Instances = %d "),
1919 (int) (hData
->getLeakCnt ()));
1920 fprintf (out_file
, GTXT ("Bytes Leaked = %lld\n"),
1921 (long long) hData
->getLeakBytes ());
1924 // There is no stack trace for <Total>
1928 // LIBRARY VISIBILITY pass extra argument if necessary to get hide stack
1929 Vector
<Histable
*> *instrs
= CallStack::getStackPCs ((void *) stackId
);
1932 int stSize
= instrs
->size ();
1933 for (int j
= 0; j
< stSize
; j
++)
1935 Histable
*instr
= instrs
->fetch (j
);
1937 fprintf (out_file
, NTXT (" %s\n"), instr
->get_name ());
1945 er_print_heapactivity::printStatistics (Hist_data
*hist_data
)
1947 Hist_data::HistItem
*hi
;
1948 HeapData
*hDataTotal
;
1949 hi
= hist_data
->fetch (0);
1950 hDataTotal
= (HeapData
*) hi
->obj
;
1951 Vector
<hrtime_t
> *pTimestamps
;
1952 if (hDataTotal
->getPeakMemUsage () > 0)
1954 fprintf (out_file
, GTXT ("\nProcess With Highest Peak Memory Usage\n"));
1956 "-------------------------------------------------------\n");
1957 fprintf (out_file
, GTXT ("Heap size bytes %lld\n"),
1958 (long long) hDataTotal
->getPeakMemUsage ());
1959 fprintf (out_file
, GTXT ("Experiment Id %d\n"),
1960 (int) (hDataTotal
->getUserExpId ()));
1961 fprintf (out_file
, GTXT ("Process Id %d\n"),
1962 (int) (hDataTotal
->getPid ()));
1963 pTimestamps
= hDataTotal
->getPeakTimestamps ();
1964 if (pTimestamps
!= NULL
)
1965 for (int i
= 0; i
< pTimestamps
->size (); i
++)
1967 GTXT ("Time of peak %.3f (secs.)\n"),
1968 (double) (pTimestamps
->fetch (i
) / (double) NANOSEC
));
1971 if (hDataTotal
->getAllocCnt () > 0)
1973 fprintf (out_file
, GTXT ("\nMemory Allocations Statistics\n"));
1975 GTXT ("Allocation Size Range Allocations \n"));
1977 "-------------------------------------------------------\n");
1978 if (hDataTotal
->getA0KB1KBCnt () > 0)
1979 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
1980 hDataTotal
->getA0KB1KBCnt ());
1981 if (hDataTotal
->getA1KB8KBCnt () > 0)
1982 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
1983 hDataTotal
->getA1KB8KBCnt ());
1984 if (hDataTotal
->getA8KB32KBCnt () > 0)
1985 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
1986 hDataTotal
->getA8KB32KBCnt ());
1987 if (hDataTotal
->getA32KB128KBCnt () > 0)
1988 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
1989 hDataTotal
->getA32KB128KBCnt ());
1990 if (hDataTotal
->getA128KB256KBCnt () > 0)
1991 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
1992 hDataTotal
->getA128KB256KBCnt ());
1993 if (hDataTotal
->getA256KB512KBCnt () > 0)
1994 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
1995 hDataTotal
->getA256KB512KBCnt ());
1996 if (hDataTotal
->getA512KB1000KBCnt () > 0)
1997 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
1998 hDataTotal
->getA512KB1000KBCnt ());
1999 if (hDataTotal
->getA1000KB10MBCnt () > 0)
2000 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
2001 hDataTotal
->getA1000KB10MBCnt ());
2002 if (hDataTotal
->getA10MB100MBCnt () > 0)
2003 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
2004 hDataTotal
->getA10MB100MBCnt ());
2005 if (hDataTotal
->getA100MB1GBCnt () > 0)
2006 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
2007 hDataTotal
->getA100MB1GBCnt ());
2008 if (hDataTotal
->getA1GB10GBCnt () > 0)
2009 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
2010 hDataTotal
->getA1GB10GBCnt ());
2011 if (hDataTotal
->getA10GB100GBCnt () > 0)
2012 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
2013 hDataTotal
->getA10GB100GBCnt ());
2014 if (hDataTotal
->getA100GB1TBCnt () > 0)
2015 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
2016 hDataTotal
->getA100GB1TBCnt ());
2017 if (hDataTotal
->getA1TB10TBCnt () > 0)
2018 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
2019 hDataTotal
->getA1TB10TBCnt ());
2020 fprintf (out_file
, GTXT ("\nSmallest allocation bytes %lld\n"),
2021 (long long) hDataTotal
->getASmallestBytes ());
2022 fprintf (out_file
, GTXT ("Largest allocation bytes %lld\n"),
2023 (long long) hDataTotal
->getALargestBytes ());
2024 fprintf (out_file
, GTXT ("Total allocations %d\n"),
2025 hDataTotal
->getAllocCnt ());
2026 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
2027 (long long) hDataTotal
->getAllocBytes ());
2030 if (hDataTotal
->getLeakCnt () > 0)
2032 fprintf (out_file
, GTXT ("\nMemory Leaks Statistics\n"));
2034 GTXT ("Leak Size Range Leaks \n"));
2036 "-------------------------------------------------------\n");
2037 if (hDataTotal
->getL0KB1KBCnt () > 0)
2038 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
2039 hDataTotal
->getL0KB1KBCnt ());
2040 if (hDataTotal
->getL1KB8KBCnt () > 0)
2041 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
2042 hDataTotal
->getL1KB8KBCnt ());
2043 if (hDataTotal
->getL8KB32KBCnt () > 0)
2044 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
2045 hDataTotal
->getL8KB32KBCnt ());
2046 if (hDataTotal
->getL32KB128KBCnt () > 0)
2047 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
2048 hDataTotal
->getL32KB128KBCnt ());
2049 if (hDataTotal
->getL128KB256KBCnt () > 0)
2050 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
2051 hDataTotal
->getL128KB256KBCnt ());
2052 if (hDataTotal
->getL256KB512KBCnt () > 0)
2053 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
2054 hDataTotal
->getL256KB512KBCnt ());
2055 if (hDataTotal
->getL512KB1000KBCnt () > 0)
2056 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
2057 hDataTotal
->getL512KB1000KBCnt ());
2058 if (hDataTotal
->getL1000KB10MBCnt () > 0)
2059 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
2060 hDataTotal
->getL1000KB10MBCnt ());
2061 if (hDataTotal
->getL10MB100MBCnt () > 0)
2062 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
2063 hDataTotal
->getL10MB100MBCnt ());
2064 if (hDataTotal
->getL100MB1GBCnt () > 0)
2065 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
2066 hDataTotal
->getL100MB1GBCnt ());
2067 if (hDataTotal
->getL1GB10GBCnt () > 0)
2068 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
2069 hDataTotal
->getL1GB10GBCnt ());
2070 if (hDataTotal
->getL10GB100GBCnt () > 0)
2071 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
2072 hDataTotal
->getL10GB100GBCnt ());
2073 if (hDataTotal
->getL100GB1TBCnt () > 0)
2074 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
2075 hDataTotal
->getL100GB1TBCnt ());
2076 if (hDataTotal
->getL1TB10TBCnt () > 0)
2077 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
2078 hDataTotal
->getL1TB10TBCnt ());
2079 fprintf (out_file
, GTXT ("\nSmallest leaked bytes %lld\n"),
2080 (long long) hDataTotal
->getLSmallestBytes ());
2081 fprintf (out_file
, GTXT ("Largest leaked bytes %lld\n"),
2082 (long long) hDataTotal
->getLLargestBytes ());
2083 fprintf (out_file
, GTXT ("Total leaked %d \n"),
2084 hDataTotal
->getLeakCnt ());
2085 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
2086 (long long) hDataTotal
->getLeakBytes ());
2088 fprintf (out_file
, NTXT ("\n"));
2092 er_print_heapactivity::data_dump ()
2094 // get the list of heap events from DbeView
2095 int numExps
= dbeSession
->nexps ();
2099 GTXT ("There is no heap event information in the experiments\n"));
2102 MetricList
*mlist
= dbev
->get_metric_list (MET_HEAP
);
2103 Hist_data
*hist_data
;
2104 hist_data
= dbev
->get_hist_data (mlist
, type
, 0, Hist_data::ALL
);
2106 printStatistics (hist_data
);
2108 printCallStacks (hist_data
);
2111 er_print_ioactivity::er_print_ioactivity (DbeView
*_dbev
, Histable::Type _type
,
2112 bool _printStat
, int _limit
)
2116 printStat
= _printStat
;
2121 er_print_ioactivity::printCallStacks (Hist_data
*hist_data
)
2123 Hist_data::HistItem
*hi
;
2126 int size
= hist_data
->size ();
2127 if (limit
> 0 && limit
< size
)
2130 for (int i
= 0; i
< size
; i
++)
2132 hi
= hist_data
->fetch (i
);
2133 fData
= (FileData
*) hi
->obj
;
2134 stackId
= fData
->id
;
2136 fprintf (out_file
, NTXT ("\n"));
2137 fprintf (out_file
, NTXT ("%s\n"), fData
->getFileName ());
2138 if (fData
->getWriteCnt () > 0)
2140 fprintf (out_file
, GTXT ("Write Time=%.6f (secs.) "),
2141 (double) (fData
->getWriteTime () / (double) NANOSEC
));
2142 fprintf (out_file
, GTXT ("Write Bytes=%lld "),
2143 (long long) fData
->getWriteBytes ());
2144 fprintf (out_file
, GTXT ("Write Count=%d\n"),
2145 (int) (fData
->getWriteCnt ()));
2147 if (fData
->getReadCnt () > 0)
2149 fprintf (out_file
, GTXT ("Read Time=%.6f (secs.) "),
2150 (double) (fData
->getReadTime () / (double) NANOSEC
));
2151 fprintf (out_file
, GTXT ("Read Bytes=%lld "),
2152 (long long) fData
->getReadBytes ());
2153 fprintf (out_file
, GTXT ("Read Count=%d\n"),
2154 (int) fData
->getReadCnt ());
2156 if (fData
->getOtherCnt () > 0)
2158 fprintf (out_file
, GTXT ("Other I/O Time=%.6f (secs.) "),
2159 (double) (fData
->getOtherTime () / (double) NANOSEC
));
2160 fprintf (out_file
, GTXT ("Other I/O Count=%d\n"),
2161 (int) (fData
->getOtherCnt ()));
2163 if (fData
->getErrorCnt () > 0)
2165 fprintf (out_file
, GTXT ("I/O Error Time=%.6f (secs.) "),
2166 (double) (fData
->getErrorTime () / (double) NANOSEC
));
2167 fprintf (out_file
, GTXT ("I/O Error Count=%d\n"),
2168 (int) (fData
->getErrorCnt ()));
2171 // There is no stack trace for <Total>
2175 // LIBRARY VISIBILITY pass extra argument if necessary to get hide stack
2176 Vector
<Histable
*> *instrs
= CallStack::getStackPCs ((void *) stackId
);
2179 int stSize
= instrs
->size ();
2180 for (int j
= 0; j
< stSize
; j
++)
2182 Histable
*instr
= instrs
->fetch (j
);
2184 fprintf (out_file
, " %s\n", instr
->get_name ());
2192 er_print_ioactivity::printStatistics (Hist_data
*hist_data
)
2194 Hist_data::HistItem
*hi
;
2195 FileData
*fDataTotal
;
2197 hi
= hist_data
->fetch (0);
2198 fDataTotal
= (FileData
*) hi
->obj
;
2200 if (fDataTotal
->getWriteCnt () > 0)
2203 GTXT ("\nWrite Statistics\n"));
2205 GTXT ("I/O Size Range Write Calls \n"));
2207 "-------------------------------------------------------\n");
2208 if (fDataTotal
->getW0KB1KBCnt () > 0)
2209 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
2210 fDataTotal
->getW0KB1KBCnt ());
2211 if (fDataTotal
->getW1KB8KBCnt () > 0)
2212 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
2213 fDataTotal
->getW1KB8KBCnt ());
2214 if (fDataTotal
->getW8KB32KBCnt () > 0)
2215 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
2216 fDataTotal
->getW8KB32KBCnt ());
2217 if (fDataTotal
->getW32KB128KBCnt () > 0)
2218 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
2219 fDataTotal
->getW32KB128KBCnt ());
2220 if (fDataTotal
->getW128KB256KBCnt () > 0)
2221 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
2222 fDataTotal
->getW128KB256KBCnt ());
2223 if (fDataTotal
->getW256KB512KBCnt () > 0)
2224 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
2225 fDataTotal
->getW256KB512KBCnt ());
2226 if (fDataTotal
->getW512KB1000KBCnt () > 0)
2227 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
2228 fDataTotal
->getW512KB1000KBCnt ());
2229 if (fDataTotal
->getW1000KB10MBCnt () > 0)
2230 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
2231 fDataTotal
->getW1000KB10MBCnt ());
2232 if (fDataTotal
->getW10MB100MBCnt () > 0)
2233 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
2234 fDataTotal
->getW10MB100MBCnt ());
2235 if (fDataTotal
->getW100MB1GBCnt () > 0)
2236 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
2237 fDataTotal
->getW100MB1GBCnt ());
2238 if (fDataTotal
->getW1GB10GBCnt () > 0)
2239 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
2240 fDataTotal
->getW1GB10GBCnt ());
2241 if (fDataTotal
->getW10GB100GBCnt () > 0)
2242 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
2243 fDataTotal
->getW10GB100GBCnt ());
2244 if (fDataTotal
->getW100GB1TBCnt () > 0)
2245 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
2246 fDataTotal
->getW100GB1TBCnt ());
2247 if (fDataTotal
->getW1TB10TBCnt () > 0)
2248 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
2249 fDataTotal
->getW1TB10TBCnt ());
2251 GTXT ("\nLongest write %.6f (secs.)\n"),
2252 (double) (fDataTotal
->getWSlowestBytes () / (double) NANOSEC
));
2253 fprintf (out_file
, GTXT ("Smallest write bytes %lld\n"),
2254 (long long) fDataTotal
->getWSmallestBytes ());
2255 fprintf (out_file
, GTXT ("Largest write bytes %lld\n"),
2256 (long long) fDataTotal
->getWLargestBytes ());
2258 GTXT ("Total time %.6f (secs.)\n"),
2259 (double) (fDataTotal
->getWriteTime () / (double) NANOSEC
));
2260 fprintf (out_file
, GTXT ("Total calls %d\n"),
2261 fDataTotal
->getWriteCnt ());
2262 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
2263 (long long) fDataTotal
->getWriteBytes ());
2266 if (fDataTotal
->getReadCnt () > 0)
2269 GTXT ("\nRead Statistics\n"));
2271 GTXT ("I/O Size Range Read Calls \n"));
2273 "------------------------------------------------------\n");
2274 if (fDataTotal
->getR0KB1KBCnt () > 0)
2275 fprintf (out_file
, NTXT (" 0KB - 1KB %d\n"),
2276 fDataTotal
->getR0KB1KBCnt ());
2277 if (fDataTotal
->getR1KB8KBCnt () > 0)
2278 fprintf (out_file
, NTXT (" 1KB - 8KB %d\n"),
2279 fDataTotal
->getR1KB8KBCnt ());
2280 if (fDataTotal
->getR8KB32KBCnt () > 0)
2281 fprintf (out_file
, NTXT (" 8KB - 32KB %d\n"),
2282 fDataTotal
->getR8KB32KBCnt ());
2283 if (fDataTotal
->getR32KB128KBCnt () > 0)
2284 fprintf (out_file
, NTXT (" 32KB - 128KB %d\n"),
2285 fDataTotal
->getR32KB128KBCnt ());
2286 if (fDataTotal
->getR128KB256KBCnt () > 0)
2287 fprintf (out_file
, NTXT (" 128KB - 256KB %d\n"),
2288 fDataTotal
->getR128KB256KBCnt ());
2289 if (fDataTotal
->getR256KB512KBCnt () > 0)
2290 fprintf (out_file
, NTXT (" 256KB - 512KB %d\n"),
2291 fDataTotal
->getR256KB512KBCnt ());
2292 if (fDataTotal
->getR512KB1000KBCnt () > 0)
2293 fprintf (out_file
, NTXT (" 512KB - 1000KB %d\n"),
2294 fDataTotal
->getR512KB1000KBCnt ());
2295 if (fDataTotal
->getR1000KB10MBCnt () > 0)
2296 fprintf (out_file
, NTXT (" 1000KB - 10MB %d\n"),
2297 fDataTotal
->getR1000KB10MBCnt ());
2298 if (fDataTotal
->getR10MB100MBCnt () > 0)
2299 fprintf (out_file
, NTXT (" 10MB - 100MB %d\n"),
2300 fDataTotal
->getR10MB100MBCnt ());
2301 if (fDataTotal
->getR100MB1GBCnt () > 0)
2302 fprintf (out_file
, NTXT (" 100MB - 1GB %d\n"),
2303 fDataTotal
->getR100MB1GBCnt ());
2304 if (fDataTotal
->getR1GB10GBCnt () > 0)
2305 fprintf (out_file
, NTXT (" 1GB - 10GB %d\n"),
2306 fDataTotal
->getR1GB10GBCnt ());
2307 if (fDataTotal
->getR10GB100GBCnt () > 0)
2308 fprintf (out_file
, NTXT (" 10GB - 100GB %d\n"),
2309 fDataTotal
->getR10GB100GBCnt ());
2310 if (fDataTotal
->getR100GB1TBCnt () > 0)
2311 fprintf (out_file
, NTXT (" 100GB - 1TB %d\n"),
2312 fDataTotal
->getR100GB1TBCnt ());
2313 if (fDataTotal
->getR1TB10TBCnt () > 0)
2314 fprintf (out_file
, NTXT (" 1TB - 10TB %d\n"),
2315 fDataTotal
->getR1TB10TBCnt ());
2317 GTXT ("\nLongest time %.6f (secs.)\n"),
2318 (double) (fDataTotal
->getRSlowestBytes () / (double) NANOSEC
));
2319 fprintf (out_file
, GTXT ("Smallest read bytes %lld\n"),
2320 (long long) fDataTotal
->getRSmallestBytes ());
2321 fprintf (out_file
, GTXT ("Largest read bytes %lld\n"),
2322 (long long) fDataTotal
->getRLargestBytes ());
2324 GTXT ("Total time %.6f (secs.)\n"),
2325 (double) (fDataTotal
->getReadTime () / (double) NANOSEC
));
2326 fprintf (out_file
, GTXT ("Total calls %d\n"),
2327 fDataTotal
->getReadCnt ());
2328 fprintf (out_file
, GTXT ("Total bytes %lld\n"),
2329 (long long) fDataTotal
->getReadBytes ());
2332 if (fDataTotal
->getOtherCnt () > 0)
2334 fprintf (out_file
, GTXT ("\nOther I/O Statistics\n"));
2336 "-----------------------------------------------------\n");
2338 GTXT ("Total time %.6f (secs.)\n"),
2339 (double) (fDataTotal
->getOtherTime () / (double) NANOSEC
));
2340 fprintf (out_file
, GTXT ("Total calls %d \n"),
2341 fDataTotal
->getOtherCnt ());
2343 if (fDataTotal
->getErrorCnt () > 0)
2345 fprintf (out_file
, GTXT ("\nI/O Error Statistics\n"));
2347 "-----------------------------------------------------\n");
2349 GTXT ("Total time %.6f (secs.)\n"),
2350 (double) (fDataTotal
->getErrorTime () / (double) NANOSEC
));
2351 fprintf (out_file
, GTXT ("Total calls %d \n"),
2352 fDataTotal
->getErrorCnt ());
2354 fprintf (out_file
, NTXT ("\n"));
2358 er_print_ioactivity::data_dump ()
2360 // get the list of io events from DbeView
2361 int numExps
= dbeSession
->nexps ();
2365 GTXT ("There is no IO event information in the experiments\n"));
2369 MetricList
*mlist
= dbev
->get_metric_list (MET_IO
);
2370 Hist_data
*hist_data
= dbev
->get_hist_data (mlist
, type
, 0, Hist_data::ALL
);
2371 if (type
== Histable::IOCALLSTACK
)
2372 printCallStacks (hist_data
);
2374 printStatistics (hist_data
);
2377 Metric::HistMetric
*hist_metric
= hist_data
->get_histmetrics ();
2378 hist_data
->print_label (out_file
, hist_metric
, 0);
2379 hist_data
->print_content (out_file
, hist_metric
, limit
);
2380 fprintf (out_file
, nl
);
2384 er_print_experiment::er_print_experiment (DbeView
*_dbev
, int bgn_idx
,
2385 int end_idx
, bool show_load
,
2386 bool show_header
, bool show_stat
,
2387 bool show_over
, bool show_odetail
)
2393 header
= show_header
;
2396 odetail
= show_odetail
;
2400 er_print_experiment::data_dump ()
2408 snprintf (fmt1
, sizeof (fmt1
), NTXT ("%%50s"));
2409 if (exp_idx2
> exp_idx1
)
2411 statistics_sum (maxlen
);
2412 fprintf (out_file
, nl
);
2415 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
2416 statistics_dump (index
, maxlen
);
2420 snprintf (fmt1
, sizeof (fmt1
), NTXT ("%%30s"));
2421 if (exp_idx2
> exp_idx1
)
2423 overview_sum (maxlen
);
2424 fprintf (out_file
, nl
);
2427 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
2428 overview_dump (index
, maxlen
);
2431 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
2433 if (index
!= exp_idx1
)
2435 "----------------------------------------------------------------\n");
2436 header_dump (index
);
2441 er_print_experiment::overview_sum (int &maxlen
)
2444 Ovw_data
*sum_data
= new Ovw_data ();
2445 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
2447 Ovw_data
*ovw_data
= dbev
->get_ovw_data (index
);
2448 if (ovw_data
== NULL
)
2450 sum_data
->sum (ovw_data
);
2454 fprintf (out_file
, GTXT ("<Sum across selected experiments>"));
2455 fprintf (out_file
, nl
);
2456 overview_summary (sum_data
, maxlen
);
2457 fprintf (out_file
, nl
);
2462 er_print_experiment::overview_dump (int exp_idx
, int &maxlen
)
2465 Ovw_data::Ovw_item ovw_item_labels
;
2466 Ovw_data::Ovw_item ovw_item
;
2470 ovw_data
= dbev
->get_ovw_data (exp_idx
);
2471 if (ovw_data
== NULL
)
2473 if (pr_params
.header
)
2474 header_dump (exp_idx
);
2476 fprintf (out_file
, GTXT ("Experiment: %s\n"),
2477 dbeSession
->get_exp (exp_idx
)->get_expt_name ());
2479 overview_summary (ovw_data
, maxlen
);
2486 //Get the collection params for the sample selection and display them.
2487 fprintf (out_file
, NTXT ("\n\n"));
2488 fprintf (out_file
, fmt1
, GTXT ("Individual samples"));
2489 fprintf (out_file
, NTXT ("\n\n"));
2491 size
= ovw_data
->size ();
2492 ovw_item_labels
= ovw_data
->get_labels ();
2494 for (index
= 0; index
< size
; index
++)
2496 ovw_item
= ovw_data
->fetch (index
);
2497 fprintf (out_file
, fmt1
, GTXT ("Sample Number"));
2498 fprintf (out_file
, NTXT (": %d\n\n"), ovw_item
.number
);
2499 overview_item (&ovw_item
, &ovw_item_labels
);
2500 fprintf (out_file
, nl
);
2507 er_print_experiment::overview_summary (Ovw_data
*ovw_data
, int &maxlen
)
2511 Ovw_data::Ovw_item totals
;
2512 Ovw_data::Ovw_item ovw_item_labels
;
2513 totals
= ovw_data
->get_totals ();
2514 len
= snprintf (buf
, sizeof (buf
), "%.3lf", tstodouble (totals
.total
.t
));
2517 snprintf (buf
, sizeof (buf
), NTXT ("%%#%d.0lf ( %#1.0f %%%%%%%%)"),
2519 snprintf (fmt2
, sizeof (fmt2
), NTXT ("%%%d.3lf"), maxlen
);
2520 snprintf (fmt3
, sizeof (fmt3
), buf
, 0.0);
2521 snprintf (fmt4
, sizeof (fmt4
), NTXT ("%%%d.3lf (%%5.1f%%%%)"), maxlen
);
2522 fprintf (out_file
, fmt1
, GTXT ("Aggregated statistics for selected samples"));
2523 fprintf (out_file
, NTXT ("\n\n"));
2525 ovw_item_labels
= ovw_data
->get_labels ();
2526 overview_item (&totals
, &ovw_item_labels
);
2530 er_print_experiment::overview_item (Ovw_data::Ovw_item
*ovw_item
,
2531 Ovw_data::Ovw_item
*ovw_item_labels
)
2533 double start
, end
, total_value
;
2535 timestruc_t total_time
= {0, 0};
2537 start
= tstodouble (ovw_item
->start
);
2538 end
= tstodouble (ovw_item
->end
);
2540 fprintf (out_file
, fmt1
, GTXT ("Start Label"));
2541 fprintf (out_file
, NTXT (": "));
2542 fprintf (out_file
, NTXT ("%s"), ovw_item
->start_label
);
2543 fprintf (out_file
, nl
);
2544 fprintf (out_file
, fmt1
, GTXT ("End Label"));
2545 fprintf (out_file
, NTXT (": %s\n"), ovw_item
->end_label
);
2547 fprintf (out_file
, fmt1
, GTXT ("Start Time (sec.)"));
2548 fprintf (out_file
, NTXT (": "));
2550 fprintf (out_file
, GTXT ("N/A"));
2552 fprintf (out_file
, fmt2
, start
);
2553 fprintf (out_file
, nl
);
2554 fprintf (out_file
, fmt1
, GTXT ("End Time (sec.)"));
2555 fprintf (out_file
, NTXT (": "));
2557 fprintf (out_file
, GTXT ("N/A"));
2559 fprintf (out_file
, fmt2
, end
);
2560 fprintf (out_file
, nl
);
2561 fprintf (out_file
, fmt1
, GTXT ("Duration (sec.)"));
2562 fprintf (out_file
, NTXT (": "));
2563 fprintf (out_file
, fmt2
, tstodouble (ovw_item
->duration
));
2564 fprintf (out_file
, NTXT ("\n"));
2566 size
= ovw_item
->size
;
2567 for (index
= 0; index
< size
; index
++)
2568 tsadd (&total_time
, &ovw_item
->values
[index
].t
);
2570 total_value
= tstodouble (total_time
);
2571 fprintf (out_file
, fmt1
, GTXT ("Total Thread Time (sec.)"));
2572 fprintf (out_file
, NTXT (": "));
2573 fprintf (out_file
, fmt2
, tstodouble (ovw_item
->tlwp
));
2574 fprintf (out_file
, NTXT ("\n"));
2575 fprintf (out_file
, fmt1
, GTXT ("Average number of Threads"));
2576 fprintf (out_file
, NTXT (": "));
2577 if (tstodouble (ovw_item
->duration
) != 0)
2578 fprintf (out_file
, fmt2
, ovw_item
->nlwp
);
2580 fprintf (out_file
, GTXT ("N/A"));
2581 fprintf (out_file
, NTXT ("\n\n"));
2582 fprintf (out_file
, fmt1
, GTXT ("Process Times (sec.)"));
2583 fprintf (out_file
, NTXT (":\n"));
2584 for (index
= 1; index
< size
; index
++)
2586 overview_value (&ovw_item_labels
->values
[index
], ovw_item_labels
->type
,
2588 overview_value (&ovw_item
->values
[index
], ovw_item
->type
,
2590 fprintf (out_file
, NTXT ("\n"));
2595 er_print_experiment::overview_value (Value
*value
, ValueTag value_tag
,
2602 fprintf (out_file
, fmt1
, value
->l
);
2603 fprintf (out_file
, NTXT (": "));
2606 dvalue
= tstodouble (value
->t
);
2608 fprintf (out_file
, fmt3
, 0., 0.);
2610 fprintf (out_file
, fmt4
, dvalue
, 100.0 * dvalue
/ total_value
);
2613 fprintf (out_file
, NTXT ("%d"), value
->i
);
2616 fprintf (out_file
, fmt3
);
2621 er_print_experiment::statistics_sum (int &maxlen
)
2625 Stats_data
*sum_data
= new Stats_data ();
2626 for (index
= exp_idx1
; index
<= exp_idx2
; index
++)
2628 Stats_data
*stats_data
= dbev
->get_stats_data (index
);
2629 if (stats_data
== NULL
)
2631 sum_data
->sum (stats_data
);
2635 // get the maximum width of values
2636 size
= sum_data
->size ();
2637 for (index
= 0; index
< size
; index
++)
2639 len
= (int) sum_data
->fetch (index
).value
.get_len ();
2644 // print overview average
2645 overview_sum (maxlen
);
2647 // print statistics data
2648 snprintf (fmt2
, sizeof (fmt2
), NTXT (": %%%ds\n"), maxlen
);
2649 statistics_item (sum_data
);
2654 er_print_experiment::statistics_dump (int exp_idx
, int &maxlen
)
2656 Stats_data
*stats_data
;
2659 stats_data
= dbev
->get_stats_data (exp_idx
);
2660 if (stats_data
== NULL
)
2662 if (pr_params
.header
)
2664 header_dump (exp_idx
);
2665 fprintf (out_file
, nl
);
2668 fprintf (out_file
, GTXT ("Experiment: %s\n"),
2669 dbeSession
->get_exp (exp_idx
)->get_expt_name ());
2671 // get the maximum width of values
2672 size
= stats_data
->size ();
2673 for (index
= 0; index
< size
; index
++)
2675 len
= (int) stats_data
->fetch (index
).value
.get_len ();
2680 // print overview average
2681 overview_dump (exp_idx
, maxlen
);
2682 fprintf (out_file
, nl
);
2684 // print statistics data
2685 snprintf (fmt2
, sizeof (fmt2
), NTXT (": %%%ds\n"), maxlen
);
2686 statistics_item (stats_data
);
2691 er_print_experiment::statistics_item (Stats_data
*stats_data
)
2694 Stats_data::Stats_item stats_item
;
2696 size
= stats_data
->size ();
2697 for (index
= 0; index
< size
; index
++)
2699 stats_item
= stats_data
->fetch (index
);
2700 fprintf (out_file
, fmt1
, stats_item
.label
);
2701 fprintf (out_file
, fmt2
, stats_item
.value
.to_str (buf
, sizeof (buf
)));
2703 fprintf (out_file
, nl
);
2706 // Print annotated source or disassembly -- called by er_print only
2708 print_anno_file (char *name
, const char *sel
, const char *srcFile
,
2709 bool isDisasm
, FILE *dis_file
, FILE *inp_file
, FILE *out_file
,
2710 DbeView
*dbev
, bool xdefault
)
2716 Hist_data
*hist_data
;
2724 bool srcmetrics_visible
;
2726 if ((name
== NULL
) || (strlen (name
) == 0))
2728 fprintf (stderr
, GTXT ("Error: No function or file has been specified.\n"));
2732 // find the function from the name
2733 if (!dbeSession
->find_obj (dis_file
, inp_file
, obj
, name
, sel
,
2734 Histable::FUNCTION
, xdefault
))
2739 // source or disassembly for <Total>, <Unknown>, or @plt
2740 if (obj
->get_type () != Histable::FUNCTION
)
2743 GTXT ("Error: %s is not a real function; no source or disassembly available.\n"),
2748 func
= (Function
*) obj
;
2749 if (func
->flags
& FUNC_FLAG_SIMULATED
)
2752 GTXT ("Error: %s is not a real function; no source or disassembly available.\n"),
2756 else if (dbev
!= NULL
&& isDisasm
)
2757 dbev
->set_func_scope (true);
2759 // function found, set module
2760 module
= func
->module
;
2761 int ix
= module
->loadobject
->seg_idx
;
2762 if (dbev
->get_lo_expand (ix
) == LIBEX_HIDE
)
2764 char *lo_name
= module
->loadobject
->get_name ();
2766 GTXT ("Error: No source or disassembly available for hidden object %s.\n"),
2773 Vector
<SourceFile
*> *sources
= func
->get_sources ();
2775 if (sources
== NULL
)
2777 fitem
= func
->getDefSrc ();
2778 found
= (func
->line_first
> 0)
2779 && strcmp (basename (srcFile
),
2780 basename (fitem
->get_name ())) == 0;
2784 Vec_loop (SourceFile
*, sources
, index
, fitem
)
2786 if (strcmp (basename (srcFile
), basename (fitem
->get_name ())) == 0)
2795 fprintf (stderr
, GTXT ("Error: Source file context %s does not contribute to function `%s'.\n"),
2803 // function not found
2804 if (sel
&& strrchr (sel
, ':'))
2806 // 'sel' was "@seg_num:address" or "file_name:address"
2808 GTXT ("Error: No function with given name `%s %s' found.\n"),
2812 // search for a file of that name
2813 if (!dbeSession
->find_obj (dis_file
, inp_file
, obj
, name
, sel
,
2814 Histable::MODULE
, xdefault
))
2818 { // neither function nor file found
2819 fprintf (stderr
, GTXT ("Error: No function or file with given name `%s' found.\n"),
2825 module
= (Module
*) obj
;
2826 int ix
= module
->loadobject
->seg_idx
;
2827 if (dbev
->get_lo_expand (ix
) == LIBEX_HIDE
)
2829 char *lo_name
= module
->loadobject
->get_name ();
2830 fprintf (stderr
, GTXT ("Error: No source or disassembly available for hidden object %s.\n"),
2838 if (module
== NULL
|| module
->get_name () == NULL
)
2840 fprintf (stderr
, GTXT ("Error: Object name not recorded in experiment\n"));
2843 module
->read_stabs ();
2845 if (!isDisasm
&& (module
->file_name
== NULL
2846 || (module
->flags
& MOD_FLAG_UNKNOWN
) != 0
2847 || *module
->file_name
== 0))
2849 fprintf (stderr
, GTXT ("Error: Source location not recorded in experiment\n"));
2853 MetricList
*metric_list
= dbev
->get_metric_list (MET_NORMAL
);
2854 int sort_ref_index
= metric_list
->get_sort_ref_index ();
2856 metric_list
->set_sort_ref_index (-1);
2858 // Ask DbeView to generate function-level data
2859 // MSI: I think this is used only to get totals to compute percentages
2860 hist_data
= dbev
->get_hist_data (metric_list
, Histable::FUNCTION
, 0,
2862 MetricList
*nmlist
= hist_data
->get_metric_list ();
2863 metric_list
->set_sort_ref_index (sort_ref_index
);
2864 if (nmlist
->get_items ()->size () != 0
2865 && hist_data
->get_status () != Hist_data::SUCCESS
)
2867 errstr
= DbeView::status_str (DbeView::DBEVIEW_NO_DATA
);
2870 fprintf (stderr
, GTXT ("Error: %s\n"), errstr
);
2876 marks
= new Vector
<int>;
2879 threshold
= dbev
->get_thresh_dis ();
2880 compcom_bits
= dbev
->get_dis_compcom ();
2881 src_visible
= dbev
->get_src_visible ();
2882 hex_visible
= dbev
->get_hex_visible ();
2883 srcmetrics_visible
= dbev
->get_srcmetric_visible ();
2887 threshold
= dbev
->get_thresh_src ();
2888 compcom_bits
= dbev
->get_src_compcom ();
2889 src_visible
= SRC_NA
;
2890 hex_visible
= false;
2891 srcmetrics_visible
= false;
2894 dump_anno_file (out_file
, isDisasm
? Histable::INSTR
: Histable::LINE
,
2895 module
, dbev
, nmlist
, hist_data
->get_totals ()->value
,
2896 srcFile
, func
, marks
, threshold
, compcom_bits
,
2897 src_visible
, hex_visible
, srcmetrics_visible
);
2901 errstr
= module
->anno_str ();
2904 fprintf (stderr
, GTXT ("Error: %s\n"), errstr
);
2911 print_html_title (FILE *out_file
, char *title
)
2913 // This will print a header row for the report
2914 fprintf (out_file
, "<html><title>%s</title>\n", title
);
2915 fprintf (out_file
, "<center><h3>%s</h3></center>\n", title
);
2919 print_html_label (FILE *out_file
, MetricList
*metrics_list
)
2923 // This will print a header row for the metrics
2924 Vector
<Metric
*> *mlist
= metrics_list
->get_items ();
2925 mlist_sz
= mlist
->size ();
2927 fprintf (out_file
, "<style type=\"text/css\">\n");
2928 fprintf (out_file
, "<!--\nBODY\n");
2929 fprintf (out_file
, ".th_C { text-align:center; background-color:lightgoldenrodyellow; }\n");
2930 fprintf (out_file
, ".th_CG { text-align:center; background-color:#ffff33; }\n");
2931 fprintf (out_file
, ".th_L { text-align:left; background-color:lightgoldenrodyellow; }\n");
2932 fprintf (out_file
, ".th_LG { text-align:left; background-color:#ffff33; }\n");
2933 fprintf (out_file
, ".td_R { text-align:right; }\n");
2934 fprintf (out_file
, ".td_RG { text-align:right; background-color:#ffff33; }\n");
2935 fprintf (out_file
, ".td_L { text-align:left; }\n");
2936 fprintf (out_file
, ".td_LG { text-align:left; background-color:#ffff33; }\n");
2937 fprintf (out_file
, "-->\n</style>");
2938 fprintf (out_file
, "<center><table border=1 cellspacing=2>\n<tr>");
2940 for (int index
= 0; index
< mlist_sz
; index
++)
2942 Metric
*mitem
= mlist
->fetch (index
);
2944 if (mitem
->is_visible ())
2946 if (mitem
->is_tvisible ())
2948 if (mitem
->is_pvisible ())
2952 char *name
= strdup (mitem
->get_name ());
2953 char *name2
= split_metric_name (name
);
2954 const char *style
= index
== metrics_list
->get_sort_ref_index () ? "G" : "";
2956 // start the column, with colspan setting, legend, and sort metric indicator
2959 if (mitem
->get_vtype () == VT_LABEL
)
2960 // left-adjust the name metric
2962 "<th class=\"th_L%s\">%s <br>%s %s <br>%s </th>",
2963 style
, mitem
->legend
== NULL
? " " : mitem
->legend
,
2964 (index
== metrics_list
->get_sort_ref_index ()) ? "∇" : " ",
2965 name
, name2
== NULL
? " " : name2
);
2967 // but center the others
2969 "<th class=\"th_C%s\">%s <br>%s %s <br>%s </th>",
2970 style
, mitem
->legend
== NULL
? " " : mitem
->legend
,
2971 (index
== metrics_list
->get_sort_ref_index ()) ?
2972 "∇" : " ",
2973 name
, name2
== NULL
? NTXT (" ") : name2
);
2976 // name metric can't span columns
2978 "<th colspan=%d class=\"th_C%s\">%s <br>%s %s <br>%s </th>",
2980 mitem
->legend
== NULL
? " " : mitem
->legend
,
2981 index
== metrics_list
->get_sort_ref_index () ?
2982 "∇" : " ",
2983 name
, name2
== NULL
? " " : name2
);
2988 // end this row, start the units row
2989 fprintf (out_file
, NTXT ("</tr>\n<tr>"));
2991 // now do the units row
2992 for (int index
= 0; index
< mlist_sz
; index
++)
2994 Metric
*mitem
= mlist
->fetch (index
);
2995 const char *style
= index
== metrics_list
->get_sort_ref_index () ? "G" : "";
2997 if (mitem
->is_tvisible ())
2998 fprintf (out_file
, "<th class=\"th_C%s\"> (%s)</th>", style
,
3000 if (mitem
->is_visible ())
3002 if (mitem
->get_abbr_unit () == NULL
)
3003 fprintf (out_file
, "<th class=\"th_C%s\"> </th>", style
);
3005 fprintf (out_file
, "<th class=\"th_C%s\">(%s)</th>", style
,
3006 mitem
->get_abbr_unit () == NULL
? " "
3007 : mitem
->get_abbr_unit ());
3009 if (mitem
->is_pvisible ())
3010 fprintf (out_file
, "<th class=\"th_C%s\"> (%%)</th>", style
);
3012 fprintf (out_file
, NTXT ("</tr>\n"));
3016 print_html_content (FILE *out_file
, Hist_data
*data
, MetricList
*metrics_list
,
3017 int limit
, Histable::NameFormat nfmt
)
3019 Hist_data::HistItem
*item
;
3021 // printing contents.
3022 for (int i
= 0; i
< limit
; i
++)
3024 item
= data
->fetch (i
);
3025 print_html_one (out_file
, data
, item
, metrics_list
, nfmt
);
3030 print_html_one (FILE *out_file
, Hist_data
*data
, Hist_data::HistItem
*item
,
3031 MetricList
*metrics_list
, Histable::NameFormat nfmt
)
3035 int visible
, tvisible
, pvisible
;
3039 fprintf (out_file
, NTXT ("<tr>"));
3040 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
3042 visible
= mitem
->is_visible ();
3043 tvisible
= mitem
->is_tvisible ();
3044 pvisible
= mitem
->is_pvisible ();
3045 const char *style
= index
== metrics_list
->get_sort_ref_index () ? "G" : "";
3049 value
= &(item
->value
[index
]);
3050 if (value
->ll
== 0LL)
3052 "<td class=\"td_R%s\"><tt>0. </tt></td>",
3055 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%4.3lf</tt></td>",
3056 style
, 1.e
-6 * value
->ll
/ dbeSession
->get_clock (-1));
3061 if (mitem
->get_vtype () == VT_LABEL
)
3063 value
= &(item
->value
[index
]);
3065 if (value
->tag
== VT_OFFSET
)
3066 r
= ((DataObject
*) (item
->obj
))->get_offset_name ();
3068 r
= item
->obj
->get_name (nfmt
);
3069 char *n
= html_ize_name (r
);
3070 fprintf (out_file
, NTXT ("<td class=\"td_L%s\">%s</td>"), style
, n
);
3075 value
= &(item
->value
[index
]);
3079 if (value
->d
== 0.0)
3081 "<td class=\"td_R%s\"><tt>0. </tt></td>",
3085 "<td class=\"td_R%s\"><tt>%4.3lf</tt></td>", style
,
3089 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%d</tt></td>",
3093 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%lld</td></tt>",
3097 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%llu</td></tt>",
3102 "<td class=\"td_R%s\"><tt>%u:0x%08x</tt></td>", style
,
3103 ADDRESS_SEG (value
->ll
), ADDRESS_OFF (value
->ll
));
3106 if (value
->f
== 0.0)
3108 "<td class=\"td_R%s\"><tt>0. </tt></td>",
3112 "<td class=\"td_R%s\"><tt>%4.3f</tt></td>",
3116 fprintf (out_file
, "<td class=\"td_R%s\"><tt>%d</tt></td>",
3119 // ignoring the following cases (why?)
3130 percent
= data
->get_percentage (item
->value
[index
].to_double (), index
);
3132 // adjust to change format from xx.yy%
3133 fprintf (out_file
, "<td class=\"td_R%s\">0. </td>",
3136 // adjust format below to change format from xx.yy%
3137 fprintf (out_file
, "<td class=\"td_R%s\">%3.2f</td>", style
,
3141 fprintf (out_file
, NTXT ("</tr>\n"));
3145 print_html_trailer (FILE *out_file
)
3147 fprintf (out_file
, NTXT ("</table></center></html>\n"));
3153 size_t len
= strlen (s
);
3160 print_delim_label (FILE *out_file
, MetricList
*metrics_list
, char delim
)
3162 char line0
[2 * MAX_LEN
], line1
[2 * MAX_LEN
];
3163 char line2
[2 * MAX_LEN
], line3
[2 * MAX_LEN
];
3166 // This will print four header rows for the metrics
3171 Vector
<Metric
*> *mlist
= metrics_list
->get_items ();
3172 for (int index
= 0, mlist_sz
= mlist
->size (); index
< mlist_sz
; index
++)
3174 Metric
*mitem
= mlist
->fetch (index
);
3175 if (!(mitem
->is_visible () || mitem
->is_tvisible ()
3176 || mitem
->is_pvisible ()))
3178 char *name
= strdup (mitem
->get_name ());
3179 char *name2
= split_metric_name (name
);
3181 if (mitem
->is_tvisible ())
3183 len
= strlen (line0
);
3184 snprintf (line0
+ len
, sizeof (line0
) - len
, NTXT ("\"%s\"%c"),
3185 mitem
->legend
== NULL
? NTXT ("") : mitem
->legend
, delim
);
3186 len
= strlen (line1
);
3187 snprintf (line1
+ len
, sizeof (line1
) - len
, NTXT ("\"%s\"%c"),
3189 len
= strlen (line2
);
3190 snprintf (line2
+ len
, sizeof (line2
) - len
, NTXT ("\"%s\"%c"),
3191 name2
== NULL
? NTXT ("") : name2
, delim
);
3192 len
= strlen (line3
);
3193 if (index
== metrics_list
->get_sort_ref_index ())
3194 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\"V %s\"%c"),
3195 GTXT ("(sec.)"), delim
);
3197 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\" %s\"%c"),
3198 GTXT ("(sec.)"), delim
);
3200 if (mitem
->is_visible ())
3202 len
= strlen (line0
);
3203 snprintf (line0
+ len
, sizeof (line0
) - len
, "\"%s\"%c",
3204 mitem
->legend
== NULL
? "" : mitem
->legend
, delim
);
3206 len
= strlen (line1
);
3207 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%s\"%c",
3210 len
= strlen (line2
);
3211 snprintf (line2
+ len
, sizeof (line2
) - len
, "\"%s\"%c",
3212 name2
== NULL
? NTXT ("") : name2
, delim
);
3214 len
= strlen (line3
);
3215 char *au
= mitem
->get_abbr_unit ();
3217 if (index
== metrics_list
->get_sort_ref_index ())
3220 snprintf (line3
+ len
, sizeof (line3
) - len
, "\"V \"%c", delim
);
3222 snprintf (line3
+ len
, sizeof (line3
) - len
, "\"V (%s)\"%c",
3228 snprintf (line3
+ len
, sizeof (line3
) - len
, "\" \"%c",
3231 snprintf (line3
+ len
, sizeof (line3
) - len
, "\" (%s)\"%c",
3235 if (mitem
->is_pvisible ())
3237 len
= strlen (line0
);
3238 snprintf (line0
+ len
, sizeof (line0
) - len
, NTXT ("\"%s\"%c"),
3239 mitem
->legend
== NULL
? NTXT ("") : mitem
->legend
, delim
);
3241 len
= strlen (line1
);
3242 snprintf (line1
+ len
, sizeof (line1
) - len
, NTXT ("\"%s\"%c"),
3245 len
= strlen (line2
);
3246 snprintf (line2
+ len
, sizeof (line2
) - len
, NTXT ("\"%s\"%c"),
3247 name2
== NULL
? NTXT ("") : name2
, delim
);
3249 len
= strlen (line3
);
3250 if (index
== metrics_list
->get_sort_ref_index ())
3251 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\"V %s\"%c"),
3252 NTXT ("%%"), delim
);
3254 snprintf (line3
+ len
, sizeof (line3
) - len
, NTXT ("\" %s\"%c"),
3255 NTXT ("%%"), delim
);
3259 // now remove the trailing delimiter, and print the four lines
3260 fprintf (out_file
, NTXT ("%s\n"), del_delim (line0
));
3261 fprintf (out_file
, NTXT ("%s\n"), del_delim (line1
));
3262 fprintf (out_file
, NTXT ("%s\n"), del_delim (line2
));
3263 fprintf (out_file
, NTXT ("%s\n"), del_delim (line3
));
3267 print_delim_content (FILE *out_file
, Hist_data
*data
, MetricList
*metrics_list
,
3268 int limit
, Histable::NameFormat nfmt
, char delim
)
3270 Hist_data::HistItem
*item
;
3273 // printing contents.
3274 for (i
= 0; i
< limit
; i
++)
3276 item
= data
->fetch (i
);
3277 print_delim_one (out_file
, data
, item
, metrics_list
, nfmt
, delim
);
3282 print_delim_trailer (FILE */
*out_file*/
, char /*delim*/) { }
3284 // EUGENE does this function work properly when "-compare ratio" is used?
3285 // how about when the ratio is nonzero-divided-by-zero?
3286 // EUGENE actually, review this entire file
3289 print_delim_one (FILE *out_file
, Hist_data
*data
, Hist_data::HistItem
*item
,
3290 MetricList
*metrics_list
, Histable::NameFormat nfmt
,
3295 int visible
, tvisible
, pvisible
;
3300 char line1
[2 * MAX_LEN
];
3302 Vec_loop (Metric
*, metrics_list
->get_items (), index
, mitem
)
3304 visible
= mitem
->is_visible ();
3305 tvisible
= mitem
->is_tvisible ();
3306 pvisible
= mitem
->is_pvisible ();
3309 value
= &(item
->value
[index
]);
3310 len
= strlen (line1
);
3311 if (value
->ll
== 0LL)
3312 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c", delim
);
3314 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%4.3lf\"%c",
3315 1.e
-6 * value
->ll
/ dbeSession
->get_clock (-1),
3321 len
= strlen (line1
);
3322 if (mitem
->get_vtype () == VT_LABEL
)
3324 value
= &(item
->value
[index
]);
3326 if (value
->tag
== VT_OFFSET
)
3327 r
= ((DataObject
*) (item
->obj
))->get_offset_name ();
3329 r
= item
->obj
->get_name (nfmt
);
3330 char *p
= csv_ize_name (r
, delim
);
3331 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%s\"%c", p
, delim
);
3336 value
= &(item
->value
[index
]);
3340 if (value
->d
== 0.0)
3341 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c",
3344 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%4.3lf\"%c",
3348 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%d\"%c",
3352 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%lld\"%c",
3356 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%llu\"%c",
3360 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%u:0x%08x\"%c",
3361 ADDRESS_SEG (value
->ll
),
3362 ADDRESS_OFF (value
->ll
), delim
);
3365 if (value
->f
== 0.0)
3366 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c",
3369 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%4.3f\"%c",
3373 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%d\"%c",
3376 // ignoring the following cases (why?)
3387 len
= strlen (line1
);
3388 percent
= data
->get_percentage (item
->value
[index
].to_double (), index
);
3390 // adjust to change format from xx.yy%
3391 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"0.\"%c", delim
);
3393 // adjust format below to change format from xx.yy%
3394 snprintf (line1
+ len
, sizeof (line1
) - len
, "\"%3.2f\"%c",
3395 (100.0 * percent
), delim
);
3398 fprintf (out_file
, NTXT ("%s\n"), del_delim (line1
));
3402 html_ize_name (char *name
)
3405 for (size_t i
= 0; i
< strlen (name
); i
++)
3409 case ' ': sb
.append (NTXT (" "));
3411 case '"': sb
.append (NTXT ("""));
3413 case '&': sb
.append (NTXT ("&"));
3415 case '<': sb
.append (NTXT ("<"));
3417 case '>': sb
.append (NTXT (">"));
3419 default: sb
.append (name
[i
]);
3423 char *ret
= sb
.toString ();
3428 csv_ize_name (char *name
, char /*delim*/)
3431 for (size_t i
= 0; i
< strlen (name
); i
++)
3432 sb
.append (name
[i
]);
3433 char *ret
= sb
.toString ();
3437 // Split a metric name into two parts, replacing a blank with
3438 // a zero and returning pointer to the rest of the string, or
3439 // leaving the string unchanged, and returning NULL;
3442 split_metric_name (char *name
)
3444 // figure out the most even split of the name
3445 size_t len
= strlen (name
);
3446 char *middle
= &name
[len
/ 2];
3448 // find the first blank
3449 char *first
= strchr (name
, (int) ' ');
3450 if (first
== NULL
) // no blanks
3456 p
= strchr (p
+ 1, (int) ' ');
3470 // pick the better of the two
3472 int f
= (int) (middle
- first
);
3473 int l
= (int) (last
- middle
);
3474 if ((first
== last
) || (f
<= l
))